+ |
+ pg_group
+ groups of database users
+
+
|
pg_indexes
indexes
currently prepared transactions
+ |
+ pg_roles
+ database roles
+
+
|
pg_rules
rules
parameter settings
+ |
+ pg_shadow
+ database users
+
+
|
pg_stats
planner statistics
+
+
pg_group
+
+
+
+
+ The view pg_group exists for backwards
+ compatibility: it emulates a catalog that existed in
+
PostgreSQL before version 8.1.
+ It shows the names and members of all roles that are marked as not
+ rolcanlogin>, which is an approximation to the set
+ of roles that are being used as groups.
+
+
+
+
pg_group> Columns
+
+
+
+ |
+ Name
+ Type
+ References
+ Description
+
+
+
+
+ |
+ groname
+ name
+ pg_authid .rolname
+ Name of the group
+
+
+ |
+ grosysid
+ oid
+ pg_authid .oid
+ ID of this group
+
+
+ |
+ grolist
+ oid[]
+ pg_authid .oid
+ An array containing the IDs of the roles in this group
+
+
+
+
+
+
+
pg_indexes
|
owner
name
- shadow">pg_shadow .usename
+ authid">pg_authid .rolname
Name of the user that executed the transaction
+
+
pg_roles
+
+
+
+
+ The view pg_roles provides access to
+ information about database roles. This is simply a publicly
+ readable view of
+ pg_authid
+ that blanks out the password field.
+
+
+
+
pg_roles> Columns
+
+
+
+ |
+ Name
+ Type
+ References
+ Description
+
+
+
+
+ |
+ rolname
+ name
+
+ Role name
+
+
+ |
+ rolsuper
+ bool
+
+ Role has superuser privileges
+
+
+ |
+ rolcreaterole
+ bool
+
+ Role may create more roles
+
+
+ |
+ rolcreatedb
+ bool
+
+ Role may create databases
+
+
+ |
+ rolcatupdate
+ bool
+
+
+ Role may update system catalogs directly. (Even a superuser may not do
+ this unless this column is true.)
+
+
+
+ |
+ rolcanlogin
+ bool
+
+
+ Role may log in, that is, this role can be given as the initial
+ session authorization identifier.
+
+
+
+ |
+ rolpassword
+ text
+
+ Not the password (always reads as ********>)
+
+
+ |
+ rolvaliduntil
+ timestamptz
+
+ Password expiry time (only used for password authentication);
+ NULL if no expiration
+
+
+ |
+ rolconfig
+ text[]
+
+ Session defaults for run-time configuration variables
+
+
+
+
+
+
+
pg_rules
+
+
pg_shadow
+
+
+
+
+ The view pg_shadow exists for backwards
+ compatibility: it emulates a catalog that existed in
+
PostgreSQL before version 8.1.
+ It shows properties of all roles that are marked as
+ rolcanlogin>.
+
+
+ The name stems from the fact that this table
+ should not be readable by the public since it contains passwords.
+ pg_user
+ is a publicly readable view on
+ pg_shadow that blanks out the password field.
+
+
+
+
pg_shadow> Columns
+
+
+
+ |
+ Name
+ Type
+ References
+ Description
+
+
+
+
+ |
+ usename
+ name
+ pg_authid .rolname
+ User name
+
+
+ |
+ usesysid
+ oid
+ pg_authid .oid
+ ID of this user
+
+
+ |
+ usecreatedb
+ bool
+
+ User may create databases
+
+
+ |
+ usesuper
+ bool
+
+ User is a superuser
+
+
+ |
+ usecatupd
+ bool
+
+
+ User may update system catalogs. (Even a superuser may not do
+ this unless this column is true.)
+
+
+
+ |
+ passwd
+ text
+
+ Password (possibly encrypted)
+
+
+ |
+ valuntil
+ abstime
+
+ Password expiry time (only used for password authentication)
+
+
+ |
+ useconfig
+ text[]
+
+ Session defaults for run-time configuration variables
+
+
+
+
+
+
+
pg_stats
|
tableowner
name
- shadow">pg_shadow .usename
+ authid">pg_authid .rolname
name of table's owner
|
The view pg_user provides access to
information about database users. This is simply a publicly
readable view of
- catalog-pg-shadow">pg_shadow
+ view-pg-shadow">pg_shadow
that blanks out the password field.
|
viewowner
name
- shadow">pg_shadow .usename
+ authid">pg_authid .rolname
name of view's owner
|
has_table_privilege checks whether a user
can access a table in a particular way. The user can be
- specified by name or by ID
- (pg_user.usesys id ), or if the argument is
+ specified by name or by O ID
+ (pg_authid.o id ), or if the argument is
omitted
current_user is assumed. The table can be specified
by name or by OID. (Thus, there are actually six variants of
in it refer to the relation indicated by the second parameter
|
-
pg_get_userbyid (user id )
+
pg_get_userbyid (role id )
name
- get user name with given ID
+ get role name with given ID
|
pg_get_serial_sequence (table_name , column_name )
pg_get_userbyid
- extracts a user's name given a user ID number .
+ extracts a role's name given its OID .
pg_get_serial_sequence
fetches the name of the sequence associated with a serial or
bigserial column. The name is suitably formatted
* 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
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 */
*/
GlobalTransaction
MarkAsPreparing(TransactionId xid, const char *gid,
- TimestampTz prepared_at, AclI d owner, Oid databaseid)
+ TimestampTz prepared_at, Oi d owner, Oid databaseid)
{
GlobalTransaction gxact;
int i;
* Locate the prepared transaction and mark it busy for COMMIT or PREPARE.
*/
static GlobalTransaction
-LockGXact(const char *gid, AclI d user)
+LockGXact(const char *gid, Oi d user)
{
int i;
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
TIMESTAMPTZOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
- INT4 OID, -1, 0);
+ OID OID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
OIDOID, -1, 0);
values[0] = TransactionIdGetDatum(gxact->proc.xid);
values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid));
values[2] = TimestampTzGetDatum(gxact->prepared_at);
- values[3] = Int32 GetDatum(gxact->owner);
+ values[3] = ObjectId GetDatum(gxact->owner);
values[4] = ObjectIdGetDatum(gxact->proc.databaseId);
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
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 */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* 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;
/* 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 */
{
TransactionState p = CurrentTransactionState;
TransactionState s;
- AclId currentUser;
+ Oid currentUser;
/*
* At present, GetUserId cannot fail, but let's not assume that. Get
#
# 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 $
#
#-------------------------------------------------------------------------
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)
*
*
* 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.
#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"
* all granted privileges appear to flow from the object owner, and there
* are never multiple "original sources" of a privilege.
*/
-static AclI d
-select_grantor(AclI d ownerId)
+static Oi d
+select_grantor(Oi d ownerId)
{
- AclId grantorId;
+ Oid grantorId;
grantorId = GetUserId();
merge_acl_with_grant(Acl *old_acl, bool is_grant,
bool grant_option, DropBehavior behavior,
List *grantees, AclMode privileges,
- AclId grantor_uid, AclId owner_ui d)
+ Oid grantorId, Oid ownerI d)
{
unsigned modechg;
ListCell *j;
{
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 user s")));
+ errmsg("grant options can only be granted to role s")));
- aclitem. ai_grantor = grantor_ui d;
+ aclitem.ai_grantor = grantorI d;
/*
* The asymmetry in the conditions here comes from the spec. In
* 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_ui d, behavior);
+ newer_acl = aclupdate(new_acl, &aclitem, modechg, ownerI d, behavior);
/* avoid memory leak when there are many grantees */
pfree(new_acl);
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];
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];
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];
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];
* Note: for now, languages are treated as owned by the bootstrap
* user. We should add an owner column to pg_language instead.
*/
- ownerId = BOOTSTRAP_USESYS ID;
+ ownerId = BOOTSTRAP_SUPERUSER ID;
grantorId = select_grantor(ownerId);
/*
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];
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];
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.
*
}
-/* 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 user id)
+has_rolcatupdate(Oid role id)
{
- bool usecatupd ;
+ bool rolcatupdate ;
HeapTuple tuple;
- tuple = SearchSysCache(SHADOWSYS ID,
- ObjectIdGetDatum(user id),
+ tuple = SearchSysCache(AUTHO ID,
+ ObjectIdGetDatum(role id),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user with ID %u does not exist", user id)));
+ errmsg("role with OID %u does not exist", role id)));
- usecatupd = ((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd ;
+ rolcatupdate = ((Form_pg_authid) GETSTRUCT(tuple))->rolcatupdate ;
ReleaseSysCache(tuple);
- return usecatupd ;
+ return rolcatupdate ;
}
* below.
*/
AclMode
-pg_class_aclmask(Oid table_oid, AclId user id,
+pg_class_aclmask(Oid table_oid, Oid role id,
AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/*
* Must get the relation's tuple from pg_class
/*
* 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.
*
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
IsSystemClass(classForm) &&
classForm->relkind != RELKIND_VIEW &&
- !has_usecatupd(user id) &&
+ !has_rolcatupdate(role id) &&
!allowSystemTableMods)
{
#ifdef ACLDEBUG
/*
* Otherwise, superusers bypass all permission-checking.
*/
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
{
#ifdef ACLDEBUG
- elog(DEBUG2, "%u is superuser, home free", user id);
+ elog(DEBUG2, "OID %u is superuser, home free", role id);
#endif
ReleaseSysCache(tuple);
return mask;
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, user id, ownerId, mask, how);
+ result = aclmask(acl, role id, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
* Exported routine for examining a user's privileges for a database
*/
AclMode
-pg_database_aclmask(Oid db_oid, AclId user id,
+pg_database_aclmask(Oid db_oid, Oid role id,
AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return mask;
/*
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, user id, ownerId, mask, how);
+ result = aclmask(acl, role id, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
* Exported routine for examining a user's privileges for a function
*/
AclMode
-pg_proc_aclmask(Oid proc_oid, AclId user id,
+pg_proc_aclmask(Oid proc_oid, Oid role id,
AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return mask;
/*
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, user id, ownerId, mask, how);
+ result = aclmask(acl, role id, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
* Exported routine for examining a user's privileges for a language
*/
AclMode
-pg_language_aclmask(Oid lang_oid, AclId user id,
+pg_language_aclmask(Oid lang_oid, Oid role id,
AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return mask;
/*
errmsg("language with OID %u does not exist", lang_oid)));
/* XXX pg_language should have an owner column, but doesn't */
- ownerId = BOOTSTRAP_USESYS ID;
+ ownerId = BOOTSTRAP_SUPERUSER ID;
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
&isNull);
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, user id, ownerId, mask, how);
+ result = aclmask(acl, role id, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
* Exported routine for examining a user's privileges for a namespace
*/
AclMode
-pg_namespace_aclmask(Oid nsp_oid, AclId user id,
+pg_namespace_aclmask(Oid nsp_oid, Oid role id,
AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return mask;
/*
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, user id, ownerId, mask, how);
+ result = aclmask(acl, role id, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
* Exported routine for examining a user's privileges for a tablespace
*/
AclMode
-pg_tablespace_aclmask(Oid spc_oid, AclId user id,
+pg_tablespace_aclmask(Oid spc_oid, Oid role id,
AclMode mask, AclMaskHow how)
{
AclMode result;
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/*
* Only shared relations can be stored in global space; don't let even
return 0;
/* Otherwise, superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return mask;
/*
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, user id, ownerId, mask, how);
+ result = aclmask(acl, role id, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
* ACLCHECK_NO_PRIV).
*/
AclResult
-pg_class_aclcheck(Oid table_oid, AclId user id, AclMode mode)
+pg_class_aclcheck(Oid table_oid, Oid role id, AclMode mode)
{
- if (pg_class_aclmask(table_oid, user id, mode, ACLMASK_ANY) != 0)
+ if (pg_class_aclmask(table_oid, role id, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
* Exported routine for checking a user's access privileges to a database
*/
AclResult
-pg_database_aclcheck(Oid db_oid, AclId user id, AclMode mode)
+pg_database_aclcheck(Oid db_oid, Oid role id, AclMode mode)
{
- if (pg_database_aclmask(db_oid, user id, mode, ACLMASK_ANY) != 0)
+ if (pg_database_aclmask(db_oid, role id, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
* Exported routine for checking a user's access privileges to a function
*/
AclResult
-pg_proc_aclcheck(Oid proc_oid, AclId user id, AclMode mode)
+pg_proc_aclcheck(Oid proc_oid, Oid role id, AclMode mode)
{
- if (pg_proc_aclmask(proc_oid, user id, mode, ACLMASK_ANY) != 0)
+ if (pg_proc_aclmask(proc_oid, role id, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
* Exported routine for checking a user's access privileges to a language
*/
AclResult
-pg_language_aclcheck(Oid lang_oid, AclId user id, AclMode mode)
+pg_language_aclcheck(Oid lang_oid, Oid role id, AclMode mode)
{
- if (pg_language_aclmask(lang_oid, user id, mode, ACLMASK_ANY) != 0)
+ if (pg_language_aclmask(lang_oid, role id, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
* Exported routine for checking a user's access privileges to a namespace
*/
AclResult
-pg_namespace_aclcheck(Oid nsp_oid, AclId user id, AclMode mode)
+pg_namespace_aclcheck(Oid nsp_oid, Oid role id, AclMode mode)
{
- if (pg_namespace_aclmask(nsp_oid, user id, mode, ACLMASK_ANY) != 0)
+ if (pg_namespace_aclmask(nsp_oid, role id, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
* Exported routine for checking a user's access privileges to a tablespace
*/
AclResult
-pg_tablespace_aclcheck(Oid spc_oid, AclId user id, AclMode mode)
+pg_tablespace_aclcheck(Oid spc_oid, Oid role id, AclMode mode)
{
- if (pg_tablespace_aclmask(spc_oid, user id, mode, ACLMASK_ANY) != 0)
+ if (pg_tablespace_aclmask(spc_oid, role id, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
* Ownership check for a relation (specified by OID).
*/
bool
-pg_class_ownercheck(Oid class_oid, AclId user id)
+pg_class_ownercheck(Oid class_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(RELOID,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation with OID %u does not exist", class_oid)));
- owner_i d = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
+ ownerI d = ((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 user id)
+pg_type_ownercheck(Oid type_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(TYPEOID,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type with OID %u does not exist", type_oid)));
- owner_i d = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
+ ownerI d = ((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 user id)
+pg_oper_ownercheck(Oid oper_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(OPEROID,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator with OID %u does not exist", oper_oid)));
- owner_i d = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
+ ownerI d = ((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 user id)
+pg_proc_ownercheck(Oid proc_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(PROCOID,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function with OID %u does not exist", proc_oid)));
- owner_i d = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
+ ownerI d = ((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 user id)
+pg_namespace_ownercheck(Oid nsp_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(NAMESPACEOID,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema with OID %u does not exist", nsp_oid)));
- owner_i d = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
+ ownerI d = ((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 user id)
+pg_tablespace_ownercheck(Oid spc_oid, Oid role id)
{
Relation pg_tablespace;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple spctuple;
- int32 spcowner;
+ Oid spcowner;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
/* There's no syscache for pg_tablespace, so must look the hard way */
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 user id)
+pg_opclass_ownercheck(Oid opc_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(CLAOID,
errmsg("operator class with OID %u does not exist",
opc_oid)));
- owner_i d = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
+ ownerI d = ((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 user id)
+pg_database_ownercheck(Oid db_oid, Oid role id)
{
Relation pg_database;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple dbtuple;
- int32 dba;
+ Oid dba;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
/* There's no syscache for pg_database, so must look the hard way */
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 user id)
+pg_conversion_ownercheck(Oid conv_oid, Oid role id)
{
HeapTuple tuple;
- AclId owner_i d;
+ Oid ownerI d;
/* Superusers bypass all permission checking. */
- if (superuser_arg(user id))
+ if (superuser_arg(role id))
return true;
tuple = SearchSysCache(CONOID,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("conversion with OID %u does not exist", conv_oid)));
- owner_i d = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
+ ownerI d = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
ReleaseSysCache(tuple);
- return userid == owner_id ;
+ return is_member_of_role(roleid, ownerId) ;
}
#
#
# 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.
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
-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 '
*
* 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 $
*/
/*
CREATE VIEW applicable_roles AS
SELECT CAST(current_user AS sql_identifier) AS grantee,
- CAST(g.gro name AS sql_identifier) AS role_name,
- CAST('NO' AS character_data) AS is_grantable
+ CAST(a.rol name 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;
*/
CREATE VIEW column_privileges AS
- SELECT CAST(u_grantor.use name AS sql_identifier) AS grantor,
+ SELECT CAST(u_grantor.rol name 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,
CAST(pr.type AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesys id, pr.type, true))
+ makeaclitem(grantee.oid, u_grantor.o id, 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
- UNION ALL
- SELECT 0, grosysid, groname FROM pg_group
+ SELECT oid, rolname FROM pg_authid
UNION ALL
- SELECT 0, 0, 'PUBLIC'
- ) AS grantee (usesysid, grosys id, name),
+ SELECT 0, 'PUBLIC'
+ ) AS grantee (o id, name),
(SELECT 'SELECT' UNION ALL
SELECT 'INSERT' UNION ALL
SELECT 'UPDATE' UNION ALL
AND NOT a.attisdropped
AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesys id, pr.type, false))
- AND (u_grantor.use name = current_user
+ makeaclitem(grantee.oid, u_grantor.o id, pr.type, false))
+ AND (u_grantor.rol name = current_user
OR grantee.name = current_user
OR grantee.name = 'PUBLIC');
*/
CREATE VIEW enabled_roles AS
- SELECT CAST(g.gro name AS sql_identifier) AS role_name
- FROM pg_group g, pg_user u
- WHERE u.usesysid = ANY (g.grolist )
- AND u.use name = current_user;
+ SELECT CAST(a.rol name 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.rol name = current_user;
GRANT SELECT ON enabled_roles TO PUBLIC;
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,
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;
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,
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;
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
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;
*/
CREATE VIEW routine_privileges AS
- SELECT CAST(u_grantor.use name AS sql_identifier) AS grantor,
+ SELECT CAST(u_grantor.rol name 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,
CAST('EXECUTE' AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(p.proacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesys id, 'EXECUTE', true))
+ makeaclitem(grantee.oid, u_grantor.o id, '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
- UNION ALL
- SELECT 0, grosysid, groname FROM pg_group
+ SELECT oid, rolname FROM pg_authid
UNION ALL
- SELECT 0, 0, 'PUBLIC'
- ) AS grantee (usesysid, grosys id, name)
+ SELECT 0, 'PUBLIC'
+ ) AS grantee (o id, name)
WHERE p.pronamespace = n.oid
AND aclcontains(p.proacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesys id, 'EXECUTE', false))
- AND (u_grantor.use name = current_user
+ makeaclitem(grantee.oid, u_grantor.o id, 'EXECUTE', false))
+ AND (u_grantor.rol name = current_user
OR grantee.name = current_user
OR grantee.name = 'PUBLIC');
*/
CREATE VIEW table_privileges AS
- SELECT CAST(u_grantor.use name AS sql_identifier) AS grantor,
+ SELECT CAST(u_grantor.rol name 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,
CAST(pr.type AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesys id, pr.type, true))
+ makeaclitem(grantee.oid, u_grantor.o id, 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
- UNION ALL
- SELECT 0, grosysid, groname FROM pg_group
+ SELECT oid, rolname FROM pg_authid
UNION ALL
- SELECT 0, 0, 'PUBLIC'
- ) AS grantee (usesysid, grosys id, name),
+ SELECT 0, 'PUBLIC'
+ ) AS grantee (o id, name),
(SELECT 'SELECT' UNION ALL
SELECT 'DELETE' UNION ALL
SELECT 'INSERT' UNION ALL
WHERE c.relnamespace = nc.oid
AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesys id, pr.type, false))
- AND (u_grantor.use name = current_user
+ makeaclitem(grantee.oid, u_grantor.o id, pr.type, false))
+ AND (u_grantor.rol name = current_user
OR grantee.name = current_user
OR grantee.name = 'PUBLIC');
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
static void
recomputeNamespacePath(void)
{
- AclId userI d = GetUserId();
+ Oid rolei d = GetUserId();
char *rawname;
List *namelist;
List *oidlist;
/*
* Do nothing if path is already valid.
*/
- if (namespaceSearchPathValid && namespaceUser == userI d)
+ if (namespaceSearchPathValid && namespaceUser == rolei d)
return;
/* Need a modifiable copy of namespace_search_path string */
/* $user --- substitute namespace matching user name, if any */
HeapTuple tuple;
- tuple = SearchSysCache(SHADOWSYS ID,
- ObjectIdGetDatum(userI d),
+ tuple = SearchSysCache(AUTHO ID,
+ ObjectIdGetDatum(rolei d),
0, 0, 0);
if (HeapTupleIsValid(tuple))
{
- char *u name;
+ char *r name;
- uname = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->use name);
+ rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rol name);
namespaceId = GetSysCacheOid(NAMESPACENAME,
- CStringGetDatum(u name),
+ CStringGetDatum(r name),
0, 0, 0);
ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
- pg_namespace_aclcheck(namespaceId, userI d,
+ pg_namespace_aclcheck(namespaceId, rolei d,
ACL_USAGE) == ACLCHECK_OK)
oidlist = lappend_oid(oidlist, namespaceId);
}
0, 0, 0);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
- pg_namespace_aclcheck(namespaceId, userI d,
+ pg_namespace_aclcheck(namespaceId, rolei d,
ACL_USAGE) == ACLCHECK_OK)
oidlist = lappend_oid(oidlist, namespaceId);
}
/* Mark the path valid. */
namespaceSearchPathValid = true;
- namespaceUser = userI d;
+ namespaceUser = rolei d;
/* Clean up. */
pfree(rawname);
* that access the temp namespace for my own backend skip
* permissions checks on it.
*/
- namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYS ID);
+ namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSER ID);
/* Advance command counter to make namespace visible */
CommandCounterIncrement();
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
*/
Oid
ConversionCreate(const char *conname, Oid connamespace,
- AclI d conowner,
+ Oi d conowner,
int32 conforencoding, int32 contoencoding,
Oid conproc, bool def)
{
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] = Int32 GetDatum(conowner);
+ values[Anum_pg_conversion_conowner - 1] = ObjectId GetDatum(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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* ---------------
*/
Oid
-NamespaceCreate(const char *nspName, int32 ownerSys Id)
+NamespaceCreate(const char *nspName, Oid owner Id)
{
Relation nspdesc;
HeapTuple tup;
}
namestrcpy(&nname, nspName);
values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
- values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSys Id);
+ values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(owner Id);
nulls[Anum_pg_namespace_nspacl - 1] = 'n';
nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
*
*
* 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.
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 */
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 */
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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] = Int32 GetDatum(GetUserId());
+ values[Anum_pg_proc_proowner - 1] = ObjectId GetDatum(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);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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 */
*
* Copyright (c) 1996-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.15 2005/06/18 19:33:4 2 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.16 2005/06/28 05:08:5 2 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,
CREATE VIEW pg_prepared_xacts AS
SELECT P.transaction, P.gid, P.prepared,
- U.use name AS owner, D.datname AS database
+ U.rol name 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.usesys id
+ (transaction xid, gid text, prepared timestamptz, ownerid oid , dbid oid)
+ LEFT JOIN pg_authid U ON P.ownerid = U.o id
LEFT JOIN pg_database D ON P.dbid = D.oid;
CREATE VIEW pg_settings AS
D.datname AS datname,
pg_stat_get_backend_pid(S.backendid) AS procpid,
pg_stat_get_backend_userid(S.backendid) AS usesysid,
- U.use name AS usename,
+ U.rol name 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,
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.usesys id;
+ pg_stat_get_backend_userid(S.backendid) = U.o id;
CREATE VIEW pg_stat_database AS
SELECT
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.26 2005/04/14 20:03:2 3 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.27 2005/06/28 05:08:5 3 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
* Change aggregate owner
*/
void
-AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSys Id)
+AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwner Id)
{
Oid basetypeOid;
Oid procOid;
* 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 != newOwnerSys Id)
+ if (procForm->proowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- procForm->proowner = newOwnerSys Id;
+ procForm->proowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.12 2004/12/31 21:59:41 pgsq l Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.13 2005/06/28 05:08:53 tg l Exp $
*
*-------------------------------------------------------------------------
*/
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;
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;
RenameTableSpace(stmt->subname, stmt->newname);
break;
- case OBJECT_USER:
- RenameUser(stmt->subname, stmt->newname);
- break;
-
case OBJECT_TABLE:
case OBJECT_INDEX:
case OBJECT_COLUMN:
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- AclId newowner = get_usesysi d(stmt->newowner);
+ Oid newowner = get_roleid_checke d(stmt->newowner);
switch (stmt->objectType)
{
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
* Change conversion owner
*/
void
-AlterConversionOwner(List *name, AclId newOwnerSys Id)
+AlterConversionOwner(List *name, Oid newOwner Id)
{
Oid conversionOid;
HeapTuple tup;
* 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 != newOwnerSys Id)
+ if (convForm->conowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- convForm->conowner = newOwnerSys Id;
+ convForm->conowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
+#include "catalog/indexing.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
-#include "catalog/indexing.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
#include "commands/tablespace.h"
/* 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,
HeapScanDesc scan;
Relation rel;
Oid src_dboid;
- AclId src_owner;
+ Oid src_owner;
int src_encoding;
bool src_istemplate;
bool src_allowconn;
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;
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())
*/
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\"",
new_record[Anum_pg_database_datname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(dbname));
- new_record[Anum_pg_database_datdba - 1] = Int32 GetDatum(datdba);
+ new_record[Anum_pg_database_datdba - 1] = ObjectId GetDatum(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);
void
dropdb(const char *dbname)
{
- int4 db_owner;
- bool db_istemplate;
Oid db_id;
+ bool db_istemplate;
Relation pgdbrel;
SysScanDesc pgdbscan;
ScanKeyData key;
*/
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);
(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);
* ALTER DATABASE name OWNER TO newowner
*/
void
-AlterDatabaseOwner(const char *dbname, AclId newOwnerSys Id)
+AlterDatabaseOwner(const char *dbname, Oid newOwner Id)
{
HeapTuple tuple;
Relation rel;
* command to have succeeded. This is to be consistent with other
* objects.
*/
- if (datForm->datdba != newOwnerSys Id)
+ if (datForm->datdba != newOwnerId)
{
Datum repl_val[Natts_pg_database];
char repl_null[Natts_pg_database];
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_database_datdba - 1] = 'r';
- repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSys Id);
+ repl_val[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(newOwner Id);
/*
* Determine the modified ACL for the new owner. This is only
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- datForm->datdba, newOwnerSys Id);
+ datForm->datdba, newOwnerId);
repl_repl[Anum_pg_database_datacl - 1] = 'r';
repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl);
}
*/
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,
/* oid of the database */
if (dbIdP)
*dbIdP = HeapTupleGetOid(tuple);
- /* sys id of the owner */
+ /* o id of the owner */
if (ownerIdP)
*ownerIdP = dbform->datdba;
/* character encoding */
bool result = false;
HeapTuple utup;
- utup = SearchSysCache(SHADOWSYS ID,
- Int32 GetDatum(GetUserId()),
+ utup = SearchSysCache(AUTHO ID,
+ ObjectId GetDatum(GetUserId()),
0, 0, 0);
if (HeapTupleIsValid(utup))
{
- result = ((Form_pg_shadow) GETSTRUCT(utup))->use createdb;
+ result = ((Form_pg_authid) GETSTRUCT(utup))->rol createdb;
ReleaseSysCache(utup);
}
return result;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.61 2005/04/14 20:03:2 3 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.62 2005/06/28 05:08:5 3 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
* Change function owner
*/
void
-AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSys Id)
+AlterFunctionOwner(List *name, List *argtypes, Oid newOwner Id)
{
Oid procOid;
HeapTuple tup;
* 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 != newOwnerSys Id)
+ if (procForm->proowner != newOwnerId)
{
Datum repl_val[Natts_pg_proc];
char repl_null[Natts_pg_proc];
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_proc_proowner - 1] = 'r';
- repl_val[Anum_pg_proc_proowner - 1] = Int32GetDatum(newOwnerSys Id);
+ repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwner Id);
/*
* Determine the modified ACL for the new owner. This is only
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- procForm->proowner, newOwnerSys Id);
+ procForm->proowner, newOwnerId);
repl_repl[Anum_pg_proc_proacl - 1] = 'r';
repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl);
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.32 2005/04/14 20:03:2 3 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.33 2005/06/28 05:08:5 3 tgl Exp $
*
*-------------------------------------------------------------------------
*/
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 */
* Change opclass owner
*/
void
-AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSys Id)
+AlterOpClassOwner(List *name, const char *access_method, Oid newOwner Id)
{
Oid opcOid;
Oid amOid;
* 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 != newOwnerSys Id)
+ if (opcForm->opcowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- opcForm->opcowner = newOwnerSys Id;
+ opcForm->opcowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.21 2005/04/14 20:03:2 4 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.22 2005/06/28 05:08:5 4 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
*/
void
AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
- AclId newOwnerSys Id)
+ Oid newOwner Id)
{
Oid operOid;
HeapTuple tup;
* 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 != newOwnerSys Id)
+ if (oprForm->oprowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- oprForm->oprowner = newOwnerSys Id;
+ oprForm->oprowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
Oid namespaceId;
List *parsetree_list;
ListCell *parsetree_item;
- AclId owner_user id;
- AclId saved_user id;
+ Oid owner_u id;
+ Oid saved_u id;
AclResult aclresult;
- saved_user id = GetUserId();
+ saved_uid = GetUserId();
/*
* Figure out user identities.
if (!authId)
{
- owner_userid = saved_user id;
+ owner_uid = saved_u id;
}
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
* (This will revert to session user on error or at the end of
* this routine.)
*/
- SetUserId(owner_user id);
+ SetUserId(owner_uid);
}
else
{
const char *owner_name;
/* not superuser */
- owner_userid = saved_user id;
- owner_name = GetUserNameFromId(owner_user id);
+ owner_uid = saved_u id;
+ owner_name = GetUserNameFromId(owner_uid);
if (strcmp(authId, owner_name) != 0)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
/*
* Permissions checks.
*/
- aclresult = pg_database_aclcheck(MyDatabaseId, saved_user id, 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));
errdetail("The prefix \"pg_\" is reserved for system schemas.")));
/* Create the schema's namespace */
- namespaceId = NamespaceCreate(schemaName, owner_user id);
+ namespaceId = NamespaceCreate(schemaName, owner_uid);
/* Advance cmd counter to make the namespace visible */
CommandCounterIncrement();
PopSpecialNamespace(namespaceId);
/* Reset current user */
- SetUserId(saved_user id);
+ SetUserId(saved_uid);
}
* Change schema owner
*/
void
-AlterSchemaOwner(const char *name, AclId newOwnerSys Id)
+AlterSchemaOwner(const char *name, Oid newOwner Id)
{
HeapTuple tup;
Relation rel;
* 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 != newOwnerSys Id)
+ if (nspForm->nspowner != newOwnerId)
{
Datum repl_val[Natts_pg_namespace];
char repl_null[Natts_pg_namespace];
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_namespace_nspowner - 1] = 'r';
- repl_val[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(newOwnerSys Id);
+ repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwner Id);
/*
* Determine the modified ACL for the new owner. This is only
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- nspForm->nspowner, newOwnerSys Id);
+ nspForm->nspowner, newOwnerId);
repl_repl[Anum_pg_namespace_nspacl - 1] = 'r';
repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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 newOwnerSys Id);
+static void ATExecChangeOwner(Oid relationOid, Oid newOwner Id);
static void change_owner_recurse_to_sequences(Oid relationOid,
- int32 newOwnerSys Id);
+ Oid newOwner Id);
static void ATExecClusterOn(Relation rel, const char *indexName);
static void ATExecDropCluster(Relation rel);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
AlterTableCreateToastTable(RelationGetRelid(rel), false);
break;
case AT_ChangeOwner: /* ALTER OWNER */
- /* get_usesysid raises an error if no such user */
- ATExecChangeOwner(RelationGetRelid(rel), get_usesysi d(cmd->name));
+ ATExecChangeOwner(RelationGetRelid(rel),
+ get_roleid_checke d(cmd->name));
break;
case AT_ClusterOn: /* CLUSTER ON */
ATExecClusterOn(rel, cmd->name);
* ALTER TABLE OWNER
*/
static void
-ATExecChangeOwner(Oid relationOid, int32 newOwnerSys Id)
+ATExecChangeOwner(Oid relationOid, Oid newOwner Id)
{
Relation target_rel;
Relation class_rel;
* 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 != newOwnerSys Id)
+ if (tuple_class->relowner != newOwnerId)
{
Datum repl_val[Natts_pg_class];
char repl_null[Natts_pg_class];
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_class_relowner - 1] = 'r';
- repl_val[Anum_pg_class_relowner - 1] = Int32GetDatum(newOwnerSys Id);
+ repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwner Id);
/*
* Determine the modified ACL for the new owner. This is only
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- tuple_class->relowner, newOwnerSys Id);
+ tuple_class->relowner, newOwnerId);
repl_repl[Anum_pg_class_relacl - 1] = 'r';
repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
}
/* For each index, recursively change its ownership */
foreach(i, index_oid_list)
- ATExecChangeOwner(lfirst_oid(i), newOwnerSys Id);
+ ATExecChangeOwner(lfirst_oid(i), newOwnerId);
list_free(index_oid_list);
}
{
/* If it has a toast table, recurse to change its ownership */
if (tuple_class->reltoastrelid != InvalidOid)
- ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSys Id);
+ ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId);
/* If it has dependent sequences, recurse to change them too */
- change_owner_recurse_to_sequences(relationOid, newOwnerSys Id);
+ change_owner_recurse_to_sequences(relationOid, newOwnerId);
}
}
* ownership.
*/
static void
-change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSys Id)
+change_owner_recurse_to_sequences(Oid relationOid, Oid newOwner Id)
{
Relation depRel;
SysScanDesc scan;
}
/* We don't need to close the sequence while we alter it. */
- ATExecChangeOwner(depForm->objid, newOwnerSys Id);
+ ATExecChangeOwner(depForm->objid, newOwnerId);
/* Now we can close it. Keep the lock till end of transaction. */
relation_close(seqRel, NoLock);
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
Oid tablespaceoid;
char *location;
char *linkloc;
- AclId owneri d;
+ Oid ownerI d;
/* validate */
/* 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
- owneri d = GetUserId();
+ ownerI d = GetUserId();
/* Unix-ify the offered path, and strip any trailing slashes */
location = pstrdup(stmt->location);
values[Anum_pg_tablespace_spcname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
values[Anum_pg_tablespace_spcowner - 1] =
- Int32GetDatum(owneri d);
+ ObjectIdGetDatum(ownerI d);
values[Anum_pg_tablespace_spclocation - 1] =
DirectFunctionCall1(textin, CStringGetDatum(location));
nulls[Anum_pg_tablespace_spcacl - 1] = 'n';
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);
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 */
* Change tablespace owner
*/
void
-AlterTableSpaceOwner(const char *name, AclId newOwnerSys Id)
+AlterTableSpaceOwner(const char *name, Oid newOwner Id)
{
Relation rel;
ScanKeyData entry[1];
* 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 != newOwnerSys Id)
+ if (spcForm->spcowner != newOwnerId)
{
Datum repl_val[Natts_pg_tablespace];
char repl_null[Natts_pg_tablespace];
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_tablespace_spcowner - 1] = 'r';
- repl_val[Anum_pg_tablespace_spcowner - 1] = Int32GetDatum(newOwnerSys Id);
+ repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwner Id);
/*
* Determine the modified ACL for the new owner. This is only
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- spcForm->spcowner, newOwnerSys Id);
+ spcForm->spcowner, newOwnerId);
repl_repl[Anum_pg_tablespace_spcacl - 1] = 'r';
repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl);
}
*
*
* 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
* Change the owner of a type.
*/
void
-AlterTypeOwner(List *names, AclId newOwnerSys Id)
+AlterTypeOwner(List *names, Oid newOwner Id)
{
TypeName *typename;
Oid typeOid;
* 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 != newOwnerSys Id)
+ if (typTup->typowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
* Modify the owner --- okay to scribble on typTup because it's a
* copy
*/
- typTup->typowner = newOwnerSys Id;
+ typTup->typowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
/*-------------------------------------------------------------------------
*
* user.c
- * Commands for manipulating users and groups .
+ * Commands for manipulating roles (formerly called users) .
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.151 2005/04/14 20:03:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.152 2005/06/28 05:08:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "access/heapam.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_shadow.h"
-#include "catalog/pg_type.h"
#include "commands/user.h"
#include "libpq/crypt.h"
#include "miscadmin.h"
-#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/catcache.h"
#include "utils/flatfiles.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
extern bool Password_encryption;
-
-static void CheckPgUserAclNotNull(void);
-static void UpdateGroupMembership(Relation group_rel, HeapTuple group_tuple,
- List *members);
-static IdList *IdListToArray(List *members);
-static List *IdArrayToList(IdList *oldarray);
+static List *roleNamesToIds(List *memberNames);
+static void AddRoleMems(const char *rolename, Oid roleid,
+ List *memberNames, List *memberIds,
+ Oid grantorId, bool admin_opt);
+static void DelRoleMems(const char *rolename, Oid roleid,
+ List *memberNames, List *memberIds,
+ bool admin_opt);
/*
- * CREATE USER
+ * CREATE ROLE
*/
void
-CreateUser(CreateUser Stmt *stmt)
+CreateRole(CreateRole Stmt *stmt)
{
- Relation pg_shadow_rel;
- TupleDesc pg_shadow_dsc;
- HeapScanDesc scan;
+ Relation pg_authid_rel;
+ TupleDesc pg_authid_dsc;
HeapTuple tuple;
- Datum new_record[Natts_pg_shadow];
- char new_record_nulls[Natts_pg_shadow];
- bool user_exists = false,
- sysid_exists = false,
- havesysid = false;
- int max_id;
+ Datum new_record[Natts_pg_authid];
+ char new_record_nulls[Natts_pg_authid];
+ Oid roleid;
ListCell *item;
ListCell *option;
- char *password = NULL; /* PostgreSQL user password */
+ char *password = NULL; /* user password */
bool encrypt_password = Password_encryption; /* encrypt password? */
char encrypted_password[MD5_PASSWD_LEN + 1];
- int sysid = 0; /* PgSQL system id (valid if havesysid) */
+ bool issuper = false; /* Make the user a superuser? */
+ bool createrole = false; /* Can this user create roles? */
bool createdb = false; /* Can the user create databases? */
- bool createuser = false; /* Can this user create users? */
- List *groupElts = NIL; /* The groups the user is a member of */
+ bool canlogin = false; /* Can this user login? */
+ List *roleElts = NIL; /* roles the user is a member of */
+ List *rolememElts = NIL; /* roles which will be members of this role */
char *validUntil = NULL; /* The time the login is valid
* until */
DefElem *dpassword = NULL;
- DefElem *dsysid = NULL;
DefElem *dcreatedb = NULL;
- DefElem *dcreateuser = NULL;
- DefElem *dgroupElts = NULL;
+ DefElem *dcreaterole = NULL;
+ DefElem *dcanlogin = NULL;
+ DefElem *droleElts = NULL;
+ DefElem *drolememElts = NULL;
DefElem *dvalidUntil = NULL;
/* Extract options from the statement node tree */
}
else if (strcmp(defel->defname, "sysid") == 0)
{
- if (dsysid)
+ ereport(WARNING,
+ (errmsg("SYSID can no longer be specified")));
+ }
+ else if (strcmp(defel->defname, "createrole") == 0)
+ {
+ if (dcreaterole)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
- dsysid = defel;
+ dcreaterole = defel;
}
else if (strcmp(defel->defname, "createdb") == 0)
{
errmsg("conflicting or redundant options")));
dcreatedb = defel;
}
- else if (strcmp(defel->defname, "createuser ") == 0)
+ else if (strcmp(defel->defname, "canlogin ") == 0)
{
- if (dcreateuser )
+ if (dcanlogin )
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
- dcreateuser = defel;
+ dcanlogin = defel;
}
- else if (strcmp(defel->defname, "group Elts") == 0)
+ else if (strcmp(defel->defname, "role Elts") == 0)
{
- if (dgroup Elts)
+ if (drole Elts)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
- dgroupElts = defel;
+ droleElts = defel;
+ }
+ else if (strcmp(defel->defname, "rolememElts") == 0)
+ {
+ if (drolememElts)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting or redundant options")));
+ drolememElts = defel;
}
else if (strcmp(defel->defname, "validUntil") == 0)
{
if (dcreatedb)
createdb = intVal(dcreatedb->arg) != 0;
- if (dcreateuser)
- createuser = intVal(dcreateuser->arg) != 0;
- if (dsysid)
+ if (dcreaterole)
{
- sysid = intVal(dsysid->arg);
- if (sysid <= 0)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("user ID must be positive")));
- havesysid = true;
+ createrole = intVal(dcreaterole->arg) != 0;
+ /* XXX issuper is implied by createrole for now */
+ issuper = createrole;
}
+ if (dcanlogin)
+ canlogin = intVal(dcanlogin->arg) != 0;
if (dvalidUntil)
validUntil = strVal(dvalidUntil->arg);
if (dpassword)
password = strVal(dpassword->arg);
- if (dgroupElts)
- groupElts = (List *) dgroupElts->arg;
+ if (droleElts)
+ roleElts = (List *) droleElts->arg;
+ if (drolememElts)
+ rolememElts = (List *) drolememElts->arg;
/* Check some permissions first */
- if (password)
- CheckPgUserAclNotNull();
-
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to create user s")));
+ errmsg("must be superuser to create role s")));
- if (strcmp(stmt->user , "public") == 0)
+ if (strcmp(stmt->role , "public") == 0)
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
- errmsg("user name \"%s\" is reserved",
- stmt->user )));
+ errmsg("role name \"%s\" is reserved",
+ stmt->role )));
/*
- * Scan the pg_shadow relation to be certain the user or id doesn't
- * already exist. Note we secure exclusive lock, because we also need
- * to be sure of what the next usesysid should be, and we need to
- * protect our eventual update of the flat password file.
+ * Check the pg_authid relation to be certain the role doesn't
+ * already exist. Note we secure exclusive lock because
+ * we need to protect our eventual update of the flat auth file.
*/
- pg_shadow_rel = heap_open(ShadowRelationId, ExclusiveLock);
- pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
-
- scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL);
- max_id = 99; /* start auto-assigned ids at 100 */
- while (!user_exists && !sysid_exists &&
- (tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
- {
- Form_pg_shadow shadow_form = (Form_pg_shadow) GETSTRUCT(tuple);
- int32 this_sysid;
-
- user_exists = (strcmp(NameStr(shadow_form->usename), stmt->user) == 0);
-
- this_sysid = shadow_form->usesysid;
- if (havesysid) /* customized id wanted */
- sysid_exists = (this_sysid == sysid);
- else
- {
- /* pick 1 + max */
- if (this_sysid > max_id)
- max_id = this_sysid;
- }
- }
- heap_endscan(scan);
+ pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock);
+ pg_authid_dsc = RelationGetDescr(pg_authid_rel);
- if (user_exists)
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("user \"%s\" already exists",
- stmt->user)));
- if (sysid_exists)
+ tuple = SearchSysCache(AUTHNAME,
+ PointerGetDatum(stmt->role),
+ 0, 0, 0);
+ if (HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("user ID %d is already assigned", sysid)));
-
- /* If no sysid given, use max existing id + 1 */
- if (!havesysid)
- sysid = max_id + 1;
+ errmsg("role \"%s\" already exists",
+ stmt->role)));
/*
* Build a tuple to insert
MemSet(new_record, 0, sizeof(new_record));
MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
- new_record[Anum_pg_shadow_use name - 1] =
- DirectFunctionCall1(namein, CStringGetDatum(stmt->user ));
- new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(sysid);
- AssertState(BoolIsValid(createdb) );
- new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb );
- AssertState(BoolIsValid(createuser) );
- new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser);
- /* superuser gets catupd right by default */
- new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser );
+ new_record[Anum_pg_authid_rol name - 1] =
+ DirectFunctionCall1(namein, CStringGetDatum(stmt->role ));
+
+ new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper );
+ new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole );
+ new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb );
+ /* superuser gets catupdate right by default */
+ new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper);
+ new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin );
if (password)
{
if (!encrypt_password || isMD5(password))
- new_record[Anum_pg_shadow_passw d - 1] =
+ new_record[Anum_pg_authid_rolpasswor d - 1] =
DirectFunctionCall1(textin, CStringGetDatum(password));
else
{
- if (!EncryptMD5(password, stmt->user, strlen(stmt->user ),
+ if (!EncryptMD5(password, stmt->role, strlen(stmt->role ),
encrypted_password))
elog(ERROR, "password encryption failed");
- new_record[Anum_pg_shadow_passw d - 1] =
+ new_record[Anum_pg_authid_rolpasswor d - 1] =
DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
}
}
else
- new_record_nulls[Anum_pg_shadow_passw d - 1] = 'n';
+ new_record_nulls[Anum_pg_authid_rolpasswor d - 1] = 'n';
if (validUntil)
- new_record[Anum_pg_shadow_valuntil - 1] =
- DirectFunctionCall1(abstimein, CStringGetDatum(validUntil));
+ new_record[Anum_pg_authid_rolvaliduntil - 1] =
+ DirectFunctionCall3(timestamptz_in,
+ CStringGetDatum(validUntil),
+ ObjectIdGetDatum(InvalidOid),
+ Int32GetDatum(-1));
+
else
- new_record_nulls[Anum_pg_shadow_val until - 1] = 'n';
+ new_record_nulls[Anum_pg_authid_rolvalid until - 1] = 'n';
- new_record_nulls[Anum_pg_shadow_use config - 1] = 'n';
+ new_record_nulls[Anum_pg_authid_rol config - 1] = 'n';
- tuple = heap_formtuple(pg_shadow _dsc, new_record, new_record_nulls);
+ tuple = heap_formtuple(pg_authid _dsc, new_record, new_record_nulls);
/*
- * Insert new record in the pg_shadow table
+ * Insert new record in the pg_authid table
*/
- simple_heap_insert(pg_shadow_rel, tuple);
+ roleid = simple_heap_insert(pg_authid_rel, tuple);
+ Assert(OidIsValid(roleid));
/* Update indexes */
- CatalogUpdateIndexes(pg_shadow _rel, tuple);
+ CatalogUpdateIndexes(pg_authid _rel, tuple);
/*
- * Add the user to the groups specified. We'll just call the below
- * AlterGroup for this.
+ * Add the new role to the specified existing roles.
*/
- foreach(item, group Elts)
+ foreach(item, role Elts)
{
- AlterGroupStmt ags;
+ char *oldrolename = strVal(lfirst(item));
+ Oid oldroleid = get_roleid_checked(oldrolename);
- ags.name = strVal(lfirst(item)); /* the group name to add
- * this in */
- ags.action = +1;
- ags.listUsers = list_make1(makeInteger(sysid));
- AlterGroup(&ags, "CREATE USER");
+ AddRoleMems(oldrolename, oldroleid,
+ list_make1(makeString(stmt->role)),
+ list_make1_oid(roleid),
+ GetUserId(), false);
}
+ /*
+ * Add the specified members to this new role.
+ */
+ AddRoleMems(stmt->role, roleid,
+ rolememElts, roleNamesToIds(rolememElts),
+ GetUserId(), false);
+
/*
* Now we can clean up; but keep lock until commit (to avoid possible
* deadlock when commit code tries to acquire lock).
*/
- heap_close(pg_shadow _rel, NoLock);
+ heap_close(pg_authid _rel, NoLock);
/*
- * Set flag to update flat password file at commit.
+ * Set flag to update flat auth file at commit.
*/
- user _file_update_needed();
+ auth _file_update_needed();
}
-
/*
- * ALTER USER
+ * ALTER ROLE
*/
void
-AlterUser(AlterUser Stmt *stmt)
+AlterRole(AlterRole Stmt *stmt)
{
- Datum new_record[Natts_pg_shadow ];
- char new_record_nulls[Natts_pg_shadow ];
- char new_record_repl[Natts_pg_shadow ];
- Relation pg_shadow _rel;
- TupleDesc pg_shadow _dsc;
+ Datum new_record[Natts_pg_authid ];
+ char new_record_nulls[Natts_pg_authid ];
+ char new_record_repl[Natts_pg_authid ];
+ Relation pg_authid _rel;
+ TupleDesc pg_authid _dsc;
HeapTuple tuple,
new_tuple;
ListCell *option;
- char *password = NULL; /* PostgreSQL user password */
+ char *password = NULL; /* user password */
bool encrypt_password = Password_encryption; /* encrypt password? */
char encrypted_password[MD5_PASSWD_LEN + 1];
- int createdb = -1; /* Can the user create databases? */
- int createuser = -1; /* Can this user create users? */
+ int issuper = -1; /* Make the user a superuser? */
+ int createrole = -1; /* Can this user create roles? */
+ int createdb = -1; /* Can the user create databases? */
+ int canlogin = -1; /* Can this user login? */
+ int adminopt = 0; /* Can this user grant this role to others? */
+ List *rolememElts = NIL; /* The roles which will be added/removed to this role */
char *validUntil = NULL; /* The time the login is valid
* until */
DefElem *dpassword = NULL;
DefElem *dcreatedb = NULL;
- DefElem *dcreateuser = NULL;
+ DefElem *dcreaterole = NULL;
+ DefElem *dcanlogin = NULL;
+ DefElem *dadminopt = NULL;
DefElem *dvalidUntil = NULL;
+ DefElem *drolememElts = NULL;
+ Oid roleid;
/* Extract options from the statement node tree */
foreach(option, stmt->options)
errmsg("conflicting or redundant options")));
dcreatedb = defel;
}
- else if (strcmp(defel->defname, "createuser ") == 0)
+ else if (strcmp(defel->defname, "createrole ") == 0)
{
- if (dcreateuser )
+ if (dcreaterole )
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting or redundant options")));
- dcreateuser = defel;
+ dcreaterole = defel;
+ }
+ else if (strcmp(defel->defname, "canlogin") == 0)
+ {
+ if (dcanlogin)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting or redundant options")));
+ dcanlogin = defel;
+ }
+ else if (strcmp(defel->defname, "adminopt") == 0)
+ {
+ if (dadminopt)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting or redundant options")));
+ dadminopt = defel;
}
else if (strcmp(defel->defname, "validUntil") == 0)
{
errmsg("conflicting or redundant options")));
dvalidUntil = defel;
}
+ else if (strcmp(defel->defname, "rolememElts") == 0 && stmt->action != 0)
+ {
+ if (drolememElts)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting or redundant options")));
+ drolememElts = defel;
+ }
else
elog(ERROR, "option \"%s\" not recognized",
defel->defname);
if (dcreatedb)
createdb = intVal(dcreatedb->arg);
- if (dcreateuser)
- createuser = intVal(dcreateuser->arg);
+ if (dcreaterole)
+ {
+ createrole = intVal(dcreaterole->arg);
+ /* XXX createrole implies issuper for now */
+ issuper = createrole;
+ }
+ if (dcanlogin)
+ canlogin = intVal(dcanlogin->arg);
+ if (dadminopt)
+ adminopt = intVal(dadminopt->arg);
if (dvalidUntil)
validUntil = strVal(dvalidUntil->arg);
if (dpassword)
password = strVal(dpassword->arg);
-
- if (password)
- CheckPgUserAclNotNull();
+ if (drolememElts)
+ rolememElts = (List *) drolememElts->arg;
/* must be superuser or just want to change your own password */
if (!superuser() &&
- !(createdb < 0 &&
- createuser < 0 &&
+ !(issuper < 0 &&
+ createrole < 0 &&
+ createdb < 0 &&
+ canlogin < 0 &&
!validUntil &&
+ !rolememElts &&
+ !adminopt &&
password &&
- strcmp(GetUserNameFromId(GetUserId()), stmt->user ) == 0))
+ strcmp(GetUserNameFromId(GetUserId()), stmt->role ) == 0))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
/*
- * Scan the pg_shadow relation to be certain the user exists. Note we
- * secure exclusive lock to protect our update of the flat password
- * file.
+ * Scan the pg_authid relation to be certain the user exists. Note we
+ * secure exclusive lock to protect our update of the flat auth file.
*/
- pg_shadow_rel = heap_open(Shadow RelationId, ExclusiveLock);
- pg_shadow_dsc = RelationGetDescr(pg_shadow _rel);
+ pg_authid_rel = heap_open(AuthId RelationId, ExclusiveLock);
+ pg_authid_dsc = RelationGetDescr(pg_authid _rel);
- tuple = SearchSysCache(SHADOW NAME,
- PointerGetDatum(stmt->user ),
+ tuple = SearchSysCache(AUTH NAME,
+ PointerGetDatum(stmt->role ),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", stmt->user)));
+ errmsg("role \"%s\" does not exist", stmt->role)));
+
+ roleid = HeapTupleGetOid(tuple);
/*
* Build an updated tuple, perusing the information just obtained
MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
MemSet(new_record_repl, ' ', sizeof(new_record_repl));
- new_record[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein,
- CStringGetDatum(stmt->user));
- new_record_repl[Anum_pg_shadow_usename - 1] = 'r';
-
- /* createdb */
- if (createdb >= 0)
- {
- new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb > 0);
- new_record_repl[Anum_pg_shadow_usecreatedb - 1] = 'r';
- }
+ new_record[Anum_pg_authid_rolname - 1] = DirectFunctionCall1(namein,
+ CStringGetDatum(stmt->role));
+ new_record_repl[Anum_pg_authid_rolname - 1] = 'r';
/*
- * createuser (superuser) and catupd
+ * issuper/createrole/catupdate/etc
*
- * XXX It's rather unclear how to handle catupd. It's probably best to
+ * XXX It's rather unclear how to handle catupdate . It's probably best to
* keep it equal to the superuser status, otherwise you could end up
* with a situation where no existing superuser can alter the
- * catalogs, including pg_shadow !
+ * catalogs, including pg_authid !
*/
- if (createus er >= 0)
+ if (issup er >= 0)
{
- new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createus er > 0);
- new_record_repl[Anum_pg_shadow_use super - 1] = 'r';
+ new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issup er > 0);
+ new_record_repl[Anum_pg_authid_rol super - 1] = 'r';
- new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser > 0);
- new_record_repl[Anum_pg_shadow_usecatupd - 1] = 'r';
+ new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper > 0);
+ new_record_repl[Anum_pg_authid_rolcatupdate - 1] = 'r';
+ }
+
+ if (createrole >= 0)
+ {
+ new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0);
+ new_record_repl[Anum_pg_authid_rolcreaterole - 1] = 'r';
+ }
+
+ if (createdb >= 0)
+ {
+ new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0);
+ new_record_repl[Anum_pg_authid_rolcreatedb - 1] = 'r';
+ }
+
+ if (canlogin >= 0)
+ {
+ new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0);
+ new_record_repl[Anum_pg_authid_rolcanlogin - 1] = 'r';
}
/* password */
if (password)
{
if (!encrypt_password || isMD5(password))
- new_record[Anum_pg_shadow_passw d - 1] =
+ new_record[Anum_pg_authid_rolpasswor d - 1] =
DirectFunctionCall1(textin, CStringGetDatum(password));
else
{
- if (!EncryptMD5(password, stmt->user, strlen(stmt->user ),
+ if (!EncryptMD5(password, stmt->role, strlen(stmt->role ),
encrypted_password))
elog(ERROR, "password encryption failed");
- new_record[Anum_pg_shadow_passw d - 1] =
+ new_record[Anum_pg_authid_rolpasswor d - 1] =
DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
}
- new_record_repl[Anum_pg_shadow_passw d - 1] = 'r';
+ new_record_repl[Anum_pg_authid_rolpasswor d - 1] = 'r';
}
/* valid until */
if (validUntil)
{
- new_record[Anum_pg_shadow_valuntil - 1] =
- DirectFunctionCall1(abstimein, CStringGetDatum(validUntil));
- new_record_repl[Anum_pg_shadow_valuntil - 1] = 'r';
+ new_record[Anum_pg_authid_rolvaliduntil - 1] =
+ DirectFunctionCall3(timestamptz_in,
+ CStringGetDatum(validUntil),
+ ObjectIdGetDatum(InvalidOid),
+ Int32GetDatum(-1));
+ new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = 'r';
}
- new_tuple = heap_modifytuple(tuple, pg_shadow _dsc, new_record,
+ new_tuple = heap_modifytuple(tuple, pg_authid _dsc, new_record,
new_record_nulls, new_record_repl);
- simple_heap_update(pg_shadow _rel, &tuple->t_self, new_tuple);
+ simple_heap_update(pg_authid _rel, &tuple->t_self, new_tuple);
/* Update indexes */
- CatalogUpdateIndexes(pg_shadow _rel, new_tuple);
+ CatalogUpdateIndexes(pg_authid _rel, new_tuple);
ReleaseSysCache(tuple);
heap_freetuple(new_tuple);
* Now we can clean up; but keep lock until commit (to avoid possible
* deadlock when commit code tries to acquire lock).
*/
- heap_close(pg_shadow_rel, NoLock);
+ heap_close(pg_authid_rel, NoLock);
+
+ if (stmt->action == +1) /* add members to role */
+ AddRoleMems(stmt->role, roleid,
+ rolememElts, roleNamesToIds(rolememElts),
+ GetUserId(), adminopt);
+ else if (stmt->action == -1) /* drop members from role */
+ DelRoleMems(stmt->role, roleid,
+ rolememElts, roleNamesToIds(rolememElts),
+ adminopt);
/*
- * Set flag to update flat password file at commit.
+ * Set flag to update flat auth file at commit.
*/
- user _file_update_needed();
+ auth _file_update_needed();
}
/*
- * ALTER USER ... SET
+ * ALTER ROLE ... SET
*/
void
-AlterUserSet(AlterUser SetStmt *stmt)
+AlterRoleSet(AlterRole SetStmt *stmt)
{
char *valuestr;
HeapTuple oldtuple,
newtuple;
Relation rel;
- Datum repl_val[Natts_pg_shadow ];
- char repl_null[Natts_pg_shadow ];
- char repl_repl[Natts_pg_shadow ];
+ Datum repl_val[Natts_pg_authid ];
+ char repl_null[Natts_pg_authid ];
+ char repl_repl[Natts_pg_authid ];
int i;
valuestr = flatten_set_variable_args(stmt->variable, stmt->value);
/*
* RowExclusiveLock is sufficient, because we don't need to update the
- * flat password file.
+ * flat auth file.
*/
- rel = heap_open(Shadow RelationId, RowExclusiveLock);
- oldtuple = SearchSysCache(SHADOW NAME,
- PointerGetDatum(stmt->user ),
+ rel = heap_open(AuthId RelationId, RowExclusiveLock);
+ oldtuple = SearchSysCache(AUTH NAME,
+ PointerGetDatum(stmt->role ),
0, 0, 0);
if (!HeapTupleIsValid(oldtuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", stmt->user )));
+ errmsg("role \"%s\" does not exist", stmt->role )));
if (!(superuser() ||
- ((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId( )))
+ (HeapTupleGetOid(oldtuple) == GetUserId() )))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
- for (i = 0; i < Natts_pg_shadow ; i++)
+ for (i = 0; i < Natts_pg_authid ; i++)
repl_repl[i] = ' ';
- repl_repl[Anum_pg_shadow_use config - 1] = 'r';
+ repl_repl[Anum_pg_authid_rol config - 1] = 'r';
if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL)
{
/* RESET ALL */
- repl_null[Anum_pg_shadow_use config - 1] = 'n';
+ repl_null[Anum_pg_authid_rol config - 1] = 'n';
}
else
{
bool isnull;
ArrayType *array;
- repl_null[Anum_pg_shadow_use config - 1] = ' ';
+ repl_null[Anum_pg_authid_rol config - 1] = ' ';
- datum = SysCacheGetAttr(SHADOW NAME, oldtuple,
- Anum_pg_shadow_use config, &isnull);
+ datum = SysCacheGetAttr(AUTH NAME, oldtuple,
+ Anum_pg_authid_rol config, &isnull);
array = isnull ? NULL : DatumGetArrayTypeP(datum);
array = GUCArrayDelete(array, stmt->variable);
if (array)
- repl_val[Anum_pg_shadow_use config - 1] = PointerGetDatum(array);
+ repl_val[Anum_pg_authid_rol config - 1] = PointerGetDatum(array);
else
- repl_null[Anum_pg_shadow_use config - 1] = 'n';
+ repl_null[Anum_pg_authid_rol config - 1] = 'n';
}
newtuple = heap_modifytuple(oldtuple, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
/*
- * DROP USER
+ * DROP ROLE
*/
void
-DropUser(DropUser Stmt *stmt)
+DropRole(DropRole Stmt *stmt)
{
- Relation pg_shadow_rel;
- TupleDesc pg_shadow_dsc;
+ Relation pg_authid_rel, pg_auth_members_rel;
ListCell *item;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to drop user s")));
+ errmsg("must be superuser to drop role s")));
/*
- * Scan the pg_shadow relation to find the usesysid of the user to be
+ * Scan the pg_authid relation to find the Oid of the role to be
* deleted. Note we secure exclusive lock, because we need to protect
- * our update of the flat password file.
+ * our update of the flat auth file.
*/
- pg_shadow_rel = heap_open(Shadow RelationId, ExclusiveLock);
- pg_shadow_dsc = RelationGetDescr(pg_shadow_rel );
+ pg_authid_rel = heap_open(AuthId RelationId, ExclusiveLock);
+ pg_auth_members_rel = heap_open(AuthMemRelationId, ExclusiveLock );
- foreach(item, stmt->user s)
+ foreach(item, stmt->role s)
{
- const char *user = strVal(lfirst(item));
+ const char *role = strVal(lfirst(item));
HeapTuple tuple,
tmp_tuple;
Relation pg_rel;
TupleDesc pg_dsc;
ScanKeyData scankey;
HeapScanDesc scan;
- AclId usesysid;
+ CatCList *auth_mem_list;
+ Oid roleid;
+ int i;
- tuple = SearchSysCache(SHADOW NAME,
- PointerGetDatum(user ),
+ tuple = SearchSysCache(AUTH NAME,
+ PointerGetDatum(role ),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", user )));
+ errmsg("role \"%s\" does not exist", role )));
- usesysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid ;
+ roleid = HeapTupleGetOid(tuple) ;
- if (usesys id == GetUserId())
+ if (role id == GetUserId())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("current user cannot be dropped")));
- if (usesys id == GetSessionUserId())
+ errmsg("current role cannot be dropped")));
+ if (role id == GetSessionUserId())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("session user cannot be dropped")));
+ errmsg("session role cannot be dropped")));
/*
- * Check if user still owns a database. If so, error out.
+ * Check if role still owns a database. If so, error out.
*
* (It used to be that this function would drop the database
* automatically. This is not only very dangerous for people that
ScanKeyInit(&scankey,
Anum_pg_database_datdba,
- BTEqualStrategyNumber, F_INT4 EQ,
- Int32GetDatum(usesysid) );
+ BTEqualStrategyNumber, F_OID EQ,
+ roleid );
scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
dbname = NameStr(((Form_pg_database) GETSTRUCT(tmp_tuple))->datname);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("user \"%s\" cannot be dropped", user ),
- errdetail("The user owns database \"%s\".", dbname)));
+ errmsg("role \"%s\" cannot be dropped", role ),
+ errdetail("The role owns database \"%s\".", dbname)));
}
heap_endscan(scan);
/*
* Somehow we'd have to check for tables, views, etc. owned by the
- * user as well, but those could be spread out over all sorts of
+ * role as well, but those could be spread out over all sorts of
* databases which we don't have access to (easily).
*/
/*
- * Remove the user from the pg_shadow table
+ * Remove the role from the pg_authid table
*/
- simple_heap_delete(pg_shadow _rel, &tuple->t_self);
+ simple_heap_delete(pg_authid _rel, &tuple->t_self);
ReleaseSysCache(tuple);
/*
- * Remove user from group s
+ * Remove role from role s
*
- * try calling alter group drop user for every group
+ * scan pg_auth_members and remove tuples which have
+ * roleid == member or roleid == role
*/
- pg_rel = heap_open(GroupRelationId, ExclusiveLock);
- pg_dsc = RelationGetDescr(pg_rel);
- scan = heap_beginscan(pg_rel, SnapshotNow, 0, NULL);
- while ((tmp_tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
- {
- AlterGroupStmt ags;
+ auth_mem_list = SearchSysCacheList(AUTHMEMROLEMEM, 1,
+ ObjectIdGetDatum(roleid),
+ 0, 0, 0);
- /* the group name from which to try to drop the user: */
- ags.name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tmp_tuple))->groname));
- ags.action = -1;
- ags.listUsers = list_make1(makeInteger(usesysid));
- AlterGroup(&ags, "DROP USER");
+ for (i = 0; i < auth_mem_list->n_members; i++)
+ {
+ HeapTuple authmemtup = &auth_mem_list->members[i]->tuple;
+ simple_heap_delete(pg_auth_members_rel, &authmemtup->t_self);
}
- heap_endscan(scan);
- heap_close(pg_rel, ExclusiveLock);
+ ReleaseSysCacheList(auth_mem_list);
- /*
- * Advance command counter so that later iterations of this loop
- * will see the changes already made. This is essential if, for
- * example, we are trying to drop two users who are members of the
- * same group --- the AlterGroup for the second user had better
- * see the tuple updated from the first one.
- */
- CommandCounterIncrement();
+ auth_mem_list = SearchSysCacheList(AUTHMEMMEMROLE, 1,
+ ObjectIdGetDatum(roleid),
+ 0, 0, 0);
+
+ for (i = 0; i < auth_mem_list->n_members; i++)
+ {
+ HeapTuple authmemtup = &auth_mem_list->members[i]->tuple;
+ simple_heap_delete(pg_auth_members_rel, &authmemtup->t_self);
+ }
+ ReleaseSysCacheList(auth_mem_list);
}
/*
* Now we can clean up; but keep lock until commit (to avoid possible
* deadlock when commit code tries to acquire lock).
*/
- heap_close(pg_shadow_rel, NoLock);
+ heap_close(pg_auth_members_rel, NoLock);
+ heap_close(pg_authid_rel, NoLock);
/*
- * Set flag to update flat password file at commit.
+ * Set flag to update flat auth file at commit.
*/
- user _file_update_needed();
+ auth _file_update_needed();
}
-
/*
- * Rename user
+ * Rename role
*/
void
-RenameUser (const char *oldname, const char *newname)
+RenameRole (const char *oldname, const char *newname)
{
HeapTuple oldtuple,
newtuple;
Relation rel;
Datum datum;
bool isnull;
- Datum repl_val[Natts_pg_shadow ];
- char repl_null[Natts_pg_shadow ];
- char repl_repl[Natts_pg_shadow ];
+ Datum repl_val[Natts_pg_authid ];
+ char repl_null[Natts_pg_authid ];
+ char repl_repl[Natts_pg_authid ];
int i;
+ Oid roleid;
/* ExclusiveLock because we need to update the password file */
- rel = heap_open(Shadow RelationId, ExclusiveLock);
+ rel = heap_open(AuthId RelationId, ExclusiveLock);
dsc = RelationGetDescr(rel);
- oldtuple = SearchSysCache(SHADOW NAME,
+ oldtuple = SearchSysCache(AUTH NAME,
CStringGetDatum(oldname),
0, 0, 0);
if (!HeapTupleIsValid(oldtuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", oldname)));
+ errmsg("role \"%s\" does not exist", oldname)));
/*
* XXX Client applications probably store the session user somewhere,
* not be an actual problem besides a little confusion, so think about
* this and decide.
*/
- if (((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetSessionUserId())
+
+ roleid = HeapTupleGetOid(oldtuple);
+
+ if (roleid == GetSessionUserId())
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("session user may not be renamed")));
+ errmsg("session role may not be renamed")));
/* make sure the new name doesn't exist */
- if (SearchSysCacheExists(SHADOW NAME,
+ if (SearchSysCacheExists(AUTH NAME,
CStringGetDatum(newname),
0, 0, 0))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("user \"%s\" already exists", newname)));
+ errmsg("role \"%s\" already exists", newname)));
/* must be superuser */
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to rename user s")));
+ errmsg("must be superuser to rename role s")));
- for (i = 0; i < Natts_pg_shadow ; i++)
+ for (i = 0; i < Natts_pg_authid ; i++)
repl_repl[i] = ' ';
- repl_repl[Anum_pg_shadow_use name - 1] = 'r';
- repl_val[Anum_pg_shadow_use name - 1] = DirectFunctionCall1(namein,
+ repl_repl[Anum_pg_authid_rol name - 1] = 'r';
+ repl_val[Anum_pg_authid_rol name - 1] = DirectFunctionCall1(namein,
CStringGetDatum(newname));
- repl_null[Anum_pg_shadow_use name - 1] = ' ';
+ repl_null[Anum_pg_authid_rol name - 1] = ' ';
- datum = heap_getattr(oldtuple, Anum_pg_shadow_passw d, dsc, &isnull);
+ datum = heap_getattr(oldtuple, Anum_pg_authid_rolpasswor d, dsc, &isnull);
if (!isnull && isMD5(DatumGetCString(DirectFunctionCall1(textout, datum))))
{
/* MD5 uses the username as salt, so just clear it on a rename */
- repl_repl[Anum_pg_shadow_passw d - 1] = 'r';
- repl_null[Anum_pg_shadow_passw d - 1] = 'n';
+ repl_repl[Anum_pg_authid_rolpasswor d - 1] = 'r';
+ repl_null[Anum_pg_authid_rolpasswor d - 1] = 'n';
ereport(NOTICE,
- (errmsg("MD5 password cleared because of user rename")));
+ (errmsg("MD5 password cleared because of role rename")));
}
newtuple = heap_modifytuple(oldtuple, dsc, repl_val, repl_null, repl_repl);
ReleaseSysCache(oldtuple);
heap_close(rel, NoLock);
- user _file_update_needed();
+ auth _file_update_needed();
}
-
/*
- * CheckPgUserAclNotNull
+ * GrantRoleStmt
*
- * check to see if there is an ACL on pg_shadow
- */
-static void
-CheckPgUserAclNotNull(void)
-{
- HeapTuple htup;
-
- htup = SearchSysCache(RELOID,
- ObjectIdGetDatum(ShadowRelationId),
- 0, 0, 0);
- if (!HeapTupleIsValid(htup)) /* should not happen, we hope */
- elog(ERROR, "cache lookup failed for relation %u", ShadowRelationId);
-
- if (heap_attisnull(htup, Anum_pg_class_relacl))
- {
- Form_pg_class classForm = (Form_pg_class) GETSTRUCT(htup);
-
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("before using passwords you must revoke privileges on %s",
- NameStr(classForm->relname)),
- errdetail("This restriction is to prevent unprivileged users from reading the passwords."),
- errhint("Try REVOKE ALL ON \"%s\" FROM PUBLIC.",
- NameStr(classForm->relname))));
- }
-
- ReleaseSysCache(htup);
-}
-
-
-/*
- * CREATE GROUP
+ * Grant/Revoke roles to/from roles
*/
void
-CreateGroup(CreateGroup Stmt *stmt)
+GrantRole(GrantRole Stmt *stmt)
{
- Relation pg_group_rel;
- HeapScanDesc scan;
- HeapTuple tuple;
- TupleDesc pg_group_dsc;
- bool group_exists = false,
- sysid_exists = false,
- havesysid = false;
- int max_id;
- Datum new_record[Natts_pg_group];
- char new_record_nulls[Natts_pg_group];
+ Oid grantor;
+ List *grantee_ids;
ListCell *item;
- ListCell *option;
- List *newlist = NIL;
- IdList *grolist;
- int sysid = 0;
- List *userElts = NIL;
- DefElem *dsysid = NULL;
- DefElem *duserElts = NULL;
-
- foreach(option, stmt->options)
- {
- DefElem *defel = (DefElem *) lfirst(option);
- if (strcmp(defel->defname, "sysid") == 0)
- {
- if (dsysid)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
- dsysid = defel;
- }
- else if (strcmp(defel->defname, "userElts") == 0)
- {
- if (duserElts)
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("conflicting or redundant options")));
- duserElts = defel;
- }
- else
- elog(ERROR, "option \"%s\" not recognized",
- defel->defname);
- }
-
- if (dsysid)
- {
- sysid = intVal(dsysid->arg);
- if (sysid <= 0)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("group ID must be positive")));
- havesysid = true;
- }
+ if (stmt->grantor)
+ grantor = get_roleid_checked(stmt->grantor);
+ else
+ grantor = GetUserId();
- if (duserElts)
- userElts = (List *) duserElts->arg;
+ grantee_ids = roleNamesToIds(stmt->grantee_roles);
/*
- * Make sure the user can do this.
- */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to create groups")));
-
- if (strcmp(stmt->name, "public") == 0)
- ereport(ERROR,
- (errcode(ERRCODE_RESERVED_NAME),
- errmsg("group name \"%s\" is reserved",
- stmt->name)));
-
- /*
- * Scan the pg_group relation to be certain the group or id doesn't
- * already exist. Note we secure exclusive lock, because we also need
- * to be sure of what the next grosysid should be, and we need to
- * protect our eventual update of the flat group file.
+ * Step through all of the granted roles and add/remove
+ * entries for the grantees, or, if admin_opt is set, then
+ * just add/remove the admin option.
+ *
+ * Note: Permissions checking is done by AddRoleMems/DelRoleMems
*/
- pg_group_rel = heap_open(GroupRelationId, ExclusiveLock);
- pg_group_dsc = RelationGetDescr(pg_group_rel);
-
- scan = heap_beginscan(pg_group_rel, SnapshotNow, 0, NULL);
- max_id = 99; /* start auto-assigned ids at 100 */
- while (!group_exists && !sysid_exists &&
- (tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
+ foreach(item, stmt->granted_roles)
{
- Form_pg_group group_form = (Form_pg_group) GETSTRUCT(tuple );
- int32 this_sysid ;
+ char *rolename = strVal(lfirst(item) );
+ Oid roleid = get_roleid_checked(rolename) ;
- group_exists = (strcmp(NameStr(group_form->groname), stmt->name) == 0);
-
- this_sysid = group_form->grosysid;
- if (havesysid) /* customized id wanted */
- sysid_exists = (this_sysid == sysid);
+ if (stmt->is_grant)
+ AddRoleMems(rolename, roleid,
+ stmt->grantee_roles, grantee_ids,
+ grantor, stmt->admin_opt);
else
- {
- /* pick 1 + max */
- if (this_sysid > max_id)
- max_id = this_sysid;
- }
+ DelRoleMems(rolename, roleid,
+ stmt->grantee_roles, grantee_ids,
+ stmt->admin_opt);
}
- heap_endscan(scan);
-
- if (group_exists)
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("group \"%s\" already exists",
- stmt->name)));
- if (sysid_exists)
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("group ID %d is already assigned", sysid)));
+}
- /* If no sysid given, use max existing id + 1 */
- if (!havesysid)
- sysid = max_id + 1;
+/*
+ * roleNamesToIds
+ *
+ * Given a list of role names (as String nodes), generate a list of role OIDs
+ * in the same order.
+ */
+static List *
+roleNamesToIds(List *memberNames)
+{
+ List *result = NIL;
+ ListCell *l;
- /*
- * Translate the given user names to ids
- */
- foreach(item, userElts)
+ foreach(l, memberNames)
{
- const char *groupuser = strVal(lfirst(item ));
- int32 userid = get_usesysid(groupuser );
+ char *rolename = strVal(lfirst(l ));
+ Oid roleid = get_roleid_checked(rolename );
- if (!list_member_int(newlist, userid))
- newlist = lappend_int(newlist, userid);
+ result = lappend_oid(result, roleid);
}
-
- /* build an array to insert */
- if (newlist)
- grolist = IdListToArray(newlist);
- else
- grolist = NULL;
-
- /*
- * Form a tuple to insert
- */
- new_record[Anum_pg_group_groname - 1] =
- DirectFunctionCall1(namein, CStringGetDatum(stmt->name));
- new_record[Anum_pg_group_grosysid - 1] = Int32GetDatum(sysid);
- new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(grolist);
-
- new_record_nulls[Anum_pg_group_groname - 1] = ' ';
- new_record_nulls[Anum_pg_group_grosysid - 1] = ' ';
- new_record_nulls[Anum_pg_group_grolist - 1] = grolist ? ' ' : 'n';
-
- tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls);
-
- /*
- * Insert a new record in the pg_group table
- */
- simple_heap_insert(pg_group_rel, tuple);
-
- /* Update indexes */
- CatalogUpdateIndexes(pg_group_rel, tuple);
-
- /*
- * Now we can clean up; but keep lock until commit (to avoid possible
- * deadlock when commit code tries to acquire lock).
- */
- heap_close(pg_group_rel, NoLock);
-
- /*
- * Set flag to update flat group file at commit.
- */
- group_file_update_needed();
+ return result;
}
-
/*
- * ALTER GROUP
+ * AddRoleMems -- Add given members to the specified role
+ *
+ * rolename: name of role to add to (used only for error messages)
+ * roleid: OID of role to add to
+ * memberNames: list of names of roles to add (used only for error messages)
+ * memberIds: OIDs of roles to add
+ * grantorId: who is granting the membership
+ * admin_opt: granting admin option?
*/
-void
-AlterGroup(AlterGroupStmt *stmt, const char *tag)
+static void
+AddRoleMems(const char *rolename, Oid roleid,
+ List *memberNames, List *memberIds,
+ Oid grantorId, bool admin_opt)
{
- Relation pg_group_rel;
- TupleDesc pg_group_dsc;
- HeapTuple group_tuple;
- IdList *oldarray;
- Datum datum;
- bool null;
- List *newlist;
- ListCell *item;
+ Relation pg_authmem_rel;
+ TupleDesc pg_authmem_dsc;
+ ListCell *nameitem;
+ ListCell *iditem;
- /*
- * Make sure the user can do this.
- */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to alter groups")));
+ Assert(list_length(memberNames) == list_length(memberIds));
- /*
- * Secure exclusive lock to protect our update of the flat group file.
- */
- pg_group_rel = heap_open(GroupRelationId, ExclusiveLock);
- pg_group_dsc = RelationGetDescr(pg_group_rel);
+ /* Skip permission check if nothing to do */
+ if (!memberIds)
+ return;
/*
- * Fetch existing tuple for group.
+ * Check permissions: must be superuser or have admin option on the
+ * role to be changed.
+ *
+ * XXX: The admin option is not considered to be inherited through
+ * multiple roles, unlike normal 'is_member_of_role' privilege checks.
*/
- group_tuple = SearchSysCache(GRONAME,
- PointerGetDatum(stmt->name),
- 0, 0, 0);
- if (!HeapTupleIsValid(group_tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("group \"%s\" does not exist", stmt->name)));
+ if (!superuser())
+ {
+ HeapTuple authmem_chk_tuple;
+ Form_pg_auth_members authmem_chk;
- /* Fetch old group membership. */
- datum = heap_getattr(group_tuple, Anum_pg_group_grolist,
- pg_group_dsc, &null);
- oldarray = null ? NULL : DatumGetIdListP(datum);
+ if (grantorId != GetUserId())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to set grantor ID")));
+
+ authmem_chk_tuple = SearchSysCache(AUTHMEMROLEMEM,
+ ObjectIdGetDatum(roleid),
+ ObjectIdGetDatum(grantorId),
+ 0, 0);
+ if (!HeapTupleIsValid(authmem_chk_tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser or have admin option on role \"%s\"",
+ rolename)));
- /* initialize list with old array contents */
- newlist = IdArrayToList(oldarray);
+ authmem_chk = (Form_pg_auth_members) GETSTRUCT(authmem_chk_tuple);
+ if (!authmem_chk->admin_option)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser or have admin option on role \"%s\"",
+ rolename)));
+ ReleaseSysCache(authmem_chk_tuple);
+ }
/*
- * Now decide what to do .
+ * Secure exclusive lock to protect our update of the flat auth file .
*/
- AssertState(stmt->action == +1 || stmt->action == -1);
+ pg_authmem_rel = heap_open(AuthMemRelationId, ExclusiveLock);
+ pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);
- if (stmt->action == +1) /* add users, might also be invoked by
- * create user */
+ forboth(nameitem, memberNames, iditem, memberIds)
{
+ const char *membername = strVal(lfirst(nameitem));
+ Oid memberid = lfirst_oid(iditem);
+ HeapTuple authmem_tuple;
+ HeapTuple tuple;
+ Datum new_record[Natts_pg_auth_members];
+ char new_record_nulls[Natts_pg_auth_members];
+ char new_record_repl[Natts_pg_auth_members];
+
/*
- * convert the to be added usernames to sysids and add them to the
- * list
+ * Check if entry for this role/member already exists;
+ * if so, give warning unless we are adding admin option.
*/
- foreach(item, stmt->listUsers)
+ authmem_tuple = SearchSysCache(AUTHMEMROLEMEM,
+ ObjectIdGetDatum(roleid),
+ ObjectIdGetDatum(memberid),
+ 0, 0);
+ if (HeapTupleIsValid(authmem_tuple) && !admin_opt)
{
- int32 sysid;
-
- if (strcmp(tag, "ALTER GROUP") == 0)
- {
- /* Get the uid of the proposed user to add. */
- sysid = get_usesysid(strVal(lfirst(item)));
- }
- else if (strcmp(tag, "CREATE USER") == 0)
- {
- /*
- * in this case we already know the uid and it wouldn't be
- * in the cache anyway yet
- */
- sysid = intVal(lfirst(item));
- }
- else
- {
- elog(ERROR, "unexpected tag: \"%s\"", tag);
- sysid = 0; /* keep compiler quiet */
- }
-
- if (!list_member_int(newlist, sysid))
- newlist = lappend_int(newlist, sysid);
+ ereport(NOTICE,
+ (errmsg("role \"%s\" is already a member of role \"%s\"",
+ membername, rolename)));
+ ReleaseSysCache(authmem_tuple);
+ continue;
}
- /* Do the update */
- UpdateGroupMembership(pg_group_rel, group_tuple, newlist);
- } /* endif alter group add user */
+ /* Build a tuple to insert or update */
+ MemSet(new_record, 0, sizeof(new_record));
+ MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
+ MemSet(new_record_repl, ' ', sizeof(new_record_repl));
- else if (stmt->action == -1) /* drop users from group */
- {
- bool is_dropuser = strcmp(tag, "DROP USER") == 0;
+ new_record[Anum_pg_auth_members_roleid - 1] = ObjectIdGetDatum(roleid);
+ new_record[Anum_pg_auth_members_member - 1] = ObjectIdGetDatum(memberid);
+ new_record[Anum_pg_auth_members_grantor - 1] = ObjectIdGetDatum(grantorId);
+ new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(admin_opt);
- if (newlist == NIL )
+ if (HeapTupleIsValid(authmem_tuple) )
{
- if (!is_dropuser)
- ereport(WARNING,
- (errcode(ERRCODE_WARNING),
- errmsg("group \"%s\" does not have any members",
- stmt->name)));
+ new_record_repl[Anum_pg_auth_members_grantor - 1] = 'r';
+ new_record_repl[Anum_pg_auth_members_admin_option - 1] = 'r';
+ tuple = heap_modifytuple(authmem_tuple, pg_authmem_dsc,
+ new_record,
+ new_record_nulls, new_record_repl);
+ simple_heap_update(pg_authmem_rel, &tuple->t_self, tuple);
+ CatalogUpdateIndexes(pg_authmem_rel, tuple);
+ ReleaseSysCache(authmem_tuple);
}
else
{
- /*
- * convert the to be dropped usernames to sysids and remove
- * them from the list
- */
- foreach(item, stmt->listUsers)
- {
- int32 sysid;
-
- if (!is_dropuser)
- {
- /* Get the uid of the proposed user to drop. */
- sysid = get_usesysid(strVal(lfirst(item)));
- }
- else
- {
- /* for dropuser we already know the uid */
- sysid = intVal(lfirst(item));
- }
- if (list_member_int(newlist, sysid))
- newlist = list_delete_int(newlist, sysid);
- else if (!is_dropuser)
- ereport(WARNING,
- (errcode(ERRCODE_WARNING),
- errmsg("user \"%s\" is not in group \"%s\"",
- strVal(lfirst(item)), stmt->name)));
- }
-
- /* Do the update */
- UpdateGroupMembership(pg_group_rel, group_tuple, newlist);
- } /* endif group not null */
- } /* endif alter group drop user */
-
- ReleaseSysCache(group_tuple);
+ tuple = heap_formtuple(pg_authmem_dsc,
+ new_record, new_record_nulls);
+ simple_heap_insert(pg_authmem_rel, tuple);
+ CatalogUpdateIndexes(pg_authmem_rel, tuple);
+ }
+ }
/*
* Now we can clean up; but keep lock until commit (to avoid possible
* deadlock when commit code tries to acquire lock).
*/
- heap_close(pg_group_rel, NoLock);
-
- /*
- * Set flag to update flat group file at commit.
- */
- group_file_update_needed();
+ heap_close(pg_authmem_rel, NoLock);
}
/*
- * Subroutine for AlterGroup: given a pg_group tuple and a desired new
- * membership (expressed as an integer list), form and write an updated tuple.
- * The pg_group relation must be open and locked already.
+ * DelRoleMems -- Remove given members from the specified role
+ *
+ * rolename: name of role to del from (used only for error messages)
+ * roleid: OID of role to del from
+ * memberNames: list of names of roles to del (used only for error messages)
+ * memberIds: OIDs of roles to del
+ * admin_opt: remove admin option only?
*/
static void
-UpdateGroupMembership(Relation group_rel, HeapTuple group_tuple,
- List *members)
+DelRoleMems(const char *rolename, Oid roleid,
+ List *memberNames, List *memberIds,
+ bool admin_opt)
{
- IdList *newarray;
- Datum new_record[Natts_pg_group];
- char new_record_nulls[Natts_pg_group];
- char new_record_repl[Natts_pg_group];
- HeapTuple tuple;
+ Relation pg_authmem_rel;
+ TupleDesc pg_authmem_dsc;
+ ListCell *nameitem;
+ ListCell *iditem;
- newarray = IdListToArray(members);
+ Assert(list_length(memberNames) == list_length(memberIds));
+
+ /* Skip permission check if nothing to do */
+ if (!memberIds)
+ return;
/*
- * Form an updated tuple with the new array and write it back.
+ * Check permissions: must be superuser or have admin option on the
+ * role to be changed.
+ *
+ * XXX: The admin option is not considered to be inherited through
+ * multiple roles, unlike normal 'is_member_of_role' privilege checks.
*/
- MemSet(new_record, 0, sizeof(new_record));
- MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
- MemSet(new_record_repl, ' ', sizeof(new_record_repl));
-
- new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray);
- new_record_repl[Anum_pg_group_grolist - 1] = 'r';
-
- tuple = heap_modifytuple(group_tuple, RelationGetDescr(group_rel),
- new_record, new_record_nulls, new_record_repl);
-
- simple_heap_update(group_rel, &group_tuple->t_self, tuple);
-
- /* Update indexes */
- CatalogUpdateIndexes(group_rel, tuple);
-}
-
-
-/*
- * Convert an integer list of sysids to an array.
- */
-static IdList *
-IdListToArray(List *members)
-{
- int nmembers = list_length(members);
- IdList *newarray;
- ListCell *item;
- int i;
-
- newarray = palloc(ARR_OVERHEAD(1) + nmembers * sizeof(int32));
- newarray->size = ARR_OVERHEAD(1) + nmembers * sizeof(int32);
- newarray->flags = 0;
- newarray->elemtype = INT4OID;
- ARR_NDIM(newarray) = 1; /* one dimensional array */
- ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */
- ARR_DIMS(newarray)[0] = nmembers; /* axis is this long */
- i = 0;
- foreach(item, members)
- ((int *) ARR_DATA_PTR(newarray))[i++] = lfirst_int(item);
-
- return newarray;
-}
-
-/*
- * Convert an array of sysids to an integer list.
- */
-static List *
-IdArrayToList(IdList *oldarray)
-{
- List *newlist = NIL;
- int hibound,
- i;
-
- if (oldarray == NULL)
- return NIL;
-
- Assert(ARR_NDIM(oldarray) == 1);
- Assert(ARR_ELEMTYPE(oldarray) == INT4OID);
-
- hibound = ARR_DIMS(oldarray)[0];
-
- for (i = 0; i < hibound; i++)
+ if (!superuser())
{
- int32 sysid;
+ HeapTuple authmem_chk_tuple;
+ Form_pg_auth_members authmem_chk;
+
+ authmem_chk_tuple = SearchSysCache(AUTHMEMROLEMEM,
+ ObjectIdGetDatum(roleid),
+ ObjectIdGetDatum(GetUserId()),
+ 0, 0);
+ if (!HeapTupleIsValid(authmem_chk_tuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser or have admin option on role \"%s\"",
+ rolename)));
- sysid = ((int32 *) ARR_DATA_PTR(oldarray))[i];
- /* filter out any duplicates --- probably a waste of time */
- if (!list_member_int(newlist, sysid))
- newlist = lappend_int(newlist, sysid);
+ authmem_chk = (Form_pg_auth_members) GETSTRUCT(authmem_chk_tuple);
+ if (!authmem_chk->admin_option)
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser or have admin option on role \"%s\"",
+ rolename)));
+ ReleaseSysCache(authmem_chk_tuple);
}
- return newlist;
-}
-
-
-/*
- * DROP GROUP
- */
-void
-DropGroup(DropGroupStmt *stmt)
-{
- Relation pg_group_rel;
- HeapTuple tuple;
-
/*
- * Make sure the user can do this .
+ * Secure exclusive lock to protect our update of the flat auth file .
*/
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to drop groups")));
+ pg_authmem_rel = heap_open(AuthMemRelationId, ExclusiveLock);
+ pg_authmem_dsc = RelationGetDescr(pg_authmem_rel);
- /*
- * Secure exclusive lock to protect our update of the flat group file.
- */
- pg_group_rel = heap_open(GroupRelationId, ExclusiveLock);
+ forboth(nameitem, memberNames, iditem, memberIds)
+ {
+ const char *membername = strVal(lfirst(nameitem));
+ Oid memberid = lfirst_oid(iditem);
+ HeapTuple authmem_tuple;
- /* Find and delete the group. */
+ /*
+ * Find entry for this role/member
+ */
+ authmem_tuple = SearchSysCache(AUTHMEMROLEMEM,
+ ObjectIdGetDatum(roleid),
+ ObjectIdGetDatum(memberid),
+ 0, 0);
+ if (!HeapTupleIsValid(authmem_tuple))
+ {
+ ereport(WARNING,
+ (errmsg("role \"%s\" is not a member of role \"%s\"",
+ membername, rolename)));
+ continue;
+ }
- tuple = SearchSysCacheCopy(GRONAME,
- PointerGetDatum(stmt->name),
- 0, 0, 0);
- if (!HeapTupleIsValid(tuple))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("group \"%s\" does not exist", stmt->name)));
+ if (!admin_opt)
+ {
+ /* Remove the entry altogether */
+ simple_heap_delete(pg_authmem_rel, &authmem_tuple->t_self);
+ }
+ else
+ {
+ /* Just turn off the admin option */
+ HeapTuple tuple;
+ Datum new_record[Natts_pg_auth_members];
+ char new_record_nulls[Natts_pg_auth_members];
+ char new_record_repl[Natts_pg_auth_members];
+
+ /* Build a tuple to update with */
+ MemSet(new_record, 0, sizeof(new_record));
+ MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
+ MemSet(new_record_repl, ' ', sizeof(new_record_repl));
+
+ new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(false);
+ new_record_repl[Anum_pg_auth_members_admin_option - 1] = 'r';
+
+ tuple = heap_modifytuple(authmem_tuple, pg_authmem_dsc,
+ new_record,
+ new_record_nulls, new_record_repl);
+ simple_heap_update(pg_authmem_rel, &tuple->t_self, tuple);
+ CatalogUpdateIndexes(pg_authmem_rel, tuple);
+ }
- simple_heap_delete(pg_group_rel, &tuple->t_self);
+ ReleaseSysCache(authmem_tuple);
+ }
/*
* Now we can clean up; but keep lock until commit (to avoid possible
* deadlock when commit code tries to acquire lock).
*/
- heap_close(pg_group_rel, NoLock);
-
- /*
- * Set flag to update flat group file at commit.
- */
- group_file_update_needed();
-}
-
-
-/*
- * Rename group
- */
-void
-RenameGroup(const char *oldname, const char *newname)
-{
- HeapTuple tup;
- Relation rel;
-
- /* ExclusiveLock because we need to update the flat group file */
- rel = heap_open(GroupRelationId, ExclusiveLock);
-
- tup = SearchSysCacheCopy(GRONAME,
- CStringGetDatum(oldname),
- 0, 0, 0);
- if (!HeapTupleIsValid(tup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("group \"%s\" does not exist", oldname)));
-
- /* make sure the new name doesn't exist */
- if (SearchSysCacheExists(GRONAME,
- CStringGetDatum(newname),
- 0, 0, 0))
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_OBJECT),
- errmsg("group \"%s\" already exists", newname)));
-
- /* must be superuser */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to rename groups")));
-
- /* rename */
- namestrcpy(&(((Form_pg_group) GETSTRUCT(tup))->groname), newname);
- simple_heap_update(rel, &tup->t_self, tup);
- CatalogUpdateIndexes(rel, tup);
-
- heap_close(rel, NoLock);
- heap_freetuple(tup);
-
- group_file_update_needed();
+ heap_close(pg_authmem_rel, NoLock);
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#include
#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"
* 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 user id
+ * lookups. Hence, the stored form of the value must provide a numeric o id
* 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
- * user name 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_user name = NULL;
+ const char *actual_role name = NULL;
char *result;
if (strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
{
/* might be a saved userid string */
- AclId savedsys id;
+ Oid savedo id;
char *endptr;
- savedsysid = (AclI d) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
+ savedoid = (Oi d) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
if (endptr != value + NAMEDATALEN + 1 && *endptr == ',')
{
/* syntactically valid, so break out the data */
- usesysid = savedsys id;
+ roleid = savedo id;
is_superuser = (value[NAMEDATALEN] == 'T');
- actual_user name = endptr + 1;
+ actual_role name = endptr + 1;
}
}
- if (usesysid == 0 )
+ if (roleid == InvalidOid )
{
/* not a saved ID, so look it up */
- HeapTuple user Tup;
+ HeapTuple role Tup;
if (!IsTransactionState())
{
return NULL;
}
- userTup = SearchSysCache(SHADOW NAME,
+ roleTup = SearchSysCache(AUTH NAME,
PointerGetDatum(value),
0, 0, 0);
- if (!HeapTupleIsValid(user Tup))
+ if (!HeapTupleIsValid(role Tup))
{
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))->use super;
- actual_user name = value;
+ roleid = HeapTupleGetOid(roleTup) ;
+ is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rol super;
+ actual_role name = value;
- ReleaseSysCache(user Tup);
+ ReleaseSysCache(role Tup);
}
if (doit)
- SetSessionAuthorization(usesys id, is_superuser);
+ SetSessionAuthorization(role id, is_superuser);
- result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_user name));
+ result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_role name));
if (!result)
return NULL;
memset(result, 'x', NAMEDATALEN);
- sprintf(result + NAMEDATALEN, "%c%l u,%s",
+ sprintf(result + NAMEDATALEN, "%c%u,%s",
is_superuser ? 'T' : 'F',
- (unsigned long) usesys id,
- actual_user name);
+ role id,
+ actual_role name);
return result;
}
* assign_session_authorization
*/
const char *value = session_authorization_string;
- AclId savedsys id;
+ Oid savedo id;
char *endptr;
Assert(strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'));
- savedsysid = (AclI d) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
+ savedoid = (Oi d) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ',');
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
AclMode requiredPerms;
Oid relOid;
- AclId userid;
+ Oid userid;
/*
* Only plain-relation RTEs need to be checked here. Subquery RTEs
* 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 $
*
*-------------------------------------------------------------------------
*/
/* Check that aggregate owner has permission to call component fns */
{
HeapTuple procTuple;
- AclId aggOwner;
+ Oid aggOwner;
procTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(aggref->aggfnoid),
* 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 $
*
*-------------------------------------------------------------------------
*/
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,
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)
/*
* 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)
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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,
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);
* 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
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';
}
}
-
/*
- * 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 *user 2 = linitial(*(List **) list);
+ char *role 2 = linitial(*(List **) list);
- return strcmp(user, user 2);
+ return strcmp(role, role 2);
}
/*
- * 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 *us er)
+check_member(const char *role, const char *memb er)
{
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 member s */
+ 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;
}
}
/*
- * 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;
{
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;
}
}
/*
- * 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;
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)
{
char *token;
char *db;
- char *user ;
+ char *role ;
struct addrinfo *gai_result;
struct addrinfo hints;
int ret;
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)
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);
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 */
/*
- * 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)
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 *));
-
- 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);
+ role_sorted = palloc(role_length * sizeof(List *));
+ foreach(line, role_lines)
+ {
+ role_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 */
}
}
/*
* 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;
token = lfirst(line_item);
file_ident_user = token;
- /* Get the PG user name token */
+ /* Get the PG role name 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;
* 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,
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;
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;
* 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 $
*
*-------------------------------------------------------------------------
*/
{
PrivGrantee *newnode = makeNode(PrivGrantee);
- COPY_STRING_FIELD(username);
- COPY_STRING_FIELD(groupname);
+ COPY_STRING_FIELD(rolname);
return newnode;
}
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)
{
return newnode;
}
-static CreateUser Stmt *
-_copyCreateUserStmt(CreateUser Stmt *from)
+static CreateRole Stmt *
+_copyCreateRoleStmt(CreateRole Stmt *from)
{
- CreateUserStmt *newnode = makeNode(CreateUser Stmt);
+ CreateRoleStmt *newnode = makeNode(CreateRole Stmt);
- COPY_STRING_FIELD(user );
+ COPY_STRING_FIELD(role );
COPY_NODE_FIELD(options);
return newnode;
}
-static AlterUser Stmt *
-_copyAlterUserStmt(AlterUser Stmt *from)
+static AlterRole Stmt *
+_copyAlterRoleStmt(AlterRole Stmt *from)
{
- AlterUserStmt *newnode = makeNode(AlterUser Stmt);
+ AlterRoleStmt *newnode = makeNode(AlterRole Stmt);
- COPY_STRING_FIELD(user );
+ COPY_STRING_FIELD(role );
COPY_NODE_FIELD(options);
+ COPY_SCALAR_FIELD(action);
return newnode;
}
-static AlterUser SetStmt *
-_copyAlterUserSetStmt(AlterUser SetStmt *from)
+static AlterRole SetStmt *
+_copyAlterRoleSetStmt(AlterRole SetStmt *from)
{
- AlterUserSetStmt *newnode = makeNode(AlterUser SetStmt);
+ AlterRoleSetStmt *newnode = makeNode(AlterRole SetStmt);
- COPY_STRING_FIELD(user );
+ COPY_STRING_FIELD(role );
COPY_STRING_FIELD(variable);
COPY_NODE_FIELD(value);
return newnode;
}
-static DropUser Stmt *
-_copyDropUserStmt(DropUser Stmt *from)
+static DropRole Stmt *
+_copyDropRoleStmt(DropRole Stmt *from)
{
- DropUserStmt *newnode = makeNode(DropUser Stmt);
+ DropRoleStmt *newnode = makeNode(DropRole Stmt);
- COPY_NODE_FIELD(user s);
+ COPY_NODE_FIELD(role s);
return newnode;
}
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)
{
case T_GrantStmt:
retval = _copyGrantStmt(from);
break;
+ case T_GrantRoleStmt:
+ retval = _copyGrantRoleStmt(from);
+ break;
case T_DeclareCursorStmt:
retval = _copyDeclareCursorStmt(from);
break;
case T_DropPLangStmt:
retval = _copyDropPLangStmt(from);
break;
- case T_CreateUser Stmt:
- retval = _copyCreateUser Stmt(from);
+ case T_CreateRole Stmt:
+ retval = _copyCreateRole Stmt(from);
break;
- case T_AlterUser Stmt:
- retval = _copyAlterUser Stmt(from);
+ case T_AlterRole Stmt:
+ retval = _copyAlterRole Stmt(from);
break;
- case T_AlterUser SetStmt:
- retval = _copyAlterUser SetStmt(from);
+ case T_AlterRole SetStmt:
+ retval = _copyAlterRole SetStmt(from);
break;
- case T_DropUser Stmt:
- retval = _copyDropUser Stmt(from);
+ case T_DropRole Stmt:
+ retval = _copyDropRole Stmt(from);
break;
case T_LockStmt:
retval = _copyLockStmt(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;
* 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:3 7 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.247 2005/06/28 05:08:5 7 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static bool
_equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
{
- COMPARE_STRING_FIELD(username);
- COMPARE_STRING_FIELD(groupname);
+ COMPARE_STRING_FIELD(rolname);
return true;
}
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)
{
}
static bool
-_equalCreateUserStmt(CreateUserStmt *a, CreateUser Stmt *b)
+_equalCreateRoleStmt(CreateRoleStmt *a, CreateRole Stmt *b)
{
- COMPARE_STRING_FIELD(user );
+ COMPARE_STRING_FIELD(role );
COMPARE_NODE_FIELD(options);
return true;
}
static bool
-_equalAlterUserStmt(AlterUserStmt *a, AlterUser Stmt *b)
+_equalAlterRoleStmt(AlterRoleStmt *a, AlterRole Stmt *b)
{
- COMPARE_STRING_FIELD(user );
+ COMPARE_STRING_FIELD(role );
COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(action);
return true;
}
static bool
-_equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUser SetStmt *b)
+_equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRole SetStmt *b)
{
- COMPARE_STRING_FIELD(user );
+ COMPARE_STRING_FIELD(role );
COMPARE_STRING_FIELD(variable);
COMPARE_NODE_FIELD(value);
}
static bool
-_equalDropUserStmt(DropUserStmt *a, DropUser Stmt *b)
+_equalDropRoleStmt(DropRoleStmt *a, DropRole Stmt *b)
{
- COMPARE_NODE_FIELD(user s);
+ COMPARE_NODE_FIELD(role s);
return true;
}
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)
{
case T_GrantStmt:
retval = _equalGrantStmt(a, b);
break;
+ case T_GrantRoleStmt:
+ retval = _equalGrantRoleStmt(a, b);
+ break;
case T_DeclareCursorStmt:
retval = _equalDeclareCursorStmt(a, b);
break;
case T_DropPLangStmt:
retval = _equalDropPLangStmt(a, b);
break;
- case T_CreateUser Stmt:
- retval = _equalCreateUser Stmt(a, b);
+ case T_CreateRole Stmt:
+ retval = _equalCreateRole Stmt(a, b);
break;
- case T_AlterUser Stmt:
- retval = _equalAlterUser Stmt(a, b);
+ case T_AlterRole Stmt:
+ retval = _equalAlterRole Stmt(a, b);
break;
- case T_AlterUser SetStmt:
- retval = _equalAlterUser SetStmt(a, b);
+ case T_AlterRole SetStmt:
+ retval = _equalAlterRole SetStmt(a, b);
break;
- case T_DropUser Stmt:
- retval = _equalDropUser Stmt(a, b);
+ case T_DropRole Stmt:
+ retval = _equalDropRole Stmt(a, b);
break;
case T_LockStmt:
retval = _equalLockStmt(a, 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;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.256 2005/06/26 22:05:3 7 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.257 2005/06/28 05:08:5 7 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
WRITE_BOOL_FIELD(inh);
WRITE_BOOL_FIELD(inFromCl);
WRITE_UINT_FIELD(requiredPerms);
- WRITE_UINT _FIELD(checkAsUser);
+ WRITE_OID _FIELD(checkAsUser);
}
static void
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.179 2005/06/26 22:05:3 7 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.180 2005/06/28 05:08:5 7 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
READ_BOOL_FIELD(inh);
READ_BOOL_FIELD(inFromCl);
READ_UINT_FIELD(requiredPerms);
- READ_UINT _FIELD(checkAsUser);
+ READ_OID _FIELD(checkAsUser);
READ_DONE();
}
*
*
* 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
%type 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 Grant Stmt IndexStmt InsertStmt ListenStmt LoadStmt
LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
- RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt
+ RemoveFuncStmt RemoveOperStmt RenameStmt RevokeRoleStmt Revoke Stmt
RuleActionStmt RuleActionStmtOrEmpty RuleStmt
SelectStmt TransactionStmt TruncateStmt
UnlistenStmt UpdateStmt VacuumStmt
%type opt_lock lock_type cast_context
%type 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 like_including_defaults
-%type user _list
+%type role _list
-%type OptGroupList
-%type OptGroupElem
-
-%type OptUserList
-%type OptUserElem
+%type OptRoleList
+%type OptRoleElem
%type OptSchemaName
%type OptSchemaEltList
%type Iconst
%type Sconst comment_text
-%type UserId opt_boolean ColId_or_Sconst
+%type RoleId opt_granted_by opt_boolean ColId_or_Sconst
%type var_list var_list_or_default
%type ColId ColLabel var_name type_name param_name
%type var_value zone_value
*/
/* ordinary key words in alphabetical order */
-%token ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER
+%token ABORT_P ABSOLUTE_P ACCESS ACTION ADD ADMIN A FTER
AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
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 CREATE USER 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
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
FREEZE FROM FULL FUNCTION
- GLOBAL GRANT GREATEST GROUP_P
+ GLOBAL GRANT GRANTED GR EATEST GROUP_P
HANDLER HAVING HEADER HOLD HOUR_P
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 NOCREATE USER 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
READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT
- ROLLBACK ROW ROWS RULE
+ ROLE ROL LBACK 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
| AlterOwnerStmt
| AlterSeqStmt
| AlterTableStmt
+ | AlterRoleSetStmt
+ | AlterRoleStmt
| AlterUserSetStmt
| AlterUserStmt
| AnalyzeStmt
| CreateStmt
| CreateTableSpaceStmt
| CreateTrigStmt
+ | CreateRoleStmt
| CreateUserStmt
| CreatedbStmt
| DeallocateStmt
| DropStmt
| DropTableSpaceStmt
| DropTrigStmt
+ | DropRoleStmt
| DropUserStmt
| DropdbStmt
| ExecuteStmt
| ExplainStmt
| FetchStmt
+ | GrantRoleStmt
| GrantStmt
| IndexStmt
| InsertStmt
| RemoveFuncStmt
| RemoveOperStmt
| RenameStmt
+ | RevokeRoleStmt
| RevokeStmt
| RuleStmt
| SelectStmt
/*****************************************************************************
*
- * Create a new Postgres DBMS user
+ * Create a new Postgres DBMS role
*
*
*****************************************************************************/
-CreateUser Stmt:
- CREATE USER UserId opt_with OptUser List
+CreateRole Stmt:
+ CREATE ROLE RoleId opt_with OptRole List
{
- CreateUserStmt *n = makeNode(CreateUser Stmt);
- n->user = $3;
+ CreateRoleStmt *n = makeNode(CreateRole Stmt);
+ n->role = $3;
n->options = $5;
$$ = (Node *)n;
}
| /*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
*****************************************************************************/
AlterUserStmt:
- ALTER USER UserId opt_with OptUser List
+ ALTER USER RoleId opt_with OptRole List
{
- AlterUserStmt *n = makeNode(AlterUser Stmt);
- n->user = $3;
+ AlterRoleStmt *n = makeNode(AlterRole Stmt);
+ n->role = $3;
n->options = $5;
$$ = (Node *)n;
}
AlterUserSetStmt:
- ALTER USER User Id SET set_rest
+ ALTER USER Role Id SET set_rest
{
- AlterUserSetStmt *n = makeNode(AlterUser SetStmt);
- n->user = $3;
+ AlterRoleSetStmt *n = makeNode(AlterRole SetStmt);
+ n->role = $3;
n->variable = $5->name;
n->value = $5->args;
$$ = (Node *)n;
}
- | ALTER USER User Id VariableResetStmt
+ | ALTER USER Role Id VariableResetStmt
{
- AlterUserSetStmt *n = makeNode(AlterUser SetStmt);
- n->user = $3;
+ AlterRoleSetStmt *n = makeNode(AlterRole SetStmt);
+ n->role = $3;
n->variable = ((VariableResetStmt *)$4)->name;
n->value = NIL;
$$ = (Node *)n;
;
+/*****************************************************************************
+ *
+ * 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
*****************************************************************************/
DropUserStmt:
- DROP USER user _list
+ DROP USER role _list
{
- DropUserStmt *n = makeNode(DropUser Stmt);
- n->user s = $3;
+ DropRoleStmt *n = makeNode(DropRole Stmt);
+ n->role s = $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)
*/
-OptUser List:
- OptUserList OptUser Elem { $$ = lappend($1, $2); }
+OptRole List:
+ OptRoleList OptRole Elem { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NIL; }
;
-OptUser Elem:
+OptRole Elem:
PASSWORD Sconst
{
$$ = makeDefElem("password", (Node *)makeString($2));
{
$$ = 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 ',' User Id { $$ = lappend($1, makeString($3)); }
- | User Id { $$ = list_make1(makeString($1)); }
+role_list: role_list ',' Role Id { $$ = lappend($1, makeString($3)); }
+ | Role Id { $$ = list_make1(makeString($1)); }
;
/*****************************************************************************
*
- * Create a postgresql group
+ * Create a postgresql group (role without login ability)
*
*
*****************************************************************************/
CreateGroupStmt:
- CREATE GROUP_P UserId opt_with OptGroup List
+ CREATE GROUP_P RoleId opt_with OptRole List
{
- CreateGroupStmt *n = makeNode(CreateGroup Stmt);
- n->nam e = $3;
+ CreateRoleStmt *n = makeNode(CreateRole Stmt);
+ n->rol e = $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));
- }
- ;
-
/*****************************************************************************
*
*****************************************************************************/
AlterGroupStmt:
- ALTER GROUP_P UserId add_drop USER user _list
+ ALTER GROUP_P RoleId add_drop USER role _list
{
- AlterGroupStmt *n = makeNode(AlterGroup Stmt);
- n->nam e = $3;
+ AlterRoleStmt *n = makeNode(AlterRole Stmt);
+ n->rol e = $3;
n->action = $4;
- n->listUsers = $6 ;
+ n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6)) ;
$$ = (Node *)n;
}
;
-add_drop: ADD { $$ = +1; }
- | DROP { $$ = -1; }
- ;
-
/*****************************************************************************
*
*****************************************************************************/
DropGroupStmt:
- DROP GROUP_P UserId
+ DROP GROUP_P role_list
{
- DropGroupStmt *n = makeNode(DropGroup Stmt);
- n->name = $3;
+ DropRoleStmt *n = makeNode(DropRole Stmt);
+ n->roles = $3;
$$ = (Node *)n;
}
;
*****************************************************************************/
CreateSchemaStmt:
- CREATE SCHEMA OptSchemaName AUTHORIZATION User Id OptSchemaEltList
+ CREATE SCHEMA OptSchemaName AUTHORIZATION Role Id OptSchemaEltList
{
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* One can omit the schema name or the authorization id. */
/* Subcommands that are for ALTER TABLE or ALTER INDEX */
alter_rel_cmd:
- /* ALTER [TABLE|INDEX] OWNER TO User Id */
- OWNER TO User Id
+ /* ALTER [TABLE|INDEX] OWNER TO Role Id */
+ OWNER TO Role Id
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_ChangeOwner;
;
+/*****************************************************************************
+ *
+ * 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
| grantee_list ',' grantee { $$ = lappend($1, $3); }
;
-grantee: Col Id
+grantee: Role Id
{
PrivGrantee *n = makeNode(PrivGrantee);
/* This hack lets us avoid reserving PUBLIC as a keyword*/
if (strcmp($1, "public") == 0)
- n->user name = NULL;
+ n->rol name = NULL;
else
- n->username = $1;
- n->groupname = NULL;
+ n->rolname = $1;
$$ = (Node *)n;
}
- | GROUP_P Col Id
+ | GROUP_P Role Id
{
PrivGrantee *n = makeNode(PrivGrantee);
/* Treat GROUP PUBLIC as a synonym for PUBLIC */
if (strcmp($2, "public") == 0)
- n->group name = NULL;
+ n->rol name = NULL;
else
- n->groupname = $2;
- n->username = NULL;
+ n->rolname = $2;
$$ = (Node *)n;
}
;
| /*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); }
n->newname = $7;
$$ = (Node *)n;
}
- | ALTER GROUP_P UserId RENAME TO User Id
+ | ALTER GROUP_P RoleId RENAME TO Role Id
{
RenameStmt *n = makeNode(RenameStmt);
- n->renameType = OBJECT_GROUP ;
+ n->renameType = OBJECT_ROLE ;
n->subname = $3;
n->newname = $6;
$$ = (Node *)n;
n->renameType = OBJECT_TRIGGER;
$$ = (Node *)n;
}
- | ALTER USER UserId RENAME TO User Id
+ | ALTER ROLE RoleId RENAME TO Role Id
{
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;
*
*****************************************************************************/
-AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO User Id
+AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_AGGREGATE;
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER CONVERSION_P any_name OWNER TO User Id
+ | ALTER CONVERSION_P any_name OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_CONVERSION;
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER DATABASE database_name OWNER TO User Id
+ | ALTER DATABASE database_name OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DATABASE;
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER DOMAIN_P any_name OWNER TO User Id
+ | ALTER DOMAIN_P any_name OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DOMAIN;
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER FUNCTION func_name func_args OWNER TO User Id
+ | ALTER FUNCTION func_name func_args OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_FUNCTION;
n->newowner = $7;
$$ = (Node *)n;
}
- | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO User Id
+ | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPERATOR;
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER OPERATOR CLASS any_name USING access_method OWNER TO User Id
+ | ALTER OPERATOR CLASS any_name USING access_method OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS;
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER SCHEMA name OWNER TO User Id
+ | ALTER SCHEMA name OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_SCHEMA;
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER TYPE_P any_name OWNER TO User Id
+ | ALTER TYPE_P any_name OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TYPE;
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER TABLESPACE name OWNER TO User Id
+ | ALTER TABLESPACE name OWNER TO Role Id
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TABLESPACE;
$$ = (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);
Iconst: ICONST { $$ = $1; };
Sconst: SCONST { $$ = $1; };
-User Id: ColId { $$ = $1; };
+Role Id: ColId { $$ = $1; };
/*
* Name classification hierarchy.
| CONVERSION_P
| COPY
| CREATEDB
+ | CREATEROLE
| CREATEUSER
| CSV
| CURSOR
| LOCAL
| LOCATION
| LOCK_P
+ | LOGIN
| MATCH
| MAXVALUE
| MINUTE_P
| NEXT
| NO
| NOCREATEDB
+ | NOCREATEROLE
| NOCREATEUSER
+ | NOLOGIN
| NOTHING
| NOTIFY
| NOWAIT
| CURRENT_DATE
| CURRENT_TIME
| CURRENT_TIMESTAMP
+ | CURRENT_ROLE
| CURRENT_USER
| DEFAULT
| DEFERRABLE
| PRIMARY
| REFERENCES
| SELECT
+ | SESSION_ROLE
| SESSION_USER
| SOME
| SYMMETRIC
| TRUE_P
| UNION
| UNIQUE
+ | ROLE
| USER
| USING
| WHEN
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{"returns", RETURNS},
{"revoke", REVOKE},
{"right", RIGHT},
+ {"role", ROLE},
{"rollback", ROLLBACK},
{"row", ROW},
{"rows", ROWS},
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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
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
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
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
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
*
* 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"
#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"
*
*
* 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
*
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
load_hba();
load_ident();
- load_user();
- load_group();
+ load_role();
#endif
/*
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))
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#include "utils/syscache.h"
-static void setRuleCheckAsUser_Query(Query *qry, AclI d userid);
-static void setRuleCheckAsUser_Expr(Node *node, AclI d userid);
-static bool setRuleCheckAsUser_walker(Node *node, AclI d *context);
+static void setRuleCheckAsUser_Query(Query *qry, Oi d userid);
+static void setRuleCheckAsUser_Expr(Node *node, Oi d userid);
+static bool setRuleCheckAsUser_walker(Node *node, Oi d *context);
/*
* them always.
*/
static void
-setRuleCheckAsUser_Query(Query *qry, AclI d userid)
+setRuleCheckAsUser_Query(Query *qry, Oi d userid)
{
ListCell *l;
* Expression-tree walker to find sublink queries
*/
static void
-setRuleCheckAsUser_Expr(Node *node, AclI d userid)
+setRuleCheckAsUser_Expr(Node *node, Oi d userid)
{
(void) setRuleCheckAsUser_walker(node, &userid);
}
static bool
-setRuleCheckAsUser_walker(Node *node, AclI d *context)
+setRuleCheckAsUser_walker(Node *node, Oi d *context)
{
if (node == NULL)
return false;
* 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 $
*
*-------------------------------------------------------------------------
*/
subrte->checkAsUser = rte->checkAsUser;
rte->requiredPerms = 0; /* no permission check on subquery itself */
- rte->checkAsUser = 0 ;
+ rte->checkAsUser = InvalidOid ;
/*
* FOR UPDATE/SHARE of view?
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.238 2005/06/22 21:14:3 0 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.239 2005/06/28 05:09:0 0 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#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"
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:
case T_CreatedbStmt:
case T_CreateDomainStmt:
case T_CreateFunctionStmt:
- case T_CreateGroup Stmt:
+ case T_CreateRole Stmt:
case T_IndexStmt:
case T_CreatePLangStmt:
case T_CreateOpClassStmt:
case T_CreateTableSpaceStmt:
case T_CreateTrigStmt:
case T_CompositeTypeStmt:
- case T_CreateUserStmt:
case T_ViewStmt:
case T_RemoveAggrStmt:
case T_DropCastStmt:
case T_DropdbStmt:
case T_DropTableSpaceStmt:
case T_RemoveFuncStmt:
- case T_DropGroup Stmt:
+ case T_DropRole Stmt:
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),
}
break;
-
case T_GrantStmt:
ExecuteGrantStmt((GrantStmt *) parsetree);
break;
+ case T_GrantRoleStmt:
+ GrantRole((GrantRoleStmt *) parsetree);
+ break;
+
/*
* ******************************** object creation /
* destruction ********************************
break;
/*
- * ******************************** USER statements ****
+ * ******************************** ROLE statements ****
*/
- case T_CreateUser Stmt:
- CreateUser((CreateUser Stmt *) parsetree);
+ case T_CreateRole Stmt:
+ CreateRole((CreateRole Stmt *) parsetree);
break;
- case T_AlterUser Stmt:
- AlterUser((AlterUser Stmt *) parsetree);
+ case T_AlterRole Stmt:
+ AlterRole((AlterRole Stmt *) parsetree);
break;
- case T_AlterUser SetStmt:
- AlterUserSet((AlterUser SetStmt *) parsetree);
+ case T_AlterRole SetStmt:
+ AlterRoleSet((AlterRole SetStmt *) parsetree);
break;
- case T_DropUser Stmt:
- DropUser((DropUser Stmt *) parsetree);
+ case T_DropRole Stmt:
+ DropRole((DropRole Stmt *) parsetree);
break;
case T_LockStmt:
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,
case OBJECT_FUNCTION:
tag = "ALTER FUNCTION";
break;
- case OBJECT_GROUP:
- tag = "ALTER GROUP";
- break;
case OBJECT_INDEX:
tag = "ALTER INDEX";
break;
case OBJECT_OPCLASS:
tag = "ALTER OPERATOR CLASS";
break;
+ case OBJECT_ROLE:
+ tag = "ALTER ROLE";
+ break;
case OBJECT_SCHEMA:
tag = "ALTER SCHEMA";
break;
case OBJECT_TRIGGER:
tag = "ALTER TRIGGER";
break;
- case OBJECT_USER:
- tag = "ALTER USER";
- break;
default:
tag = "ALTER TABLE";
}
}
break;
+ case T_GrantRoleStmt:
+ {
+ GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
+
+ tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
+ }
+ break;
+
case T_DefineStmt:
switch (((DefineStmt *) parsetree)->kind)
{
tag = "DROP LANGUAGE";
break;
- case T_CreateUser Stmt:
- tag = "CREATE USER ";
+ case T_CreateRole Stmt:
+ tag = "CREATE ROLE ";
break;
- case T_AlterUser Stmt:
- tag = "ALTER USER ";
+ case T_AlterRole Stmt:
+ tag = "ALTER ROLE ";
break;
- case T_AlterUser SetStmt:
- tag = "ALTER USER ";
+ case T_AlterRole SetStmt:
+ tag = "ALTER ROLE ";
break;
- case T_DropUser Stmt:
- tag = "DROP USER ";
+ case T_DropRole Stmt:
+ tag = "DROP ROLE ";
break;
case T_LockStmt:
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;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.114 2005/05/27 00:57:49 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.115 2005/06/28 05:09:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include
#include "catalog/namespace.h"
-#include "catalog/pg_group .h"
-#include "catalog/pg_shadow .h"
+#include "catalog/pg_authid .h"
+#include "catalog/pg_auth_members .h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/catcache.h"
+#include "utils/inval.h"
#include "utils/lsyscache.h"
+#include "utils/memutils.h"
#include "utils/syscache.h"
-#define ACL_IDTYPE_GID_KEYWORD "group"
-#define ACL_IDTYPE_UID_KEYWORD "user"
+#define ACL_IDTYPE_ROLE_KEYWORD "role"
+
+/* The rolmemcache is a possibly-empty list of role OIDs.
+ * rolmemRole is the Role for which the cache was generated.
+ * In the event of a Role change the cache will be regenerated.
+ */
+static List *rolmemcache = NIL;
+static Oid rolmemRole = InvalidOid;
+
+/* rolmemcache and rolmemRole only valid when
+ * rolmemcacheValid is true */
+static bool rolmemcacheValid = false;
static const char *getid(const char *s, char *n);
static void putid(char *p, const char *s);
static const char *aclparse(const char *s, AclItem *aip);
static bool aclitem_match(const AclItem *a1, const AclItem *a2);
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
- AclId ownerid);
-static Acl *recursive_revoke(Acl *acl, AclId grantee, AclMode revoke_privs,
- AclId ownerid, DropBehavior behavior);
-static bool in_group(AclId uid, AclId gid);
+ Oid ownerId);
+static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs,
+ Oid ownerId, DropBehavior behavior);
static AclMode convert_priv_string(text *priv_type_text);
static Oid convert_tablespace_name(text *tablespacename);
static AclMode convert_tablespace_priv_string(text *priv_type_text);
+static void RolMemCacheCallback(Datum arg, Oid relid);
+static void recomputeRolMemCache(Oid roleid);
+
/*
* getid
AclMode privs,
goption,
read;
- uint32 idtype;
char name[NAMEDATALEN];
char name2[NAMEDATALEN];
#ifdef ACLDEBUG
elog(LOG, "aclparse: input = \"%s\"", s);
#endif
- idtype = ACL_IDTYPE_UID;
s = getid(s, name);
if (*s != '=')
{
/* we just read a keyword, not a name */
- if (strcmp(name, ACL_IDTYPE_GID_KEYWORD) == 0)
- idtype = ACL_IDTYPE_GID;
- else if (strcmp(name, ACL_IDTYPE_UID_KEYWORD) != 0)
+ if (strcmp(name, ACL_IDTYPE_ROLE_KEYWORD) != 0)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("unrecognized key word: \"%s\"", name),
- errhint("ACL key word must be \"group\" or \"user \".")));
+ errhint("ACL key word must be \"role \".")));
s = getid(s, name); /* move s to the name beyond the keyword */
if (name[0] == '\0')
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("missing name"),
- errhint("A name must follow the \"group\" or \"user \" key word.")));
+ errhint("A name must follow the \"role \" key word.")));
}
- if (name[0] == '\0')
- idtype = ACL_IDTYPE_WORLD;
if (*s != '=')
ereport(ERROR,
privs |= read;
}
- switch (idtype)
- {
- case ACL_IDTYPE_UID:
- aip->ai_grantee = get_usesysid(name);
- break;
- case ACL_IDTYPE_GID:
- aip->ai_grantee = get_grosysid(name);
- break;
- case ACL_IDTYPE_WORLD:
- aip->ai_grantee = ACL_ID_WORLD;
- break;
- }
+ if (name[0] == '\0')
+ aip->ai_grantee = ACL_ID_PUBLIC;
+ else
+ aip->ai_grantee = get_roleid_checked(name);
/*
* XXX Allow a degree of backward compatibility by defaulting the
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("a name must follow the \"/\" sign")));
-
- aip->ai_grantor = get_usesysid(name2);
+ aip->ai_grantor = get_roleid_checked(name2);
}
else
{
- aip->ai_grantor = BOOTSTRAP_USESYS ID;
+ aip->ai_grantor = BOOTSTRAP_SUPERUSER ID;
ereport(WARNING,
(errcode(ERRCODE_INVALID_GRANTOR),
- errmsg("defaulting grantor to user ID %u", BOOTSTRAP_USESYSID)));
+ errmsg("defaulting grantor to user ID %u",
+ BOOTSTRAP_SUPERUSERID)));
}
- ACLITEM_SET_PRIVS_IDTYPE(*aip, privs, goption, idtype );
+ ACLITEM_SET_PRIVS_GOPTIONS(*aip, privs, goption );
#ifdef ACLDEBUG
- elog(LOG, "aclparse: correctly read [%x %d %x]",
- idtype, aip->ai_grantee, privs );
+ elog(LOG, "aclparse: correctly read [%u %x %x]",
+ aip->ai_grantee, privs, goption );
#endif
+
return s;
}
char *out;
HeapTuple htup;
unsigned i;
- char *tmpname;
out = palloc(strlen("group =/") +
2 * N_ACL_RIGHTS +
p = out;
*p = '\0';
- switch (ACLITEM_GET_IDTYPE(*aip) )
+ if (aip->ai_grantee != ACL_ID_PUBLIC )
{
- case ACL_IDTYPE_UID:
- htup = SearchSysCache(SHADOWSYSID,
- ObjectIdGetDatum(aip->ai_grantee),
- 0, 0, 0);
- if (HeapTupleIsValid(htup))
- {
- putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename));
- ReleaseSysCache(htup);
- }
- else
- {
- /* Generate numeric UID if we don't find an entry */
- sprintf(p, "%d", aip->ai_grantee);
- }
- break;
- case ACL_IDTYPE_GID:
- strcpy(p, "group ");
- p += strlen(p);
- tmpname = get_groname(aip->ai_grantee);
- if (tmpname != NULL)
- putid(p, tmpname);
- else
- {
- /* Generate numeric GID if we don't find an entry */
- sprintf(p, "%d", aip->ai_grantee);
- }
- break;
- case ACL_IDTYPE_WORLD:
- break;
- default:
- elog(ERROR, "unrecognized idtype: %d",
- (int) ACLITEM_GET_IDTYPE(*aip));
- break;
+ htup = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(aip->ai_grantee),
+ 0, 0, 0);
+ if (HeapTupleIsValid(htup))
+ {
+ putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname));
+ ReleaseSysCache(htup);
+ }
+ else
+ {
+ /* Generate numeric OID if we don't find an entry */
+ sprintf(p, "%u", aip->ai_grantee);
+ }
}
while (*p)
++p;
*p++ = '/';
*p = '\0';
- htup = SearchSysCache(SHADOWSYS ID,
+ htup = SearchSysCache(AUTHO ID,
ObjectIdGetDatum(aip->ai_grantor),
0, 0, 0);
if (HeapTupleIsValid(htup))
{
- putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->use name));
+ putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rol name));
ReleaseSysCache(htup);
}
else
{
- /* Generate numeric U ID if we don't find an entry */
- sprintf(p, "%d ", aip->ai_grantor);
+ /* Generate numeric O ID if we don't find an entry */
+ sprintf(p, "%u ", aip->ai_grantor);
}
while (*p)
static bool
aclitem_match(const AclItem *a1, const AclItem *a2)
{
- return ACLITEM_GET_IDTYPE(*a1) == ACLITEM_GET_IDTYPE(*a2) &&
- a1->ai_grantee == a2->ai_grantee &&
+ return a1->ai_grantee == a2->ai_grantee &&
a1->ai_grantor == a2->ai_grantor;
}
* newly-created objects (or any object with a NULL acl entry).
*/
Acl *
-acldefault(GrantObjectType objtype, AclId owneri d)
+acldefault(GrantObjectType objtype, Oid ownerI d)
{
AclMode world_default;
AclMode owner_default;
if (world_default != ACL_NO_RIGHTS)
{
- aip->ai_grantee = ACL_ID_WORLD;
- aip->ai_grantor = ownerid;
- ACLITEM_SET_PRIVS_IDTYPE(*aip, world_default, ACL_NO_RIGHTS,
- ACL_IDTYPE_WORLD);
+ aip->ai_grantee = ACL_ID_PUBLIC;
+ aip->ai_grantor = ownerId;
+ ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS);
aip++;
}
* without any explicit "_SYSTEM"-like ACL entry, by internally
* special-casing the owner whereever we are testing grant options.
*/
- aip->ai_grantee = ownerid;
- aip->ai_grantor = ownerid;
- ACLITEM_SET_PRIVS_IDTYPE(*aip, owner_default, ACL_NO_RIGHTS,
- ACL_IDTYPE_UID);
+ aip->ai_grantee = ownerId;
+ aip->ai_grantor = ownerId;
+ ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS);
return acl;
}
* old_acl: the input ACL array
* mod_aip: defines the privileges to be added, removed, or substituted
* modechg: ACL_MODECHG_ADD, ACL_MODECHG_DEL, or ACL_MODECHG_EQL
- * ownerid: AclI d of object owner
+ * ownerId: Oi d of object owner
* behavior: RESTRICT or CASCADE behavior for recursive removal
*
* ownerid and behavior are only relevant when the update operation specifies
*/
Acl *
aclupdate(const Acl *old_acl, const AclItem *mod_aip,
- int modechg, AclId owneri d, DropBehavior behavior)
+ int modechg, Oid ownerI d, DropBehavior behavior)
{
Acl *new_acl = NULL;
AclItem *old_aip,
/* If granting grant options, check for circularity */
if (modechg != ACL_MODECHG_DEL &&
ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS)
- check_circularity(old_acl, mod_aip, owneri d);
+ check_circularity(old_acl, mod_aip, ownerI d);
num = ACL_NUM(old_acl);
old_aip = ACL_DAT(old_acl);
/* initialize the new entry with no permissions */
new_aip[dst].ai_grantee = mod_aip->ai_grantee;
new_aip[dst].ai_grantor = mod_aip->ai_grantor;
- ACLITEM_SET_PRIVS_IDTYPE(new_aip[dst],
- ACL_NO_RIGHTS, ACL_NO_RIGHTS,
- ACLITEM_GET_IDTYPE(*mod_aip));
+ ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst],
+ ACL_NO_RIGHTS, ACL_NO_RIGHTS);
num++; /* set num to the size of new_acl */
}
/*
* Remove abandoned privileges (cascading revoke). Currently we can
- * only handle this when the grantee is a user .
+ * only handle this when the grantee is not PUBLIC .
*/
if ((old_goptions & ~new_goptions) != 0)
{
- Assert(ACLITEM_GET_IDTYPE(*mod_aip) == ACL_IDTYPE_UID );
+ Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC );
new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee,
(old_goptions & ~new_goptions),
- owneri d, behavior);
+ ownerI d, behavior);
}
return new_acl;
* Update an ACL array to reflect a change of owner to the parent object
*
* old_acl: the input ACL array (must not be NULL)
- * oldownerid: AclI d of the old object owner
- * newownerid: AclI d of the new object owner
+ * oldOwnerId: Oi d of the old object owner
+ * newOwnerId: Oi d of the new object owner
*
* The result is a modified copy; the input object is not changed.
*
* NB: caller is responsible for having detoasted the input ACL, if needed.
*/
Acl *
-aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newowneri d)
+aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerI d)
{
Acl *new_acl;
AclItem *new_aip;
memcpy(new_aip, old_aip, num * sizeof(AclItem));
for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
{
- /* grantor is always a UID, but grantee might not be */
- if (dst_aip->ai_grantor == oldownerid)
- dst_aip->ai_grantor = newownerid;
- else if (dst_aip->ai_grantor == newownerid)
+ if (dst_aip->ai_grantor == oldOwnerId)
+ dst_aip->ai_grantor = newOwnerId;
+ else if (dst_aip->ai_grantor == newOwnerId)
+ newpresent = true;
+ if (dst_aip->ai_grantee == oldOwnerId)
+ dst_aip->ai_grantee = newOwnerId;
+ else if (dst_aip->ai_grantee == newOwnerId)
newpresent = true;
- if (ACLITEM_GET_IDTYPE(*dst_aip) == ACL_IDTYPE_UID)
- {
- if (dst_aip->ai_grantee == oldownerid)
- dst_aip->ai_grantee = newownerid;
- else if (dst_aip->ai_grantee == newownerid)
- newpresent = true;
- }
}
/*
*/
static void
check_circularity(const Acl *old_acl, const AclItem *mod_aip,
- AclId owneri d)
+ Oid ownerI d)
{
Acl *acl;
AclItem *aip;
AclMode own_privs;
/*
- * For now, grant options can only be granted to users, not groups or
- * PUBLIC. Otherwise we'd have to work a bit harder here.
+ * For now, grant options can only be granted to roles, not PUBLIC.
+ * Otherwise we'd have to work a bit harder here.
*/
- Assert(ACLITEM_GET_IDTYPE(*mod_aip) == ACL_IDTYPE_UID );
+ Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC );
/* The owner always has grant options, no need to check */
- if (mod_aip->ai_grantor == owneri d)
+ if (mod_aip->ai_grantor == ownerI d)
return;
/* Make a working copy */
aip = ACL_DAT(acl);
for (i = 0; i < num; i++)
{
- if (ACLITEM_GET_IDTYPE(aip[i]) == ACL_IDTYPE_UID &&
- aip[i].ai_grantee == mod_aip->ai_grantee &&
+ if (aip[i].ai_grantee == mod_aip->ai_grantee &&
ACLITEM_GET_GOPTIONS(aip[i]) != ACL_NO_RIGHTS)
{
Acl *new_acl;
/* We'll actually zap ordinary privs too, but no matter */
new_acl = aclupdate(acl, &aip[i], ACL_MODECHG_DEL,
- owneri d, DROP_CASCADE);
+ ownerI d, DROP_CASCADE);
pfree(acl);
acl = new_acl;
/* Now we can compute grantor's independently-derived privileges */
own_privs = aclmask(acl,
mod_aip->ai_grantor,
- owneri d,
+ ownerI d,
ACL_GRANT_OPTION_FOR(ACLITEM_GET_GOPTIONS(*mod_aip)),
ACLMASK_ALL);
own_privs = ACL_OPTION_TO_PRIVS(own_privs);
* acl: the input ACL list
* grantee: the user from whom some grant options have been revoked
* revoke_privs: the grant options being revoked
- * ownerid: AclI d of object owner
+ * ownerId: Oi d of object owner
* behavior: RESTRICT or CASCADE behavior for recursive removal
*
* The input Acl object is pfree'd if replaced.
*/
static Acl *
recursive_revoke(Acl *acl,
- AclI d grantee,
+ Oi d grantee,
AclMode revoke_privs,
- AclId owneri d,
+ Oid ownerI d,
DropBehavior behavior)
{
AclMode still_has;
num;
/* The owner can never truly lose grant options, so short-circuit */
- if (grantee == owneri d)
+ if (grantee == ownerI d)
return acl;
/* The grantee might still have the privileges via another grantor */
- still_has = aclmask(acl, grantee, owneri d,
+ still_has = aclmask(acl, grantee, ownerI d,
ACL_GRANT_OPTION_FOR(revoke_privs),
ACLMASK_ALL);
revoke_privs &= ~still_has;
mod_acl.ai_grantor = grantee;
mod_acl.ai_grantee = aip[i].ai_grantee;
- ACLITEM_SET_PRIVS_IDTYPE(mod_acl,
- revoke_privs,
- revoke_privs,
- ACLITEM_GET_IDTYPE(aip[i]));
+ ACLITEM_SET_PRIVS_GOPTIONS(mod_acl,
+ revoke_privs,
+ revoke_privs);
new_acl = aclupdate(acl, &mod_acl, ACL_MODECHG_DEL,
- owneri d, behavior);
+ ownerI d, behavior);
pfree(acl);
acl = new_acl;
/*
- * aclmask --- compute bitmask of all privileges held by user id.
+ * aclmask --- compute bitmask of all privileges held by role id.
*
* When 'how' = ACLMASK_ALL, this simply returns the privilege bits
- * held by the given user id according to the given ACL list, ANDed
+ * held by the given role id according to the given ACL list, ANDed
* with 'mask'. (The point of passing 'mask' is to let the routine
* exit early if all privileges of interest have been found.)
*
* Usage patterns:
*
* To see if any of a set of privileges are held:
- * if (aclmask(acl, userid, owneri d, privs, ACLMASK_ANY) != 0)
+ * if (aclmask(acl, roleid, ownerI d, privs, ACLMASK_ANY) != 0)
*
* To see if all of a set of privileges are held:
- * if (aclmask(acl, userid, owneri d, privs, ACLMASK_ALL) == privs)
+ * if (aclmask(acl, roleid, ownerI d, privs, ACLMASK_ALL) == privs)
*
* To determine exactly which of a set of privileges are held:
- * heldprivs = aclmask(acl, userid, ownerid, privs, ACLMASK_ALL);
+ * heldprivs = aclmask(acl, roleid, ownerId, privs, ACLMASK_ALL);
+ *
*/
AclMode
-aclmask(const Acl *acl, AclId userid, AclId owneri d,
+aclmask(const Acl *acl, Oid roleid, Oid ownerI d,
AclMode mask, AclMaskHow how)
{
AclMode result;
- AclMode remaining;
AclItem *aidat;
int i,
num;
result = 0;
/* Owner always implicitly has all grant options */
- if (userid == ownerid )
+ if (is_member_of_role(roleid,ownerId) )
{
result = mask & ACLITEM_ALL_GOPTION_BITS;
if (result == mask)
aidat = ACL_DAT(acl);
/*
- * Check privileges granted directly to user or to public
- */
- for (i = 0; i < num; i++)
- {
- AclItem *aidata = &aidat[i];
-
- if (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_WORLD
- || (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_UID
- && aidata->ai_grantee == userid))
- {
- result |= (aidata->ai_privs & mask);
- if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
- return result;
- }
- }
-
- /*
- * Check privileges granted via groups. We do this in a separate pass
- * to minimize expensive lookups in pg_group.
+ * Check privileges granted directly to role, indirectly
+ * via role membership or to public
*/
- remaining = (mask & ~result);
for (i = 0; i < num; i++)
{
AclItem *aidata = &aidat[i];
- if (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_GID
- && (aidata->ai_privs & remaining)
- && in_group(userid, aidata->ai_grantee))
+ if (aidata->ai_grantee == ACL_ID_PUBLIC ||
+ is_member_of_role(roleid, aidata->ai_grantee))
{
result |= (aidata->ai_privs & mask);
if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0))
return result;
- remaining = (mask & ~result);
}
}
/*
- * Is user a member of group?
+ * Is member a member of role?
+ * relmemcache includes the role itself too
*/
-static bool
-in_group(AclId uid, AclId gid)
-{
- bool result = false;
- HeapTuple tuple;
- Datum att;
- bool isNull;
- IdList *glist;
- AclId *aidp;
- int i,
- num;
+bool
+is_member_of_role(Oid member, Oid role)
+{
+ /* Fast path for simple case */
+ if (member == role)
+ return true;
- tuple = SearchSysCache(GROSYSID,
- ObjectIdGetDatum(gid),
- 0, 0, 0);
- if (HeapTupleIsValid(tuple))
- {
- att = SysCacheGetAttr(GROSYSID,
- tuple,
- Anum_pg_group_grolist,
- &isNull);
- if (!isNull)
- {
- /* be sure the IdList is not toasted */
- glist = DatumGetIdListP(att);
- /* scan it */
- num = IDLIST_NUM(glist);
- aidp = IDLIST_DAT(glist);
- for (i = 0; i < num; ++i)
- {
- if (aidp[i] == uid)
- {
- result = true;
- break;
- }
- }
- /* if IdList was toasted, free detoasted copy */
- if ((Pointer) glist != DatumGetPointer(att))
- pfree(glist);
- }
- ReleaseSysCache(tuple);
- }
- else
- ereport(WARNING,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("group with ID %u does not exist", gid)));
- return result;
+ recomputeRolMemCache(member);
+
+ return list_member_oid(rolmemcache, role);
}
aidat = ACL_DAT(acl);
for (i = 0; i < num; ++i)
{
- if (aip->ai_grantee == aidat[i].ai_grantee
- && ACLITEM_GET_IDTYPE(*aip) == ACLITEM_GET_IDTYPE(aidat[i])
- && aip->ai_grantor == aidat[i].ai_grantor
- && (ACLITEM_GET_RIGHTS(*aip) & ACLITEM_GET_RIGHTS(aidat[i])) == ACLITEM_GET_RIGHTS(*aip))
+ if (aip->ai_grantee == aidat[i].ai_grantee &&
+ aip->ai_grantor == aidat[i].ai_grantor &&
+ (ACLITEM_GET_RIGHTS(*aip) & ACLITEM_GET_RIGHTS(aidat[i])) == ACLITEM_GET_RIGHTS(*aip))
PG_RETURN_BOOL(true);
}
PG_RETURN_BOOL(false);
Datum
makeaclitem(PG_FUNCTION_ARGS)
{
- int32 u_grantee = PG_GETARG_INT32(0);
- int32 g_grantee = PG_GETARG_INT32(1);
- int32 grantor = PG_GETARG_INT32(2);
- text *privtext = PG_GETARG_TEXT_P(3);
- bool goption = PG_GETARG_BOOL(4);
+ Oid grantee = PG_GETARG_OID(0);
+ Oid grantor = PG_GETARG_OID(1);
+ text *privtext = PG_GETARG_TEXT_P(2);
+ bool goption = PG_GETARG_BOOL(3);
AclItem *aclitem;
AclMode priv;
priv = convert_priv_string(privtext);
- aclitem = (AclItem *) palloc(sizeof(*acli tem));
+ aclitem = (AclItem *) palloc(sizeof(AclI tem));
- if (u_grantee == 0 && g_grantee == 0)
- {
- aclitem ->ai_grantee = ACL_ID_WORLD;
+ aclitem->ai_grantee = grantee;
+ aclitem->ai_grantor = grantor;
- ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_WORLD);
- }
- else if (u_grantee != 0 && g_grantee != 0)
- {
- ereport(ERROR,
- (errcode(ERRCODE_DATA_EXCEPTION),
- errmsg("cannot specify both user and group")));
- }
- else if (u_grantee != 0)
- {
- aclitem ->ai_grantee = u_grantee;
-
- ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_UID);
- }
- else
- /* (g_grantee != 0) */
- {
- aclitem ->ai_grantee = g_grantee;
-
- ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_GID);
- }
-
- aclitem ->ai_grantor = grantor;
-
- ACLITEM_SET_PRIVS(*aclitem, priv);
- if (goption)
- ACLITEM_SET_GOPTIONS(*aclitem, priv);
- else
- ACLITEM_SET_GOPTIONS(*aclitem, ACL_NO_RIGHTS);
+ ACLITEM_SET_PRIVS_GOPTIONS(*aclitem, priv,
+ (goption ? priv : ACL_NO_RIGHTS));
PG_RETURN_ACLITEM_P(aclitem);
}
* has_table_privilege variants
* These are all named "has_table_privilege" at the SQL level.
* They take various combinations of relation name, relation OID,
- * user name, user sysid , or implicit user = current_user.
+ * user name, user OID , or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
Datum
has_table_privilege_name_name(PG_FUNCTION_ARGS)
{
- Name user name = PG_GETARG_NAME(0);
+ Name role name = PG_GETARG_NAME(0);
text *tablename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
Oid tableoid;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*rolename));
+
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesys id, mode);
+ aclresult = pg_class_aclcheck(tableoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
text *tablename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
Oid tableoid;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesys id, mode);
+ aclresult = pg_class_aclcheck(tableoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
Name username = PG_GETARG_NAME(0);
Oid tableoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesys id, mode);
+ aclresult = pg_class_aclcheck(tableoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
Oid tableoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesys id, mode);
+ aclresult = pg_class_aclcheck(tableoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_id_name
* Check user privileges on a table given
- * usesys id, text tablename, and text priv name.
+ * role id, text tablename, and text priv name.
*/
Datum
has_table_privilege_id_name(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
text *tablename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid tableoid;
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesys id, mode);
+ aclresult = pg_class_aclcheck(tableoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_id_id
* Check user privileges on a table given
- * usesys id, table oid, and text priv name.
+ * role id, table oid, and text priv name.
*/
Datum
has_table_privilege_id_id(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Oid tableoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesys id, mode);
+ aclresult = pg_class_aclcheck(tableoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
* has_database_privilege variants
* These are all named "has_database_privilege" at the SQL level.
* They take various combinations of database name, database OID,
- * user name, user sysid , or implicit user = current_user.
+ * user name, user OID , or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
Name username = PG_GETARG_NAME(0);
text *databasename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
Oid databaseoid;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesys id, mode);
+ aclresult = pg_database_aclcheck(databaseoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
text *databasename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
Oid databaseoid;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesys id, mode);
+ aclresult = pg_database_aclcheck(databaseoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
Name username = PG_GETARG_NAME(0);
Oid databaseoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesys id, mode);
+ aclresult = pg_database_aclcheck(databaseoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
Oid databaseoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesys id, mode);
+ aclresult = pg_database_aclcheck(databaseoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_id_name
* Check user privileges on a database given
- * usesys id, text databasename, and text priv name.
+ * role id, text databasename, and text priv name.
*/
Datum
has_database_privilege_id_name(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
text *databasename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid databaseoid;
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesys id, mode);
+ aclresult = pg_database_aclcheck(databaseoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_id_id
* Check user privileges on a database given
- * usesys id, database oid, and text priv name.
+ * role id, database oid, and text priv name.
*/
Datum
has_database_privilege_id_id(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Oid databaseoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesys id, mode);
+ aclresult = pg_database_aclcheck(databaseoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
* has_function_privilege variants
* These are all named "has_function_privilege" at the SQL level.
* They take various combinations of function name, function OID,
- * user name, user sysid , or implicit user = current_user.
+ * user name, user OID , or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
Name username = PG_GETARG_NAME(0);
text *functionname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
Oid functionoid;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesys id, mode);
+ aclresult = pg_proc_aclcheck(functionoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
text *functionname = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
Oid functionoid;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesys id, mode);
+ aclresult = pg_proc_aclcheck(functionoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
Name username = PG_GETARG_NAME(0);
Oid functionoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesys id, mode);
+ aclresult = pg_proc_aclcheck(functionoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
Oid functionoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesys id, mode);
+ aclresult = pg_proc_aclcheck(functionoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_id_name
* Check user privileges on a function given
- * usesys id, text functionname, and text priv name.
+ * role id, text functionname, and text priv name.
*/
Datum
has_function_privilege_id_name(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
text *functionname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid functionoid;
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesys id, mode);
+ aclresult = pg_proc_aclcheck(functionoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_id_id
* Check user privileges on a function given
- * usesys id, function oid, and text priv name.
+ * role id, function oid, and text priv name.
*/
Datum
has_function_privilege_id_id(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Oid functionoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesys id, mode);
+ aclresult = pg_proc_aclcheck(functionoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
* has_language_privilege variants
* These are all named "has_language_privilege" at the SQL level.
* They take various combinations of language name, language OID,
- * user name, user sysid , or implicit user = current_user.
+ * user name, user OID , or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
Name username = PG_GETARG_NAME(0);
text *languagename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
Oid languageoid;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesys id, mode);
+ aclresult = pg_language_aclcheck(languageoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
text *languagename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
Oid languageoid;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesys id, mode);
+ aclresult = pg_language_aclcheck(languageoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
Name username = PG_GETARG_NAME(0);
Oid languageoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesys id, mode);
+ aclresult = pg_language_aclcheck(languageoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
Oid languageoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesys id, mode);
+ aclresult = pg_language_aclcheck(languageoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_id_name
* Check user privileges on a language given
- * usesys id, text languagename, and text priv name.
+ * role id, text languagename, and text priv name.
*/
Datum
has_language_privilege_id_name(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
text *languagename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid languageoid;
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesys id, mode);
+ aclresult = pg_language_aclcheck(languageoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_id_id
* Check user privileges on a language given
- * usesys id, language oid, and text priv name.
+ * role id, language oid, and text priv name.
*/
Datum
has_language_privilege_id_id(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Oid languageoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesys id, mode);
+ aclresult = pg_language_aclcheck(languageoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
* has_schema_privilege variants
* These are all named "has_schema_privilege" at the SQL level.
* They take various combinations of schema name, schema OID,
- * user name, user sysid , or implicit user = current_user.
+ * user name, user OID , or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
Name username = PG_GETARG_NAME(0);
text *schemaname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
Oid schemaoid;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesys id, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
text *schemaname = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
Oid schemaoid;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesys id, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
Name username = PG_GETARG_NAME(0);
Oid schemaoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesys id, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
Oid schemaoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesys id, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_id_name
* Check user privileges on a schema given
- * usesys id, text schemaname, and text priv name.
+ * role id, text schemaname, and text priv name.
*/
Datum
has_schema_privilege_id_name(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
text *schemaname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid schemaoid;
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesys id, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_id_id
* Check user privileges on a schema given
- * usesys id, schema oid, and text priv name.
+ * role id, schema oid, and text priv name.
*/
Datum
has_schema_privilege_id_id(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Oid schemaoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesys id, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
* has_tablespace_privilege variants
* These are all named "has_tablespace_privilege" at the SQL level.
* They take various combinations of tablespace name, tablespace OID,
- * user name, user sysid , or implicit user = current_user.
+ * user name, user OID , or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
Name username = PG_GETARG_NAME(0);
text *tablespacename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
Oid tablespaceoid;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesys id, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
text *tablespacename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
Oid tablespaceoid;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesys id, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
Name username = PG_GETARG_NAME(0);
Oid tablespaceoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesysid = get_usesysid(NameStr(*username));
+ roleid = get_roleid_checked(NameStr(*username));
+
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesys id, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
{
Oid tablespaceoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesys id;
+ Oid role id;
AclMode mode;
AclResult aclresult;
- usesys id = GetUserId();
+ role id = GetUserId();
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesys id, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_tablespace_privilege_id_name
* Check user privileges on a tablespace given
- * usesys id, text tablespacename, and text priv name.
+ * role id, text tablespacename, and text priv name.
*/
Datum
has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
text *tablespacename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid tablespaceoid;
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesys id, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_tablespace_privilege_id_id
* Check user privileges on a tablespace given
- * usesys id, tablespace oid, and text priv name.
+ * role id, tablespace oid, and text priv name.
*/
Datum
has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
{
- int32 usesysid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Oid tablespaceoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesys id, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, role id, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
errmsg("unrecognized privilege type: \"%s\"", priv_type)));
return ACL_NO_RIGHTS; /* keep compiler quiet */
}
+
+void
+InitializeAcl(void)
+{
+ if (!IsBootstrapProcessingMode())
+ {
+ /*
+ * In normal mode, set a callback on any syscache
+ * invalidation of pg_auth_members rows
+ */
+ CacheRegisterSyscacheCallback(AUTHMEMROLEMEM,
+ RolMemCacheCallback,
+ (Datum) 0);
+
+ /* Force role/member cache to be recomputed on next use */
+ rolmemcacheValid = false;
+ }
+}
+
+/*
+ * RolMemCacheCallback
+ * Syscache inval callback function
+ */
+static void
+RolMemCacheCallback(Datum arg, Oid relid)
+{
+ /* Force role/member cache to be recomputed on next use */
+ rolmemcacheValid = false;
+}
+
+
+/*
+ * recomputeRolMemCache - recompute the role/member cache if needed
+ */
+static void
+recomputeRolMemCache(Oid roleid)
+{
+ int i;
+ Oid memberOid;
+ List *roles_list_hunt = NIL;
+ List *roles_list = NIL;
+ List *newrolmemcache;
+ CatCList *memlist;
+ MemoryContext oldctx;
+
+ /* Do nothing if rolmemcache is already valid */
+ if (rolmemcacheValid && rolmemRole == roleid)
+ return;
+
+ if (rolmemRole != roleid)
+ rolmemcacheValid = false;
+
+ /*
+ * Find all the roles which this role is a member of,
+ * including multi-level recursion
+ */
+
+ /*
+ * Include the current role itself to simplify checks
+ * later on, also should be at the head so lookup should
+ * be fast.
+ */
+ roles_list = lappend_oid(roles_list, roleid);
+ roles_list_hunt = lappend_oid(roles_list_hunt, roleid);
+
+ while (roles_list_hunt)
+ {
+ memberOid = linitial_oid(roles_list_hunt);
+ memlist = SearchSysCacheList(AUTHMEMMEMROLE, 1,
+ ObjectIdGetDatum(memberOid),
+ 0, 0, 0);
+ for (i = 0; i < memlist->n_members; i++) {
+ HeapTuple roletup = &memlist->members[i]->tuple;
+ Form_pg_auth_members rolemem = (Form_pg_auth_members) GETSTRUCT(roletup);
+
+ if (!list_member_oid(roles_list,rolemem->roleid)) {
+ roles_list = lappend_oid(roles_list,rolemem->roleid);
+ roles_list_hunt = lappend_oid(roles_list_hunt,rolemem->roleid);
+ }
+ }
+ roles_list_hunt = list_delete_oid(roles_list_hunt, memberOid);
+ ReleaseSysCacheList(memlist);
+ }
+
+ /*
+ * Now that we've built the list of role Oids this
+ * role is a member of, save it in permanent storage
+ */
+ oldctx = MemoryContextSwitchTo(TopMemoryContext);
+ newrolmemcache = list_copy(roles_list);
+ MemoryContextSwitchTo(oldctx);
+
+ /*
+ * Now safe to assign to state variable
+ */
+ list_free(rolmemcache);
+ rolmemcache = newrolmemcache;
+
+ /*
+ * Mark as valid
+ */
+ rolmemRole = roleid;
+ rolmemcacheValid = true;
+
+ /* Clean up */
+ list_free(roles_list);
+}
*
*
* 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"
if (!OidIsValid(beentry->userid))
PG_RETURN_NULL();
- PG_RETURN_INT32 (beentry->userid);
+ PG_RETURN_OID (beentry->userid);
}
*
* 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 $
*
* ----------
*/
{
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
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];
* 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.
*
#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"
/* ----------
- * get_userbyid - Get a user name by usesys id and
- * fallback to 'unknown (U ID=n)'
+ * get_userbyid - Get a user name by role id and
+ * fallback to 'unknown (O ID=n)'
* ----------
*/
Datum
pg_get_userbyid(PG_FUNCTION_ARGS)
{
- int32 uid = PG_GETARG_INT32 (0);
+ Oid roleid = PG_GETARG_OID (0);
Name result;
- HeapTuple user tup;
- Form_pg_shadow user _rec;
+ HeapTuple role tup;
+ Form_pg_authid role _rec;
/*
* Allocate space for the result
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(SHADOWSYS ID,
- ObjectIdGetDatum(u id),
+ roletup = SearchSysCache(AUTHO ID,
+ ObjectIdGetDatum(role id),
0, 0, 0);
- if (HeapTupleIsValid(user tup))
+ if (HeapTupleIsValid(role tup))
{
- user_rec = (Form_pg_shadow) GETSTRUCT(user tup);
- StrNCpy(NameStr(*result), NameStr(user_rec->use name), NAMEDATALEN);
- ReleaseSysCache(user tup);
+ role_rec = (Form_pg_authid) GETSTRUCT(role tup);
+ StrNCpy(NameStr(*result), NameStr(role_rec->rol name), NAMEDATALEN);
+ ReleaseSysCache(role tup);
}
else
- sprintf(NameStr(*result), "unknown (UID=%d)", u id);
+ sprintf(NameStr(*result), "unknown (OID=%u)", role id);
PG_RETURN_NAME(result);
}
* 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.
#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"
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.
*/
-AclI d
-get_usesysid(const char *user name)
+Oi d
+get_roleid(const char *rol name)
{
- 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.
*/
-AclI d
-get_grosysid(char *gro name)
+Oi d
+get_roleid_checked(const char *rol name)
{
- 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;
}
-
*
*
* 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
#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"
#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"
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,
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,
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,
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
struct fmgr_security_definer_cache
{
FmgrInfo flinfo;
- AclId userid;
+ Oid userid;
};
/*
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)
* 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
* 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 $
*
*-------------------------------------------------------------------------
*/
#include
#include
+#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"
#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
/*
* 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;
/*
}
/*
- * 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();
}
}
/*
- * group_getflatfilename --- get full pathname of group file
- *
- * Note that result string is palloc'd, and should be freed by the caller.
- */
-char *
-group_getflatfilename(void)
-{
- int bufsize;
- char *pfnam;
-
- bufsize = strlen(DataDir) + strlen("/global/") +
- strlen(GROUP_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.
+ * Get full pathname of auth file.
*
* Note that result string is palloc'd, and should be freed by the caller.
*/
char *
-user _getflatfilename(void)
+auth _getflatfilename(void)
{
int bufsize;
char *pfnam;
bufsize = strlen(DataDir) + strlen("/global/") +
- strlen(USER _FLAT_FILE) + 1;
+ strlen(AUTH _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;
}
/*
* 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
/*
- * write_group_file: update the flat group file
+ * Support for write_auth_ file
*/
-static void
-write_group_file(Relation grel)
-{
- char *filename,
- *tempname;
- int bufsize;
- FILE *fp;
- mode_t oumask;
- HeapScanDesc scan;
- HeapTuple tuple;
-
- /*
- * 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);
+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)
+{
+ const auth_entry *a_auth = (const auth_entry*) a;
+ const auth_entry *b_auth = (const auth_entry*) b;
- /*
- * 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 (a_auth->roleid < b_auth->roleid) return -1;
+ if (a_auth->roleid > b_auth->roleid) return 1;
+ return 0;
+}
- /* if IdList was toasted, free detoasted copy */
- if ((Pointer) grolist_p != DatumGetPointer(datum) )
- pfree(grolist_p);
- }
- heap_endscan(scan) ;
+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 ;
- if (FreeFile(fp))
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not write to temporary file \"%s\": %m",
- tempname)));
+ return strcmp(a_auth->rolname,b_auth->rolname);
+}
- /*
- * 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)));
+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;
- pfree(tempname);
- pfree(filename);
+ 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);
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. passw d is the first possibly-null
+ * not have any tupdesc for pg_authid . Fortunately it's not too
+ * hard to work around this. rolpasswor d is the first possibly-null
* field so we can compute its offset directly.
*/
tp = (char *) tup + tup->t_hoff;
- off = offsetof(FormData_pg_shadow, passw d);
+ off = offsetof(FormData_pg_authid, rolpasswor d);
if (HeapTupleHasNulls(tuple) &&
- att_isnull(Anum_pg_shadow_passw d - 1, bp))
+ att_isnull(Anum_pg_authid_rolpasswor d - 1, bp))
{
/* passwd is null, emit as an empty string */
- passw d = pstrdup("");
+ auth_info[curr_role].rolpasswor d = pstrdup("");
}
else
{
* if it is, ignore it, since we can't handle that in startup mode.
*/
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)))
- passw d = pstrdup("");
+ auth_info[curr_role].rolpasswor d = pstrdup("");
else
- passw d = DatumGetCString(DirectFunctionCall1(textout, datum));
+ auth_info[curr_role].rolpasswor d = DatumGetCString(DirectFunctionCall1(textout, datum));
/* assume passwd has attlen -1 */
off = att_addlength(off, -1, tp + off);
}
if (HeapTupleHasNulls(tuple) &&
- att_isnull(Anum_pg_shadow_val until - 1, bp))
+ att_isnull(Anum_pg_authid_rolvalid until - 1, bp))
{
- /* val until is null, emit as an empty string */
- val until = pstrdup("");
+ /* rolvalid until is null, emit as an empty string */
+ auth_info[curr_role].rolvalid until = 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(use name))
+ if (!name_okay(auth_info[curr_role].rol name))
{
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(passw d))
+ if (!name_okay(auth_info[curr_role].rolpasswor d))
{
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"
+ 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(use name, fp);
- fprintf(fp, " %u ", usesysid );
- fputs_quote(passw d, fp);
+ fputs_quote(auth_info[curr_role].rol name, fp);
+ fputs(" ", fp );
+ fputs_quote(auth_info[curr_role].rolpasswor d, fp);
fputs(" ", fp);
- fputs_quote(valuntil, 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(passwd);
- pfree(valuntil);
+ pfree(auth_info[curr_role].rolname);
+ pfree(auth_info[curr_role].rolpassword);
+ pfree(auth_info[curr_role].rolvaliduntil);
}
- heap_endscan(scan);
if (FreeFile(fp))
ereport(ERROR,
errmsg("could not rename file \"%s\" to \"%s\": %m",
tempname, filename)));
+ pfree(auth_info);
+ pfree(authmem_info);
pfree(tempname);
pfree(filename);
}
{
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
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;
AtEOXact_UpdateFlatFiles(bool isCommit)
{
Relation drel = NULL;
- Relation g rel = NULL;
- Relation u rel = NULL;
+ Relation a rel = NULL;
+ Relation m rel = 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;
}
*/
if (database_file_update_subid != InvalidSubTransactionId)
drel = heap_open(DatabaseRelationId, ExclusiveLock);
- if (group_file_update_subid != InvalidSubTransactionId)
- grel = heap_open(Group RelationId, ExclusiveLock);
- if (user_file_update_subid != InvalidSubTransactionId)
- urel = heap_open(ShadowRelationId, ExclusiveLock);
+ if (auth_file_update_subid != InvalidSubTransactionId) {
+ arel = heap_open(AuthId RelationId, ExclusiveLock);
+ mrel = heap_open(AuthMemRelationId, ExclusiveLock);
+ }
/* Okay to write the files */
if (database_file_update_subid != InvalidSubTransactionId)
heap_close(drel, NoLock);
}
- if (group_file_update_subid != InvalidSubTransactionId)
- {
- group_file_update_subid = InvalidSubTransactionId;
- write_group_file(grel);
- heap_close(grel, NoLock);
- }
-
- if (user_file_update_subid != InvalidSubTransactionId)
+ if (auth_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);
}
/*
database_file_update_subid = InvalidSubTransactionId;
info |= FF_BIT_DATABASE;
}
- if (group_file_update_subid != InvalidSubTransactionId)
- {
- group_file_update_subid = InvalidSubTransactionId;
- info |= FF_BIT_GROUP;
- }
- if (user_file_update_subid != InvalidSubTransactionId)
+ if (auth_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,
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
case DatabaseRelationId:
database_file_update_needed();
break;
- case Group RelationId:
- group _file_update_needed();
+ case AuthId RelationId:
+ auth _file_update_needed();
break;
- case Shadow RelationId:
- user _file_update_needed();
+ case AuthMem RelationId:
+ auth _file_update_needed();
break;
default:
elog(ERROR, "flatfile_update_trigger was called for wrong table");
*/
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();
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#include
#endif
-#include "catalog/pg_shadow .h"
+#include "catalog/pg_authid .h"
#include "libpq/libpq-be.h"
#include "miscadmin.h"
#include "storage/fd.h"
/* ----------------------------------------------------------------
- * 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
* 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.
*/
-AclI d
+Oi d
GetUserId(void)
{
- AssertState(AclI dIsValid(CurrentUserId));
+ AssertState(Oi dIsValid(CurrentUserId));
return CurrentUserId;
}
void
-SetUserId(AclId new id)
+SetUserId(Oid role id)
{
- AssertArg(AclIdIsValid(new id));
- CurrentUserId = new id;
+ AssertArg(OidIsValid(role id));
+ CurrentUserId = role id;
}
/*
* This value is only relevant for informational purposes.
*/
-AclI d
+Oi d
GetSessionUserId(void)
{
- AssertState(AclI dIsValid(SessionUserId));
+ AssertState(Oi dIsValid(SessionUserId));
return SessionUserId;
}
void
-SetSessionUserId(AclId new id)
+SetSessionUserId(Oid role id)
{
- AssertArg(AclIdIsValid(new id));
- SessionUserId = new id;
+ AssertArg(OidIsValid(role id));
+ SessionUserId = role id;
/* Current user defaults to session user. */
- if (!AclI dIsValid(CurrentUserId))
- CurrentUserId = new id;
+ if (!Oi dIsValid(CurrentUserId))
+ CurrentUserId = role id;
}
void
-InitializeSessionUserId(const char *user name)
+InitializeSessionUserId(const char *role name)
{
- HeapTuple user Tup;
+ HeapTuple role Tup;
Datum datum;
bool isnull;
- AclId usesys id;
+ Oid role id;
/*
* Don't do scans if we're bootstrapping, none of the system catalogs
/* call only once */
AssertState(!OidIsValid(AuthenticatedUserId));
- userTup = SearchSysCache(SHADOW NAME,
- PointerGetDatum(user name),
+ roleTup = SearchSysCache(AUTH NAME,
+ PointerGetDatum(role name),
0, 0, 0);
- if (!HeapTupleIsValid(user Tup))
+ if (!HeapTupleIsValid(role Tup))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", user name)));
+ errmsg("role \"%s\" does not exist", role name)));
- usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid ;
+ roleid = HeapTupleGetOid(roleTup) ;
- AuthenticatedUserId = usesys id;
- AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->use super;
+ AuthenticatedUserId = role id;
+ AuthenticatedUserIsSuperuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rol super;
- SetSessionUserId(usesysid); /* sets CurrentUserId too */
+ SetSessionUserId(roleid); /* sets CurrentUserId too */
/* Record username and superuser status as GUC settings too */
- SetConfigOption("session_authorization", user name,
+ SetConfigOption("session_authorization", role name,
PGC_BACKEND, PGC_S_OVERRIDE);
SetConfigOption("is_superuser",
AuthenticatedUserIsSuperuser ? "on" : "off",
/*
* 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, user Tup,
- Anum_pg_shadow_use config, &isnull);
+ datum = SysCacheGetAttr(AUTHNAME, role Tup,
+ Anum_pg_authid_rol config, &isnull);
if (!isnull)
{
ArrayType *a = DatumGetArrayTypeP(datum);
ProcessGUCArray(a, PGC_S_USER);
}
- ReleaseSysCache(user Tup);
+ ReleaseSysCache(role Tup);
}
/* call only once */
AssertState(!OidIsValid(AuthenticatedUserId));
- AuthenticatedUserId = BOOTSTRAP_USESYS ID;
+ AuthenticatedUserId = BOOTSTRAP_SUPERUSER ID;
AuthenticatedUserIsSuperuser = true;
- SetSessionUserId(BOOTSTRAP_USESYS ID);
+ SetSessionUserId(BOOTSTRAP_SUPERUSER ID);
}
* to indicate whether the *current* session userid is a superuser.
*/
void
-SetSessionAuthorization(AclId user id, bool is_superuser)
+SetSessionAuthorization(Oid role id, bool is_superuser)
{
/* Must have authenticated already, else can't make permission check */
- AssertState(AclI dIsValid(AuthenticatedUserId));
+ AssertState(Oi dIsValid(AuthenticatedUserId));
- if (user id != AuthenticatedUserId &&
+ if (role id != AuthenticatedUserId &&
!AuthenticatedUserIsSuperuser)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to set session authorization")));
- SetSessionUserId(user id);
- SetUserId(user id);
+ SetSessionUserId(role id);
+ SetUserId(role id);
SetConfigOption("is_superuser",
is_superuser ? "on" : "off",
/*
- * Get user name from user id
+ * Get user name from user o id
*/
char *
-GetUserNameFromId(AclId user id)
+GetUserNameFromId(Oid role id)
{
HeapTuple tuple;
char *result;
- tuple = SearchSysCache(SHADOWSYS ID,
- ObjectIdGetDatum(user id),
+ tuple = SearchSysCache(AUTHO ID,
+ ObjectIdGetDatum(role id),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("invalid user ID: %d", user id)));
+ errmsg("invalid role OID: %u", role id)));
- result = pstrdup(NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->use name));
+ result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rol name));
ReleaseSysCache(tuple);
return result;
}
-
/*-------------------------------------------------------------------------
* Interlock-file support
*
*
*
* 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 $
*
*
*-------------------------------------------------------------------------
#include
#include
-#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"
#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"
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 ***/
else if (!IsUnderPostmaster)
{
InitializeSessionUserIdStandalone();
- if (!ThereIsAtLeastOneUser ())
+ if (!ThereIsAtLeastOneRole ())
ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("no user s are defined in this database system"),
- errhint("You should immediately run CREATE USER \"%s\" WITH SYSID %d CREATEUSER;.",
- username, BOOTSTRAP_USESYSID )));
+ errmsg("no role s are defined in this database system"),
+ errhint("You should immediately run CREATE USER \"%s\" CREATEUSER;.",
+ username)));
}
else
{
/* set default namespace search path */
InitializeSearchPath();
+ /* set up ACL framework (currently just sets RolMemCache callback) */
+ InitializeAcl();
+
/* initialize client encoding */
InitializeClientEncoding();
/*
- * 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(Shadow RelationId, AccessExclusiveLock);
+ pg_authid_rel = heap_open(AuthId RelationId, 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;
}
* Written by Peter Eisentraut
.
*
* 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 $
*
*--------------------------------------------------------------------
*/
/*
- * Handle options fetched from pg_database.datconfig or pg_shadow.use config.
+ * Handle options fetched from pg_database.datconfig or pg_authid.rol config.
* The array parameter must be an array of TEXT (it must not be NULL).
*/
void
/*
* 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);
*
*
* 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 user id (ie, the session or current ID) will
+ * In common cases the same role id (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 user id. The cache can be flushed
- * at need by watching for cache update events on pg_shadow .
+ * the status of the last requested role id. 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_user id_is_super = false;
-static bool user id_callback_registered = false;
+static Oid last_roleid = InvalidOid; /* InvalidOid == cache not valid */
+static bool last_role id_is_super = false;
+static bool role id_callback_registered = false;
-static void User idCallback(Datum arg, Oid relid);
+static void Role idCallback(Datum arg, Oid relid);
/*
/*
- * The specified userid has Postgres superuser privileges
+ * The specified role has Postgres superuser privileges
*/
bool
-superuser_arg(AclId user id)
+superuser_arg(Oid role id)
{
bool result;
- HeapTuple u tup;
+ HeapTuple r tup;
/* Quick out for cache hit */
- if (AclIdIsValid(last_userid) && last_userid == user id)
- return last_user id_is_super;
+ if (OidIsValid(last_roleid) && last_roleid == role id)
+ return last_role id_is_super;
/* Special escape path in case you deleted all your users. */
- if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYS ID)
+ if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSER ID)
return true;
- /* OK, look up the information in pg_shadow */
- utup = SearchSysCache(SHADOWSYS ID,
- Int32GetDatum(user id),
+ /* OK, look up the information in pg_authid */
+ rtup = SearchSysCache(AUTHO ID,
+ ObjectIdGetDatum(role id),
0, 0, 0);
- if (HeapTupleIsValid(u tup))
+ if (HeapTupleIsValid(r tup))
{
- result = ((Form_pg_shadow) GETSTRUCT(utup))->use super;
- ReleaseSysCache(u tup);
+ result = ((Form_pg_authid) GETSTRUCT(rtup))->rol super;
+ ReleaseSysCache(r tup);
}
else
{
- /* Report "not superuser" for invalid user ids */
+ /* Report "not superuser" for invalid role ids */
result = false;
}
/* If first time through, set up callback for cache flushes */
- if (!user id_callback_registered)
+ if (!role id_callback_registered)
{
- CacheRegisterSyscacheCallback(SHADOWSYS ID,
- User idCallback,
+ CacheRegisterSyscacheCallback(AUTHO ID,
+ Role idCallback,
(Datum) 0);
- user id_callback_registered = true;
+ role id_callback_registered = true;
}
/* Cache the result for next time */
- last_userid = user id;
- last_user id_is_super = result;
+ last_roleid = role id;
+ last_role id_is_super = result;
return result;
}
* Syscache inval callback function
*/
static void
-User idCallback(Datum arg, Oid relid)
+Role idCallback(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 ;
}
* Portions Copyright (c) 1994, Regents of the University of California
* Portions taken from FreeBSD.
*
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.86 2005/06/26 03:03:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.87 2005/06/28 05:09:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static void test_buffers(void);
static void setup_config(void);
static void bootstrap_template1(char *short_version);
-static void setup_shadow (void);
+static void setup_auth (void);
static void get_set_pwd(void);
static void unlimit_systables(void);
static void setup_depend(void);
* set up the shadow password table
*/
static void
-setup_shadow (void)
+setup_auth (void)
{
PG_CMD_DECL;
char **line;
- static char *pg_shadow _setup[] = {
+ static char *pg_authid _setup[] = {
/*
* Create triggers to ensure manual updates to shared catalogs
* will be reflected into their "flat file" copies.
"CREATE TRIGGER pg_sync_pg_database "
" AFTER INSERT OR UPDATE OR DELETE ON pg_database "
" FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
- "CREATE TRIGGER pg_sync_pg_group "
- " AFTER INSERT OR UPDATE OR DELETE ON pg_group "
+ "CREATE TRIGGER pg_sync_pg_authid "
+ " AFTER INSERT OR UPDATE OR DELETE ON pg_authid "
" FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
- "CREATE TRIGGER pg_sync_pg_pwd "
- " AFTER INSERT OR UPDATE OR DELETE ON pg_shadow "
+ "CREATE TRIGGER pg_sync_pg_auth_members "
+ " AFTER INSERT OR UPDATE OR DELETE ON pg_auth_members "
" FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
/*
- * needs to be done before alter user, because alter user checks
- * that pg_shadow is secure .. .
+ * The authid table shouldn't be readable except through views,
+ * to ensure passwords are not publicly visible .
*/
- "REVOKE ALL on pg_shadow FROM public;\n",
+ "REVOKE ALL on pg_authid FROM public;\n",
NULL
};
- fputs(_("initializing pg_shadow ... "), stdout);
+ fputs(_("initializing pg_authid ... "), stdout);
fflush(stdout);
snprintf(cmd, sizeof(cmd),
PG_CMD_OPEN;
- for (line = pg_shadow _setup; *line != NULL; line++)
+ for (line = pg_authid _setup; *line != NULL; line++)
PG_CMD_PUTS(*line);
PG_CMD_CLOSE;
char **line;
static char *systables_setup[] = {
"ALTER TABLE pg_attrdef CREATE TOAST TABLE;\n",
+ "ALTER TABLE pg_authid CREATE TOAST TABLE;\n",
"ALTER TABLE pg_constraint CREATE TOAST TABLE;\n",
"ALTER TABLE pg_database CREATE TOAST TABLE;\n",
"ALTER TABLE pg_description CREATE TOAST TABLE;\n",
- "ALTER TABLE pg_group CREATE TOAST TABLE;\n",
"ALTER TABLE pg_proc CREATE TOAST TABLE;\n",
"ALTER TABLE pg_rewrite CREATE TOAST TABLE;\n",
- "ALTER TABLE pg_shadow CREATE TOAST TABLE;\n",
"ALTER TABLE pg_statistic CREATE TOAST TABLE;\n",
NULL
};
/* Create the stuff we don't need to use bootstrap mode for */
- setup_shadow ();
+ setup_auth ();
if (pwprompt || pwfilename)
get_set_pwd();
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/access/twophase.h,v 1.3 2005/06/19 20:00:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/twophase.h,v 1.4 2005/06/28 05:09:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid,
TimestampTz prepared_at,
- AclI d owner, Oid databaseid);
+ Oi d owner, Oid databaseid);
extern void StartPrepare(GlobalTransaction gxact);
extern void EndPrepare(GlobalTransaction gxact);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/c.h,v 1.185 2005/06/08 15:50:28 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.186 2005/06/28 05:09:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
- * CommandId, AclId
+ * CommandId
*/
/* typedef Oid is in postgres_ext.h */
#define FirstCommandId ((CommandId) 0)
-typedef int32 AclId; /* user and group identifiers */
-
/*
* Array indexing support
*/
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
-#define AclIdIsValid(aclId) ((bool) ((aclId) != 0))
-
#define RegProcedureIsValid(p) OidIsValid(p)
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.282 2005/06/27 12:45:22 teodor Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.283 2005/06/28 05:09:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200506271
+#define CATALOG_VERSION_NO 200506272
#endif
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.87 2005/04/14 20:03:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.88 2005/06/28 05:09:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index,2659, on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
#define AttributeRelidNumIndexId 2659
+DECLARE_UNIQUE_INDEX(pg_authid_rolname_index,2676, on pg_authid using btree(rolname name_ops));
+#define AuthIdRolnameIndexId 2676
+DECLARE_UNIQUE_INDEX(pg_authid_oid_index,2677, on pg_authid using btree(oid oid_ops));
+#define AuthIdOidIndexId 2677
+
+DECLARE_UNIQUE_INDEX(pg_auth_members_role_member_index,2694, on pg_auth_members using btree(roleid oid_ops, member oid_ops));
+#define AuthMemRoleMemIndexId 2694
+DECLARE_UNIQUE_INDEX(pg_auth_members_member_role_index,2695, on pg_auth_members using btree(member oid_ops, roleid oid_ops));
+#define AuthMemMemRoleIndexId 2695
+
DECLARE_UNIQUE_INDEX(pg_cast_oid_index,2660, on pg_cast using btree(oid oid_ops));
#define CastOidIndexId 2660
DECLARE_UNIQUE_INDEX(pg_cast_source_target_index,2661, on pg_cast using btree(castsource oid_ops, casttarget oid_ops));
DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index,2675, on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops));
#define DescriptionObjIndexId 2675
-DECLARE_UNIQUE_INDEX(pg_group_name_index,2676, on pg_group using btree(groname name_ops));
-#define GroupNameIndexId 2676
-DECLARE_UNIQUE_INDEX(pg_group_sysid_index,2677, on pg_group using btree(grosysid int4_ops));
-#define GroupSysidIndexId 2677
-
/* This following index is not used for a cache and is not unique */
DECLARE_INDEX(pg_index_indrelid_index,2678, on pg_index using btree(indrelid oid_ops));
#define IndexIndrelidIndexId 2678
DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index,2693, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
#define RewriteRelRulenameIndexId 2693
-DECLARE_UNIQUE_INDEX(pg_shadow_usename_index,2694, on pg_shadow using btree(usename name_ops));
-#define ShadowNameIndexId 2694
-DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index,2695, on pg_shadow using btree(usesysid int4_ops));
-#define ShadowSysidIndexId 2695
-
DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index,2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
#define StatisticRelidAttnumIndexId 2696
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.117 2005/04/29 22:28:2 4 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.118 2005/06/28 05:09:0 4 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
#define Schema_pg_type \
{ 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typnamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1247, {"typowner"}, 23 , -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1247, {"typowner"}, 26 , -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1247, {"typlen"}, 21, -1, 2, 4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
{ 1247, {"typbyval"}, 16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1247, {"typtype"}, 18, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1247 typnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1247 typowner 23 -1 4 3 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1247 typowner 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1247 typlen 21 -1 2 4 0 -1 -1 t p s t f f t 0));
DATA(insert ( 1247 typbyval 16 -1 1 5 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1247 typtype 18 -1 1 6 0 -1 -1 t p c t f f t 0));
#define Schema_pg_proc \
{ 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"pronamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1255, {"proowner"}, 23 , -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1255, {"proowner"}, 26 , -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"prolang"}, 26, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1255, {"proisagg"}, 16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
{ 1255, {"prosecdef"}, 16, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1255 pronamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1255 proowner 23 -1 4 3 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1255 proowner 26 -1 4 3 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 prolang 26 -1 4 4 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1255 proisagg 16 -1 1 5 0 -1 -1 t p c t f f t 0));
DATA(insert ( 1255 prosecdef 16 -1 1 6 0 -1 -1 t p c t f f t 0));
{ 1259, {"relname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"relnamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"reltype"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
-{ 1259, {"relowner"}, 23 , -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
+{ 1259, {"relowner"}, 26 , -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"relam"}, 26, -1, 4, 5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"relfilenode"}, 26, -1, 4, 6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
{ 1259, {"reltablespace"}, 26, -1, 4, 7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
DATA(insert ( 1259 relnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 reltype 26 -1 4 3 0 -1 -1 t p i t f f t 0));
-DATA(insert ( 1259 relowner 23 -1 4 4 0 -1 -1 t p i t f f t 0));
+DATA(insert ( 1259 relowner 26 -1 4 4 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 relam 26 -1 4 5 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 relfilenode 26 -1 4 6 0 -1 -1 t p i t f f t 0));
DATA(insert ( 1259 reltablespace 26 -1 4 7 0 -1 -1 t p i t f f t 0));
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pg_auth_members.h
+ * definition of the system "authorization identifier members" relation
+ * (pg_auth_members) along with the relation's initial contents.
+ *
+ *
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_auth_members.h,v 1.1 2005/06/28 05:09:04 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_AUTH_MEMBERS_H
+#define PG_AUTH_MEMBERS_H
+
+/* ----------------
+ * pg_auth_members definition. cpp turns this into
+ * typedef struct FormData_pg_auth_members
+ * ----------------
+ */
+#define AuthMemRelationId 1261
+
+CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
+{
+ Oid roleid; /* ID of a role */
+ Oid member; /* ID of a member of that role */
+ Oid grantor; /* who granted the membership */
+ bool admin_option; /* granted with admin option? */
+} FormData_pg_auth_members;
+
+/* ----------------
+ * Form_pg_auth_members corresponds to a pointer to a tuple with
+ * the format of pg_auth_members relation.
+ * ----------------
+ */
+typedef FormData_pg_auth_members *Form_pg_auth_members;
+
+/* ----------------
+ * compiler constants for pg_auth_members
+ * ----------------
+ */
+#define Natts_pg_auth_members 4
+#define Anum_pg_auth_members_roleid 1
+#define Anum_pg_auth_members_member 2
+#define Anum_pg_auth_members_grantor 3
+#define Anum_pg_auth_members_admin_option 4
+
+#endif /* PG_AUTH_MEMBERS_H */
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * pg_authid.h
+ * definition of the system "authorization identifier" relation (pg_authid)
+ * along with the relation's initial contents.
+ *
+ * pg_shadow and pg_group are now publicly accessible views on pg_authid.
+ *
+ *
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/catalog/pg_authid.h,v 1.1 2005/06/28 05:09:05 tgl Exp $
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_AUTHID_H
+#define PG_AUTHID_H
+
+/*
+ * The CATALOG definition has to refer to the type of rolvaliduntil as
+ * "timestamptz" (lower case) so that bootstrap mode recognizes it. But
+ * the C header files define this type as TimestampTz. Since the field is
+ * potentially-null and therefore can't be accessed directly from C code,
+ * there is no particular need for the C struct definition to show the
+ * field type as TimestampTz --- instead we just make it Datum.
+ */
+
+#define timestamptz Datum
+
+
+/* ----------------
+ * pg_authid definition. cpp turns this into
+ * typedef struct FormData_pg_authid
+ * ----------------
+ */
+#define AuthIdRelationId 1260
+
+CATALOG(pg_authid,1260) BKI_SHARED_RELATION
+{
+ NameData rolname; /* name of role */
+ bool rolsuper; /* read this field via superuser() only! */
+ bool rolcreaterole; /* allowed to create more roles? */
+ bool rolcreatedb; /* allowed to create databases? */
+ bool rolcatupdate; /* allowed to alter catalogs manually? */
+ bool rolcanlogin; /* allowed to log in as session user? */
+
+ /* remaining fields may be null; use heap_getattr to read them! */
+ text rolpassword; /* password, if any */
+ timestamptz rolvaliduntil; /* password expiration time, if any */
+ text rolconfig[1]; /* GUC settings to apply at login */
+} FormData_pg_authid;
+
+#undef timestamptz
+
+
+/* ----------------
+ * Form_pg_authid corresponds to a pointer to a tuple with
+ * the format of pg_authid relation.
+ * ----------------
+ */
+typedef FormData_pg_authid *Form_pg_authid;
+
+/* ----------------
+ * compiler constants for pg_authid
+ * ----------------
+ */
+#define Natts_pg_authid 9
+#define Anum_pg_authid_rolname 1
+#define Anum_pg_authid_rolsuper 2
+#define Anum_pg_authid_rolcreaterole 3
+#define Anum_pg_authid_rolcreatedb 4
+#define Anum_pg_authid_rolcatupdate 5
+#define Anum_pg_authid_rolcanlogin 6
+#define Anum_pg_authid_rolpassword 7
+#define Anum_pg_authid_rolvaliduntil 8
+#define Anum_pg_authid_rolconfig 9
+
+/* ----------------
+ * initial contents of pg_authid
+ *
+ * The uppercase quantities will be replaced at initdb time with
+ * user choices.
+ * ----------------
+ */
+DATA(insert OID = 10 ( "POSTGRES" t t t t t _null_ _null_ _null_ ));
+
+#define BOOTSTRAP_SUPERUSERID 10
+
+#endif /* PG_AUTHID_H */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.88 2005/04/29 22:28:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.89 2005/06/28 05:09:05 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
NameData relname; /* class name */
Oid relnamespace; /* OID of namespace containing this class */
Oid reltype; /* OID of associated entry in pg_type */
- int4 relowner; /* class owner */
+ Oid relowner; /* class owner */
Oid relam; /* index access method; 0 if not an index */
Oid relfilenode; /* identifier of physical storage file */
Oid reltablespace; /* identifier of table space for relation */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_conversion.h,v 1.15 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_conversion.h,v 1.16 2005/06/28 05:09:05 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
{
NameData conname;
Oid connamespace;
- int4 conowner;
+ Oid conowner;
int4 conforencoding;
int4 contoencoding;
regproc conproc;
#include "nodes/parsenodes.h"
extern Oid ConversionCreate(const char *conname, Oid connamespace,
- AclI d conowner,
+ Oi d conowner,
int32 conforencoding, int32 contoencoding,
Oid conproc, bool def);
extern void ConversionDrop(Oid conversionOid, DropBehavior behavior);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.35 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.36 2005/06/28 05:09:06 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
CATALOG(pg_database,1262) BKI_SHARED_RELATION
{
NameData datname; /* database name */
- int4 datdba; /* sysid of owner */
+ Oid datdba; /* owner of database */
int4 encoding; /* character encoding */
bool datistemplate; /* allowed as CREATE DATABASE template? */
bool datallowconn; /* new connections allowed? */
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * pg_group.h
- *
- *
- *
- * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $PostgreSQL: pgsql/src/include/catalog/pg_group.h,v 1.21 2005/04/14 01:38:20 tgl Exp $
- *
- * NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
- *
- *-------------------------------------------------------------------------
- */
-#ifndef PG_GROUP_H
-#define PG_GROUP_H
-
-/* ----------------
- * postgres.h contains the system type definitions and the
- * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file
- * can be read by both genbki.sh and the C compiler.
- * ----------------
- */
-#define GroupRelationId 1261
-
-CATALOG(pg_group,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
-{
- NameData groname;
- int4 grosysid;
- int4 grolist[1];
-} FormData_pg_group;
-
-/* VARIABLE LENGTH STRUCTURE */
-
-typedef FormData_pg_group *Form_pg_group;
-
-#define Natts_pg_group 3
-#define Anum_pg_group_groname 1
-#define Anum_pg_group_grosysid 2
-#define Anum_pg_group_grolist 3
-
-#endif /* PG_GROUP_H */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_namespace.h,v 1.17 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_namespace.h,v 1.18 2005/06/28 05:09:06 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
CATALOG(pg_namespace,2615)
{
NameData nspname;
- int4 nspowner;
+ Oid nspowner;
aclitem nspacl[1]; /* VARIABLE LENGTH FIELD */
} FormData_pg_namespace;
/*
* prototypes for functions in pg_namespace.c
*/
-extern Oid NamespaceCreate(const char *nspName, int32 ownerSys Id);
+extern Oid NamespaceCreate(const char *nspName, Oid owner Id);
#endif /* PG_NAMESPACE_H */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.64 2005/04/14 01:38:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.65 2005/06/28 05:09:07 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
Oid opcamid; /* index access method opclass is for */
NameData opcname; /* name of this opclass */
Oid opcnamespace; /* namespace of this opclass */
- int4 opcowner; /* opclass owner */
+ Oid opcowner; /* opclass owner */
Oid opcintype; /* type of data indexed by opclass */
bool opcdefault; /* T if opclass is default for opcintype */
Oid opckeytype; /* type of data in index, or InvalidOid */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.134 2005/06/24 20:53:31 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.135 2005/06/28 05:09:07 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
{
NameData oprname; /* name of operator */
Oid oprnamespace; /* OID of namespace containing this oper */
- int4 oprowner; /* ope r owner */
+ Oid oprowner; /* operato r owner */
char oprkind; /* 'l', 'r', or 'b' */
bool oprcanhash; /* can be used in hash join? */
Oid oprleft; /* left arg type, or 0 if 'l' oprkind */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.371 2005/06/26 03:04:01 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.372 2005/06/28 05:09:09 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
{
NameData proname; /* procedure name */
Oid pronamespace; /* OID of namespace containing this proc */
- int4 proowner; /* proc owner */
+ Oid proowner; /* procedure owner */
Oid prolang; /* OID of pg_language entry */
bool proisagg; /* is it an aggregate? */
bool prosecdef; /* security definer */
DESCR("does ACL contain item?");
DATA(insert OID = 1062 ( aclitemeq PGNSP PGUID 12 f f t f i 2 16 "1033 1033" _null_ _null_ _null_ aclitem_eq - _null_ ));
DESCR("equality operator for ACL items");
-DATA(insert OID = 1365 ( makeaclitem PGNSP PGUID 12 f f t f i 5 1033 "23 23 23 25 16" _null_ _null_ _null_ makeaclitem - _null_ ));
+DATA(insert OID = 1365 ( makeaclitem PGNSP PGUID 12 f f t f i 4 1033 "26 26 25 16" _null_ _null_ _null_ makeaclitem - _null_ ));
DESCR("make ACL item");
DATA(insert OID = 1044 ( bpcharin PGNSP PGUID 12 f f t f i 3 1042 "2275 26 23" _null_ _null_ _null_ bpcharin - _null_ ));
DESCR("I/O");
DESCR("select statement of a view");
DATA(insert OID = 1641 ( pg_get_viewdef PGNSP PGUID 12 f f t f s 1 25 "26" _null_ _null_ _null_ pg_get_viewdef - _null_ ));
DESCR("select statement of a view");
-DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 f f t f s 1 19 "23 " _null_ _null_ _null_ pg_get_userbyid - _null_ ));
-DESCR("user name by U ID (with fallback)");
+DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 f f t f s 1 19 "26 " _null_ _null_ _null_ pg_get_userbyid - _null_ ));
+DESCR("role name by O ID (with fallback)");
DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 f f t f s 1 25 "26" _null_ _null_ _null_ pg_get_indexdef - _null_ ));
DESCR("index description");
DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 f f t f s 1 25 "26" _null_ _null_ _null_ pg_get_triggerdef - _null_ ));
DESCR("user privilege on relation by username, rel name");
DATA(insert OID = 1923 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_table_privilege_name_id - _null_ ));
DESCR("user privilege on relation by username, rel oid");
-DATA(insert OID = 1924 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_table_privilege_id_name - _null_ ));
-DESCR("user privilege on relation by usesys id, rel name");
-DATA(insert OID = 1925 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_table_privilege_id_id - _null_ ));
-DESCR("user privilege on relation by usesys id, rel oid");
+DATA(insert OID = 1924 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_table_privilege_id_name - _null_ ));
+DESCR("user privilege on relation by user o id, rel name");
+DATA(insert OID = 1925 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_table_privilege_id_id - _null_ ));
+DESCR("user privilege on relation by user o id, rel oid");
DATA(insert OID = 1926 ( has_table_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_table_privilege_name - _null_ ));
DESCR("current user privilege on relation by rel name");
DATA(insert OID = 1927 ( has_table_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_table_privilege_id - _null_ ));
DESCR("Statistics: PID of backend");
DATA(insert OID = 1938 ( pg_stat_get_backend_dbid PGNSP PGUID 12 f f t f s 1 26 "23" _null_ _null_ _null_ pg_stat_get_backend_dbid - _null_ ));
DESCR("Statistics: Database ID of backend");
-DATA(insert OID = 1939 ( pg_stat_get_backend_userid PGNSP PGUID 12 f f t f s 1 23 "23" _null_ _null_ _null_ pg_stat_get_backend_userid - _null_ ));
+DATA(insert OID = 1939 ( pg_stat_get_backend_userid PGNSP PGUID 12 f f t f s 1 26 "23" _null_ _null_ _null_ pg_stat_get_backend_userid - _null_ ));
DESCR("Statistics: User ID of backend");
DATA(insert OID = 1940 ( pg_stat_get_backend_activity PGNSP PGUID 12 f f t f s 1 25 "23" _null_ _null_ _null_ pg_stat_get_backend_activity - _null_ ));
DESCR("Statistics: Current query of backend");
DESCR("user privilege on database by username, database name");
DATA(insert OID = 2251 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_database_privilege_name_id - _null_ ));
DESCR("user privilege on database by username, database oid");
-DATA(insert OID = 2252 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_database_privilege_id_name - _null_ ));
-DESCR("user privilege on database by usesys id, database name");
-DATA(insert OID = 2253 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_database_privilege_id_id - _null_ ));
-DESCR("user privilege on database by usesys id, database oid");
+DATA(insert OID = 2252 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_database_privilege_id_name - _null_ ));
+DESCR("user privilege on database by user o id, database name");
+DATA(insert OID = 2253 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_database_privilege_id_id - _null_ ));
+DESCR("user privilege on database by user o id, database oid");
DATA(insert OID = 2254 ( has_database_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_database_privilege_name - _null_ ));
DESCR("current user privilege on database by database name");
DATA(insert OID = 2255 ( has_database_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_database_privilege_id - _null_ ));
DESCR("user privilege on function by username, function name");
DATA(insert OID = 2257 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_function_privilege_name_id - _null_ ));
DESCR("user privilege on function by username, function oid");
-DATA(insert OID = 2258 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_function_privilege_id_name - _null_ ));
-DESCR("user privilege on function by usesys id, function name");
-DATA(insert OID = 2259 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_function_privilege_id_id - _null_ ));
-DESCR("user privilege on function by usesys id, function oid");
+DATA(insert OID = 2258 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_function_privilege_id_name - _null_ ));
+DESCR("user privilege on function by user o id, function name");
+DATA(insert OID = 2259 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_function_privilege_id_id - _null_ ));
+DESCR("user privilege on function by user o id, function oid");
DATA(insert OID = 2260 ( has_function_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_function_privilege_name - _null_ ));
DESCR("current user privilege on function by function name");
DATA(insert OID = 2261 ( has_function_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_function_privilege_id - _null_ ));
DESCR("user privilege on language by username, language name");
DATA(insert OID = 2263 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_language_privilege_name_id - _null_ ));
DESCR("user privilege on language by username, language oid");
-DATA(insert OID = 2264 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_language_privilege_id_name - _null_ ));
-DESCR("user privilege on language by usesys id, language name");
-DATA(insert OID = 2265 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_language_privilege_id_id - _null_ ));
-DESCR("user privilege on language by usesys id, language oid");
+DATA(insert OID = 2264 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_language_privilege_id_name - _null_ ));
+DESCR("user privilege on language by user o id, language name");
+DATA(insert OID = 2265 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_language_privilege_id_id - _null_ ));
+DESCR("user privilege on language by user o id, language oid");
DATA(insert OID = 2266 ( has_language_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_language_privilege_name - _null_ ));
DESCR("current user privilege on language by language name");
DATA(insert OID = 2267 ( has_language_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_language_privilege_id - _null_ ));
DESCR("user privilege on schema by username, schema name");
DATA(insert OID = 2269 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_schema_privilege_name_id - _null_ ));
DESCR("user privilege on schema by username, schema oid");
-DATA(insert OID = 2270 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_schema_privilege_id_name - _null_ ));
-DESCR("user privilege on schema by usesys id, schema name");
-DATA(insert OID = 2271 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_schema_privilege_id_id - _null_ ));
-DESCR("user privilege on schema by usesys id, schema oid");
+DATA(insert OID = 2270 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_schema_privilege_id_name - _null_ ));
+DESCR("user privilege on schema by user o id, schema name");
+DATA(insert OID = 2271 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_schema_privilege_id_id - _null_ ));
+DESCR("user privilege on schema by user o id, schema oid");
DATA(insert OID = 2272 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_schema_privilege_name - _null_ ));
DESCR("current user privilege on schema by schema name");
DATA(insert OID = 2273 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_schema_privilege_id - _null_ ));
DESCR("user privilege on tablespace by username, tablespace name");
DATA(insert OID = 2391 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_tablespace_privilege_name_id - _null_ ));
DESCR("user privilege on tablespace by username, tablespace oid");
-DATA(insert OID = 2392 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_tablespace_privilege_id_name - _null_ ));
-DESCR("user privilege on tablespace by usesys id, tablespace name");
-DATA(insert OID = 2393 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_tablespace_privilege_id_id - _null_ ));
-DESCR("user privilege on tablespace by usesys id, tablespace oid");
+DATA(insert OID = 2392 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_tablespace_privilege_id_name - _null_ ));
+DESCR("user privilege on tablespace by user o id, tablespace name");
+DATA(insert OID = 2393 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_tablespace_privilege_id_id - _null_ ));
+DESCR("user privilege on tablespace by user o id, tablespace oid");
DATA(insert OID = 2394 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_tablespace_privilege_name - _null_ ));
DESCR("current user privilege on tablespace by tablespace name");
DATA(insert OID = 2395 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_tablespace_privilege_id - _null_ ));
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * pg_shadow.h
- * definition of the system "shadow" relation (pg_shadow)
- * along with the relation's initial contents.
- *
- * pg_user is now a publicly accessible view on pg_shadow.
- *
- *
- * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $PostgreSQL: pgsql/src/include/catalog/pg_shadow.h,v 1.28 2005/04/14 01:38:21 tgl Exp $
- *
- * NOTES
- * the genbki.sh script reads this file and generates .bki
- * information from the DATA() statements.
- *
- *-------------------------------------------------------------------------
- */
-#ifndef PG_SHADOW_H
-#define PG_SHADOW_H
-
-
-/* ----------------
- * pg_shadow definition. cpp turns this into
- * typedef struct FormData_pg_shadow
- * ----------------
- */
-#define ShadowRelationId 1260
-
-CATALOG(pg_shadow,1260) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
-{
- NameData usename;
- int4 usesysid;
- bool usecreatedb;
- bool usesuper; /* read this field via superuser() only */
- bool usecatupd;
-
- /* remaining fields may be null; use heap_getattr to read them! */
- text passwd;
- int4 valuntil; /* actually abstime */
- text useconfig[1];
-} FormData_pg_shadow;
-
-/* ----------------
- * Form_pg_shadow corresponds to a pointer to a tuple with
- * the format of pg_shadow relation.
- * ----------------
- */
-typedef FormData_pg_shadow *Form_pg_shadow;
-
-/* ----------------
- * compiler constants for pg_shadow
- * ----------------
- */
-#define Natts_pg_shadow 8
-#define Anum_pg_shadow_usename 1
-#define Anum_pg_shadow_usesysid 2
-#define Anum_pg_shadow_usecreatedb 3
-#define Anum_pg_shadow_usesuper 4
-#define Anum_pg_shadow_usecatupd 5
-#define Anum_pg_shadow_passwd 6
-#define Anum_pg_shadow_valuntil 7
-#define Anum_pg_shadow_useconfig 8
-
-/* ----------------
- * initial contents of pg_shadow
- *
- * The uppercase quantities will be replaced at initdb time with
- * user choices.
- * ----------------
- */
-DATA(insert ( "POSTGRES" PGUID t t t _null_ _null_ _null_ ));
-
-#define BOOTSTRAP_USESYSID 1
-
-#endif /* PG_SHADOW_H */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.6 2005/04/14 01:38:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.7 2005/06/28 05:09:12 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION
{
NameData spcname; /* tablespace name */
- int4 spcowner; /* sysid of owner */
+ Oid spcowner; /* owner of tablespace */
text spclocation; /* physical location (VAR LENGTH) */
aclitem spcacl[1]; /* access permissions (VAR LENGTH) */
} FormData_pg_tablespace;
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.161 2005/05/30 01:20:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.162 2005/06/28 05:09:12 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
{
NameData typname; /* type name */
Oid typnamespace; /* OID of namespace containing this type */
- int4 typowner; /* type owner */
+ Oid typowner; /* type owner */
/*
* For a fixed-size type, typlen is the number of bytes we use to
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.9 2004/12/31 22:03:28 pgsq l Exp $
+ * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.10 2005/06/28 05:09:12 tg l Exp $
*
*-------------------------------------------------------------------------
*/
extern void CreateConversionCommand(CreateConversionStmt *parsetree);
extern void DropConversionCommand(List *conversion_name, DropBehavior behavior);
extern void RenameConversion(List *name, const char *newname);
-extern void AlterConversionOwner(List *name, AclId newOwnerSys Id);
+extern void AlterConversionOwner(List *name, Oid newOwner Id);
#endif /* CONVERSIONCMDS_H */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.38 2005/06/06 17:01:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.39 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void dropdb(const char *dbname);
extern void RenameDatabase(const char *oldname, const char *newname);
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
-extern void AlterDatabaseOwner(const char *dbname, AclId newOwnerSys Id);
+extern void AlterDatabaseOwner(const char *dbname, Oid newOwner Id);
extern Oid get_database_oid(const char *dbname);
extern char *get_database_name(Oid dbid);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.65 2005/06/22 21:14:31 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.66 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void SetFunctionReturnType(Oid funcOid, Oid newRetType);
extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType);
extern void RenameFunction(List *name, List *argtypes, const char *newname);
-extern void AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSys Id);
+extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwner Id);
extern void AlterFunction(AlterFunctionStmt *stmt);
extern void CreateCast(CreateCastStmt *stmt);
extern void DropCast(DropCastStmt *stmt);
extern void RemoveOperator(RemoveOperStmt *stmt);
extern void RemoveOperatorById(Oid operOid);
extern void AlterOperatorOwner(List *name, TypeName *typeName1,
- TypeName *typename2, AclId newOwnerSys Id);
+ TypeName *typename2, Oid newOwner Id);
/* commands/aggregatecmds.c */
extern void DefineAggregate(List *names, List *parameters);
extern void RemoveAggregate(RemoveAggrStmt *stmt);
extern void RenameAggregate(List *name, TypeName *basetype, const char *newname);
-extern void AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSys Id);
+extern void AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwner Id);
/* commands/opclasscmds.c */
extern void DefineOpClass(CreateOpClassStmt *stmt);
extern void RemoveOpClass(RemoveOpClassStmt *stmt);
extern void RemoveOpClassById(Oid opclassOid);
extern void RenameOpClass(List *name, const char *access_method, const char *newname);
-extern void AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSys Id);
+extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwner Id);
/* support routines in commands/define.c */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.9 2004/12/31 22:03:28 pgsq l Exp $
+ * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.10 2005/06/28 05:09:12 tg l Exp $
*
*-------------------------------------------------------------------------
*/
extern void RemoveSchemaById(Oid schemaOid);
extern void RenameSchema(const char *oldname, const char *newname);
-extern void AlterSchemaOwner(const char *name, AclId newOwnerSys Id);
+extern void AlterSchemaOwner(const char *name, Oid newOwner Id);
#endif /* SCHEMACMDS_H */
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.9 2005/06/06 17:01:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.10 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern void CreateTableSpace(CreateTableSpaceStmt *stmt);
extern void DropTableSpace(DropTableSpaceStmt *stmt);
extern void RenameTableSpace(const char *oldname, const char *newname);
-extern void AlterTableSpaceOwner(const char *name, AclId newOwnerSys Id);
+extern void AlterTableSpaceOwner(const char *name, Oid newOwner Id);
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.10 2004/12/31 22:03:28 pgsq l Exp $
+ * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.11 2005/06/28 05:09:12 tg l Exp $
*
*-------------------------------------------------------------------------
*/
extern List *GetDomainConstraints(Oid typeOid);
-extern void AlterTypeOwner(List *names, AclId newOwnerSys Id);
+extern void AlterTypeOwner(List *names, Oid newOwner Id);
#endif /* TYPECMDS_H */
/*-------------------------------------------------------------------------
*
* user.h
- * Commands for manipulating users and groups .
+ * Commands for manipulating roles (formerly called users) .
*
*
- * $PostgreSQL: pgsql/src/include/commands/user.h,v 1.26 2005/02/20 02:22:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/user.h,v 1.27 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "nodes/parsenodes.h"
-extern void CreateUser(CreateUserStmt *stmt);
-extern void AlterUser(AlterUserStmt *stmt);
-extern void AlterUserSet(AlterUserSetStmt *stmt);
-extern void DropUser(DropUserStmt *stmt);
-extern void RenameUser(const char *oldname, const char *newname);
-
-extern void CreateGroup(CreateGroupStmt *stmt);
-extern void AlterGroup(AlterGroupStmt *stmt, const char *tag);
-extern void DropGroup(DropGroupStmt *stmt);
-extern void RenameGroup(const char *oldname, const char *newname);
+extern void CreateRole(CreateRoleStmt *stmt);
+extern void AlterRole(AlterRoleStmt *stmt);
+extern void AlterRoleSet(AlterRoleSetStmt *stmt);
+extern void DropRole(DropRoleStmt *stmt);
+extern void GrantRole(GrantRoleStmt *stmt);
+extern void RenameRole(const char *oldname, const char *newname);
#endif /* USER_H */
* Interface to hba.c
*
*
- * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.37 2005/06/27 02:04:25 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.38 2005/06/28 05:09:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
typedef struct Port hbaPort;
-extern List **get_user_line(const char *user );
+extern List **get_role_line(const char *role );
extern void load_hba(void);
extern void load_ident(void);
-extern void load_user(void);
-extern void load_group(void);
+extern void load_role(void);
extern int hba_getauthmethod(hbaPort *port);
extern int authident(hbaPort *port);
extern bool read_pg_database_line(FILE *fp, char *dbname,
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.175 2005/02/26 18:43:3 4 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.176 2005/06/28 05:09:0 4 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to other files.
/* now in utils/init/miscinit.c */
extern void SetDatabasePath(const char *path);
-extern char *GetUserNameFromId(AclId user id);
-extern AclI d GetUserId(void);
-extern void SetUserId(AclId user id);
-extern AclI d GetSessionUserId(void);
-extern void SetSessionUserId(AclId user id);
-extern void InitializeSessionUserId(const char *user name);
+extern char *GetUserNameFromId(Oid role id);
+extern Oi d GetUserId(void);
+extern void SetUserId(Oid role id);
+extern Oi d GetSessionUserId(void);
+extern void SetSessionUserId(Oid role id);
+extern void InitializeSessionUserId(const char *role name);
extern void InitializeSessionUserIdStandalone(void);
-extern void SetSessionAuthorization(AclId user id, bool is_superuser);
+extern void SetSessionAuthorization(Oid role id, bool is_superuser);
extern void SetDataDir(const char *dir);
extern char *make_absolute_path(const char *path);
/* in utils/misc/superuser.c */
extern bool superuser(void); /* current user is superuser */
-extern bool superuser_arg(AclId userid); /* given user is superuser */
+extern bool superuser_arg(Oid roleid); /* given user is superuser */
/*****************************************************************************
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.171 2005/06/26 22:05:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.172 2005/06/28 05:09:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
T_AlterDomainStmt,
T_SetOperationStmt,
T_GrantStmt,
+ T_GrantRoleStmt,
T_ClosePortalStmt,
T_ClusterStmt,
T_CopyStmt,
T_DropPropertyStmt,
T_CreatePLangStmt,
T_DropPLangStmt,
- T_CreateUser Stmt,
- T_AlterUser Stmt,
- T_DropUser Stmt,
+ T_CreateRole Stmt,
+ T_AlterRole Stmt,
+ T_DropRole Stmt,
T_LockStmt,
T_ConstraintsSetStmt,
- T_CreateGroupStmt,
- T_AlterGroupStmt,
- T_DropGroupStmt,
T_ReindexStmt,
T_CheckPointStmt,
T_CreateSchemaStmt,
T_AlterDatabaseSetStmt,
- T_AlterUser SetStmt,
+ T_AlterRole SetStmt,
T_CreateConversionStmt,
T_CreateCastStmt,
T_DropCastStmt,
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.283 2005/06/22 21:14:31 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.284 2005/06/28 05:09:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
bool inh; /* inheritance requested? */
bool inFromCl; /* present in FROM clause? */
AclMode requiredPerms; /* bitmask of required access permissions */
- AclId checkAsUser; /* if not zero, check access as this user */
+ Oid checkAsUser; /* if valid, check access as this role */
} RangeTblEntry;
/*
OBJECT_DATABASE,
OBJECT_DOMAIN,
OBJECT_FUNCTION,
- OBJECT_GROUP,
OBJECT_INDEX,
OBJECT_LANGUAGE,
OBJECT_LARGEOBJECT,
OBJECT_OPCLASS,
OBJECT_OPERATOR,
+ OBJECT_ROLE,
OBJECT_RULE,
OBJECT_SCHEMA,
OBJECT_SEQUENCE,
OBJECT_TABLESPACE,
OBJECT_TRIGGER,
OBJECT_TYPE,
- OBJECT_USER,
OBJECT_VIEW
} ObjectType;
typedef struct PrivGrantee
{
NodeTag type;
- char *username; /* if both are NULL then PUBLIC */
- char *groupname;
+ char *rolname; /* if NULL then PUBLIC */
} PrivGrantee;
/*
List *objs;
} PrivTarget;
+/* ----------------------
+ * Grant/Revoke Role Statement
+ *
+ * Note: the lists of roles are lists of names, as Value strings
+ * ----------------------
+ */
+typedef struct GrantRoleStmt
+{
+ NodeTag type;
+ List *granted_roles; /* list of roles to be granted/revoked */
+ List *grantee_roles; /* list of member roles to add/delete */
+ bool is_grant; /* true = GRANT, false = REVOKE */
+ bool admin_opt; /* with admin option */
+ char *grantor; /* set grantor to other than current role */
+ DropBehavior behavior; /* drop behavior (for REVOKE) */
+} GrantRoleStmt;
+
/* ----------------------
* Copy Statement
* ----------------------
} DropPLangStmt;
/* ----------------------
- * Create/Alter/Drop User Statements
+ * Create/Alter/Drop Role Statements
* ----------------------
*/
-typedef struct CreateUser Stmt
+typedef struct CreateRole Stmt
{
NodeTag type;
- char *user; /* PostgreSQL user login name */
+ char *role; /* role name */
List *options; /* List of DefElem nodes */
-} CreateUser Stmt;
+} CreateRole Stmt;
-typedef struct AlterUser Stmt
+typedef struct AlterRole Stmt
{
NodeTag type;
- char *user; /* PostgreSQL user login name */
+ char *role; /* role name */
List *options; /* List of DefElem nodes */
-} AlterUserStmt;
+ int action; /* +1 = add members, -1 = drop members */
+} AlterRoleStmt;
-typedef struct AlterUser SetStmt
+typedef struct AlterRole SetStmt
{
NodeTag type;
- char *user;
- char *variable;
- List *value;
-} AlterUser SetStmt;
+ char *role; /* role name */
+ char *variable; /* GUC variable name */
+ List *value; /* value for variable, or NIL for Reset */
+} AlterRole SetStmt;
-typedef struct DropUser Stmt
+typedef struct DropRole Stmt
{
NodeTag type;
- List *users; /* List of users to remove */
-} DropUserStmt;
-
-/* ----------------------
- * Create/Alter/Drop Group Statements
- * ----------------------
- */
-typedef struct CreateGroupStmt
-{
- NodeTag type;
- char *name; /* name of the new group */
- List *options; /* List of DefElem nodes */
-} CreateGroupStmt;
-
-typedef struct AlterGroupStmt
-{
- NodeTag type;
- char *name; /* name of group to alter */
- int action; /* +1 = add, -1 = drop user */
- List *listUsers; /* list of users to add/drop */
-} AlterGroupStmt;
-
-typedef struct DropGroupStmt
-{
- NodeTag type;
- char *name;
-} DropGroupStmt;
+ List *roles; /* List of roles to remove */
+} DropRoleStmt;
/* ----------------------
* {Create|Alter} SEQUENCE Statement
*
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.30 2005/06/25 23:58:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.31 2005/06/28 05:09:04 tgl Exp $
* ----------
*/
#ifndef PGSTAT_H
{
PgStat_MsgHdr m_hdr;
Oid m_databaseid;
- AclId m_userid;
+ Oid m_userid;
SockAddr m_clientaddr;
} PgStat_MsgBestart;
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.77 2005/01/27 23:36:14 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.78 2005/06/28 05:09:13 tgl Exp $
*
* NOTES
* An ACL array is simply an array of AclItems, representing the union
/*
- * typedef AclId is declared in c.h
- *
* typedef AclMode is declared in parsenodes.h, also the individual privilege
* bit meanings are defined there
*/
-#define ACL_ID_WORLD 0 /* placeholder for id in a WORLD acl item */
-
-/*
- * AclIdType tag that describes if the AclId is a user, group, etc.
- */
-#define ACL_IDTYPE_WORLD 0x00 /* PUBLIC */
-#define ACL_IDTYPE_UID 0x01 /* user id - from pg_shadow */
-#define ACL_IDTYPE_GID 0x02 /* group id - from pg_group */
+#define ACL_ID_PUBLIC 0 /* placeholder for id in a PUBLIC acl item */
/*
* AclItem
*
- * The IDTYPE included in ai_privs identifies the type of the grantee ID.
- * The grantor ID currently must always be a user, never a group. (FIXME)
- *
* Note: must be same size on all platforms, because the size is hardcoded
* in the pg_type.h entry for aclitem.
*/
typedef struct AclItem
{
- AclId ai_grantee; /* ID that this item grants privs to */
- AclId ai_grantor; /* grantor of privs (always a user id) */
- AclMode ai_privs; /* AclIdType plus privilege bits */
+ Oid ai_grantee; /* ID that this item grants privs to */
+ Oid ai_grantor; /* grantor of privs */
+ AclMode ai_privs; /* privilege bits */
} AclItem;
/*
- * The AclIdType is stored in the top two bits of the ai_privs field
- * of an AclItem. The middle 15 bits are the grant option markers,
- * and the lower 15 bits are the actual privileges. We use "rights"
+ * The upper 16 bits of the ai_privs field of an AclItem are the grant option
+ * bits, and the lower 16 bits are the actual privileges. We use "rights"
* to mean the combined grant option and privilege bits fields.
*/
-#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0x7FFF)
-#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 15) & 0x7FFF)
-#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs & 0x3FFFFFFF)
-#define ACLITEM_GET_IDTYPE(item) ((item).ai_privs >> 30)
+#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0xFFFF)
+#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 16) & 0xFFFF)
+#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs)
-#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0x7FFF) << 15 )
-#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 15) & 0x7 FFF)
+#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16 )
+#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 16) & 0xF FFF)
#define ACLITEM_SET_PRIVS(item,privs) \
- ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x7 FFF)) | \
- ((AclMode) (privs) & 0x7 FFF))
+ ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xF FFF)) | \
+ ((AclMode) (privs) & 0xF FFF))
#define ACLITEM_SET_GOPTIONS(item,goptions) \
- ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0x7FFF) << 15 )) | \
- (((AclMode) (goptions) & 0x7FFF) << 15 ))
+ ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFF) << 16 )) | \
+ (((AclMode) (goptions) & 0xFFFF) << 16 ))
#define ACLITEM_SET_RIGHTS(item,rights) \
- ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x3FFFFFFF)) | \
- ((AclMode) (rights) & 0x3FFFFFFF))
-#define ACLITEM_SET_IDTYPE(item,idtype ) \
- ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0x03) << 30) ) | \
- (((AclMode) (idtype) & 0x03) << 30 ))
+ ((item).ai_privs = (AclMode) (rights))
+
+#define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions ) \
+ ((item).ai_privs = ((AclMode) (privs) & 0xFFFF ) | \
+ (((AclMode) (goptions) & 0xFFFF) << 16 ))
-#define ACLITEM_SET_PRIVS_IDTYPE(item,privs,goption,idtype) \
- ((item).ai_privs = ((AclMode) (privs) & 0x7FFF) | \
- (((AclMode) (goption) & 0x7FFF) << 15) | \
- ((AclMode) (idtype) << 30))
-#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0x7 FFF)
-#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0x7FFF << 15 )
+#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0xF FFF)
+#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16 )
/*
* Definitions for convenient access to Acl (array of AclItem) and IdList
- * (array of AclI d). These are standard PostgreSQL arrays, but are restricted
+ * (array of Oi d). These are standard PostgreSQL arrays, but are restricted
* to have one dimension. We also ignore the lower bound when reading,
* and set it to one when writing.
*
* CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
* other array types). Therefore, be careful to detoast them with the
* macros provided, unless you know for certain that a particular array
- * can't have been toasted. Presently, we do not provide toast tables for
- * pg_class or pg_group, so the entries in those tables won't have been
- * stored externally --- but they could have been compressed!
+ * can't have been toasted.
*/
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
/*
- * IdList a one-dimensional array of AclI d
+ * IdList a one-dimensional array of Oi d
*/
typedef ArrayType IdList;
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
-#define IDLIST_DAT(IDL) ((AclI d *) ARR_DATA_PTR(IDL))
-#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(AclI d)))
+#define IDLIST_DAT(IDL) ((Oi d *) ARR_DATA_PTR(IDL))
+#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(Oi d)))
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
/*
/*
* routines used internally
*/
-extern Acl *acldefault(GrantObjectType objtype, AclId owneri d);
+extern Acl *acldefault(GrantObjectType objtype, Oid ownerI d);
extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
- int modechg, AclId owneri d, DropBehavior behavior);
-extern Acl *aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newowneri d);
+ int modechg, Oid ownerI d, DropBehavior behavior);
+extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerI d);
-extern AclMode aclmask(const Acl *acl, AclId userid, AclId owneri d,
+extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerI d,
AclMode mask, AclMaskHow how);
+extern bool is_member_of_role(Oid member, Oid role);
+
+extern void InitializeAcl(void);
+
/*
* SQL functions (from acl.c)
*/
* prototypes for functions in aclchk.c
*/
extern void ExecuteGrantStmt(GrantStmt *stmt);
-extern char *get_groname(AclId grosysid);
-extern AclMode pg_class_aclmask(Oid table_oid, AclId user id,
+extern AclMode pg_class_aclmask(Oid table_oid, Oid role id,
AclMode mask, AclMaskHow how);
-extern AclMode pg_database_aclmask(Oid db_oid, AclId user id,
+extern AclMode pg_database_aclmask(Oid db_oid, Oid role id,
AclMode mask, AclMaskHow how);
-extern AclMode pg_proc_aclmask(Oid proc_oid, AclId user id,
+extern AclMode pg_proc_aclmask(Oid proc_oid, Oid role id,
AclMode mask, AclMaskHow how);
-extern AclMode pg_language_aclmask(Oid lang_oid, AclId user id,
+extern AclMode pg_language_aclmask(Oid lang_oid, Oid role id,
AclMode mask, AclMaskHow how);
-extern AclMode pg_namespace_aclmask(Oid nsp_oid, AclId user id,
+extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid role id,
AclMode mask, AclMaskHow how);
-extern AclMode pg_tablespace_aclmask(Oid spc_oid, AclId user id,
+extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid role id,
AclMode mask, AclMaskHow how);
-extern AclResult pg_class_aclcheck(Oid table_oid, AclId user id, AclMode mode);
-extern AclResult pg_database_aclcheck(Oid db_oid, AclId user id, AclMode mode);
-extern AclResult pg_proc_aclcheck(Oid proc_oid, AclId user id, AclMode mode);
-extern AclResult pg_language_aclcheck(Oid lang_oid, AclId user id, AclMode mode);
-extern AclResult pg_namespace_aclcheck(Oid nsp_oid, AclId user id, AclMode mode);
-extern AclResult pg_tablespace_aclcheck(Oid spc_oid, AclId user id, AclMode mode);
+extern AclResult pg_class_aclcheck(Oid table_oid, Oid role id, AclMode mode);
+extern AclResult pg_database_aclcheck(Oid db_oid, Oid role id, AclMode mode);
+extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid role id, AclMode mode);
+extern AclResult pg_language_aclcheck(Oid lang_oid, Oid role id, AclMode mode);
+extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid role id, AclMode mode);
+extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid role id, AclMode mode);
extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
const char *objectname);
/* ownercheck routines just return true (owner) or false (not) */
-extern bool pg_class_ownercheck(Oid class_oid, AclId user id);
-extern bool pg_type_ownercheck(Oid type_oid, AclId user id);
-extern bool pg_oper_ownercheck(Oid oper_oid, AclId user id);
-extern bool pg_proc_ownercheck(Oid proc_oid, AclId user id);
-extern bool pg_namespace_ownercheck(Oid nsp_oid, AclId user id);
-extern bool pg_tablespace_ownercheck(Oid spc_oid, AclId user id);
-extern bool pg_opclass_ownercheck(Oid opc_oid, AclId user id);
-extern bool pg_database_ownercheck(Oid db_oid, AclId user id);
-extern bool pg_conversion_ownercheck(Oid conv_oid, AclId user id);
+extern bool pg_class_ownercheck(Oid class_oid, Oid role id);
+extern bool pg_type_ownercheck(Oid type_oid, Oid role id);
+extern bool pg_oper_ownercheck(Oid oper_oid, Oid role id);
+extern bool pg_proc_ownercheck(Oid proc_oid, Oid role id);
+extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid role id);
+extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid role id);
+extern bool pg_opclass_ownercheck(Oid opc_oid, Oid role id);
+extern bool pg_database_ownercheck(Oid db_oid, Oid role id);
+extern bool pg_conversion_ownercheck(Oid conv_oid, Oid role id);
#endif /* ACL_H */
* Routines for maintaining "flat file" images of the shared catalogs.
*
*
- * $PostgreSQL: pgsql/src/include/utils/flatfiles.h,v 1.4 2005/06/17 22:32:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/flatfiles.h,v 1.5 2005/06/28 05:09:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "fmgr.h"
extern void database_file_update_needed(void);
-extern void group_file_update_needed(void);
-extern void user_file_update_needed(void);
+extern void auth_file_update_needed(void);
extern char *database_getflatfilename(void);
-extern char *group_getflatfilename(void);
-extern char *user_getflatfilename(void);
+extern char *auth_getflatfilename(void);
extern void BuildFlatFiles(bool database_only);
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.99 2005/05/01 18:56:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.100 2005/06/28 05:09:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
Datum *values, int nvalues,
float4 *numbers, int nnumbers);
extern char *get_namespace_name(Oid nspid);
-extern AclId get_usesysid(const char *user name);
-extern AclId get_grosysid(char *gro name);
+extern Oid get_roleid(const char *rol name);
+extern Oid get_roleid_checked(const char *rol name);
#define is_array_type(typid) (get_element_type(typid) != InvalidOid)
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.59 2005/03/29 00:17:18 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.60 2005/06/28 05:09:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#define AMPROCNUM 5
#define ATTNAME 6
#define ATTNUM 7
-#define CASTSOURCETARGET 8
-#define CLAAMNAMENSP 9
-#define CLAOID 10
-#define CONDEFAULT 11
-#define CONNAMENSP 12
-#define CONOID 13
-#define GRONAME 14
-#define GROSYSID 15
-#define INDEXRELID 16
-#define INHRELID 17
-#define LANGNAME 18
-#define LANGOID 19
-#define NAMESPACENAME 20
-#define NAMESPACEOID 21
-#define OPERNAMENSP 22
-#define OPEROID 23
-#define PROCNAMEARGSNSP 24
-#define PROC OID 25
-#define RELNAMENSP 26
-#define RELOID 27
-#define RULERELNAME 28
-#define SHADOWNAME 29
-#define SHADOWSYSID 30
+#define AUTHMEMMEMROLE 8
+#define AUTHMEMROLEMEM 9
+#define AUTHNAME 10
+#define AUTHOID 11
+#define CASTSOURCETARGET 12
+#define CLAAMNAMENSP 13
+#define CLAOID 14
+#define CONDEFAULT 15
+#define CONNAMENSP 16
+#define CONOID 17
+#define INDEXRELID 18
+#define INHRELID 19
+#define LANGNAME 20
+#define LANGOID 21
+#define NAMESPACENAME 22
+#define NAMESPACEOID 23
+#define OPERNAMENSP 24
+#define OPER OID 25
+#define PROCNAMEARGSNSP 26
+#define PROCOID 27
+#define RELNAMENSP 28
+#define RELOID 29
+#define RULERELNAME 30
#define STATRELATT 31
#define TYPENAMENSP 32
#define TYPEOID 33
CREATE USER regressuser3;
CREATE USER regressuser4;
CREATE USER regressuser4; -- duplicate
-ERROR: user "regressuser4" already exists
+ERROR: role "regressuser4" already exists
CREATE GROUP regressgroup1;
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
ALTER GROUP regressgroup1 ADD USER regressuser4;
ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate
+NOTICE: role "regressuser2" is already a member of role "regressgroup2"
ALTER GROUP regressgroup2 DROP USER regressuser2;
ALTER GROUP regressgroup2 ADD USER regressuser4;
-- test owner privileges
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
-- has_table_privilege function
-- bad-input checks
-select has_table_privilege(NULL,'pg_shadow ','select');
+select has_table_privilege(NULL,'pg_authid ','select');
has_table_privilege
---------------------
select has_table_privilege('pg_shad','select');
ERROR: relation "pg_shad" does not exist
-select has_table_privilege('nosuchuser','pg_shadow ','select');
-ERROR: user "nosuchuser" does not exist
-select has_table_privilege('pg_shadow ','sel');
+select has_table_privilege('nosuchuser','pg_authid ','select');
+ERROR: role "nosuchuser" does not exist
+select has_table_privilege('pg_authid ','sel');
ERROR: unrecognized privilege type: "sel"
-select has_table_privilege(-999999,'pg_shadow ','update');
-ERROR: user with ID 4293967297 does not exist
+select has_table_privilege(-999999,'pg_authid ','update');
+ERROR: role with O ID 4293967297 does not exist
select has_table_privilege(1,'rule');
ERROR: relation with OID 1 does not exist
-- superuser
\c -
-select has_table_privilege(current_user,'pg_shadow ','select');
+select has_table_privilege(current_user,'pg_authid ','select');
has_table_privilege
---------------------
t
(1 row)
-select has_table_privilege(current_user,'pg_shadow ','insert');
+select has_table_privilege(current_user,'pg_authid ','insert');
has_table_privilege
---------------------
t
(1 row)
-select has_table_privilege(t2.usesysid,'pg_shadow ','update')
+select has_table_privilege(t2.usesysid,'pg_authid ','update')
from (select usesysid from pg_user where usename = current_user) as t2;
has_table_privilege
---------------------
t
(1 row)
-select has_table_privilege(t2.usesysid,'pg_shadow ','delete')
+select has_table_privilege(t2.usesysid,'pg_authid ','delete')
from (select usesysid from pg_user where usename = current_user) as t2;
has_table_privilege
---------------------
(1 row)
select has_table_privilege(current_user,t1.oid,'rule')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(t2.usesysid,t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1,
+from (select oid from pg_class where relname = 'pg_authid ') as t1,
(select usesysid from pg_user where usename = current_user) as t2;
has_table_privilege
---------------------
(1 row)
select has_table_privilege(t2.usesysid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1,
+from (select oid from pg_class where relname = 'pg_authid ') as t1,
(select usesysid from pg_user where usename = current_user) as t2;
has_table_privilege
---------------------
t
(1 row)
-select has_table_privilege('pg_shadow ','update');
+select has_table_privilege('pg_authid ','update');
has_table_privilege
---------------------
t
(1 row)
-select has_table_privilege('pg_shadow ','delete');
+select has_table_privilege('pg_authid ','delete');
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
has_table_privilege
---------------------
t
(1 row)
select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
has_table_privilege
---------------------
t
CREATE TABLE atest4 (a int);
GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regressuser2;
-GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; -- fail
-ERROR: grant options can only be granted to individual users
+GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
SET SESSION AUTHORIZATION regressuser2;
GRANT SELECT ON atest4 TO regressuser3;
GRANT UPDATE ON atest4 TO regressuser3; -- fail
viewname | definition
--------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
+ pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin);
pg_indexes | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS "tablespace", pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char"));
pg_locks | SELECT l.locktype, l."database", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(locktype text, "database" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, "transaction" xid, pid integer, "mode" text, granted boolean);
- pg_prepared_xacts | SELECT p."transaction", p.gid, p."prepared", u.usename AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid integer, dbid oid) LEFT JOIN pg_shadow u ON ((p.ownerid = u.usesysid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
+ pg_prepared_xacts | SELECT p."transaction", p.gid, p."prepared", u.rolname AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid oid, dbid oid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid)));
+ pg_roles | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, '********'::text AS rolpassword, pg_authid.rolvaliduntil, pg_authid.rolconfig FROM pg_authid;
pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name);
pg_settings | SELECT a.name, a.setting, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a(name text, setting text, category text, short_desc text, extra_desc text, context text, vartype text, source text, min_val text, max_val text);
- pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.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, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid));
+ pg_shadow | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin;
+ pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, 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, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid));
pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char");
pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname;
pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d;
shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color))));
street | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath);
toyemp | SELECT emp.name, emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp;
-(41 rows)
+(44 rows)
SELECT tablename, rulename, definition FROM pg_rules
ORDER BY tablename, rulename;
pg_amproc | t
pg_attrdef | t
pg_attribute | t
+ pg_auth_members | t
+ pg_authid | t
pg_cast | t
pg_class | t
pg_constraint | t
pg_database | t
pg_depend | t
pg_description | t
- pg_group | t
pg_index | t
pg_inherits | t
pg_language | t
pg_operator | t
pg_proc | t
pg_rewrite | t
- pg_shadow | t
pg_statistic | t
pg_tablespace | t
pg_trigger | t
-- has_table_privilege function
-- bad-input checks
-select has_table_privilege(NULL,'pg_shadow ','select');
+select has_table_privilege(NULL,'pg_authid ','select');
select has_table_privilege('pg_shad','select');
-select has_table_privilege('nosuchuser','pg_shadow ','select');
-select has_table_privilege('pg_shadow ','sel');
-select has_table_privilege(-999999,'pg_shadow ','update');
+select has_table_privilege('nosuchuser','pg_authid ','select');
+select has_table_privilege('pg_authid ','sel');
+select has_table_privilege(-999999,'pg_authid ','update');
select has_table_privilege(1,'rule');
-- superuser
\c -
-select has_table_privilege(current_user,'pg_shadow ','select');
-select has_table_privilege(current_user,'pg_shadow ','insert');
+select has_table_privilege(current_user,'pg_authid ','select');
+select has_table_privilege(current_user,'pg_authid ','insert');
-select has_table_privilege(t2.usesysid,'pg_shadow ','update')
+select has_table_privilege(t2.usesysid,'pg_authid ','update')
from (select usesysid from pg_user where usename = current_user) as t2;
-select has_table_privilege(t2.usesysid,'pg_shadow ','delete')
+select has_table_privilege(t2.usesysid,'pg_authid ','delete')
from (select usesysid from pg_user where usename = current_user) as t2;
select has_table_privilege(current_user,t1.oid,'rule')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
select has_table_privilege(current_user,t1.oid,'references')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
select has_table_privilege(t2.usesysid,t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1,
+from (select oid from pg_class where relname = 'pg_authid ') as t1,
(select usesysid from pg_user where usename = current_user) as t2;
select has_table_privilege(t2.usesysid,t1.oid,'insert')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1,
+from (select oid from pg_class where relname = 'pg_authid ') as t1,
(select usesysid from pg_user where usename = current_user) as t2;
-select has_table_privilege('pg_shadow ','update');
-select has_table_privilege('pg_shadow ','delete');
+select has_table_privilege('pg_authid ','update');
+select has_table_privilege('pg_authid ','delete');
select has_table_privilege(t1.oid,'select')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
select has_table_privilege(t1.oid,'trigger')
-from (select oid from pg_class where relname = 'pg_shadow ') as t1;
+from (select oid from pg_class where relname = 'pg_authid ') as t1;
-- non-superuser
SET SESSION AUTHORIZATION regressuser3;
GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regressuser2;
-GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; -- fail
+GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
SET SESSION AUTHORIZATION regressuser2;