aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-06-28 05:09:14 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-06-28 05:09:14 +0000
commit7762619e95272974f90a38d8d85aafbe0e94add5 (patch)
treed7f756687beb883406489d59d13f722995fd7660
parent977530d8da2683dff036c2994395ab518527b93e (diff)
downloadpostgresql-7762619e95272974f90a38d8d85aafbe0e94add5.tar.gz
postgresql-7762619e95272974f90a38d8d85aafbe0e94add5.zip
Replace pg_shadow and pg_group by new role-capable catalogs pg_authid
and pg_auth_members. There are still many loose ends to finish in this patch (no documentation, no regression tests, no pg_dump support for instance). But I'm going to commit it now anyway so that Alvaro can make some progress on shared dependencies. The catalog changes should be pretty much done.
-rw-r--r--doc/src/sgml/catalogs.sgml710
-rw-r--r--doc/src/sgml/func.sgml12
-rw-r--r--src/backend/access/transam/twophase.c14
-rw-r--r--src/backend/access/transam/xact.c12
-rw-r--r--src/backend/catalog/Makefile7
-rw-r--r--src/backend/catalog/aclchk.c286
-rw-r--r--src/backend/catalog/genbki.sh12
-rw-r--r--src/backend/catalog/information_schema.sql86
-rw-r--r--src/backend/catalog/namespace.c26
-rw-r--r--src/backend/catalog/pg_conversion.c6
-rw-r--r--src/backend/catalog/pg_namespace.c6
-rw-r--r--src/backend/catalog/pg_operator.c6
-rw-r--r--src/backend/catalog/pg_proc.c4
-rw-r--r--src/backend/catalog/pg_type.c4
-rw-r--r--src/backend/catalog/system_views.sql50
-rw-r--r--src/backend/commands/aggregatecmds.c8
-rw-r--r--src/backend/commands/alter.c16
-rw-r--r--src/backend/commands/conversioncmds.c8
-rw-r--r--src/backend/commands/copy.c3
-rw-r--r--src/backend/commands/dbcommands.c50
-rw-r--r--src/backend/commands/functioncmds.c10
-rw-r--r--src/backend/commands/opclasscmds.c10
-rw-r--r--src/backend/commands/operatorcmds.c8
-rw-r--r--src/backend/commands/schemacmds.c33
-rw-r--r--src/backend/commands/tablecmds.c28
-rw-r--r--src/backend/commands/tablespace.c30
-rw-r--r--src/backend/commands/typecmds.c8
-rw-r--r--src/backend/commands/user.c1335
-rw-r--r--src/backend/commands/variable.c56
-rw-r--r--src/backend/executor/execMain.c4
-rw-r--r--src/backend/executor/nodeAgg.c4
-rw-r--r--src/backend/libpq/crypt.c39
-rw-r--r--src/backend/libpq/hba.c276
-rw-r--r--src/backend/nodes/copyfuncs.c114
-rw-r--r--src/backend/nodes/equalfuncs.c90
-rw-r--r--src/backend/nodes/outfuncs.c4
-rw-r--r--src/backend/nodes/readfuncs.c4
-rw-r--r--src/backend/parser/gram.y404
-rw-r--r--src/backend/parser/keywords.c3
-rw-r--r--src/backend/parser/parse_relation.c12
-rw-r--r--src/backend/postmaster/pgstat.c3
-rw-r--r--src/backend/postmaster/postmaster.c19
-rw-r--r--src/backend/rewrite/rewriteDefine.c14
-rw-r--r--src/backend/rewrite/rewriteHandler.c4
-rw-r--r--src/backend/tcop/utility.c95
-rw-r--r--src/backend/utils/adt/acl.c734
-rw-r--r--src/backend/utils/adt/pgstatfuncs.c5
-rw-r--r--src/backend/utils/adt/ri_triggers.c6
-rw-r--r--src/backend/utils/adt/ruleutils.c30
-rw-r--r--src/backend/utils/cache/lsyscache.c73
-rw-r--r--src/backend/utils/cache/syscache.c86
-rw-r--r--src/backend/utils/fmgr/fmgr.c6
-rw-r--r--src/backend/utils/init/flatfiles.c544
-rw-r--r--src/backend/utils/init/miscinit.c95
-rw-r--r--src/backend/utils/init/postinit.c32
-rw-r--r--src/backend/utils/misc/guc.c6
-rw-r--r--src/backend/utils/misc/superuser.c62
-rw-r--r--src/bin/initdb/initdb.c31
-rw-r--r--src/include/access/twophase.h4
-rw-r--r--src/include/c.h8
-rw-r--r--src/include/catalog/catversion.h4
-rw-r--r--src/include/catalog/indexing.h22
-rw-r--r--src/include/catalog/pg_attribute.h14
-rw-r--r--src/include/catalog/pg_auth_members.h54
-rw-r--r--src/include/catalog/pg_authid.h94
-rw-r--r--src/include/catalog/pg_class.h4
-rw-r--r--src/include/catalog/pg_conversion.h6
-rw-r--r--src/include/catalog/pg_database.h4
-rw-r--r--src/include/catalog/pg_group.h45
-rw-r--r--src/include/catalog/pg_namespace.h6
-rw-r--r--src/include/catalog/pg_opclass.h4
-rw-r--r--src/include/catalog/pg_operator.h4
-rw-r--r--src/include/catalog/pg_proc.h60
-rw-r--r--src/include/catalog/pg_shadow.h78
-rw-r--r--src/include/catalog/pg_tablespace.h4
-rw-r--r--src/include/catalog/pg_type.h4
-rw-r--r--src/include/commands/conversioncmds.h4
-rw-r--r--src/include/commands/dbcommands.h4
-rw-r--r--src/include/commands/defrem.h10
-rw-r--r--src/include/commands/schemacmds.h4
-rw-r--r--src/include/commands/tablespace.h4
-rw-r--r--src/include/commands/typecmds.h4
-rw-r--r--src/include/commands/user.h20
-rw-r--r--src/include/libpq/hba.h7
-rw-r--r--src/include/miscadmin.h18
-rw-r--r--src/include/nodes/nodes.h14
-rw-r--r--src/include/nodes/parsenodes.h83
-rw-r--r--src/include/pgstat.h4
-rw-r--r--src/include/utils/acl.h131
-rw-r--r--src/include/utils/flatfiles.h8
-rw-r--r--src/include/utils/lsyscache.h6
-rw-r--r--src/include/utils/syscache.h48
-rw-r--r--src/test/regress/expected/privileges.out42
-rw-r--r--src/test/regress/expected/rules.out9
-rw-r--r--src/test/regress/expected/sanity_check.out4
-rw-r--r--src/test/regress/sql/privileges.sql34
96 files changed, 3309 insertions, 3211 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 2b1318b05e4..7358dfb5122 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,6 +1,6 @@
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.105 2005/06/18 19:33:41 tgl Exp $
+ $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.106 2005/06/28 05:08:50 tgl Exp $
-->
<chapter id="catalogs">
@@ -79,6 +79,16 @@
</row>
<row>
+ <entry><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link></entry>
+ <entry>authorization identifiers (roles)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-auth-members"><structname>pg_auth_members</structname></link></entry>
+ <entry>authorization identifier membership relationships</entry>
+ </row>
+
+ <row>
<entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry>
<entry>casts (data type conversions)</entry>
</row>
@@ -114,11 +124,6 @@
</row>
<row>
- <entry><link linkend="catalog-pg-group"><structname>pg_group</structname></link></entry>
- <entry>groups of database users</entry>
- </row>
-
- <row>
<entry><link linkend="catalog-pg-index"><structname>pg_index</structname></link></entry>
<entry>additional index information</entry>
</row>
@@ -169,11 +174,6 @@
</row>
<row>
- <entry><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link></entry>
- <entry>database users</entry>
- </row>
-
- <row>
<entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry>
<entry>planner statistics</entry>
</row>
@@ -902,6 +902,201 @@
</sect1>
+ <sect1 id="catalog-pg-authid">
+ <title><structname>pg_authid</structname></title>
+
+ <indexterm zone="catalog-pg-authid">
+ <primary>pg_authid</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_authid</structname> contains information about
+ database authorization identifiers (roles). A role subsumes the concepts
+ of <quote>users</> and <quote>groups</>. A user is essentially just a
+ role with the <structfield>rolcanlogin</> flag set. Any role (with or
+ without <structfield>rolcanlogin</>) may have other roles as members; see
+ <link linkend="catalog-pg-auth-members"><structname>pg_auth_members</structname></link>.
+ </para>
+
+ <para>
+ Since this catalog contains passwords, it must not be publicly readable.
+ <link linkend="view-pg-roles"><structname>pg_roles</structname></link>
+ is a publicly readable view on
+ <structname>pg_authid</structname> that blanks out the password field.
+ </para>
+
+ <para>
+ <xref linkend="user-manag"> contains detailed information about user and
+ privilege management.
+ </para>
+
+ <para>
+ Because user identities are cluster-wide,
+ <structname>pg_authid</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_authid</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_authid</> Columns</title>
+
+ <tgroup cols=4>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>rolname</structfield></entry>
+ <entry><type>name</type></entry>
+ <entry></entry>
+ <entry>Role name</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolsuper</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Role has superuser privileges</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcreaterole</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Role may create more roles</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcreatedb</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Role may create databases</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcatupdate</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>
+ Role may update system catalogs directly. (Even a superuser may not do
+ this unless this column is true.)
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcanlogin</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>
+ Role may log in, that is, this role can be given as the initial
+ session authorization identifier.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolpassword</structfield></entry>
+ <entry><type>text</type></entry>
+ <entry></entry>
+ <entry>Password (possibly encrypted); NULL if none</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolvaliduntil</structfield></entry>
+ <entry><type>timestamptz</type></entry>
+ <entry></entry>
+ <entry>Password expiry time (only used for password authentication);
+ NULL if no expiration</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolconfig</structfield></entry>
+ <entry><type>text[]</type></entry>
+ <entry></entry>
+ <entry>Session defaults for run-time configuration variables</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-auth-members">
+ <title><structname>pg_auth_members</structname></title>
+
+ <indexterm zone="catalog-pg-auth-members">
+ <primary>pg_auth_members</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_auth_members</structname> shows the membership
+ relations between roles. Any non-circular set of relationships is allowed.
+ </para>
+
+ <para>
+ Because user identities are cluster-wide,
+ <structname>pg_auth_members</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_auth_members</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_auth_members</> Columns</title>
+
+ <tgroup cols=4>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>roleid</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>ID of a role that has a member</entry>
+ </row>
+
+ <row>
+ <entry><structfield>member</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>ID of a role that is a member of <structfield>roleid</></entry>
+ </row>
+
+ <row>
+ <entry><structfield>grantor</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>ID of the role that granted this membership</entry>
+ </row>
+
+ <row>
+ <entry><structfield>admin_option</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>True if <structfield>member</> may grant membership in
+ <structfield>roleid</> to others</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
<sect1 id="catalog-pg-cast">
<title><structname>pg_cast</structname></title>
@@ -1065,8 +1260,8 @@
<row>
<entry><structfield>relowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the relation</entry>
</row>
@@ -1492,8 +1687,8 @@
<row>
<entry><structfield>conowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the conversion</entry>
</row>
@@ -1576,8 +1771,8 @@
<row>
<entry><structfield>datdba</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the database, usually the user who created it</entry>
</row>
@@ -1917,69 +2112,6 @@
</sect1>
- <sect1 id="catalog-pg-group">
- <title><structname>pg_group</structname></title>
-
- <indexterm zone="catalog-pg-group">
- <primary>pg_group</primary>
- </indexterm>
-
- <para>
- The catalog <structname>pg_group</structname> defines groups and stores what users belong to what
- groups. Groups are created with the <command>CREATE
- GROUP</command> command. Consult <xref linkend="user-manag"> for information
- about user privilege management.
- </para>
-
- <para>
- Because user and group identities are cluster-wide,
- <structname>pg_group</structname>
- is shared across all databases of a cluster: there is only one
- copy of <structname>pg_group</structname> per cluster, not
- one per database.
- </para>
-
- <table>
- <title><structname>pg_group</> Columns</title>
-
- <tgroup cols=4>
- <thead>
- <row>
- <entry>Name</entry>
- <entry>Type</entry>
- <entry>References</entry>
- <entry>Description</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry><structfield>groname</structfield></entry>
- <entry><type>name</type></entry>
- <entry></entry>
- <entry>Name of the group</entry>
- </row>
-
- <row>
- <entry><structfield>grosysid</structfield></entry>
- <entry><type>int4</type></entry>
- <entry></entry>
- <entry>An arbitrary number to identify this group</entry>
- </row>
-
- <row>
- <entry><structfield>grolist</structfield></entry>
- <entry><type>int4[]</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
- <entry>An array containing the IDs of the users in this group</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- </sect1>
-
-
<sect1 id="catalog-pg-index">
<title><structname>pg_index</structname></title>
@@ -2437,8 +2569,8 @@
<row>
<entry><structfield>nspowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the namespace</entry>
</row>
@@ -2517,9 +2649,9 @@
<row>
<entry><structfield>opcowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
- <entry>Operator class owner</entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>Owner of the operator class</entry>
</row>
<row>
@@ -2606,8 +2738,8 @@
<row>
<entry><structfield>oprowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the operator</entry>
</row>
@@ -2786,8 +2918,8 @@
<row>
<entry><structfield>proowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the function</entry>
</row>
@@ -3066,114 +3198,6 @@
</sect1>
- <sect1 id="catalog-pg-shadow">
- <title><structname>pg_shadow</structname></title>
-
- <indexterm zone="catalog-pg-shadow">
- <primary>pg_shadow</primary>
- </indexterm>
-
- <para>
- The catalog <structname>pg_shadow</structname> contains information about
- database users. The name stems from the fact that this table
- should not be readable by the public since it contains passwords.
- <link linkend="view-pg-user"><structname>pg_user</structname></link>
- is a publicly readable view on
- <structname>pg_shadow</structname> that blanks out the password field.
- </para>
-
- <para>
- <xref linkend="user-manag"> contains detailed information about user and
- privilege management.
- </para>
-
- <para>
- Because user identities are cluster-wide,
- <structname>pg_shadow</structname>
- is shared across all databases of a cluster: there is only one
- copy of <structname>pg_shadow</structname> per cluster, not
- one per database.
- </para>
-
- <table>
- <title><structname>pg_shadow</> Columns</title>
-
- <tgroup cols=4>
- <thead>
- <row>
- <entry>Name</entry>
- <entry>Type</entry>
- <entry>References</entry>
- <entry>Description</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry><structfield>usename</structfield></entry>
- <entry><type>name</type></entry>
- <entry></entry>
- <entry>User name</entry>
- </row>
-
- <row>
- <entry><structfield>usesysid</structfield></entry>
- <entry><type>int4</type></entry>
- <entry></entry>
- <entry>User ID (arbitrary number used to reference this user)</entry>
- </row>
-
- <row>
- <entry><structfield>usecreatedb</structfield></entry>
- <entry><type>bool</type></entry>
- <entry></entry>
- <entry>User may create databases</entry>
- </row>
-
- <row>
- <entry><structfield>usesuper</structfield></entry>
- <entry><type>bool</type></entry>
- <entry></entry>
- <entry>User is a superuser</entry>
- </row>
-
- <row>
- <entry><structfield>usecatupd</structfield></entry>
- <entry><type>bool</type></entry>
- <entry></entry>
- <entry>
- User may update system catalogs. (Even a superuser may not do
- this unless this column is true.)
- </entry>
- </row>
-
- <row>
- <entry><structfield>passwd</structfield></entry>
- <entry><type>text</type></entry>
- <entry></entry>
- <entry>Password (possibly encrypted)</entry>
- </row>
-
- <row>
- <entry><structfield>valuntil</structfield></entry>
- <entry><type>abstime</type></entry>
- <entry></entry>
- <entry>Password expiry time (only used for password authentication)</entry>
- </row>
-
- <row>
- <entry><structfield>useconfig</structfield></entry>
- <entry><type>text[]</type></entry>
- <entry></entry>
- <entry>Session defaults for run-time configuration variables</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- </sect1>
-
-
<sect1 id="catalog-pg-statistic">
<title><structname>pg_statistic</structname></title>
@@ -3374,8 +3398,8 @@
<row>
<entry><structfield>spcowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the tablespace, usually the user who created it</entry>
</row>
@@ -3586,8 +3610,8 @@
<row>
<entry><structfield>typowner</structfield></entry>
- <entry><type>int4</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the type</entry>
</row>
@@ -3923,6 +3947,11 @@
<tbody>
<row>
+ <entry><link linkend="view-pg-group"><structname>pg_group</structname></link></entry>
+ <entry>groups of database users</entry>
+ </row>
+
+ <row>
<entry><link linkend="view-pg-indexes"><structname>pg_indexes</structname></link></entry>
<entry>indexes</entry>
</row>
@@ -3938,6 +3967,11 @@
</row>
<row>
+ <entry><link linkend="view-pg-roles"><structname>pg_roles</structname></link></entry>
+ <entry>database roles</entry>
+ </row>
+
+ <row>
<entry><link linkend="view-pg-rules"><structname>pg_rules</structname></link></entry>
<entry>rules</entry>
</row>
@@ -3948,6 +3982,11 @@
</row>
<row>
+ <entry><link linkend="view-pg-shadow"><structname>pg_shadow</structname></link></entry>
+ <entry>database users</entry>
+ </row>
+
+ <row>
<entry><link linkend="view-pg-stats"><structname>pg_stats</structname></link></entry>
<entry>planner statistics</entry>
</row>
@@ -3972,6 +4011,62 @@
</table>
</sect1>
+ <sect1 id="view-pg-group">
+ <title><structname>pg_group</structname></title>
+
+ <indexterm zone="view-pg-group">
+ <primary>pg_group</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_group</structname> exists for backwards
+ compatibility: it emulates a catalog that existed in
+ <productname>PostgreSQL</productname> before version 8.1.
+ It shows the names and members of all roles that are marked as not
+ <structfield>rolcanlogin</>, which is an approximation to the set
+ of roles that are being used as groups.
+ </para>
+
+ <table>
+ <title><structname>pg_group</> Columns</title>
+
+ <tgroup cols=4>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>groname</structfield></entry>
+ <entry><type>name</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry>
+ <entry>Name of the group</entry>
+ </row>
+
+ <row>
+ <entry><structfield>grosysid</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>ID of this group</entry>
+ </row>
+
+ <row>
+ <entry><structfield>grolist</structfield></entry>
+ <entry><type>oid[]</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>An array containing the IDs of the roles in this group</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
<sect1 id="view-pg-indexes">
<title><structname>pg_indexes</structname></title>
@@ -4332,7 +4427,7 @@
<row>
<entry><structfield>owner</structfield></entry>
<entry><type>name</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usename</literal></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry>
<entry>
Name of the user that executed the transaction
</entry>
@@ -4361,6 +4456,110 @@
</sect1>
+ <sect1 id="view-pg-roles">
+ <title><structname>pg_roles</structname></title>
+
+ <indexterm zone="view-pg-roles">
+ <primary>pg_roles</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_roles</structname> provides access to
+ information about database roles. This is simply a publicly
+ readable view of
+ <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>
+ that blanks out the password field.
+ </para>
+
+ <table>
+ <title><structname>pg_roles</> Columns</title>
+
+ <tgroup cols=4>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>rolname</structfield></entry>
+ <entry><type>name</type></entry>
+ <entry></entry>
+ <entry>Role name</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolsuper</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Role has superuser privileges</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcreaterole</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Role may create more roles</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcreatedb</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>Role may create databases</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcatupdate</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>
+ Role may update system catalogs directly. (Even a superuser may not do
+ this unless this column is true.)
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolcanlogin</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>
+ Role may log in, that is, this role can be given as the initial
+ session authorization identifier.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolpassword</structfield></entry>
+ <entry><type>text</type></entry>
+ <entry></entry>
+ <entry>Not the password (always reads as <literal>********</>)</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolvaliduntil</structfield></entry>
+ <entry><type>timestamptz</type></entry>
+ <entry></entry>
+ <entry>Password expiry time (only used for password authentication);
+ NULL if no expiration</entry>
+ </row>
+
+ <row>
+ <entry><structfield>rolconfig</structfield></entry>
+ <entry><type>text[]</type></entry>
+ <entry></entry>
+ <entry>Session defaults for run-time configuration variables</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
<sect1 id="view-pg-rules">
<title><structname>pg_rules</structname></title>
@@ -4534,6 +4733,107 @@
</sect1>
+ <sect1 id="view-pg-shadow">
+ <title><structname>pg_shadow</structname></title>
+
+ <indexterm zone="view-pg-shadow">
+ <primary>pg_shadow</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_shadow</structname> exists for backwards
+ compatibility: it emulates a catalog that existed in
+ <productname>PostgreSQL</productname> before version 8.1.
+ It shows properties of all roles that are marked as
+ <structfield>rolcanlogin</>.
+ </para>
+
+ <para>
+ The name stems from the fact that this table
+ should not be readable by the public since it contains passwords.
+ <link linkend="view-pg-user"><structname>pg_user</structname></link>
+ is a publicly readable view on
+ <structname>pg_shadow</structname> that blanks out the password field.
+ </para>
+
+ <table>
+ <title><structname>pg_shadow</> Columns</title>
+
+ <tgroup cols=4>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>usename</structfield></entry>
+ <entry><type>name</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry>
+ <entry>User name</entry>
+ </row>
+
+ <row>
+ <entry><structfield>usesysid</structfield></entry>
+ <entry><type>oid</type></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
+ <entry>ID of this user</entry>
+ </row>
+
+ <row>
+ <entry><structfield>usecreatedb</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>User may create databases</entry>
+ </row>
+
+ <row>
+ <entry><structfield>usesuper</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>User is a superuser</entry>
+ </row>
+
+ <row>
+ <entry><structfield>usecatupd</structfield></entry>
+ <entry><type>bool</type></entry>
+ <entry></entry>
+ <entry>
+ User may update system catalogs. (Even a superuser may not do
+ this unless this column is true.)
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>passwd</structfield></entry>
+ <entry><type>text</type></entry>
+ <entry></entry>
+ <entry>Password (possibly encrypted)</entry>
+ </row>
+
+ <row>
+ <entry><structfield>valuntil</structfield></entry>
+ <entry><type>abstime</type></entry>
+ <entry></entry>
+ <entry>Password expiry time (only used for password authentication)</entry>
+ </row>
+
+ <row>
+ <entry><structfield>useconfig</structfield></entry>
+ <entry><type>text[]</type></entry>
+ <entry></entry>
+ <entry>Session defaults for run-time configuration variables</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
<sect1 id="view-pg-stats">
<title><structname>pg_stats</structname></title>
@@ -4720,7 +5020,7 @@
<row>
<entry><structfield>tableowner</structfield></entry>
<entry><type>name</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usename</literal></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry>
<entry>name of table's owner</entry>
</row>
<row>
@@ -4764,7 +5064,7 @@
The view <structname>pg_user</structname> provides access to
information about database users. This is simply a publicly
readable view of
- <link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>
+ <link linkend="view-pg-shadow"><structname>pg_shadow</structname></link>
that blanks out the password field.
</para>
@@ -4885,7 +5185,7 @@
<row>
<entry><structfield>viewowner</structfield></entry>
<entry><type>name</type></entry>
- <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usename</literal></entry>
+ <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry>
<entry>name of view's owner</entry>
</row>
<row>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index d7430f1ccf8..734686bf4a4 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1,5 +1,5 @@
<!--
-$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.260 2005/06/26 22:05:35 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.261 2005/06/28 05:08:50 tgl Exp $
PostgreSQL documentation
-->
@@ -8443,8 +8443,8 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
<para>
<function>has_table_privilege</function> checks whether a user
can access a table in a particular way. The user can be
- specified by name or by ID
- (<literal>pg_user.usesysid</literal>), or if the argument is
+ specified by name or by OID
+ (<literal>pg_authid.oid</literal>), or if the argument is
omitted
<function>current_user</function> is assumed. The table can be specified
by name or by OID. (Thus, there are actually six variants of
@@ -8756,9 +8756,9 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
in it refer to the relation indicated by the second parameter</entry>
</row>
<row>
- <entry><literal><function>pg_get_userbyid</function>(<parameter>userid</parameter>)</literal></entry>
+ <entry><literal><function>pg_get_userbyid</function>(<parameter>roleid</parameter>)</literal></entry>
<entry><type>name</type></entry>
- <entry>get user name with given ID</entry>
+ <entry>get role name with given ID</entry>
</row>
<row>
<entry><literal><function>pg_get_serial_sequence</function>(<parameter>table_name</parameter>, <parameter>column_name</parameter>)</literal></entry>
@@ -8805,7 +8805,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<para>
<function>pg_get_userbyid</function>
- extracts a user's name given a user ID number.
+ extracts a role's name given its OID.
<function>pg_get_serial_sequence</function>
fetches the name of the sequence associated with a serial or
bigserial column. The name is suitably formatted
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 7c8102d87c9..ccd8b802157 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.6 2005/06/19 22:34:56 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.7 2005/06/28 05:08:51 tgl Exp $
*
* NOTES
* Each global transaction is associated with a global transaction
@@ -107,7 +107,7 @@ typedef struct GlobalTransactionData
PGPROC proc; /* dummy proc */
TimestampTz prepared_at; /* time of preparation */
XLogRecPtr prepare_lsn; /* XLOG offset of prepare record */
- AclId owner; /* ID of user that executed the xact */
+ Oid owner; /* ID of user that executed the xact */
TransactionId locking_xid; /* top-level XID of backend working on xact */
bool valid; /* TRUE if fully prepared */
char gid[GIDSIZE]; /* The GID assigned to the prepared xact */
@@ -206,7 +206,7 @@ TwoPhaseShmemInit(void)
*/
GlobalTransaction
MarkAsPreparing(TransactionId xid, const char *gid,
- TimestampTz prepared_at, AclId owner, Oid databaseid)
+ TimestampTz prepared_at, Oid owner, Oid databaseid)
{
GlobalTransaction gxact;
int i;
@@ -350,7 +350,7 @@ MarkAsPrepared(GlobalTransaction gxact)
* Locate the prepared transaction and mark it busy for COMMIT or PREPARE.
*/
static GlobalTransaction
-LockGXact(const char *gid, AclId user)
+LockGXact(const char *gid, Oid user)
{
int i;
@@ -559,7 +559,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
TIMESTAMPTZOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
- INT4OID, -1, 0);
+ OIDOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
OIDOID, -1, 0);
@@ -601,7 +601,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
values[0] = TransactionIdGetDatum(gxact->proc.xid);
values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid));
values[2] = TimestampTzGetDatum(gxact->prepared_at);
- values[3] = Int32GetDatum(gxact->owner);
+ values[3] = ObjectIdGetDatum(gxact->owner);
values[4] = ObjectIdGetDatum(gxact->proc.databaseId);
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
@@ -690,7 +690,7 @@ typedef struct TwoPhaseFileHeader
TransactionId xid; /* original transaction XID */
Oid database; /* OID of database it was in */
TimestampTz prepared_at; /* time of preparation */
- AclId owner; /* user running the transaction */
+ Oid owner; /* user running the transaction */
int32 nsubxacts; /* number of following subxact XIDs */
int32 ncommitrels; /* number of delete-on-commit rels */
int32 nabortrels; /* number of delete-on-abort rels */
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 98e56c40020..a5d53d3e145 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.207 2005/06/19 20:00:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.208 2005/06/28 05:08:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -121,7 +121,7 @@ typedef struct TransactionStateData
* context */
ResourceOwner curTransactionOwner; /* my query resources */
List *childXids; /* subcommitted child XIDs */
- AclId currentUser; /* subxact start current_user */
+ Oid currentUser; /* subxact start current_user */
bool prevXactReadOnly; /* entry-time xact r/o state */
struct TransactionStateData *parent; /* back link to parent */
} TransactionStateData;
@@ -1488,8 +1488,10 @@ CommitTransaction(void)
/* NOTIFY commit must come before lower-level cleanup */
AtCommit_Notify();
- /* Update flat files if we changed pg_database, pg_shadow or pg_group */
- /* This should be the last step before commit */
+ /*
+ * Update flat files if we changed pg_database, pg_authid or
+ * pg_auth_members. This should be the last step before commit.
+ */
AtEOXact_UpdateFlatFiles(true);
/* Prevent cancel/die interrupt while cleaning up */
@@ -3847,7 +3849,7 @@ PushTransaction(void)
{
TransactionState p = CurrentTransactionState;
TransactionState s;
- AclId currentUser;
+ Oid currentUser;
/*
* At present, GetUserId cannot fail, but let's not assume that. Get
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index a77b41b441f..09addc4af1c 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -2,7 +2,7 @@
#
# Makefile for backend/catalog
#
-# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.53 2004/07/21 20:34:45 momjian Exp $
+# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.54 2005/06/28 05:08:52 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -31,8 +31,9 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
- pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \
- pg_tablespace.h pg_depend.h indexing.h \
+ pg_namespace.h pg_conversion.h pg_database.h \
+ pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \
+ indexing.h \
)
pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 5eba84f995f..6ff89eb0425 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.112 2005/05/29 23:38:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.113 2005/06/28 05:08:52 tgl Exp $
*
* NOTES
* See acl.h.
@@ -21,15 +21,15 @@
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
+#include "catalog/pg_auth_members.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
-#include "catalog/pg_group.h"
#include "catalog/pg_language.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
@@ -76,10 +76,10 @@ dumpacl(Acl *acl)
* all granted privileges appear to flow from the object owner, and there
* are never multiple "original sources" of a privilege.
*/
-static AclId
-select_grantor(AclId ownerId)
+static Oid
+select_grantor(Oid ownerId)
{
- AclId grantorId;
+ Oid grantorId;
grantorId = GetUserId();
@@ -105,7 +105,7 @@ static Acl *
merge_acl_with_grant(Acl *old_acl, bool is_grant,
bool grant_option, DropBehavior behavior,
List *grantees, AclMode privileges,
- AclId grantor_uid, AclId owner_uid)
+ Oid grantorId, Oid ownerId)
{
unsigned modechg;
ListCell *j;
@@ -122,41 +122,25 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
{
PrivGrantee *grantee = (PrivGrantee *) lfirst(j);
AclItem aclitem;
- uint32 idtype;
Acl *newer_acl;
- if (grantee->username)
- {
- aclitem. ai_grantee = get_usesysid(grantee->username);
-
- idtype = ACL_IDTYPE_UID;
- }
- else if (grantee->groupname)
- {
- aclitem. ai_grantee = get_grosysid(grantee->groupname);
-
- idtype = ACL_IDTYPE_GID;
- }
+ if (grantee->rolname)
+ aclitem.ai_grantee = get_roleid_checked(grantee->rolname);
else
- {
- aclitem. ai_grantee = ACL_ID_WORLD;
-
- idtype = ACL_IDTYPE_WORLD;
- }
+ aclitem.ai_grantee = ACL_ID_PUBLIC;
/*
- * Grant options can only be granted to individual users, not
- * groups or public. The reason is that if a user would re-grant
- * a privilege that he held through a group having a grant option,
- * and later the user is removed from the group, the situation is
- * impossible to clean up.
+ * Grant options can only be granted to individual roles, not PUBLIC.
+ * The reason is that if a user would re-grant a privilege that he
+ * held through PUBLIC, and later the user is removed, the situation
+ * is impossible to clean up.
*/
- if (is_grant && grant_option && idtype != ACL_IDTYPE_UID)
+ if (is_grant && grant_option && aclitem.ai_grantee == ACL_ID_PUBLIC)
ereport(ERROR,
(errcode(ERRCODE_INVALID_GRANT_OPERATION),
- errmsg("grant options can only be granted to individual users")));
+ errmsg("grant options can only be granted to roles")));
- aclitem. ai_grantor = grantor_uid;
+ aclitem.ai_grantor = grantorId;
/*
* The asymmetry in the conditions here comes from the spec. In
@@ -166,12 +150,11 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
* and its grant option, while REVOKE GRANT OPTION revokes only
* the option.
*/
- ACLITEM_SET_PRIVS_IDTYPE(aclitem,
+ ACLITEM_SET_PRIVS_GOPTIONS(aclitem,
(is_grant || !grant_option) ? privileges : ACL_NO_RIGHTS,
- (!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS,
- idtype);
+ (!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS);
- newer_acl = aclupdate(new_acl, &aclitem, modechg, owner_uid, behavior);
+ newer_acl = aclupdate(new_acl, &aclitem, modechg, ownerId, behavior);
/* avoid memory leak when there are many grantees */
pfree(new_acl);
@@ -261,8 +244,8 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
AclMode this_privileges;
Acl *old_acl;
Acl *new_acl;
- AclId grantorId;
- AclId ownerId;
+ Oid grantorId;
+ Oid ownerId;
HeapTuple newtuple;
Datum values[Natts_pg_class];
char nulls[Natts_pg_class];
@@ -430,8 +413,8 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
AclMode this_privileges;
Acl *old_acl;
Acl *new_acl;
- AclId grantorId;
- AclId ownerId;
+ Oid grantorId;
+ Oid ownerId;
HeapTuple newtuple;
Datum values[Natts_pg_database];
char nulls[Natts_pg_database];
@@ -587,8 +570,8 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
AclMode this_privileges;
Acl *old_acl;
Acl *new_acl;
- AclId grantorId;
- AclId ownerId;
+ Oid grantorId;
+ Oid ownerId;
HeapTuple newtuple;
Datum values[Natts_pg_proc];
char nulls[Natts_pg_proc];
@@ -740,8 +723,8 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
AclMode this_privileges;
Acl *old_acl;
Acl *new_acl;
- AclId grantorId;
- AclId ownerId;
+ Oid grantorId;
+ Oid ownerId;
HeapTuple newtuple;
Datum values[Natts_pg_language];
char nulls[Natts_pg_language];
@@ -767,7 +750,7 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
* Note: for now, languages are treated as owned by the bootstrap
* user. We should add an owner column to pg_language instead.
*/
- ownerId = BOOTSTRAP_USESYSID;
+ ownerId = BOOTSTRAP_SUPERUSERID;
grantorId = select_grantor(ownerId);
/*
@@ -903,8 +886,8 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
AclMode this_privileges;
Acl *old_acl;
Acl *new_acl;
- AclId grantorId;
- AclId ownerId;
+ Oid grantorId;
+ Oid ownerId;
HeapTuple newtuple;
Datum values[Natts_pg_namespace];
char nulls[Natts_pg_namespace];
@@ -1059,8 +1042,8 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
AclMode this_privileges;
Acl *old_acl;
Acl *new_acl;
- AclId grantorId;
- AclId ownerId;
+ Oid grantorId;
+ Oid ownerId;
HeapTuple newtuple;
Datum values[Natts_pg_tablespace];
char nulls[Natts_pg_tablespace];
@@ -1208,27 +1191,6 @@ privilege_to_string(AclMode privilege)
}
/*
- * 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.
*
* Note: we do not double-quote the %s's below, because many callers
@@ -1310,26 +1272,26 @@ aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
}
-/* Check if given userid has usecatupd privilege according to pg_shadow */
+/* Check if given user has rolcatupdate privilege according to pg_authid */
static bool
-has_usecatupd(AclId userid)
+has_rolcatupdate(Oid roleid)
{
- bool usecatupd;
+ bool rolcatupdate;
HeapTuple tuple;
- tuple = SearchSysCache(SHADOWSYSID,
- ObjectIdGetDatum(userid),
+ tuple = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(roleid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user with ID %u does not exist", userid)));
+ errmsg("role with OID %u does not exist", roleid)));
- usecatupd = ((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd;
+ rolcatupdate = ((Form_pg_authid) GETSTRUCT(tuple))->rolcatupdate;
ReleaseSysCache(tuple);
- return usecatupd;
+ return rolcatupdate;
}
@@ -1344,7 +1306,7 @@ has_usecatupd(AclId userid)
* below.
*/
AclMode
-pg_class_aclmask(Oid table_oid, AclId userid,
+pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -1353,7 +1315,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/*
* Must get the relation's tuple from pg_class
@@ -1370,7 +1332,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
/*
* Deny anyone permission to update a system catalog unless
- * pg_shadow.usecatupd is set. (This is to let superusers protect
+ * pg_authid.rolcatupdate is set. (This is to let superusers protect
* themselves from themselves.) Also allow it if
* allowSystemTableMods.
*
@@ -1381,7 +1343,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
IsSystemClass(classForm) &&
classForm->relkind != RELKIND_VIEW &&
- !has_usecatupd(userid) &&
+ !has_rolcatupdate(roleid) &&
!allowSystemTableMods)
{
#ifdef ACLDEBUG
@@ -1393,10 +1355,10 @@ pg_class_aclmask(Oid table_oid, AclId userid,
/*
* Otherwise, superusers bypass all permission-checking.
*/
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
{
#ifdef ACLDEBUG
- elog(DEBUG2, "%u is superuser, home free", userid);
+ elog(DEBUG2, "OID %u is superuser, home free", roleid);
#endif
ReleaseSysCache(tuple);
return mask;
@@ -1421,7 +1383,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, userid, ownerId, mask, how);
+ result = aclmask(acl, roleid, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@@ -1436,7 +1398,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
* Exported routine for examining a user's privileges for a database
*/
AclMode
-pg_database_aclmask(Oid db_oid, AclId userid,
+pg_database_aclmask(Oid db_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -1447,10 +1409,10 @@ pg_database_aclmask(Oid db_oid, AclId userid,
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return mask;
/*
@@ -1487,7 +1449,7 @@ pg_database_aclmask(Oid db_oid, AclId userid,
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, userid, ownerId, mask, how);
+ result = aclmask(acl, roleid, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@@ -1503,7 +1465,7 @@ pg_database_aclmask(Oid db_oid, AclId userid,
* Exported routine for examining a user's privileges for a function
*/
AclMode
-pg_proc_aclmask(Oid proc_oid, AclId userid,
+pg_proc_aclmask(Oid proc_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -1511,10 +1473,10 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return mask;
/*
@@ -1544,7 +1506,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, userid, ownerId, mask, how);
+ result = aclmask(acl, roleid, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@@ -1559,7 +1521,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
* Exported routine for examining a user's privileges for a language
*/
AclMode
-pg_language_aclmask(Oid lang_oid, AclId userid,
+pg_language_aclmask(Oid lang_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -1567,10 +1529,10 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return mask;
/*
@@ -1585,7 +1547,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
errmsg("language with OID %u does not exist", lang_oid)));
/* XXX pg_language should have an owner column, but doesn't */
- ownerId = BOOTSTRAP_USESYSID;
+ ownerId = BOOTSTRAP_SUPERUSERID;
aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
&isNull);
@@ -1601,7 +1563,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, userid, ownerId, mask, how);
+ result = aclmask(acl, roleid, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@@ -1616,7 +1578,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
* Exported routine for examining a user's privileges for a namespace
*/
AclMode
-pg_namespace_aclmask(Oid nsp_oid, AclId userid,
+pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -1624,10 +1586,10 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return mask;
/*
@@ -1685,7 +1647,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, userid, ownerId, mask, how);
+ result = aclmask(acl, roleid, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@@ -1700,7 +1662,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
* Exported routine for examining a user's privileges for a tablespace
*/
AclMode
-pg_tablespace_aclmask(Oid spc_oid, AclId userid,
+pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
AclMode mask, AclMaskHow how)
{
AclMode result;
@@ -1711,7 +1673,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
Datum aclDatum;
bool isNull;
Acl *acl;
- AclId ownerId;
+ Oid ownerId;
/*
* Only shared relations can be stored in global space; don't let even
@@ -1721,7 +1683,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
return 0;
/* Otherwise, superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return mask;
/*
@@ -1758,7 +1720,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
acl = DatumGetAclP(aclDatum);
}
- result = aclmask(acl, userid, ownerId, mask, how);
+ result = aclmask(acl, roleid, ownerId, mask, how);
/* if we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@@ -1779,9 +1741,9 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
* ACLCHECK_NO_PRIV).
*/
AclResult
-pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode)
+pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
{
- if (pg_class_aclmask(table_oid, userid, mode, ACLMASK_ANY) != 0)
+ if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -1791,9 +1753,9 @@ pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode)
* Exported routine for checking a user's access privileges to a database
*/
AclResult
-pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode)
+pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
{
- if (pg_database_aclmask(db_oid, userid, mode, ACLMASK_ANY) != 0)
+ if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -1803,9 +1765,9 @@ pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode)
* Exported routine for checking a user's access privileges to a function
*/
AclResult
-pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode)
+pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode)
{
- if (pg_proc_aclmask(proc_oid, userid, mode, ACLMASK_ANY) != 0)
+ if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -1815,9 +1777,9 @@ pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode)
* Exported routine for checking a user's access privileges to a language
*/
AclResult
-pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode)
+pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
{
- if (pg_language_aclmask(lang_oid, userid, mode, ACLMASK_ANY) != 0)
+ if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -1827,9 +1789,9 @@ pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode)
* Exported routine for checking a user's access privileges to a namespace
*/
AclResult
-pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode)
+pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
{
- if (pg_namespace_aclmask(nsp_oid, userid, mode, ACLMASK_ANY) != 0)
+ if (pg_namespace_aclmask(nsp_oid, roleid, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -1839,9 +1801,9 @@ pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode)
* Exported routine for checking a user's access privileges to a tablespace
*/
AclResult
-pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode)
+pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
{
- if (pg_tablespace_aclmask(spc_oid, userid, mode, ACLMASK_ANY) != 0)
+ if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0)
return ACLCHECK_OK;
else
return ACLCHECK_NO_PRIV;
@@ -1852,13 +1814,13 @@ pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode)
* Ownership check for a relation (specified by OID).
*/
bool
-pg_class_ownercheck(Oid class_oid, AclId userid)
+pg_class_ownercheck(Oid class_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(RELOID,
@@ -1869,24 +1831,24 @@ pg_class_ownercheck(Oid class_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation with OID %u does not exist", class_oid)));
- owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
+ ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
/*
* Ownership check for a type (specified by OID).
*/
bool
-pg_type_ownercheck(Oid type_oid, AclId userid)
+pg_type_ownercheck(Oid type_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(TYPEOID,
@@ -1897,24 +1859,24 @@ pg_type_ownercheck(Oid type_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type with OID %u does not exist", type_oid)));
- owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
+ ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
/*
* Ownership check for an operator (specified by OID).
*/
bool
-pg_oper_ownercheck(Oid oper_oid, AclId userid)
+pg_oper_ownercheck(Oid oper_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(OPEROID,
@@ -1925,24 +1887,24 @@ pg_oper_ownercheck(Oid oper_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator with OID %u does not exist", oper_oid)));
- owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
+ ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
/*
* Ownership check for a function (specified by OID).
*/
bool
-pg_proc_ownercheck(Oid proc_oid, AclId userid)
+pg_proc_ownercheck(Oid proc_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(PROCOID,
@@ -1953,24 +1915,24 @@ pg_proc_ownercheck(Oid proc_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function with OID %u does not exist", proc_oid)));
- owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
+ ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
/*
* Ownership check for a namespace (specified by OID).
*/
bool
-pg_namespace_ownercheck(Oid nsp_oid, AclId userid)
+pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(NAMESPACEOID,
@@ -1981,27 +1943,27 @@ pg_namespace_ownercheck(Oid nsp_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema with OID %u does not exist", nsp_oid)));
- owner_id = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
+ ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
/*
* Ownership check for a tablespace (specified by OID).
*/
bool
-pg_tablespace_ownercheck(Oid spc_oid, AclId userid)
+pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
{
Relation pg_tablespace;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple spctuple;
- int32 spcowner;
+ Oid spcowner;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
/* There's no syscache for pg_tablespace, so must look the hard way */
@@ -2024,20 +1986,20 @@ pg_tablespace_ownercheck(Oid spc_oid, AclId userid)
heap_endscan(scan);
heap_close(pg_tablespace, AccessShareLock);
- return userid == spcowner;
+ return is_member_of_role(roleid, spcowner);
}
/*
* Ownership check for an operator class (specified by OID).
*/
bool
-pg_opclass_ownercheck(Oid opc_oid, AclId userid)
+pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(CLAOID,
@@ -2049,27 +2011,27 @@ pg_opclass_ownercheck(Oid opc_oid, AclId userid)
errmsg("operator class with OID %u does not exist",
opc_oid)));
- owner_id = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
+ ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
/*
* Ownership check for a database (specified by OID).
*/
bool
-pg_database_ownercheck(Oid db_oid, AclId userid)
+pg_database_ownercheck(Oid db_oid, Oid roleid)
{
Relation pg_database;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple dbtuple;
- int32 dba;
+ Oid dba;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
/* There's no syscache for pg_database, so must look the hard way */
@@ -2092,20 +2054,20 @@ pg_database_ownercheck(Oid db_oid, AclId userid)
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
- return userid == dba;
+ return is_member_of_role(roleid, dba);
}
/*
* Ownership check for a conversion (specified by OID).
*/
bool
-pg_conversion_ownercheck(Oid conv_oid, AclId userid)
+pg_conversion_ownercheck(Oid conv_oid, Oid roleid)
{
HeapTuple tuple;
- AclId owner_id;
+ Oid ownerId;
/* Superusers bypass all permission checking. */
- if (superuser_arg(userid))
+ if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(CONOID,
@@ -2116,9 +2078,9 @@ pg_conversion_ownercheck(Oid conv_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("conversion with OID %u does not exist", conv_oid)));
- owner_id = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
+ ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner;
ReleaseSysCache(tuple);
- return userid == owner_id;
+ return is_member_of_role(roleid, ownerId);
}
diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh
index 92a3ac5eecc..9d9b75bde58 100644
--- a/src/backend/catalog/genbki.sh
+++ b/src/backend/catalog/genbki.sh
@@ -11,7 +11,7 @@
#
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.36 2005/04/14 20:03:23 tgl Exp $
+# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.37 2005/06/28 05:08:52 tgl Exp $
#
# NOTES
# non-essential whitespace is removed from the generated file.
@@ -114,6 +114,14 @@ for dir in $INCLUDE_DIRS; do
fi
done
+# Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h
+for dir in $INCLUDE_DIRS; do
+ if [ -f "$dir/catalog/pg_authid.h" ]; then
+ BOOTSTRAP_SUPERUSERID=`grep '^#define[ ]*BOOTSTRAP_SUPERUSERID' $dir/catalog/pg_authid.h | $AWK '{ print $3 }'`
+ break
+ fi
+done
+
# Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
for dir in $INCLUDE_DIRS; do
if [ -f "$dir/catalog/pg_namespace.h" ]; then
@@ -153,7 +161,7 @@ sed -e "s/;[ ]*$//g" \
-e "s/[ ]TransactionId/ xid/g" \
-e "s/^TransactionId/xid/g" \
-e "s/(TransactionId/(xid/g" \
- -e "s/PGUID/1/g" \
+ -e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \
-e "s/NAMEDATALEN/$NAMEDATALEN/g" \
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
| $AWK '
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index 83e6fa82b0f..6d90887ba6c 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -4,7 +4,7 @@
*
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.28 2005/05/31 03:36:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.29 2005/06/28 05:08:52 tgl Exp $
*/
/*
@@ -210,13 +210,13 @@ CREATE DOMAIN time_stamp AS timestamp(2)
CREATE VIEW applicable_roles AS
SELECT CAST(current_user AS sql_identifier) AS grantee,
- CAST(g.groname AS sql_identifier) AS role_name,
- CAST('NO' AS character_data) AS is_grantable
+ CAST(a.rolname AS sql_identifier) AS role_name,
+ CAST(CASE WHEN m.admin_option = 'true' THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
- FROM pg_group g, pg_user u
+ FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid))
+ join pg_authid b ON (m.member = b.oid))
- WHERE u.usesysid = ANY (g.grolist)
- AND u.usename = current_user;
+ WHERE b.rolname = current_user;
GRANT SELECT ON applicable_roles TO PUBLIC;
@@ -282,7 +282,7 @@ GRANT SELECT ON column_domain_usage TO PUBLIC;
*/
CREATE VIEW column_privileges AS
- SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor,
+ SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
CAST(grantee.name AS sql_identifier) AS grantee,
CAST(current_database() AS sql_identifier) AS table_catalog,
CAST(nc.nspname AS sql_identifier) AS table_schema,
@@ -291,20 +291,18 @@ CREATE VIEW column_privileges AS
CAST(pr.type AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, true))
+ makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_attribute a,
pg_class c,
pg_namespace nc,
- pg_user u_grantor,
+ pg_authid u_grantor,
(
- SELECT usesysid, 0, usename FROM pg_user
- UNION ALL
- SELECT 0, grosysid, groname FROM pg_group
+ SELECT oid, rolname FROM pg_authid
UNION ALL
- SELECT 0, 0, 'PUBLIC'
- ) AS grantee (usesysid, grosysid, name),
+ SELECT 0, 'PUBLIC'
+ ) AS grantee (oid, name),
(SELECT 'SELECT' UNION ALL
SELECT 'INSERT' UNION ALL
SELECT 'UPDATE' UNION ALL
@@ -316,8 +314,8 @@ CREATE VIEW column_privileges AS
AND NOT a.attisdropped
AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false))
- AND (u_grantor.usename = current_user
+ makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
+ AND (u_grantor.rolname = current_user
OR grantee.name = current_user
OR grantee.name = 'PUBLIC');
@@ -693,10 +691,10 @@ GRANT SELECT ON domains TO PUBLIC;
*/
CREATE VIEW enabled_roles AS
- SELECT CAST(g.groname AS sql_identifier) AS role_name
- FROM pg_group g, pg_user u
- WHERE u.usesysid = ANY (g.grolist)
- AND u.usename = current_user;
+ SELECT CAST(a.rolname AS sql_identifier) AS role_name
+ FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid))
+ join pg_authid b ON (m.member = b.oid))
+ WHERE b.rolname = current_user;
GRANT SELECT ON enabled_roles TO PUBLIC;
@@ -865,7 +863,7 @@ CREATE VIEW role_column_grants AS
CAST(pr.type AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(c.relacl,
- makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
+ makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_attribute a,
@@ -884,7 +882,7 @@ CREATE VIEW role_column_grants AS
AND NOT a.attisdropped
AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl,
- makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
+ makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
GRANT SELECT ON role_column_grants TO PUBLIC;
@@ -907,7 +905,7 @@ CREATE VIEW role_routine_grants AS
CAST('EXECUTE' AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(p.proacl,
- makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true))
+ makeaclitem(g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true))
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_proc p,
@@ -917,7 +915,7 @@ CREATE VIEW role_routine_grants AS
WHERE p.pronamespace = n.oid
AND aclcontains(p.proacl,
- makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false))
+ makeaclitem(g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false))
AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
GRANT SELECT ON role_routine_grants TO PUBLIC;
@@ -937,7 +935,7 @@ CREATE VIEW role_table_grants AS
CAST(pr.type AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(c.relacl,
- makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
+ makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, true))
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
CAST('NO' AS character_data) AS with_hierarchy
@@ -956,7 +954,7 @@ CREATE VIEW role_table_grants AS
WHERE c.relnamespace = nc.oid
AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl,
- makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
+ makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, false))
AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
GRANT SELECT ON role_table_grants TO PUBLIC;
@@ -990,7 +988,7 @@ GRANT SELECT ON role_usage_grants TO PUBLIC;
*/
CREATE VIEW routine_privileges AS
- SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor,
+ SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
CAST(grantee.name AS sql_identifier) AS grantee,
CAST(current_database() AS sql_identifier) AS specific_catalog,
CAST(n.nspname AS sql_identifier) AS specific_schema,
@@ -1001,24 +999,22 @@ CREATE VIEW routine_privileges AS
CAST('EXECUTE' AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(p.proacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true))
+ makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', true))
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_proc p,
pg_namespace n,
- pg_user u_grantor,
+ pg_authid u_grantor,
(
- SELECT usesysid, 0, usename FROM pg_user
- UNION ALL
- SELECT 0, grosysid, groname FROM pg_group
+ SELECT oid, rolname FROM pg_authid
UNION ALL
- SELECT 0, 0, 'PUBLIC'
- ) AS grantee (usesysid, grosysid, name)
+ SELECT 0, 'PUBLIC'
+ ) AS grantee (oid, name)
WHERE p.pronamespace = n.oid
AND aclcontains(p.proacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false))
- AND (u_grantor.usename = current_user
+ makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', false))
+ AND (u_grantor.rolname = current_user
OR grantee.name = current_user
OR grantee.name = 'PUBLIC');
@@ -1338,7 +1334,7 @@ GRANT SELECT ON table_constraints TO PUBLIC;
*/
CREATE VIEW table_privileges AS
- SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor,
+ SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor,
CAST(grantee.name AS sql_identifier) AS grantee,
CAST(current_database() AS sql_identifier) AS table_catalog,
CAST(nc.nspname AS sql_identifier) AS table_schema,
@@ -1346,20 +1342,18 @@ CREATE VIEW table_privileges AS
CAST(pr.type AS character_data) AS privilege_type,
CAST(
CASE WHEN aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, true))
+ makeaclitem(grantee.oid, u_grantor.oid, pr.type, true))
THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
CAST('NO' AS character_data) AS with_hierarchy
FROM pg_class c,
pg_namespace nc,
- pg_user u_grantor,
+ pg_authid u_grantor,
(
- SELECT usesysid, 0, usename FROM pg_user
- UNION ALL
- SELECT 0, grosysid, groname FROM pg_group
+ SELECT oid, rolname FROM pg_authid
UNION ALL
- SELECT 0, 0, 'PUBLIC'
- ) AS grantee (usesysid, grosysid, name),
+ SELECT 0, 'PUBLIC'
+ ) AS grantee (oid, name),
(SELECT 'SELECT' UNION ALL
SELECT 'DELETE' UNION ALL
SELECT 'INSERT' UNION ALL
@@ -1371,8 +1365,8 @@ CREATE VIEW table_privileges AS
WHERE c.relnamespace = nc.oid
AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl,
- makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false))
- AND (u_grantor.usename = current_user
+ makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
+ AND (u_grantor.rolname = current_user
OR grantee.name = current_user
OR grantee.name = 'PUBLIC');
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 3cfcc6f9b46..6b12bda6615 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.75 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.76 2005/06/28 05:08:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,12 +22,12 @@
#include "access/xact.h"
#include "catalog/dependency.h"
#include "catalog/namespace.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
#include "commands/dbcommands.h"
#include "lib/stringinfo.h"
@@ -1499,7 +1499,7 @@ FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
static void
recomputeNamespacePath(void)
{
- AclId userId = GetUserId();
+ Oid roleid = GetUserId();
char *rawname;
List *namelist;
List *oidlist;
@@ -1511,7 +1511,7 @@ recomputeNamespacePath(void)
/*
* Do nothing if path is already valid.
*/
- if (namespaceSearchPathValid && namespaceUser == userId)
+ if (namespaceSearchPathValid && namespaceUser == roleid)
return;
/* Need a modifiable copy of namespace_search_path string */
@@ -1542,21 +1542,21 @@ recomputeNamespacePath(void)
/* $user --- substitute namespace matching user name, if any */
HeapTuple tuple;
- tuple = SearchSysCache(SHADOWSYSID,
- ObjectIdGetDatum(userId),
+ tuple = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(roleid),
0, 0, 0);
if (HeapTupleIsValid(tuple))
{
- char *uname;
+ char *rname;
- uname = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
+ rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname);
namespaceId = GetSysCacheOid(NAMESPACENAME,
- CStringGetDatum(uname),
+ CStringGetDatum(rname),
0, 0, 0);
ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
- pg_namespace_aclcheck(namespaceId, userId,
+ pg_namespace_aclcheck(namespaceId, roleid,
ACL_USAGE) == ACLCHECK_OK)
oidlist = lappend_oid(oidlist, namespaceId);
}
@@ -1569,7 +1569,7 @@ recomputeNamespacePath(void)
0, 0, 0);
if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) &&
- pg_namespace_aclcheck(namespaceId, userId,
+ pg_namespace_aclcheck(namespaceId, roleid,
ACL_USAGE) == ACLCHECK_OK)
oidlist = lappend_oid(oidlist, namespaceId);
}
@@ -1622,7 +1622,7 @@ recomputeNamespacePath(void)
/* Mark the path valid. */
namespaceSearchPathValid = true;
- namespaceUser = userId;
+ namespaceUser = roleid;
/* Clean up. */
pfree(rawname);
@@ -1674,7 +1674,7 @@ InitTempTableNamespace(void)
* that access the temp namespace for my own backend skip
* permissions checks on it.
*/
- namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID);
+ namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
/* Advance command counter to make namespace visible */
CommandCounterIncrement();
}
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index 797583f6c04..61a1a53902a 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.23 2005/05/27 00:57:49 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.24 2005/06/28 05:08:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,7 +36,7 @@
*/
Oid
ConversionCreate(const char *conname, Oid connamespace,
- AclId conowner,
+ Oid conowner,
int32 conforencoding, int32 contoencoding,
Oid conproc, bool def)
{
@@ -95,7 +95,7 @@ ConversionCreate(const char *conname, Oid connamespace,
namestrcpy(&cname, conname);
values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname);
values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace);
- values[Anum_pg_conversion_conowner - 1] = Int32GetDatum(conowner);
+ values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner);
values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding);
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);
diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c
index c2266f22d4d..8144d64136b 100644
--- a/src/backend/catalog/pg_namespace.c
+++ b/src/backend/catalog/pg_namespace.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.13 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.14 2005/06/28 05:08:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -26,7 +26,7 @@
* ---------------
*/
Oid
-NamespaceCreate(const char *nspName, int32 ownerSysId)
+NamespaceCreate(const char *nspName, Oid ownerId)
{
Relation nspdesc;
HeapTuple tup;
@@ -57,7 +57,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId)
}
namestrcpy(&nname, nspName);
values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
- values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId);
+ values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
nulls[Anum_pg_namespace_nspacl - 1] = 'n';
nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 6f50e4dabdd..55fa9e127cf 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.91 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.92 2005/06/28 05:08:52 tgl Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
@@ -235,7 +235,7 @@ OperatorShellMake(const char *operatorName,
namestrcpy(&oname, operatorName);
values[i++] = NameGetDatum(&oname); /* oprname */
values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */
- values[i++] = Int32GetDatum(GetUserId()); /* oprowner */
+ values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */
values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */
values[i++] = BoolGetDatum(false); /* oprcanhash */
values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */
@@ -519,7 +519,7 @@ OperatorCreate(const char *operatorName,
namestrcpy(&oname, operatorName);
values[i++] = NameGetDatum(&oname); /* oprname */
values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */
- values[i++] = Int32GetDatum(GetUserId()); /* oprowner */
+ values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */
values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */
values[i++] = BoolGetDatum(canHash); /* oprcanhash */
values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 12f6c64634f..7d1384ed382 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.129 2005/05/03 16:51:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.130 2005/06/28 05:08:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -217,7 +217,7 @@ ProcedureCreate(const char *procedureName,
namestrcpy(&procname, procedureName);
values[Anum_pg_proc_proname - 1] = NameGetDatum(&procname);
values[Anum_pg_proc_pronamespace - 1] = ObjectIdGetDatum(procNamespace);
- values[Anum_pg_proc_proowner - 1] = Int32GetDatum(GetUserId());
+ values[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(GetUserId());
values[Anum_pg_proc_prolang - 1] = ObjectIdGetDatum(languageObjectId);
values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg);
values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer);
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index acadded40d7..fa4068bf9f6 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.100 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.101 2005/06/28 05:08:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -227,7 +227,7 @@ TypeCreate(const char *typeName,
namestrcpy(&name, typeName);
values[i++] = NameGetDatum(&name); /* typname */
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
- values[i++] = Int32GetDatum(GetUserId()); /* typowner */
+ values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */
values[i++] = Int16GetDatum(internalSize); /* typlen */
values[i++] = BoolGetDatum(passedByValue); /* typbyval */
values[i++] = CharGetDatum(typeType); /* typtype */
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index f757e21039d..d20a3b6d7f2 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -3,9 +3,45 @@
*
* Copyright (c) 1996-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.15 2005/06/18 19:33:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.16 2005/06/28 05:08:52 tgl Exp $
*/
+CREATE VIEW pg_roles AS
+ SELECT
+ rolname,
+ rolsuper,
+ rolcreaterole,
+ rolcreatedb,
+ rolcatupdate,
+ rolcanlogin,
+ '********'::text as rolpassword,
+ rolvaliduntil,
+ rolconfig
+ FROM pg_authid;
+
+CREATE VIEW pg_shadow AS
+ SELECT
+ rolname AS usename,
+ oid AS usesysid,
+ rolcreatedb AS usecreatedb,
+ rolsuper AS usesuper,
+ rolcatupdate AS usecatupd,
+ rolpassword AS passwd,
+ rolvaliduntil::abstime AS valuntil,
+ rolconfig AS useconfig
+ FROM pg_authid
+ WHERE rolcanlogin;
+
+REVOKE ALL on pg_shadow FROM public;
+
+CREATE VIEW pg_group AS
+ SELECT
+ rolname AS groname,
+ oid AS grosysid,
+ ARRAY(SELECT member FROM pg_auth_members WHERE roleid = oid) AS grolist
+ FROM pg_authid
+ WHERE NOT rolcanlogin;
+
CREATE VIEW pg_user AS
SELECT
usename,
@@ -111,10 +147,10 @@ CREATE VIEW pg_locks AS
CREATE VIEW pg_prepared_xacts AS
SELECT P.transaction, P.gid, P.prepared,
- U.usename AS owner, D.datname AS database
+ U.rolname AS owner, D.datname AS database
FROM pg_prepared_xact() AS P
- (transaction xid, gid text, prepared timestamptz, ownerid int4, dbid oid)
- LEFT JOIN pg_shadow U ON P.ownerid = U.usesysid
+ (transaction xid, gid text, prepared timestamptz, ownerid oid, dbid oid)
+ LEFT JOIN pg_authid U ON P.ownerid = U.oid
LEFT JOIN pg_database D ON P.dbid = D.oid;
CREATE VIEW pg_settings AS
@@ -269,7 +305,7 @@ CREATE VIEW pg_stat_activity AS
D.datname AS datname,
pg_stat_get_backend_pid(S.backendid) AS procpid,
pg_stat_get_backend_userid(S.backendid) AS usesysid,
- U.usename AS usename,
+ U.rolname AS usename,
pg_stat_get_backend_activity(S.backendid) AS current_query,
pg_stat_get_backend_activity_start(S.backendid) AS query_start,
pg_stat_get_backend_start(S.backendid) AS backend_start,
@@ -277,9 +313,9 @@ CREATE VIEW pg_stat_activity AS
pg_stat_get_backend_client_port(S.backendid) AS client_port
FROM pg_database D,
(SELECT pg_stat_get_backend_idset() AS backendid) AS S,
- pg_shadow U
+ pg_authid U
WHERE pg_stat_get_backend_dbid(S.backendid) = D.oid AND
- pg_stat_get_backend_userid(S.backendid) = U.usesysid;
+ pg_stat_get_backend_userid(S.backendid) = U.oid;
CREATE VIEW pg_stat_database AS
SELECT
diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c
index 9833937b705..6335757981e 100644
--- a/src/backend/commands/aggregatecmds.c
+++ b/src/backend/commands/aggregatecmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.26 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.27 2005/06/28 05:08:53 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -295,7 +295,7 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname)
* Change aggregate owner
*/
void
-AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
+AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
{
Oid basetypeOid;
Oid procOid;
@@ -329,7 +329,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (procForm->proowner != newOwnerSysId)
+ if (procForm->proowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
@@ -341,7 +341,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId)
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- procForm->proowner = newOwnerSysId;
+ procForm->proowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 9bb40f35164..a19b500152d 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.12 2004/12/31 21:59:41 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.13 2005/06/28 05:08:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -64,10 +64,6 @@ ExecRenameStmt(RenameStmt *stmt)
RenameFunction(stmt->object, stmt->objarg, stmt->newname);
break;
- case OBJECT_GROUP:
- RenameGroup(stmt->subname, stmt->newname);
- break;
-
case OBJECT_LANGUAGE:
RenameLanguage(stmt->subname, stmt->newname);
break;
@@ -76,6 +72,10 @@ ExecRenameStmt(RenameStmt *stmt)
RenameOpClass(stmt->object, stmt->subname, stmt->newname);
break;
+ case OBJECT_ROLE:
+ RenameRole(stmt->subname, stmt->newname);
+ break;
+
case OBJECT_SCHEMA:
RenameSchema(stmt->subname, stmt->newname);
break;
@@ -84,10 +84,6 @@ ExecRenameStmt(RenameStmt *stmt)
RenameTableSpace(stmt->subname, stmt->newname);
break;
- case OBJECT_USER:
- RenameUser(stmt->subname, stmt->newname);
- break;
-
case OBJECT_TABLE:
case OBJECT_INDEX:
case OBJECT_COLUMN:
@@ -153,7 +149,7 @@ ExecRenameStmt(RenameStmt *stmt)
void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{
- AclId newowner = get_usesysid(stmt->newowner);
+ Oid newowner = get_roleid_checked(stmt->newowner);
switch (stmt->objectType)
{
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index fb71bf59f92..c2aa48614e6 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.18 2005/05/03 19:17:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.19 2005/06/28 05:08:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -175,7 +175,7 @@ RenameConversion(List *name, const char *newname)
* Change conversion owner
*/
void
-AlterConversionOwner(List *name, AclId newOwnerSysId)
+AlterConversionOwner(List *name, Oid newOwnerId)
{
Oid conversionOid;
HeapTuple tup;
@@ -203,7 +203,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (convForm->conowner != newOwnerSysId)
+ if (convForm->conowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
@@ -215,7 +215,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId)
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- convForm->conowner = newOwnerSysId;
+ convForm->conowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 30eeefded8e..10e68684b8e 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.245 2005/06/02 01:21:22 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.246 2005/06/28 05:08:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,7 +25,6 @@
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_index.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
#include "commands/copy.h"
#include "commands/trigger.h"
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 6fa6aa5b44b..1dac14ead2e 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.161 2005/06/25 22:47:29 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.162 2005/06/28 05:08:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,10 +28,10 @@
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
+#include "catalog/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"
@@ -52,7 +52,7 @@
/* non-export function prototypes */
-static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
+static bool get_db_info(const char *name, Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
@@ -70,7 +70,7 @@ createdb(const CreatedbStmt *stmt)
HeapScanDesc scan;
Relation rel;
Oid src_dboid;
- AclId src_owner;
+ Oid src_owner;
int src_encoding;
bool src_istemplate;
bool src_allowconn;
@@ -85,7 +85,7 @@ createdb(const CreatedbStmt *stmt)
Datum new_record[Natts_pg_database];
char new_record_nulls[Natts_pg_database];
Oid dboid;
- AclId datdba;
+ Oid datdba;
ListCell *option;
DefElem *dtablespacename = NULL;
DefElem *downer = NULL;
@@ -186,13 +186,13 @@ createdb(const CreatedbStmt *stmt)
nodeTag(dencoding->arg));
}
- /* obtain sysid of proposed owner */
+ /* obtain OID of proposed owner */
if (dbowner)
- datdba = get_usesysid(dbowner); /* will ereport if no such user */
+ datdba = get_roleid_checked(dbowner);
else
datdba = GetUserId();
- if (datdba == GetUserId())
+ if (is_member_of_role(GetUserId(), datdba))
{
/* creating database for self: can be superuser or createdb */
if (!superuser() && !have_createdb_privilege())
@@ -243,7 +243,7 @@ createdb(const CreatedbStmt *stmt)
*/
if (!src_istemplate)
{
- if (!superuser() && GetUserId() != src_owner)
+ if (!pg_database_ownercheck(src_dboid, GetUserId()))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to copy database \"%s\"",
@@ -483,7 +483,7 @@ createdb(const CreatedbStmt *stmt)
new_record[Anum_pg_database_datname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(dbname));
- new_record[Anum_pg_database_datdba - 1] = Int32GetDatum(datdba);
+ new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
@@ -557,9 +557,8 @@ createdb(const CreatedbStmt *stmt)
void
dropdb(const char *dbname)
{
- int4 db_owner;
- bool db_istemplate;
Oid db_id;
+ bool db_istemplate;
Relation pgdbrel;
SysScanDesc pgdbscan;
ScanKeyData key;
@@ -588,13 +587,13 @@ dropdb(const char *dbname)
*/
pgdbrel = heap_open(DatabaseRelationId, ExclusiveLock);
- if (!get_db_info(dbname, &db_id, &db_owner, NULL,
+ if (!get_db_info(dbname, &db_id, NULL, NULL,
&db_istemplate, NULL, NULL, NULL, NULL, NULL))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", dbname)));
- if (GetUserId() != db_owner && !superuser())
+ if (!pg_database_ownercheck(db_id, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
dbname);
@@ -818,8 +817,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", stmt->dbname)));
- if (!(superuser()
- || ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId()))
+ if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
stmt->dbname);
@@ -878,7 +876,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
* ALTER DATABASE name OWNER TO newowner
*/
void
-AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
+AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
{
HeapTuple tuple;
Relation rel;
@@ -910,7 +908,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
* command to have succeeded. This is to be consistent with other
* objects.
*/
- if (datForm->datdba != newOwnerSysId)
+ if (datForm->datdba != newOwnerId)
{
Datum repl_val[Natts_pg_database];
char repl_null[Natts_pg_database];
@@ -930,7 +928,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_database_datdba - 1] = 'r';
- repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId);
+ repl_val[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
@@ -943,7 +941,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- datForm->datdba, newOwnerSysId);
+ datForm->datdba, newOwnerId);
repl_repl[Anum_pg_database_datacl - 1] = 'r';
repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl);
}
@@ -972,7 +970,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
*/
static bool
-get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
+get_db_info(const char *name, Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
@@ -1007,7 +1005,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* oid of the database */
if (dbIdP)
*dbIdP = HeapTupleGetOid(tuple);
- /* sysid of the owner */
+ /* oid of the owner */
if (ownerIdP)
*ownerIdP = dbform->datdba;
/* character encoding */
@@ -1046,12 +1044,12 @@ have_createdb_privilege(void)
bool result = false;
HeapTuple utup;
- utup = SearchSysCache(SHADOWSYSID,
- Int32GetDatum(GetUserId()),
+ utup = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(GetUserId()),
0, 0, 0);
if (HeapTupleIsValid(utup))
{
- result = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb;
+ result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreatedb;
ReleaseSysCache(utup);
}
return result;
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index ea3c3811837..3329822fe62 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.61 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.62 2005/06/28 05:08:53 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@@ -853,7 +853,7 @@ RenameFunction(List *name, List *argtypes, const char *newname)
* Change function owner
*/
void
-AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
+AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
{
Oid procOid;
HeapTuple tup;
@@ -882,7 +882,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (procForm->proowner != newOwnerSysId)
+ if (procForm->proowner != newOwnerId)
{
Datum repl_val[Natts_pg_proc];
char repl_null[Natts_pg_proc];
@@ -902,7 +902,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_proc_proowner - 1] = 'r';
- repl_val[Anum_pg_proc_proowner - 1] = Int32GetDatum(newOwnerSysId);
+ repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
@@ -914,7 +914,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- procForm->proowner, newOwnerSysId);
+ procForm->proowner, newOwnerId);
repl_repl[Anum_pg_proc_proacl - 1] = 'r';
repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl);
}
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index e64924c43a7..3610269644a 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.32 2005/04/14 20:03:23 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.33 2005/06/28 05:08:53 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -321,7 +321,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
namestrcpy(&opcName, opcname);
values[i++] = NameGetDatum(&opcName); /* opcname */
values[i++] = ObjectIdGetDatum(namespaceoid); /* opcnamespace */
- values[i++] = Int32GetDatum(GetUserId()); /* opcowner */
+ values[i++] = ObjectIdGetDatum(GetUserId()); /* opcowner */
values[i++] = ObjectIdGetDatum(typeoid); /* opcintype */
values[i++] = BoolGetDatum(stmt->isDefault); /* opcdefault */
values[i++] = ObjectIdGetDatum(storageoid); /* opckeytype */
@@ -880,7 +880,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
* Change opclass owner
*/
void
-AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId)
+AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
{
Oid opcOid;
Oid amOid;
@@ -945,7 +945,7 @@ AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (opcForm->opcowner != newOwnerSysId)
+ if (opcForm->opcowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
@@ -957,7 +957,7 @@ AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId)
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- opcForm->opcowner = newOwnerSysId;
+ opcForm->opcowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index 45dc1eafeaa..adea1b2b5d7 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.21 2005/04/14 20:03:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.22 2005/06/28 05:08:54 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -269,7 +269,7 @@ RemoveOperatorById(Oid operOid)
*/
void
AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
- AclId newOwnerSysId)
+ Oid newOwnerId)
{
Oid operOid;
HeapTuple tup;
@@ -293,7 +293,7 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (oprForm->oprowner != newOwnerSysId)
+ if (oprForm->oprowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
@@ -305,7 +305,7 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
* Modify the owner --- okay to scribble on tup because it's a
* copy
*/
- oprForm->oprowner = newOwnerSysId;
+ oprForm->oprowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index 5754c1dfcb4..d92812f1fcf 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.30 2005/06/21 00:58:15 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.31 2005/06/28 05:08:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,11 +42,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
Oid namespaceId;
List *parsetree_list;
ListCell *parsetree_item;
- AclId owner_userid;
- AclId saved_userid;
+ Oid owner_uid;
+ Oid saved_uid;
AclResult aclresult;
- saved_userid = GetUserId();
+ saved_uid = GetUserId();
/*
* Figure out user identities.
@@ -54,12 +54,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
if (!authId)
{
- owner_userid = saved_userid;
+ owner_uid = saved_uid;
}
else if (superuser())
{
- /* The following will error out if user does not exist */
- owner_userid = get_usesysid(authId);
+ owner_uid = get_roleid_checked(authId);
/*
* Set the current user to the requested authorization so that
@@ -67,15 +66,15 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
* (This will revert to session user on error or at the end of
* this routine.)
*/
- SetUserId(owner_userid);
+ SetUserId(owner_uid);
}
else
{
const char *owner_name;
/* not superuser */
- owner_userid = saved_userid;
- owner_name = GetUserNameFromId(owner_userid);
+ owner_uid = saved_uid;
+ owner_name = GetUserNameFromId(owner_uid);
if (strcmp(authId, owner_name) != 0)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -87,7 +86,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
/*
* Permissions checks.
*/
- aclresult = pg_database_aclcheck(MyDatabaseId, saved_userid, ACL_CREATE);
+ aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_DATABASE,
get_database_name(MyDatabaseId));
@@ -99,7 +98,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
errdetail("The prefix \"pg_\" is reserved for system schemas.")));
/* Create the schema's namespace */
- namespaceId = NamespaceCreate(schemaName, owner_userid);
+ namespaceId = NamespaceCreate(schemaName, owner_uid);
/* Advance cmd counter to make the namespace visible */
CommandCounterIncrement();
@@ -149,7 +148,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
PopSpecialNamespace(namespaceId);
/* Reset current user */
- SetUserId(saved_userid);
+ SetUserId(saved_uid);
}
@@ -279,7 +278,7 @@ RenameSchema(const char *oldname, const char *newname)
* Change schema owner
*/
void
-AlterSchemaOwner(const char *name, AclId newOwnerSysId)
+AlterSchemaOwner(const char *name, Oid newOwnerId)
{
HeapTuple tup;
Relation rel;
@@ -300,7 +299,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (nspForm->nspowner != newOwnerSysId)
+ if (nspForm->nspowner != newOwnerId)
{
Datum repl_val[Natts_pg_namespace];
char repl_null[Natts_pg_namespace];
@@ -320,7 +319,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_namespace_nspowner - 1] = 'r';
- repl_val[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(newOwnerSysId);
+ repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
@@ -332,7 +331,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- nspForm->nspowner, newOwnerSysId);
+ nspForm->nspowner, newOwnerId);
repl_repl[Anum_pg_namespace_nspacl - 1] = 'r';
repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
}
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 9981129c0eb..dda9532baf8 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.161 2005/06/06 20:22:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.162 2005/06/28 05:08:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -231,9 +231,9 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
const char *colName, TypeName *typename);
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
static void ATPostAlterTypeParse(char *cmd, List **wqueue);
-static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId);
+static void ATExecChangeOwner(Oid relationOid, Oid newOwnerId);
static void change_owner_recurse_to_sequences(Oid relationOid,
- int32 newOwnerSysId);
+ Oid newOwnerId);
static void ATExecClusterOn(Relation rel, const char *indexName);
static void ATExecDropCluster(Relation rel);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
@@ -2133,8 +2133,8 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
AlterTableCreateToastTable(RelationGetRelid(rel), false);
break;
case AT_ChangeOwner: /* ALTER OWNER */
- /* get_usesysid raises an error if no such user */
- ATExecChangeOwner(RelationGetRelid(rel), get_usesysid(cmd->name));
+ ATExecChangeOwner(RelationGetRelid(rel),
+ get_roleid_checked(cmd->name));
break;
case AT_ClusterOn: /* CLUSTER ON */
ATExecClusterOn(rel, cmd->name);
@@ -5233,7 +5233,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
* ALTER TABLE OWNER
*/
static void
-ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
+ATExecChangeOwner(Oid relationOid, Oid newOwnerId)
{
Relation target_rel;
Relation class_rel;
@@ -5277,7 +5277,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (tuple_class->relowner != newOwnerSysId)
+ if (tuple_class->relowner != newOwnerId)
{
Datum repl_val[Natts_pg_class];
char repl_null[Natts_pg_class];
@@ -5297,7 +5297,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_class_relowner - 1] = 'r';
- repl_val[Anum_pg_class_relowner - 1] = Int32GetDatum(newOwnerSysId);
+ repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
@@ -5309,7 +5309,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- tuple_class->relowner, newOwnerSysId);
+ tuple_class->relowner, newOwnerId);
repl_repl[Anum_pg_class_relacl - 1] = 'r';
repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl);
}
@@ -5337,7 +5337,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
/* For each index, recursively change its ownership */
foreach(i, index_oid_list)
- ATExecChangeOwner(lfirst_oid(i), newOwnerSysId);
+ ATExecChangeOwner(lfirst_oid(i), newOwnerId);
list_free(index_oid_list);
}
@@ -5346,10 +5346,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
{
/* If it has a toast table, recurse to change its ownership */
if (tuple_class->reltoastrelid != InvalidOid)
- ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId);
+ ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId);
/* If it has dependent sequences, recurse to change them too */
- change_owner_recurse_to_sequences(relationOid, newOwnerSysId);
+ change_owner_recurse_to_sequences(relationOid, newOwnerId);
}
}
@@ -5366,7 +5366,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
* ownership.
*/
static void
-change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
+change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId)
{
Relation depRel;
SysScanDesc scan;
@@ -5416,7 +5416,7 @@ change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId)
}
/* We don't need to close the sequence while we alter it. */
- ATExecChangeOwner(depForm->objid, newOwnerSysId);
+ ATExecChangeOwner(depForm->objid, newOwnerId);
/* Now we can close it. Keep the lock till end of transaction. */
relation_close(seqRel, NoLock);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index a469a8fa349..15a263b8efd 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.22 2005/06/19 21:34:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.23 2005/06/28 05:08:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -208,7 +208,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
Oid tablespaceoid;
char *location;
char *linkloc;
- AclId ownerid;
+ Oid ownerId;
/* validate */
@@ -225,12 +225,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */
if (stmt->owner)
- {
- /* No need to check result, get_usesysid() does that */
- ownerid = get_usesysid(stmt->owner);
- }
+ ownerId = get_roleid_checked(stmt->owner);
else
- ownerid = GetUserId();
+ ownerId = GetUserId();
/* Unix-ify the offered path, and strip any trailing slashes */
location = pstrdup(stmt->location);
@@ -297,7 +294,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
values[Anum_pg_tablespace_spcname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
values[Anum_pg_tablespace_spcowner - 1] =
- Int32GetDatum(ownerid);
+ ObjectIdGetDatum(ownerId);
values[Anum_pg_tablespace_spclocation - 1] =
DirectFunctionCall1(textin, CStringGetDatum(location));
nulls[Anum_pg_tablespace_spcacl - 1] = 'n';
@@ -426,9 +423,8 @@ DropTableSpace(DropTableSpaceStmt *stmt)
tablespaceoid = HeapTupleGetOid(tuple);
- /* Must be superuser or owner */
- if (GetUserId() != ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner &&
- !superuser())
+ /* Must be tablespace owner */
+ if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
tablespacename);
@@ -711,8 +707,8 @@ RenameTableSpace(const char *oldname, const char *newname)
heap_endscan(scan);
- /* Must be owner or superuser */
- if (newform->spcowner != GetUserId() && !superuser())
+ /* Must be owner */
+ if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId()))
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname);
/* Validate new name */
@@ -750,7 +746,7 @@ RenameTableSpace(const char *oldname, const char *newname)
* Change tablespace owner
*/
void
-AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
+AlterTableSpaceOwner(const char *name, Oid newOwnerId)
{
Relation rel;
ScanKeyData entry[1];
@@ -778,7 +774,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (spcForm->spcowner != newOwnerSysId)
+ if (spcForm->spcowner != newOwnerId)
{
Datum repl_val[Natts_pg_tablespace];
char repl_null[Natts_pg_tablespace];
@@ -798,7 +794,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_tablespace_spcowner - 1] = 'r';
- repl_val[Anum_pg_tablespace_spcowner - 1] = Int32GetDatum(newOwnerSysId);
+ repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwnerId);
/*
* Determine the modified ACL for the new owner. This is only
@@ -811,7 +807,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
if (!isNull)
{
newAcl = aclnewowner(DatumGetAclP(aclDatum),
- spcForm->spcowner, newOwnerSysId);
+ spcForm->spcowner, newOwnerId);
repl_repl[Anum_pg_tablespace_spcacl - 1] = 'r';
repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl);
}
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 280022feaa1..53570c77409 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.72 2005/05/06 17:24:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.73 2005/06/28 05:08:54 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -2016,7 +2016,7 @@ GetDomainConstraints(Oid typeOid)
* Change the owner of a type.
*/
void
-AlterTypeOwner(List *names, AclId newOwnerSysId)
+AlterTypeOwner(List *names, Oid newOwnerId)
{
TypeName *typename;
Oid typeOid;
@@ -2063,7 +2063,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes.
*/
- if (typTup->typowner != newOwnerSysId)
+ if (typTup->typowner != newOwnerId)
{
/* Otherwise, must be superuser to change object ownership */
if (!superuser())
@@ -2075,7 +2075,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId)
* Modify the owner --- okay to scribble on typTup because it's a
* copy
*/
- typTup->typowner = newOwnerSysId;
+ typTup->typowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup);
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 3c70c579785..131f1896f92 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -1,12 +1,12 @@
/*-------------------------------------------------------------------------
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -14,15 +14,14 @@
#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"
@@ -32,46 +31,46 @@
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(CreateUserStmt *stmt)
+CreateRole(CreateRoleStmt *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 */
@@ -95,11 +94,16 @@ CreateUser(CreateUserStmt *stmt)
}
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)
{
@@ -109,21 +113,29 @@ CreateUser(CreateUserStmt *stmt)
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, "groupElts") == 0)
+ else if (strcmp(defel->defname, "roleElts") == 0)
{
- if (dgroupElts)
+ if (droleElts)
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)
{
@@ -140,83 +152,51 @@ CreateUser(CreateUserStmt *stmt)
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 users")));
+ errmsg("must be superuser to create roles")));
- 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
@@ -224,105 +204,123 @@ CreateUser(CreateUserStmt *stmt)
MemSet(new_record, 0, sizeof(new_record));
MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
- new_record[Anum_pg_shadow_usename - 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_rolname - 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_passwd - 1] =
+ new_record[Anum_pg_authid_rolpassword - 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_passwd - 1] =
+ new_record[Anum_pg_authid_rolpassword - 1] =
DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
}
}
else
- new_record_nulls[Anum_pg_shadow_passwd - 1] = 'n';
+ new_record_nulls[Anum_pg_authid_rolpassword - 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_valuntil - 1] = 'n';
+ new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = 'n';
- new_record_nulls[Anum_pg_shadow_useconfig - 1] = 'n';
+ new_record_nulls[Anum_pg_authid_rolconfig - 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, groupElts)
+ foreach(item, roleElts)
{
- 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(AlterUserStmt *stmt)
+AlterRole(AlterRoleStmt *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)
@@ -351,13 +349,29 @@ AlterUser(AlterUserStmt *stmt)
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)
{
@@ -367,6 +381,14 @@ AlterUser(AlterUserStmt *stmt)
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);
@@ -374,42 +396,54 @@ AlterUser(AlterUserStmt *stmt)
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(ShadowRelationId, ExclusiveLock);
- pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
+ pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock);
+ pg_authid_dsc = RelationGetDescr(pg_authid_rel);
- tuple = SearchSysCache(SHADOWNAME,
- PointerGetDatum(stmt->user),
+ tuple = SearchSysCache(AUTHNAME,
+ 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
@@ -418,65 +452,79 @@ AlterUser(AlterUserStmt *stmt)
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 (createuser >= 0)
+ if (issuper >= 0)
{
- new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser > 0);
- new_record_repl[Anum_pg_shadow_usesuper - 1] = 'r';
+ new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0);
+ new_record_repl[Anum_pg_authid_rolsuper - 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_passwd - 1] =
+ new_record[Anum_pg_authid_rolpassword - 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_passwd - 1] =
+ new_record[Anum_pg_authid_rolpassword - 1] =
DirectFunctionCall1(textin, CStringGetDatum(encrypted_password));
}
- new_record_repl[Anum_pg_shadow_passwd - 1] = 'r';
+ new_record_repl[Anum_pg_authid_rolpassword - 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);
@@ -485,59 +533,68 @@ AlterUser(AlterUserStmt *stmt)
* 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(AlterUserSetStmt *stmt)
+AlterRoleSet(AlterRoleSetStmt *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(ShadowRelationId, RowExclusiveLock);
- oldtuple = SearchSysCache(SHADOWNAME,
- PointerGetDatum(stmt->user),
+ rel = heap_open(AuthIdRelationId, RowExclusiveLock);
+ oldtuple = SearchSysCache(AUTHNAME,
+ 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_useconfig - 1] = 'r';
+ repl_repl[Anum_pg_authid_rolconfig - 1] = 'r';
if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL)
{
/* RESET ALL */
- repl_null[Anum_pg_shadow_useconfig - 1] = 'n';
+ repl_null[Anum_pg_authid_rolconfig - 1] = 'n';
}
else
{
@@ -545,10 +602,10 @@ AlterUserSet(AlterUserSetStmt *stmt)
bool isnull;
ArrayType *array;
- repl_null[Anum_pg_shadow_useconfig - 1] = ' ';
+ repl_null[Anum_pg_authid_rolconfig - 1] = ' ';
- datum = SysCacheGetAttr(SHADOWNAME, oldtuple,
- Anum_pg_shadow_useconfig, &isnull);
+ datum = SysCacheGetAttr(AUTHNAME, oldtuple,
+ Anum_pg_authid_rolconfig, &isnull);
array = isnull ? NULL : DatumGetArrayTypeP(datum);
@@ -558,9 +615,9 @@ AlterUserSet(AlterUserSetStmt *stmt)
array = GUCArrayDelete(array, stmt->variable);
if (array)
- repl_val[Anum_pg_shadow_useconfig - 1] = PointerGetDatum(array);
+ repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array);
else
- repl_null[Anum_pg_shadow_useconfig - 1] = 'n';
+ repl_null[Anum_pg_authid_rolconfig - 1] = 'n';
}
newtuple = heap_modifytuple(oldtuple, RelationGetDescr(rel), repl_val, repl_null, repl_repl);
@@ -574,60 +631,61 @@ AlterUserSet(AlterUserSetStmt *stmt)
/*
- * DROP USER
+ * DROP ROLE
*/
void
-DropUser(DropUserStmt *stmt)
+DropRole(DropRoleStmt *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 users")));
+ errmsg("must be superuser to drop roles")));
/*
- * 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(ShadowRelationId, ExclusiveLock);
- pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
+ pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock);
+ pg_auth_members_rel = heap_open(AuthMemRelationId, ExclusiveLock);
- foreach(item, stmt->users)
+ foreach(item, stmt->roles)
{
- 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(SHADOWNAME,
- PointerGetDatum(user),
+ tuple = SearchSysCache(AUTHNAME,
+ 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 (usesysid == GetUserId())
+ if (roleid == GetUserId())
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("current user cannot be dropped")));
- if (usesysid == GetSessionUserId())
+ errmsg("current role cannot be dropped")));
+ if (roleid == 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
@@ -639,8 +697,8 @@ DropUser(DropUserStmt *stmt)
ScanKeyInit(&scankey,
Anum_pg_database_datdba,
- BTEqualStrategyNumber, F_INT4EQ,
- Int32GetDatum(usesysid));
+ BTEqualStrategyNumber, F_OIDEQ,
+ roleid);
scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
@@ -651,8 +709,8 @@ DropUser(DropUserStmt *stmt)
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);
@@ -660,66 +718,64 @@ DropUser(DropUserStmt *stmt)
/*
* 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 groups
+ * Remove role from roles
*
- * 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;
@@ -727,22 +783,23 @@ RenameUser(const char *oldname, const char *newname)
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(ShadowRelationId, ExclusiveLock);
+ rel = heap_open(AuthIdRelationId, ExclusiveLock);
dsc = RelationGetDescr(rel);
- oldtuple = SearchSysCache(SHADOWNAME,
+ oldtuple = SearchSysCache(AUTHNAME,
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,
@@ -750,43 +807,46 @@ RenameUser(const char *oldname, const char *newname)
* 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(SHADOWNAME,
+ if (SearchSysCacheExists(AUTHNAME,
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 users")));
+ errmsg("must be superuser to rename roles")));
- for (i = 0; i < Natts_pg_shadow; i++)
+ for (i = 0; i < Natts_pg_authid; i++)
repl_repl[i] = ' ';
- repl_repl[Anum_pg_shadow_usename - 1] = 'r';
- repl_val[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein,
+ repl_repl[Anum_pg_authid_rolname - 1] = 'r';
+ repl_val[Anum_pg_authid_rolname - 1] = DirectFunctionCall1(namein,
CStringGetDatum(newname));
- repl_null[Anum_pg_shadow_usename - 1] = ' ';
+ repl_null[Anum_pg_authid_rolname - 1] = ' ';
- datum = heap_getattr(oldtuple, Anum_pg_shadow_passwd, dsc, &isnull);
+ datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, 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_passwd - 1] = 'r';
- repl_null[Anum_pg_shadow_passwd - 1] = 'n';
+ repl_repl[Anum_pg_authid_rolpassword - 1] = 'r';
+ repl_null[Anum_pg_authid_rolpassword - 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);
@@ -797,551 +857,322 @@ RenameUser(const char *oldname, const char *newname)
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(CreateGroupStmt *stmt)
+GrantRole(GrantRoleStmt *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);
}
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 048a3e41562..7df2a92a6c6 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.108 2005/06/09 21:52:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.109 2005/06/28 05:08:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
#include <ctype.h>
#include "access/xact.h"
-#include "catalog/pg_shadow.h"
+#include "catalog/pg_authid.h"
#include "commands/variable.h"
#include "miscadmin.h"
#include "parser/scansup.h"
@@ -567,46 +567,46 @@ assign_client_encoding(const char *value, bool doit, GucSource source)
* SET SESSION AUTHORIZATION
*
* When resetting session auth after an error, we can't expect to do catalog
- * lookups. Hence, the stored form of the value must provide a numeric userid
+ * lookups. Hence, the stored form of the value must provide a numeric oid
* that can be re-used directly. We store the string in the form of
* NAMEDATALEN 'x's, followed by T or F to indicate superuserness, followed
- * by the numeric userid, followed by a comma, followed by the user name.
- * This cannot be confused with a plain user name because of the NAMEDATALEN
+ * by the numeric oid, followed by a comma, followed by the role name.
+ * This cannot be confused with a plain role name because of the NAMEDATALEN
* limit on names, so we can tell whether we're being passed an initial
- * username or a saved/restored value.
+ * role name or a saved/restored value.
*/
extern char *session_authorization_string; /* in guc.c */
const char *
assign_session_authorization(const char *value, bool doit, GucSource source)
{
- AclId usesysid = 0;
+ Oid roleid = InvalidOid;
bool is_superuser = false;
- const char *actual_username = NULL;
+ const char *actual_rolename = NULL;
char *result;
if (strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
{
/* might be a saved userid string */
- AclId savedsysid;
+ Oid savedoid;
char *endptr;
- savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
+ savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
if (endptr != value + NAMEDATALEN + 1 && *endptr == ',')
{
/* syntactically valid, so break out the data */
- usesysid = savedsysid;
+ roleid = savedoid;
is_superuser = (value[NAMEDATALEN] == 'T');
- actual_username = endptr + 1;
+ actual_rolename = endptr + 1;
}
}
- if (usesysid == 0)
+ if (roleid == InvalidOid)
{
/* not a saved ID, so look it up */
- HeapTuple userTup;
+ HeapTuple roleTup;
if (!IsTransactionState())
{
@@ -618,38 +618,38 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
return NULL;
}
- userTup = SearchSysCache(SHADOWNAME,
+ roleTup = SearchSysCache(AUTHNAME,
PointerGetDatum(value),
0, 0, 0);
- if (!HeapTupleIsValid(userTup))
+ if (!HeapTupleIsValid(roleTup))
{
if (source >= PGC_S_INTERACTIVE)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", value)));
+ errmsg("role \"%s\" does not exist", value)));
return NULL;
}
- usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
- is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
- actual_username = value;
+ roleid = HeapTupleGetOid(roleTup);
+ is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
+ actual_rolename = value;
- ReleaseSysCache(userTup);
+ ReleaseSysCache(roleTup);
}
if (doit)
- SetSessionAuthorization(usesysid, is_superuser);
+ SetSessionAuthorization(roleid, is_superuser);
- result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_username));
+ result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_rolename));
if (!result)
return NULL;
memset(result, 'x', NAMEDATALEN);
- sprintf(result + NAMEDATALEN, "%c%lu,%s",
+ sprintf(result + NAMEDATALEN, "%c%u,%s",
is_superuser ? 'T' : 'F',
- (unsigned long) usesysid,
- actual_username);
+ roleid,
+ actual_rolename);
return result;
}
@@ -662,13 +662,13 @@ show_session_authorization(void)
* assign_session_authorization
*/
const char *value = session_authorization_string;
- AclId savedsysid;
+ Oid savedoid;
char *endptr;
Assert(strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'));
- savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
+ savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ',');
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 938474610ae..3ef33cfd39f 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.250 2005/06/20 18:37:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.251 2005/06/28 05:08:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -352,7 +352,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
{
AclMode requiredPerms;
Oid relOid;
- AclId userid;
+ Oid userid;
/*
* Only plain-relation RTEs need to be checked here. Subquery RTEs
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 5b5499454b8..b7a0bc344ff 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -61,7 +61,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.133 2005/05/06 17:24:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.134 2005/06/28 05:08:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1270,7 +1270,7 @@ ExecInitAgg(Agg *node, EState *estate)
/* Check that aggregate owner has permission to call component fns */
{
HeapTuple procTuple;
- AclId aggOwner;
+ Oid aggOwner;
procTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(aggref->aggfnoid),
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c
index 58e80334f61..d9c95d1b9ac 100644
--- a/src/backend/libpq/crypt.c
+++ b/src/backend/libpq/crypt.c
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.62 2005/02/20 04:45:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.63 2005/06/28 05:08:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,7 +29,7 @@
int
-md5_crypt_verify(const Port *port, const char *user, char *client_pass)
+md5_crypt_verify(const Port *port, const char *role, char *client_pass)
{
char *shadow_pass = NULL,
*valuntil = NULL,
@@ -39,16 +39,14 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
ListCell *token;
char *crypt_client_pass = client_pass;
- if ((line = get_user_line(user)) == NULL)
+ if ((line = get_role_line(role)) == NULL)
return STATUS_ERROR;
- /* Skip over username and usesysid */
+ /* Skip over rolename */
token = list_head(*line);
if (token)
token = lnext(token);
if (token)
- token = lnext(token);
- if (token)
{
shadow_pass = (char *) lfirst(token);
token = lnext(token);
@@ -146,17 +144,28 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
/*
* Password OK, now check to be sure we are not past valuntil
*/
- AbsoluteTime vuntil;
-
if (valuntil == NULL || *valuntil == '\0')
- vuntil = INVALID_ABSTIME;
- else
- vuntil = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein,
- CStringGetDatum(valuntil)));
- if (vuntil != INVALID_ABSTIME && vuntil < GetCurrentAbsoluteTime())
- retval = STATUS_ERROR;
- else
retval = STATUS_OK;
+ else
+ {
+ TimestampTz vuntil;
+ AbsoluteTime sec;
+ int usec;
+ TimestampTz curtime;
+
+ vuntil = DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in,
+ CStringGetDatum(valuntil),
+ ObjectIdGetDatum(InvalidOid),
+ Int32GetDatum(-1)));
+
+ sec = GetCurrentAbsoluteTimeUsec(&usec);
+ curtime = AbsoluteTimeUsecToTimestampTz(sec, usec);
+
+ if (vuntil < curtime)
+ retval = STATUS_ERROR;
+ else
+ retval = STATUS_OK;
+ }
}
if (port->auth_method == uaMD5)
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index ab5d7e41674..52608eb4537 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.142 2005/06/27 02:04:25 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.143 2005/06/28 05:08:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -53,7 +53,8 @@
/*
* These variables hold the pre-parsed contents of the hba and ident
- * configuration files. Each is a list of sublists, one sublist for
+ * configuration files, as well as the flat auth file.
+ * Each is a list of sublists, one sublist for
* each (non-empty, non-comment) line of the file. Each sublist's
* first item is an integer line number (so we can give somewhat-useful
* location info in error messages). Remaining items are palloc'd strings,
@@ -69,20 +70,13 @@ static List *hba_line_nums = NIL;
static List *ident_lines = NIL;
static List *ident_line_nums = NIL;
-/* pre-parsed content of group file and corresponding line #s */
-static List *group_lines = NIL;
-static List *group_line_nums = NIL;
-
-/* pre-parsed content of user passwd file and corresponding line #s */
-static List *user_lines = NIL;
-static List *user_line_nums = NIL;
+/* pre-parsed content of flat auth file and corresponding line #s */
+static List *role_lines = NIL;
+static List *role_line_nums = NIL;
/* sorted entries so we can do binary search lookups */
-static List **user_sorted = NULL; /* sorted user list, for bsearch() */
-static List **group_sorted = NULL; /* sorted group list, for
- * bsearch() */
-static int user_length;
-static int group_length;
+static List **role_sorted = NULL; /* sorted role list, for bsearch() */
+static int role_length;
static void tokenize_file(const char *filename, FILE *file,
List **lines, List **line_nums);
@@ -109,7 +103,7 @@ pg_isblank(const char c)
* return empty string as *buf and position the file to the beginning
* of the next line or EOF, whichever comes first. Allow spaces in
* quoted strings. Terminate on unquoted commas. Handle
- * comments. Treat unquoted keywords that might be user names or
+ * comments. Treat unquoted keywords that might be role names or
* database names specially, by appending a newline to them.
*/
static void
@@ -199,7 +193,8 @@ next_token(FILE *fp, char *buf, int bufsz)
if (!saw_quote &&
(strcmp(start_buf, "all") == 0 ||
strcmp(start_buf, "sameuser") == 0 ||
- strcmp(start_buf, "samegroup") == 0))
+ strcmp(start_buf, "samegroup") == 0 ||
+ strcmp(start_buf, "samerole") == 0))
{
/* append newline to a magical keyword */
*buf++ = '\n';
@@ -434,94 +429,58 @@ tokenize_file(const char *filename, FILE *file,
}
}
-
/*
- * Compare two lines based on their user/group names.
- *
- * Used for qsort() sorting.
- */
-static int
-user_group_qsort_cmp(const void *list1, const void *list2)
-{
- char *user1 = linitial(*(List **) list1);
- char *user2 = linitial(*(List **) list2);
-
- return strcmp(user1, user2);
-}
-
-
-/*
- * Compare two lines based on their user/group names.
+ * Compare two lines based on their role/member names.
*
* Used for bsearch() lookup.
*/
static int
-user_group_bsearch_cmp(const void *user, const void *list)
+role_bsearch_cmp(const void *role, const void *list)
{
- char *user2 = linitial(*(List **) list);
+ char *role2 = linitial(*(List **) list);
- return strcmp(user, user2);
+ return strcmp(role, role2);
}
/*
- * Lookup a group name in the pg_group file
+ * Lookup a role name in the pg_auth file
*/
-static List **
-get_group_line(const char *group)
+List **
+get_role_line(const char *role)
{
/* On some versions of Solaris, bsearch of zero items dumps core */
- if (group_length == 0)
+ if (role_length == 0)
return NULL;
- return (List **) bsearch((void *) group,
- (void *) group_sorted,
- group_length,
+ return (List **) bsearch((void *) role,
+ (void *) role_sorted,
+ role_length,
sizeof(List *),
- user_group_bsearch_cmp);
+ role_bsearch_cmp);
}
/*
- * Lookup a user name in the pg_shadow file
- */
-List **
-get_user_line(const char *user)
-{
- /* On some versions of Solaris, bsearch of zero items dumps core */
- if (user_length == 0)
- return NULL;
-
- return (List **) bsearch((void *) user,
- (void *) user_sorted,
- user_length,
- sizeof(List *),
- user_group_bsearch_cmp);
-}
-
-
-/*
- * Does user belong to group?
+ * Does member belong to role?
*/
static bool
-check_group(char *group, char *user)
+check_member(const char *role, const char *member)
{
List **line;
+ List **line2;
ListCell *line_item;
- char *usesysid;
- if ((line = get_user_line(user)) == NULL)
- return false; /* if user not exist, say "no" */
- /* Skip over username to get usesysid */
- usesysid = (char *) lsecond(*line);
+ if ((line = get_role_line(member)) == NULL)
+ return false; /* if member not exist, say "no" */
- if ((line = get_group_line(group)) == NULL)
- return false; /* if group not exist, say "no" */
+ if ((line2 = get_role_line(role)) == NULL)
+ return false; /* if role not exist, say "no" */
- /* skip over the group name, examine all the member usesysid's */
- for_each_cell(line_item, lnext(list_head(*line)))
+ /* skip over the role name, password, valuntil, examine all the members */
+ for_each_cell(line_item, lfourth(*line2))
{
- if (strcmp((char *) lfirst(line_item), usesysid) == 0)
+ if (strcmp((char *) lfirst(line_item), member) == 0)
return true;
}
@@ -529,10 +488,10 @@ check_group(char *group, char *user)
}
/*
- * Check comma user list for a specific user, handle group names.
+ * Check comma member list for a specific role, handle role names.
*/
static bool
-check_user(char *user, char *param_str)
+check_role(char *role, char *param_str)
{
char *tok;
@@ -540,10 +499,10 @@ check_user(char *user, char *param_str)
{
if (tok[0] == '+')
{
- if (check_group(tok + 1, user))
+ if (check_member(tok + 1, role))
return true;
}
- else if (strcmp(tok, user) == 0 ||
+ else if (strcmp(tok, role) == 0 ||
strcmp(tok, "all\n") == 0)
return true;
}
@@ -552,10 +511,10 @@ check_user(char *user, char *param_str)
}
/*
- * Check to see if db/user combination matches param string.
+ * Check to see if db/role combination matches param string.
*/
static bool
-check_db(char *dbname, char *user, char *param_str)
+check_db(char *dbname, char *role, char *param_str)
{
char *tok;
@@ -565,12 +524,13 @@ check_db(char *dbname, char *user, char *param_str)
return true;
else if (strcmp(tok, "sameuser\n") == 0)
{
- if (strcmp(dbname, user) == 0)
+ if (strcmp(dbname, role) == 0)
return true;
}
- else if (strcmp(tok, "samegroup\n") == 0)
+ else if (strcmp(tok, "samegroup\n") == 0 ||
+ strcmp(tok, "samerole\n") == 0)
{
- if (check_group(dbname, user))
+ if (check_member(dbname, role))
return true;
}
else if (strcmp(tok, dbname) == 0)
@@ -655,7 +615,7 @@ parse_hba(List *line, int line_num, hbaPort *port,
{
char *token;
char *db;
- char *user;
+ char *role;
struct addrinfo *gai_result;
struct addrinfo hints;
int ret;
@@ -675,11 +635,11 @@ parse_hba(List *line, int line_num, hbaPort *port,
goto hba_syntax;
db = lfirst(line_item);
- /* Get the user. */
+ /* Get the role. */
line_item = lnext(line_item);
if (!line_item)
goto hba_syntax;
- user = lfirst(line_item);
+ role = lfirst(line_item);
line_item = lnext(line_item);
if (!line_item)
@@ -735,11 +695,11 @@ parse_hba(List *line, int line_num, hbaPort *port,
goto hba_syntax;
db = lfirst(line_item);
- /* Get the user. */
+ /* Get the role. */
line_item = lnext(line_item);
if (!line_item)
goto hba_syntax;
- user = lfirst(line_item);
+ role = lfirst(line_item);
/* Read the IP address field. (with or without CIDR netmask) */
line_item = lnext(line_item);
@@ -861,10 +821,10 @@ parse_hba(List *line, int line_num, hbaPort *port,
else
goto hba_syntax;
- /* Does the entry match database and user? */
+ /* Does the entry match database and role? */
if (!check_db(port->database_name, port->user_name, db))
return;
- if (!check_user(port->user_name, user))
+ if (!check_role(port->user_name, role))
return;
/* Success */
@@ -923,27 +883,27 @@ check_hba(hbaPort *port)
/*
- * Load group/user name mapping file
+ * Load role/password mapping file
*/
void
-load_group(void)
+load_role(void)
{
char *filename;
- FILE *group_file;
+ FILE *role_file;
/* Discard any old data */
- if (group_lines || group_line_nums)
- free_lines(&group_lines, &group_line_nums);
- if (group_sorted)
- pfree(group_sorted);
- group_sorted = NULL;
- group_length = 0;
+ if (role_lines || role_line_nums)
+ free_lines(&role_lines, &role_line_nums);
+ if (role_sorted)
+ pfree(role_sorted);
+ role_sorted = NULL;
+ role_length = 0;
/* Read in the file contents */
- filename = group_getflatfilename();
- group_file = AllocateFile(filename, "r");
+ filename = auth_getflatfilename();
+ role_file = AllocateFile(filename, "r");
- if (group_file == NULL)
+ if (role_file == NULL)
{
/* no complaint if not there */
if (errno != ENOENT)
@@ -954,84 +914,25 @@ load_group(void)
return;
}
- tokenize_file(filename, group_file, &group_lines, &group_line_nums);
+ tokenize_file(filename, role_file, &role_lines, &role_line_nums);
- FreeFile(group_file);
+ FreeFile(role_file);
pfree(filename);
- /* create sorted lines for binary searching */
- group_length = list_length(group_lines);
- if (group_length)
+ /* create array for binary searching */
+ role_length = list_length(role_lines);
+ if (role_length)
{
- int i = 0;
- ListCell *line;
+ int i = 0;
+ ListCell *line;
- group_sorted = palloc(group_length * sizeof(List *));
-
- 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 */
}
}
@@ -1108,18 +1009,18 @@ read_pg_database_line(FILE *fp, char *dbname,
/*
* Process one line from the ident config file.
*
- * Take the line and compare it to the needed map, pg_user and ident_user.
+ * Take the line and compare it to the needed map, pg_role and ident_user.
* *found_p and *error_p are set according to our results.
*/
static void
parse_ident_usermap(List *line, int line_number, const char *usermap_name,
- const char *pg_user, const char *ident_user,
+ const char *pg_role, const char *ident_user,
bool *found_p, bool *error_p)
{
ListCell *line_item;
char *token;
char *file_map;
- char *file_pguser;
+ char *file_pgrole;
char *file_ident_user;
*found_p = false;
@@ -1139,16 +1040,16 @@ parse_ident_usermap(List *line, int line_number, const char *usermap_name,
token = lfirst(line_item);
file_ident_user = token;
- /* Get the PG username token */
+ /* Get the PG rolename token */
line_item = lnext(line_item);
if (!line_item)
goto ident_syntax;
token = lfirst(line_item);
- file_pguser = token;
+ file_pgrole = token;
/* Match? */
if (strcmp(file_map, usermap_name) == 0 &&
- strcmp(file_pguser, pg_user) == 0 &&
+ strcmp(file_pgrole, pg_role) == 0 &&
strcmp(file_ident_user, ident_user) == 0)
*found_p = true;
@@ -1167,17 +1068,17 @@ ident_syntax:
* Scan the (pre-parsed) ident usermap file line by line, looking for a match
*
* See if the user with ident username "ident_user" is allowed to act
- * as Postgres user "pguser" according to usermap "usermap_name".
+ * as Postgres user "pgrole" according to usermap "usermap_name".
*
- * Special case: For usermap "sameuser", don't look in the usermap
- * file. That's an implied map where "pguser" must be identical to
+ * Special case: For usermap "samerole", don't look in the usermap
+ * file. That's an implied map where "pgrole" must be identical to
* "ident_user" in order to be authorized.
*
* Iff authorized, return true.
*/
static bool
check_ident_usermap(const char *usermap_name,
- const char *pg_user,
+ const char *pg_role,
const char *ident_user)
{
bool found_entry = false,
@@ -1190,9 +1091,10 @@ check_ident_usermap(const char *usermap_name,
errmsg("cannot use Ident authentication without usermap field")));
found_entry = false;
}
- else if (strcmp(usermap_name, "sameuser\n") == 0)
+ else if (strcmp(usermap_name, "sameuser\n") == 0 ||
+ strcmp(usermap_name, "samerole\n") == 0)
{
- if (strcmp(pg_user, ident_user) == 0)
+ if (strcmp(pg_role, ident_user) == 0)
found_entry = true;
else
found_entry = false;
@@ -1205,7 +1107,7 @@ check_ident_usermap(const char *usermap_name,
forboth(line_cell, ident_lines, num_cell, ident_line_nums)
{
parse_ident_usermap(lfirst(line_cell), lfirst_int(num_cell),
- usermap_name, pg_user, ident_user,
+ usermap_name, pg_role, ident_user,
&found_entry, &error);
if (found_entry || error)
break;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index b6885f0d149..ce16d2eba18 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.309 2005/06/26 22:05:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.310 2005/06/28 05:08:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1761,8 +1761,7 @@ _copyPrivGrantee(PrivGrantee *from)
{
PrivGrantee *newnode = makeNode(PrivGrantee);
- COPY_STRING_FIELD(username);
- COPY_STRING_FIELD(groupname);
+ COPY_STRING_FIELD(rolname);
return newnode;
}
@@ -1778,6 +1777,21 @@ _copyFuncWithArgs(FuncWithArgs *from)
return newnode;
}
+static GrantRoleStmt *
+_copyGrantRoleStmt(GrantRoleStmt *from)
+{
+ GrantRoleStmt *newnode = makeNode(GrantRoleStmt);
+
+ COPY_NODE_FIELD(granted_roles);
+ COPY_NODE_FIELD(grantee_roles);
+ COPY_SCALAR_FIELD(is_grant);
+ COPY_SCALAR_FIELD(admin_opt);
+ COPY_STRING_FIELD(grantor);
+ COPY_SCALAR_FIELD(behavior);
+
+ return newnode;
+}
+
static DeclareCursorStmt *
_copyDeclareCursorStmt(DeclareCursorStmt *from)
{
@@ -2374,46 +2388,47 @@ _copyDropPLangStmt(DropPLangStmt *from)
return newnode;
}
-static CreateUserStmt *
-_copyCreateUserStmt(CreateUserStmt *from)
+static CreateRoleStmt *
+_copyCreateRoleStmt(CreateRoleStmt *from)
{
- CreateUserStmt *newnode = makeNode(CreateUserStmt);
+ CreateRoleStmt *newnode = makeNode(CreateRoleStmt);
- COPY_STRING_FIELD(user);
+ COPY_STRING_FIELD(role);
COPY_NODE_FIELD(options);
return newnode;
}
-static AlterUserStmt *
-_copyAlterUserStmt(AlterUserStmt *from)
+static AlterRoleStmt *
+_copyAlterRoleStmt(AlterRoleStmt *from)
{
- AlterUserStmt *newnode = makeNode(AlterUserStmt);
+ AlterRoleStmt *newnode = makeNode(AlterRoleStmt);
- COPY_STRING_FIELD(user);
+ COPY_STRING_FIELD(role);
COPY_NODE_FIELD(options);
+ COPY_SCALAR_FIELD(action);
return newnode;
}
-static AlterUserSetStmt *
-_copyAlterUserSetStmt(AlterUserSetStmt *from)
+static AlterRoleSetStmt *
+_copyAlterRoleSetStmt(AlterRoleSetStmt *from)
{
- AlterUserSetStmt *newnode = makeNode(AlterUserSetStmt);
+ AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
- COPY_STRING_FIELD(user);
+ COPY_STRING_FIELD(role);
COPY_STRING_FIELD(variable);
COPY_NODE_FIELD(value);
return newnode;
}
-static DropUserStmt *
-_copyDropUserStmt(DropUserStmt *from)
+static DropRoleStmt *
+_copyDropRoleStmt(DropRoleStmt *from)
{
- DropUserStmt *newnode = makeNode(DropUserStmt);
+ DropRoleStmt *newnode = makeNode(DropRoleStmt);
- COPY_NODE_FIELD(users);
+ COPY_NODE_FIELD(roles);
return newnode;
}
@@ -2441,39 +2456,6 @@ _copyConstraintsSetStmt(ConstraintsSetStmt *from)
return newnode;
}
-static CreateGroupStmt *
-_copyCreateGroupStmt(CreateGroupStmt *from)
-{
- CreateGroupStmt *newnode = makeNode(CreateGroupStmt);
-
- COPY_STRING_FIELD(name);
- COPY_NODE_FIELD(options);
-
- return newnode;
-}
-
-static AlterGroupStmt *
-_copyAlterGroupStmt(AlterGroupStmt *from)
-{
- AlterGroupStmt *newnode = makeNode(AlterGroupStmt);
-
- COPY_STRING_FIELD(name);
- COPY_SCALAR_FIELD(action);
- COPY_NODE_FIELD(listUsers);
-
- return newnode;
-}
-
-static DropGroupStmt *
-_copyDropGroupStmt(DropGroupStmt *from)
-{
- DropGroupStmt *newnode = makeNode(DropGroupStmt);
-
- COPY_STRING_FIELD(name);
-
- return newnode;
-}
-
static ReindexStmt *
_copyReindexStmt(ReindexStmt *from)
{
@@ -2927,6 +2909,9 @@ copyObject(void *from)
case T_GrantStmt:
retval = _copyGrantStmt(from);
break;
+ case T_GrantRoleStmt:
+ retval = _copyGrantRoleStmt(from);
+ break;
case T_DeclareCursorStmt:
retval = _copyDeclareCursorStmt(from);
break;
@@ -3071,17 +3056,17 @@ copyObject(void *from)
case T_DropPLangStmt:
retval = _copyDropPLangStmt(from);
break;
- case T_CreateUserStmt:
- retval = _copyCreateUserStmt(from);
+ case T_CreateRoleStmt:
+ retval = _copyCreateRoleStmt(from);
break;
- case T_AlterUserStmt:
- retval = _copyAlterUserStmt(from);
+ case T_AlterRoleStmt:
+ retval = _copyAlterRoleStmt(from);
break;
- case T_AlterUserSetStmt:
- retval = _copyAlterUserSetStmt(from);
+ case T_AlterRoleSetStmt:
+ retval = _copyAlterRoleSetStmt(from);
break;
- case T_DropUserStmt:
- retval = _copyDropUserStmt(from);
+ case T_DropRoleStmt:
+ retval = _copyDropRoleStmt(from);
break;
case T_LockStmt:
retval = _copyLockStmt(from);
@@ -3089,15 +3074,6 @@ copyObject(void *from)
case T_ConstraintsSetStmt:
retval = _copyConstraintsSetStmt(from);
break;
- case T_CreateGroupStmt:
- retval = _copyCreateGroupStmt(from);
- break;
- case T_AlterGroupStmt:
- retval = _copyAlterGroupStmt(from);
- break;
- case T_DropGroupStmt:
- retval = _copyDropGroupStmt(from);
- break;
case T_ReindexStmt:
retval = _copyReindexStmt(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 31a2c302244..ade4f16a090 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.246 2005/06/26 22:05:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.247 2005/06/28 05:08:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -778,8 +778,7 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b)
static bool
_equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
{
- COMPARE_STRING_FIELD(username);
- COMPARE_STRING_FIELD(groupname);
+ COMPARE_STRING_FIELD(rolname);
return true;
}
@@ -794,6 +793,19 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
}
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)
{
COMPARE_STRING_FIELD(portalname);
@@ -1295,27 +1307,28 @@ _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
}
static bool
-_equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b)
+_equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
{
- COMPARE_STRING_FIELD(user);
+ COMPARE_STRING_FIELD(role);
COMPARE_NODE_FIELD(options);
return true;
}
static bool
-_equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b)
+_equalAlterRoleStmt(AlterRoleStmt *a, AlterRoleStmt *b)
{
- COMPARE_STRING_FIELD(user);
+ COMPARE_STRING_FIELD(role);
COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(action);
return true;
}
static bool
-_equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
+_equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b)
{
- COMPARE_STRING_FIELD(user);
+ COMPARE_STRING_FIELD(role);
COMPARE_STRING_FIELD(variable);
COMPARE_NODE_FIELD(value);
@@ -1323,9 +1336,9 @@ _equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
}
static bool
-_equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
+_equalDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b)
{
- COMPARE_NODE_FIELD(users);
+ COMPARE_NODE_FIELD(roles);
return true;
}
@@ -1350,33 +1363,6 @@ _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
}
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)
{
COMPARE_SCALAR_FIELD(kind);
@@ -1971,6 +1957,9 @@ equal(void *a, void *b)
case T_GrantStmt:
retval = _equalGrantStmt(a, b);
break;
+ case T_GrantRoleStmt:
+ retval = _equalGrantRoleStmt(a, b);
+ break;
case T_DeclareCursorStmt:
retval = _equalDeclareCursorStmt(a, b);
break;
@@ -2115,17 +2104,17 @@ equal(void *a, void *b)
case T_DropPLangStmt:
retval = _equalDropPLangStmt(a, b);
break;
- case T_CreateUserStmt:
- retval = _equalCreateUserStmt(a, b);
+ case T_CreateRoleStmt:
+ retval = _equalCreateRoleStmt(a, b);
break;
- case T_AlterUserStmt:
- retval = _equalAlterUserStmt(a, b);
+ case T_AlterRoleStmt:
+ retval = _equalAlterRoleStmt(a, b);
break;
- case T_AlterUserSetStmt:
- retval = _equalAlterUserSetStmt(a, b);
+ case T_AlterRoleSetStmt:
+ retval = _equalAlterRoleSetStmt(a, b);
break;
- case T_DropUserStmt:
- retval = _equalDropUserStmt(a, b);
+ case T_DropRoleStmt:
+ retval = _equalDropRoleStmt(a, b);
break;
case T_LockStmt:
retval = _equalLockStmt(a, b);
@@ -2133,15 +2122,6 @@ equal(void *a, void *b)
case T_ConstraintsSetStmt:
retval = _equalConstraintsSetStmt(a, b);
break;
- case T_CreateGroupStmt:
- retval = _equalCreateGroupStmt(a, b);
- break;
- case T_AlterGroupStmt:
- retval = _equalAlterGroupStmt(a, b);
- break;
- case T_DropGroupStmt:
- retval = _equalDropGroupStmt(a, b);
- break;
case T_ReindexStmt:
retval = _equalReindexStmt(a, b);
break;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 91705123bd7..81fb9c88fa6 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.256 2005/06/26 22:05:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.257 2005/06/28 05:08:57 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1535,7 +1535,7 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node)
WRITE_BOOL_FIELD(inh);
WRITE_BOOL_FIELD(inFromCl);
WRITE_UINT_FIELD(requiredPerms);
- WRITE_UINT_FIELD(checkAsUser);
+ WRITE_OID_FIELD(checkAsUser);
}
static void
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 9b27dc478ef..2e9c842051a 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.179 2005/06/26 22:05:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.180 2005/06/28 05:08:57 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
@@ -917,7 +917,7 @@ _readRangeTblEntry(void)
READ_BOOL_FIELD(inh);
READ_BOOL_FIELD(inFromCl);
READ_UINT_FIELD(requiredPerms);
- READ_UINT_FIELD(checkAsUser);
+ READ_OID_FIELD(checkAsUser);
READ_DONE();
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 28e1ac0264d..d822a7176a7 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.498 2005/06/26 22:05:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.499 2005/06/28 05:08:57 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -133,19 +133,20 @@ static void doNegateFloat(Value *v);
%type <node> stmt schema_stmt
AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt AlterOwnerStmt
AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserSetStmt
+ AlterRoleStmt AlterRoleSetStmt
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
- CreateAssertStmt CreateTrigStmt CreateUserStmt
+ CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt
- DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt
+ DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
- GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
+ GrantRoleStmt GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
- RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt
+ RemoveFuncStmt RemoveOperStmt RenameStmt RevokeRoleStmt RevokeStmt
RuleActionStmt RuleActionStmtOrEmpty RuleStmt
SelectStmt TransactionStmt TruncateStmt
UnlistenStmt UpdateStmt VacuumStmt
@@ -170,17 +171,16 @@ static void doNegateFloat(Value *v);
%type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace
opt_grant_grant_option opt_revoke_grant_option
+ opt_alter_admin_option
+ opt_grant_admin_option opt_revoke_admin_option
opt_nowait
%type <boolean> like_including_defaults
-%type <list> user_list
+%type <list> role_list
-%type <list> OptGroupList
-%type <defelt> OptGroupElem
-
-%type <list> OptUserList
-%type <defelt> OptUserElem
+%type <list> OptRoleList
+%type <defelt> OptRoleElem
%type <str> OptSchemaName
%type <list> OptSchemaEltList
@@ -308,7 +308,7 @@ static void doNegateFloat(Value *v);
%type <ival> Iconst
%type <str> Sconst comment_text
-%type <str> UserId opt_boolean ColId_or_Sconst
+%type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst
%type <list> var_list var_list_or_default
%type <str> ColId ColLabel var_name type_name param_name
%type <node> var_value zone_value
@@ -336,7 +336,7 @@ static void doNegateFloat(Value *v);
*/
/* ordinary key words in alphabetical order */
-%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER
+%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD ADMIN AFTER
AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
@@ -347,8 +347,8 @@ static void doNegateFloat(Value *v);
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
- CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME
- CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
+ CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME
+ CURRENT_TIMESTAMP CURRENT_ROLE CURRENT_USER CURSOR CYCLE
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
@@ -360,7 +360,7 @@ static void doNegateFloat(Value *v);
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
FREEZE FROM FULL FUNCTION
- GLOBAL GRANT GREATEST GROUP_P
+ GLOBAL GRANT GRANTED GREATEST GROUP_P
HANDLER HAVING HEADER HOLD HOUR_P
@@ -375,13 +375,13 @@ static void doNegateFloat(Value *v);
LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
- LOCK_P
+ LOCK_P LOGIN
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
- NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P
- NULLIF NUMERIC
+ NOCREATEROLE NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P
+ NULLIF NUMERIC NOLOGIN
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER
@@ -394,10 +394,10 @@ static void doNegateFloat(Value *v);
READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT
- ROLLBACK ROW ROWS RULE
+ ROLE ROLLBACK ROW ROWS RULE
SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
- SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
+ SERIALIZABLE SESSION SESSION_ROLE SESSION_USER SET SETOF SHARE
SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYMMETRIC
SYSID SYSTEM_P
@@ -497,6 +497,8 @@ stmt :
| AlterOwnerStmt
| AlterSeqStmt
| AlterTableStmt
+ | AlterRoleSetStmt
+ | AlterRoleStmt
| AlterUserSetStmt
| AlterUserStmt
| AnalyzeStmt
@@ -520,6 +522,7 @@ stmt :
| CreateStmt
| CreateTableSpaceStmt
| CreateTrigStmt
+ | CreateRoleStmt
| CreateUserStmt
| CreatedbStmt
| DeallocateStmt
@@ -535,11 +538,13 @@ stmt :
| DropStmt
| DropTableSpaceStmt
| DropTrigStmt
+ | DropRoleStmt
| DropUserStmt
| DropdbStmt
| ExecuteStmt
| ExplainStmt
| FetchStmt
+ | GrantRoleStmt
| GrantStmt
| IndexStmt
| InsertStmt
@@ -553,6 +558,7 @@ stmt :
| RemoveFuncStmt
| RemoveOperStmt
| RenameStmt
+ | RevokeRoleStmt
| RevokeStmt
| RuleStmt
| SelectStmt
@@ -571,16 +577,16 @@ stmt :
/*****************************************************************************
*
- * Create a new Postgres DBMS user
+ * Create a new Postgres DBMS role
*
*
*****************************************************************************/
-CreateUserStmt:
- CREATE USER UserId opt_with OptUserList
+CreateRoleStmt:
+ CREATE ROLE RoleId opt_with OptRoleList
{
- CreateUserStmt *n = makeNode(CreateUserStmt);
- n->user = $3;
+ CreateRoleStmt *n = makeNode(CreateRoleStmt);
+ n->role = $3;
n->options = $5;
$$ = (Node *)n;
}
@@ -593,16 +599,90 @@ opt_with: WITH {}
/*****************************************************************************
*
+ * 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 OptUserList
+ ALTER USER RoleId opt_with OptRoleList
{
- AlterUserStmt *n = makeNode(AlterUserStmt);
- n->user = $3;
+ AlterRoleStmt *n = makeNode(AlterRoleStmt);
+ n->role = $3;
n->options = $5;
$$ = (Node *)n;
}
@@ -610,18 +690,18 @@ AlterUserStmt:
AlterUserSetStmt:
- ALTER USER UserId SET set_rest
+ ALTER USER RoleId SET set_rest
{
- AlterUserSetStmt *n = makeNode(AlterUserSetStmt);
- n->user = $3;
+ AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
+ n->role = $3;
n->variable = $5->name;
n->value = $5->args;
$$ = (Node *)n;
}
- | ALTER USER UserId VariableResetStmt
+ | ALTER USER RoleId VariableResetStmt
{
- AlterUserSetStmt *n = makeNode(AlterUserSetStmt);
- n->user = $3;
+ AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
+ n->role = $3;
n->variable = ((VariableResetStmt *)$4)->name;
n->value = NIL;
$$ = (Node *)n;
@@ -631,6 +711,24 @@ AlterUserSetStmt:
/*****************************************************************************
*
+ * Drop a postgresql DBMS role
+ *
+ * XXX Ideally this would have CASCADE/RESTRICT options, but since a role
+ * might own objects in multiple databases, there is presently no way to
+ * implement either cascading or restricting. Caveat DBA.
+ *****************************************************************************/
+
+DropRoleStmt:
+ DROP ROLE role_list
+ {
+ DropRoleStmt *n = makeNode(DropRoleStmt);
+ n->roles = $3;
+ $$ = (Node *)n;
+ }
+ ;
+
+/*****************************************************************************
+ *
* Drop a postgresql DBMS user
*
* XXX Ideally this would have CASCADE/RESTRICT options, but since a user
@@ -639,23 +737,23 @@ AlterUserSetStmt:
*****************************************************************************/
DropUserStmt:
- DROP USER user_list
+ DROP USER role_list
{
- DropUserStmt *n = makeNode(DropUserStmt);
- n->users = $3;
+ DropRoleStmt *n = makeNode(DropRoleStmt);
+ n->roles = $3;
$$ = (Node *)n;
}
;
/*
- * Options for CREATE USER and ALTER USER
+ * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER for backwards compat)
*/
-OptUserList:
- OptUserList OptUserElem { $$ = lappend($1, $2); }
+OptRoleList:
+ OptRoleList OptRoleElem { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NIL; }
;
-OptUserElem:
+OptRoleElem:
PASSWORD Sconst
{
$$ = makeDefElem("password", (Node *)makeString($2));
@@ -680,66 +778,75 @@ OptUserElem:
{
$$ = makeDefElem("createdb", (Node *)makeInteger(FALSE));
}
+ | CREATEROLE
+ {
+ $$ = makeDefElem("createrole", (Node *)makeInteger(TRUE));
+ }
| CREATEUSER
{
- $$ = makeDefElem("createuser", (Node *)makeInteger(TRUE));
+ $$ = makeDefElem("createrole", (Node *)makeInteger(TRUE));
+ }
+ | LOGIN
+ {
+ $$ = makeDefElem("canlogin", (Node *)makeInteger(TRUE));
+ }
+ | NOCREATEROLE
+ {
+ $$ = makeDefElem("createrole", (Node *)makeInteger(FALSE));
}
| NOCREATEUSER
{
- $$ = makeDefElem("createuser", (Node *)makeInteger(FALSE));
+ $$ = makeDefElem("createrole", (Node *)makeInteger(FALSE));
}
- | IN_P GROUP_P user_list
+ | NOLOGIN
{
- $$ = makeDefElem("groupElts", (Node *)$3);
+ $$ = makeDefElem("canlogin", (Node *)makeInteger(FALSE));
+ }
+ | IN_P ROLE role_list
+ {
+ $$ = makeDefElem("roleElts", (Node *)$3);
+ }
+ | IN_P GROUP_P role_list
+ {
+ $$ = makeDefElem("roleElts", (Node *)$3);
}
| VALID UNTIL Sconst
{
$$ = makeDefElem("validUntil", (Node *)makeString($3));
}
+ | ROLE role_list
+ {
+ $$ = makeDefElem("rolememElts", (Node *)$2);
+ }
+ | USER role_list
+ {
+ $$ = makeDefElem("rolememElts", (Node *)$2);
+ }
;
-user_list: user_list ',' UserId { $$ = lappend($1, makeString($3)); }
- | UserId { $$ = list_make1(makeString($1)); }
+role_list: role_list ',' RoleId { $$ = lappend($1, makeString($3)); }
+ | RoleId { $$ = list_make1(makeString($1)); }
;
/*****************************************************************************
*
- * Create a postgresql group
+ * Create a postgresql group (role without login ability)
*
*
*****************************************************************************/
CreateGroupStmt:
- CREATE GROUP_P UserId opt_with OptGroupList
+ CREATE GROUP_P RoleId opt_with OptRoleList
{
- CreateGroupStmt *n = makeNode(CreateGroupStmt);
- n->name = $3;
+ CreateRoleStmt *n = makeNode(CreateRoleStmt);
+ n->role = $3;
n->options = $5;
$$ = (Node *)n;
}
;
-/*
- * Options for CREATE GROUP
- */
-OptGroupList:
- OptGroupList OptGroupElem { $$ = lappend($1, $2); }
- | /* EMPTY */ { $$ = NIL; }
- ;
-
-OptGroupElem:
- USER user_list
- {
- $$ = makeDefElem("userElts", (Node *)$2);
- }
- | SYSID Iconst
- {
- $$ = makeDefElem("sysid", (Node *)makeInteger($2));
- }
- ;
-
/*****************************************************************************
*
@@ -749,20 +856,16 @@ OptGroupElem:
*****************************************************************************/
AlterGroupStmt:
- ALTER GROUP_P UserId add_drop USER user_list
+ ALTER GROUP_P RoleId add_drop USER role_list
{
- AlterGroupStmt *n = makeNode(AlterGroupStmt);
- n->name = $3;
+ AlterRoleStmt *n = makeNode(AlterRoleStmt);
+ n->role = $3;
n->action = $4;
- n->listUsers = $6;
+ n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6));
$$ = (Node *)n;
}
;
-add_drop: ADD { $$ = +1; }
- | DROP { $$ = -1; }
- ;
-
/*****************************************************************************
*
@@ -772,10 +875,10 @@ add_drop: ADD { $$ = +1; }
*****************************************************************************/
DropGroupStmt:
- DROP GROUP_P UserId
+ DROP GROUP_P role_list
{
- DropGroupStmt *n = makeNode(DropGroupStmt);
- n->name = $3;
+ DropRoleStmt *n = makeNode(DropRoleStmt);
+ n->roles = $3;
$$ = (Node *)n;
}
;
@@ -788,7 +891,7 @@ DropGroupStmt:
*****************************************************************************/
CreateSchemaStmt:
- CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList
+ CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
{
CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* One can omit the schema name or the authorization id. */
@@ -1307,8 +1410,8 @@ alter_rel_cmds:
/* Subcommands that are for ALTER TABLE or ALTER INDEX */
alter_rel_cmd:
- /* ALTER [TABLE|INDEX] <name> OWNER TO UserId */
- OWNER TO UserId
+ /* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
+ OWNER TO RoleId
{
AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_ChangeOwner;
@@ -3015,6 +3118,36 @@ from_in: FROM {}
/*****************************************************************************
*
+ * GRANT and REVOKE ROLE statements
+ *
+ *****************************************************************************/
+
+GrantRoleStmt: GRANT ROLE role_list TO role_list opt_grant_admin_option
+ opt_granted_by
+ {
+ GrantRoleStmt *n = makeNode(GrantRoleStmt);
+ n->granted_roles = $3;
+ n->grantee_roles = $5;
+ n->is_grant = true;
+ n->admin_opt = $6;
+ n->grantor = $7;
+ $$ = (Node*)n;
+ }
+
+RevokeRoleStmt: REVOKE ROLE opt_revoke_admin_option role_list FROM role_list
+ opt_drop_behavior
+ {
+ GrantRoleStmt *n = makeNode(GrantRoleStmt);
+ n->granted_roles = $4;
+ n->grantee_roles = $6;
+ n->is_grant = false;
+ n->admin_opt = $3;
+ n->behavior = $7;
+ $$ = (Node*)n;
+ }
+
+/*****************************************************************************
+ *
* GRANT and REVOKE statements
*
*****************************************************************************/
@@ -3139,26 +3272,24 @@ grantee_list:
| grantee_list ',' grantee { $$ = lappend($1, $3); }
;
-grantee: ColId
+grantee: RoleId
{
PrivGrantee *n = makeNode(PrivGrantee);
/* This hack lets us avoid reserving PUBLIC as a keyword*/
if (strcmp($1, "public") == 0)
- n->username = NULL;
+ n->rolname = NULL;
else
- n->username = $1;
- n->groupname = NULL;
+ n->rolname = $1;
$$ = (Node *)n;
}
- | GROUP_P ColId
+ | GROUP_P RoleId
{
PrivGrantee *n = makeNode(PrivGrantee);
/* Treat GROUP PUBLIC as a synonym for PUBLIC */
if (strcmp($2, "public") == 0)
- n->groupname = NULL;
+ n->rolname = NULL;
else
- n->groupname = $2;
- n->username = NULL;
+ n->rolname = $2;
$$ = (Node *)n;
}
;
@@ -3169,11 +3300,26 @@ opt_grant_grant_option:
| /*EMPTY*/ { $$ = FALSE; }
;
+opt_grant_admin_option:
+ WITH ADMIN OPTION { $$ = TRUE; }
+ | /*EMPTY*/ { $$ = FALSE; }
+ ;
+
+opt_granted_by:
+ GRANTED BY RoleId { $$ = $3; }
+ | /*EMPTY*/ { $$ = NULL; }
+ ;
+
opt_revoke_grant_option:
GRANT OPTION FOR { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
+opt_revoke_admin_option:
+ ADMIN OPTION FOR { $$ = TRUE; }
+ | /*EMPTY*/ { $$ = FALSE; }
+ ;
+
function_with_argtypes_list:
function_with_argtypes { $$ = list_make1($1); }
@@ -3727,10 +3873,10 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
n->newname = $7;
$$ = (Node *)n;
}
- | ALTER GROUP_P UserId RENAME TO UserId
+ | ALTER GROUP_P RoleId RENAME TO RoleId
{
RenameStmt *n = makeNode(RenameStmt);
- n->renameType = OBJECT_GROUP;
+ n->renameType = OBJECT_ROLE;
n->subname = $3;
n->newname = $6;
$$ = (Node *)n;
@@ -3796,10 +3942,18 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
n->renameType = OBJECT_TRIGGER;
$$ = (Node *)n;
}
- | ALTER USER UserId RENAME TO UserId
+ | ALTER ROLE RoleId RENAME TO RoleId
{
RenameStmt *n = makeNode(RenameStmt);
- n->renameType = OBJECT_USER;
+ n->renameType = OBJECT_ROLE;
+ n->subname = $3;
+ n->newname = $6;
+ $$ = (Node *)n;
+ }
+ | ALTER USER RoleId RENAME TO RoleId
+ {
+ RenameStmt *n = makeNode(RenameStmt);
+ n->renameType = OBJECT_ROLE;
n->subname = $3;
n->newname = $6;
$$ = (Node *)n;
@@ -3825,7 +3979,7 @@ opt_column: COLUMN { $$ = COLUMN; }
*
*****************************************************************************/
-AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
+AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_AGGREGATE;
@@ -3834,7 +3988,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER CONVERSION_P any_name OWNER TO UserId
+ | ALTER CONVERSION_P any_name OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_CONVERSION;
@@ -3842,7 +3996,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER DATABASE database_name OWNER TO UserId
+ | ALTER DATABASE database_name OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DATABASE;
@@ -3850,7 +4004,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER DOMAIN_P any_name OWNER TO UserId
+ | ALTER DOMAIN_P any_name OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DOMAIN;
@@ -3858,7 +4012,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER FUNCTION func_name func_args OWNER TO UserId
+ | ALTER FUNCTION func_name func_args OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_FUNCTION;
@@ -3867,7 +4021,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $7;
$$ = (Node *)n;
}
- | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO UserId
+ | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPERATOR;
@@ -3876,7 +4030,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER OPERATOR CLASS any_name USING access_method OWNER TO UserId
+ | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS;
@@ -3885,7 +4039,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $9;
$$ = (Node *)n;
}
- | ALTER SCHEMA name OWNER TO UserId
+ | ALTER SCHEMA name OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_SCHEMA;
@@ -3893,7 +4047,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER TYPE_P any_name OWNER TO UserId
+ | ALTER TYPE_P any_name OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TYPE;
@@ -3901,7 +4055,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6;
$$ = (Node *)n;
}
- | ALTER TABLESPACE name OWNER TO UserId
+ | ALTER TABLESPACE name OWNER TO RoleId
{
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TABLESPACE;
@@ -6903,6 +7057,33 @@ func_expr: func_name '(' ')'
$$ = (Node *)makeTypeCast((Node *)s, d);
}
+ | CURRENT_ROLE
+ {
+ FuncCall *n = makeNode(FuncCall);
+ n->funcname = SystemFuncName("current_user");
+ n->args = NIL;
+ n->agg_star = FALSE;
+ n->agg_distinct = FALSE;
+ $$ = (Node *)n;
+ }
+ | SESSION_ROLE
+ {
+ FuncCall *n = makeNode(FuncCall);
+ n->funcname = SystemFuncName("session_user");
+ n->args = NIL;
+ n->agg_star = FALSE;
+ n->agg_distinct = FALSE;
+ $$ = (Node *)n;
+ }
+ | ROLE
+ {
+ FuncCall *n = makeNode(FuncCall);
+ n->funcname = SystemFuncName("current_user");
+ n->args = NIL;
+ n->agg_star = FALSE;
+ n->agg_distinct = FALSE;
+ $$ = (Node *)n;
+ }
| CURRENT_USER
{
FuncCall *n = makeNode(FuncCall);
@@ -7685,7 +7866,7 @@ AexprConst: Iconst
Iconst: ICONST { $$ = $1; };
Sconst: SCONST { $$ = $1; };
-UserId: ColId { $$ = $1; };
+RoleId: ColId { $$ = $1; };
/*
* Name classification hierarchy.
@@ -7774,6 +7955,7 @@ unreserved_keyword:
| CONVERSION_P
| COPY
| CREATEDB
+ | CREATEROLE
| CREATEUSER
| CSV
| CURSOR
@@ -7834,6 +8016,7 @@ unreserved_keyword:
| LOCAL
| LOCATION
| LOCK_P
+ | LOGIN
| MATCH
| MAXVALUE
| MINUTE_P
@@ -7845,7 +8028,9 @@ unreserved_keyword:
| NEXT
| NO
| NOCREATEDB
+ | NOCREATEROLE
| NOCREATEUSER
+ | NOLOGIN
| NOTHING
| NOTIFY
| NOWAIT
@@ -8045,6 +8230,7 @@ reserved_keyword:
| CURRENT_DATE
| CURRENT_TIME
| CURRENT_TIMESTAMP
+ | CURRENT_ROLE
| CURRENT_USER
| DEFAULT
| DEFERRABLE
@@ -8083,6 +8269,7 @@ reserved_keyword:
| PRIMARY
| REFERENCES
| SELECT
+ | SESSION_ROLE
| SESSION_USER
| SOME
| SYMMETRIC
@@ -8093,6 +8280,7 @@ reserved_keyword:
| TRUE_P
| UNION
| UNIQUE
+ | ROLE
| USER
| USING
| WHEN
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 41e45bc7475..a11d4affc1d 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.159 2005/06/26 22:05:39 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.160 2005/06/28 05:08:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -269,6 +269,7 @@ static const ScanKeyword ScanKeywords[] = {
{"returns", RETURNS},
{"revoke", REVOKE},
{"right", RIGHT},
+ {"role", ROLE},
{"rollback", ROLLBACK},
{"row", ROW},
{"rows", ROWS},
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 5786ac44d07..51d200736b0 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.111 2005/06/05 00:38:09 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.112 2005/06/28 05:08:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -567,7 +567,7 @@ addRangeTableEntry(ParseState *pstate,
rte->inFromCl = inFromCl;
rte->requiredPerms = ACL_SELECT;
- rte->checkAsUser = 0; /* not set-uid by default, either */
+ rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
/*
* Add completed RTE to pstate's range table list, but not to join
@@ -620,7 +620,7 @@ addRangeTableEntryForRelation(ParseState *pstate,
rte->inFromCl = inFromCl;
rte->requiredPerms = ACL_SELECT;
- rte->checkAsUser = 0; /* not set-uid by default, either */
+ rte->checkAsUser = InvalidOid; /* not set-uid by default, either */
/*
* Add completed RTE to pstate's range table list, but not to join
@@ -698,7 +698,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
rte->inFromCl = inFromCl;
rte->requiredPerms = 0;
- rte->checkAsUser = 0;
+ rte->checkAsUser = InvalidOid;
/*
* Add completed RTE to pstate's range table list, but not to join
@@ -823,7 +823,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
rte->inFromCl = inFromCl;
rte->requiredPerms = 0;
- rte->checkAsUser = 0;
+ rte->checkAsUser = InvalidOid;
/*
* Add completed RTE to pstate's range table list, but not to join
@@ -882,7 +882,7 @@ addRangeTableEntryForJoin(ParseState *pstate,
rte->inFromCl = inFromCl;
rte->requiredPerms = 0;
- rte->checkAsUser = 0;
+ rte->checkAsUser = InvalidOid;
/*
* Add completed RTE to pstate's range table list, but not to join
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 8366bdb8b4c..b429275d9f6 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.96 2005/06/25 23:58:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.97 2005/06/28 05:08:59 tgl Exp $
* ----------
*/
#include "postgres.h"
@@ -34,7 +34,6 @@
#include "access/heapam.h"
#include "access/xact.h"
#include "catalog/pg_database.h"
-#include "catalog/pg_shadow.h"
#include "libpq/libpq.h"
#include "libpq/pqsignal.h"
#include "mb/pg_wchar.h"
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 6ca13944f8a..27b28b89f54 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.454 2005/06/17 22:32:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.455 2005/06/28 05:08:59 tgl Exp $
*
* NOTES
*
@@ -2032,12 +2032,11 @@ reaper(SIGNAL_ARGS)
FatalError = false;
/*
- * Load the flat user/group files into postmaster's caches.
- * The startup process has recomputed these from the database
- * contents, so we wait till it finishes before loading them.
+ * Load the flat authorization file into postmaster's cache.
+ * The startup process has recomputed this from the database
+ * contents, so we wait till it finishes before loading it.
*/
- load_user();
- load_group();
+ load_role();
/*
* Crank up the background writer. It doesn't matter if this
@@ -2664,8 +2663,7 @@ BackendRun(Port *port)
load_hba();
load_ident();
- load_user();
- load_group();
+ load_role();
#endif
/*
@@ -3290,10 +3288,9 @@ sigusr1_handler(SIGNAL_ARGS)
if (CheckPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE))
{
/*
- * Password or group file has changed.
+ * Authorization file has changed.
*/
- load_user();
- load_group();
+ load_role();
}
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN))
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index c793cabd2a9..c28ea627e50 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.104 2005/04/14 20:03:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.105 2005/06/28 05:08:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -33,9 +33,9 @@
#include "utils/syscache.h"
-static void setRuleCheckAsUser_Query(Query *qry, AclId userid);
-static void setRuleCheckAsUser_Expr(Node *node, AclId userid);
-static bool setRuleCheckAsUser_walker(Node *node, AclId *context);
+static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
+static void setRuleCheckAsUser_Expr(Node *node, Oid userid);
+static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
/*
@@ -505,7 +505,7 @@ DefineQueryRewrite(RuleStmt *stmt)
* them always.
*/
static void
-setRuleCheckAsUser_Query(Query *qry, AclId userid)
+setRuleCheckAsUser_Query(Query *qry, Oid userid)
{
ListCell *l;
@@ -534,13 +534,13 @@ setRuleCheckAsUser_Query(Query *qry, AclId userid)
* Expression-tree walker to find sublink queries
*/
static void
-setRuleCheckAsUser_Expr(Node *node, AclId userid)
+setRuleCheckAsUser_Expr(Node *node, Oid userid)
{
(void) setRuleCheckAsUser_walker(node, &userid);
}
static bool
-setRuleCheckAsUser_walker(Node *node, AclId *context)
+setRuleCheckAsUser_walker(Node *node, Oid *context)
{
if (node == NULL)
return false;
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index b7a96922e94..3677fd2ebac 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.154 2005/06/04 19:19:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.155 2005/06/28 05:08:59 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -945,7 +945,7 @@ ApplyRetrieveRule(Query *parsetree,
subrte->checkAsUser = rte->checkAsUser;
rte->requiredPerms = 0; /* no permission check on subquery itself */
- rte->checkAsUser = 0;
+ rte->checkAsUser = InvalidOid;
/*
* FOR UPDATE/SHARE of view?
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 82bd8eafc11..40d5e7d7ce6 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.238 2005/06/22 21:14:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.239 2005/06/28 05:09:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,7 +20,6 @@
#include "access/twophase.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
-#include "catalog/pg_shadow.h"
#include "commands/alter.h"
#include "commands/async.h"
#include "commands/cluster.h"
@@ -279,12 +278,11 @@ check_xact_readonly(Node *parsetree)
case T_AlterDatabaseSetStmt:
case T_AlterDomainStmt:
case T_AlterFunctionStmt:
- case T_AlterGroupStmt:
+ case T_AlterRoleStmt:
+ case T_AlterRoleSetStmt:
case T_AlterOwnerStmt:
case T_AlterSeqStmt:
case T_AlterTableStmt:
- case T_AlterUserStmt:
- case T_AlterUserSetStmt:
case T_RenameStmt:
case T_CommentStmt:
case T_DefineStmt:
@@ -293,7 +291,7 @@ check_xact_readonly(Node *parsetree)
case T_CreatedbStmt:
case T_CreateDomainStmt:
case T_CreateFunctionStmt:
- case T_CreateGroupStmt:
+ case T_CreateRoleStmt:
case T_IndexStmt:
case T_CreatePLangStmt:
case T_CreateOpClassStmt:
@@ -304,7 +302,6 @@ check_xact_readonly(Node *parsetree)
case T_CreateTableSpaceStmt:
case T_CreateTrigStmt:
case T_CompositeTypeStmt:
- case T_CreateUserStmt:
case T_ViewStmt:
case T_RemoveAggrStmt:
case T_DropCastStmt:
@@ -312,13 +309,13 @@ check_xact_readonly(Node *parsetree)
case T_DropdbStmt:
case T_DropTableSpaceStmt:
case T_RemoveFuncStmt:
- case T_DropGroupStmt:
+ case T_DropRoleStmt:
case T_DropPLangStmt:
case T_RemoveOperStmt:
case T_RemoveOpClassStmt:
case T_DropPropertyStmt:
- case T_DropUserStmt:
case T_GrantStmt:
+ case T_GrantRoleStmt:
case T_TruncateStmt:
ereport(ERROR,
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
@@ -679,11 +676,14 @@ ProcessUtility(Node *parsetree,
}
break;
-
case T_GrantStmt:
ExecuteGrantStmt((GrantStmt *) parsetree);
break;
+ case T_GrantRoleStmt:
+ GrantRole((GrantRoleStmt *) parsetree);
+ break;
+
/*
* ******************************** object creation /
* destruction ********************************
@@ -958,22 +958,22 @@ ProcessUtility(Node *parsetree,
break;
/*
- * ******************************** USER statements ****
+ * ******************************** ROLE statements ****
*/
- case T_CreateUserStmt:
- CreateUser((CreateUserStmt *) parsetree);
+ case T_CreateRoleStmt:
+ CreateRole((CreateRoleStmt *) parsetree);
break;
- case T_AlterUserStmt:
- AlterUser((AlterUserStmt *) parsetree);
+ case T_AlterRoleStmt:
+ AlterRole((AlterRoleStmt *) parsetree);
break;
- case T_AlterUserSetStmt:
- AlterUserSet((AlterUserSetStmt *) parsetree);
+ case T_AlterRoleSetStmt:
+ AlterRoleSet((AlterRoleSetStmt *) parsetree);
break;
- case T_DropUserStmt:
- DropUser((DropUserStmt *) parsetree);
+ case T_DropRoleStmt:
+ DropRole((DropRoleStmt *) parsetree);
break;
case T_LockStmt:
@@ -984,18 +984,6 @@ ProcessUtility(Node *parsetree,
AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
break;
- case T_CreateGroupStmt:
- CreateGroup((CreateGroupStmt *) parsetree);
- break;
-
- case T_AlterGroupStmt:
- AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP");
- break;
-
- case T_DropGroupStmt:
- DropGroup((DropGroupStmt *) parsetree);
- break;
-
case T_CheckPointStmt:
if (!superuser())
ereport(ERROR,
@@ -1350,9 +1338,6 @@ CreateCommandTag(Node *parsetree)
case OBJECT_FUNCTION:
tag = "ALTER FUNCTION";
break;
- case OBJECT_GROUP:
- tag = "ALTER GROUP";
- break;
case OBJECT_INDEX:
tag = "ALTER INDEX";
break;
@@ -1362,6 +1347,9 @@ CreateCommandTag(Node *parsetree)
case OBJECT_OPCLASS:
tag = "ALTER OPERATOR CLASS";
break;
+ case OBJECT_ROLE:
+ tag = "ALTER ROLE";
+ break;
case OBJECT_SCHEMA:
tag = "ALTER SCHEMA";
break;
@@ -1371,9 +1359,6 @@ CreateCommandTag(Node *parsetree)
case OBJECT_TRIGGER:
tag = "ALTER TRIGGER";
break;
- case OBJECT_USER:
- tag = "ALTER USER";
- break;
default:
tag = "ALTER TABLE";
}
@@ -1450,6 +1435,14 @@ CreateCommandTag(Node *parsetree)
}
break;
+ case T_GrantRoleStmt:
+ {
+ GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
+
+ tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
+ }
+ break;
+
case T_DefineStmt:
switch (((DefineStmt *) parsetree)->kind)
{
@@ -1588,20 +1581,20 @@ CreateCommandTag(Node *parsetree)
tag = "DROP LANGUAGE";
break;
- case T_CreateUserStmt:
- tag = "CREATE USER";
+ case T_CreateRoleStmt:
+ tag = "CREATE ROLE";
break;
- case T_AlterUserStmt:
- tag = "ALTER USER";
+ case T_AlterRoleStmt:
+ tag = "ALTER ROLE";
break;
- case T_AlterUserSetStmt:
- tag = "ALTER USER";
+ case T_AlterRoleSetStmt:
+ tag = "ALTER ROLE";
break;
- case T_DropUserStmt:
- tag = "DROP USER";
+ case T_DropRoleStmt:
+ tag = "DROP ROLE";
break;
case T_LockStmt:
@@ -1612,18 +1605,6 @@ CreateCommandTag(Node *parsetree)
tag = "SET CONSTRAINTS";
break;
- case T_CreateGroupStmt:
- tag = "CREATE GROUP";
- break;
-
- case T_AlterGroupStmt:
- tag = "ALTER GROUP";
- break;
-
- case T_DropGroupStmt:
- tag = "DROP GROUP";
- break;
-
case T_CheckPointStmt:
tag = "CHECKPOINT";
break;
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 68b34f3dce5..4d5904b7690 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -8,7 +8,7 @@
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -17,20 +17,33 @@
#include <ctype.h>
#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);
@@ -38,10 +51,9 @@ static Acl *allocacl(int n);
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);
@@ -58,6 +70,9 @@ static AclMode convert_schema_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
@@ -175,7 +190,6 @@ aclparse(const char *s, AclItem *aip)
AclMode privs,
goption,
read;
- uint32 idtype;
char name[NAMEDATALEN];
char name2[NAMEDATALEN];
@@ -184,27 +198,22 @@ aclparse(const char *s, AclItem *aip)
#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,
@@ -263,18 +272,10 @@ aclparse(const char *s, AclItem *aip)
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
@@ -287,23 +288,24 @@ aclparse(const char *s, AclItem *aip)
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_USESYSID;
+ aip->ai_grantor = BOOTSTRAP_SUPERUSERID;
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;
}
@@ -375,7 +377,6 @@ aclitemout(PG_FUNCTION_ARGS)
char *out;
HeapTuple htup;
unsigned i;
- char *tmpname;
out = palloc(strlen("group =/") +
2 * N_ACL_RIGHTS +
@@ -385,41 +386,21 @@ aclitemout(PG_FUNCTION_ARGS)
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;
@@ -437,18 +418,18 @@ aclitemout(PG_FUNCTION_ARGS)
*p++ = '/';
*p = '\0';
- htup = SearchSysCache(SHADOWSYSID,
+ htup = SearchSysCache(AUTHOID,
ObjectIdGetDatum(aip->ai_grantor),
0, 0, 0);
if (HeapTupleIsValid(htup))
{
- putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename));
+ putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname));
ReleaseSysCache(htup);
}
else
{
- /* Generate numeric UID if we don't find an entry */
- sprintf(p, "%d", aip->ai_grantor);
+ /* Generate numeric OID if we don't find an entry */
+ sprintf(p, "%u", aip->ai_grantor);
}
while (*p)
@@ -466,8 +447,7 @@ aclitemout(PG_FUNCTION_ARGS)
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;
}
@@ -511,7 +491,7 @@ hash_aclitem(PG_FUNCTION_ARGS)
* newly-created objects (or any object with a NULL acl entry).
*/
Acl *
-acldefault(GrantObjectType objtype, AclId ownerid)
+acldefault(GrantObjectType objtype, Oid ownerId)
{
AclMode world_default;
AclMode owner_default;
@@ -558,10 +538,9 @@ acldefault(GrantObjectType objtype, AclId ownerid)
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++;
}
@@ -575,10 +554,9 @@ acldefault(GrantObjectType objtype, AclId ownerid)
* 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;
}
@@ -590,7 +568,7 @@ acldefault(GrantObjectType objtype, AclId ownerid)
* 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: AclId of object owner
+ * ownerId: Oid of object owner
* behavior: RESTRICT or CASCADE behavior for recursive removal
*
* ownerid and behavior are only relevant when the update operation specifies
@@ -602,7 +580,7 @@ acldefault(GrantObjectType objtype, AclId ownerid)
*/
Acl *
aclupdate(const Acl *old_acl, const AclItem *mod_aip,
- int modechg, AclId ownerid, DropBehavior behavior)
+ int modechg, Oid ownerId, DropBehavior behavior)
{
Acl *new_acl = NULL;
AclItem *old_aip,
@@ -627,7 +605,7 @@ aclupdate(const Acl *old_acl, const AclItem *mod_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, ownerid);
+ check_circularity(old_acl, mod_aip, ownerId);
num = ACL_NUM(old_acl);
old_aip = ACL_DAT(old_acl);
@@ -661,9 +639,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
/* 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 */
}
@@ -704,14 +681,14 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
/*
* 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),
- ownerid, behavior);
+ ownerId, behavior);
}
return new_acl;
@@ -721,15 +698,15 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip,
* 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: AclId of the old object owner
- * newownerid: AclId of the new object owner
+ * oldOwnerId: Oid of the old object owner
+ * newOwnerId: Oid 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 newownerid)
+aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
{
Acl *new_acl;
AclItem *new_aip;
@@ -755,18 +732,14 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid)
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;
- }
}
/*
@@ -836,7 +809,7 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid)
*/
static void
check_circularity(const Acl *old_acl, const AclItem *mod_aip,
- AclId ownerid)
+ Oid ownerId)
{
Acl *acl;
AclItem *aip;
@@ -845,13 +818,13 @@ check_circularity(const Acl *old_acl, const AclItem *mod_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 == ownerid)
+ if (mod_aip->ai_grantor == ownerId)
return;
/* Make a working copy */
@@ -864,15 +837,14 @@ cc_restart:
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,
- ownerid, DROP_CASCADE);
+ ownerId, DROP_CASCADE);
pfree(acl);
acl = new_acl;
@@ -884,7 +856,7 @@ cc_restart:
/* Now we can compute grantor's independently-derived privileges */
own_privs = aclmask(acl,
mod_aip->ai_grantor,
- ownerid,
+ ownerId,
ACL_GRANT_OPTION_FOR(ACLITEM_GET_GOPTIONS(*mod_aip)),
ACLMASK_ALL);
own_privs = ACL_OPTION_TO_PRIVS(own_privs);
@@ -908,16 +880,16 @@ cc_restart:
* acl: the input ACL list
* grantee: the user from whom some grant options have been revoked
* revoke_privs: the grant options being revoked
- * ownerid: AclId of object owner
+ * ownerId: Oid 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,
- AclId grantee,
+ Oid grantee,
AclMode revoke_privs,
- AclId ownerid,
+ Oid ownerId,
DropBehavior behavior)
{
AclMode still_has;
@@ -926,11 +898,11 @@ recursive_revoke(Acl *acl,
num;
/* The owner can never truly lose grant options, so short-circuit */
- if (grantee == ownerid)
+ if (grantee == ownerId)
return acl;
/* The grantee might still have the privileges via another grantor */
- still_has = aclmask(acl, grantee, ownerid,
+ still_has = aclmask(acl, grantee, ownerId,
ACL_GRANT_OPTION_FOR(revoke_privs),
ACLMASK_ALL);
revoke_privs &= ~still_has;
@@ -956,13 +928,12 @@ restart:
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,
- ownerid, behavior);
+ ownerId, behavior);
pfree(acl);
acl = new_acl;
@@ -976,10 +947,10 @@ restart:
/*
- * aclmask --- compute bitmask of all privileges held by userid.
+ * aclmask --- compute bitmask of all privileges held by roleid.
*
* When 'how' = ACLMASK_ALL, this simply returns the privilege bits
- * held by the given userid according to the given ACL list, ANDed
+ * held by the given roleid 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.)
*
@@ -990,20 +961,20 @@ restart:
* Usage patterns:
*
* To see if any of a set of privileges are held:
- * if (aclmask(acl, userid, ownerid, privs, ACLMASK_ANY) != 0)
+ * if (aclmask(acl, roleid, ownerId, privs, ACLMASK_ANY) != 0)
*
* To see if all of a set of privileges are held:
- * if (aclmask(acl, userid, ownerid, privs, ACLMASK_ALL) == privs)
+ * if (aclmask(acl, roleid, ownerId, 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 ownerid,
+aclmask(const Acl *acl, Oid roleid, Oid ownerId,
AclMode mask, AclMaskHow how)
{
AclMode result;
- AclMode remaining;
AclItem *aidat;
int i,
num;
@@ -1022,7 +993,7 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid,
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)
@@ -1033,39 +1004,19 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid,
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);
}
}
@@ -1074,55 +1025,19 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid,
/*
- * 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);
}
@@ -1162,10 +1077,9 @@ aclcontains(PG_FUNCTION_ARGS)
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);
@@ -1174,51 +1088,22 @@ aclcontains(PG_FUNCTION_ARGS)
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(*aclitem));
+ aclitem = (AclItem *) palloc(sizeof(AclItem));
- 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);
}
@@ -1267,7 +1152,7 @@ convert_priv_string(text *priv_type_text)
* 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.
@@ -1281,19 +1166,20 @@ convert_priv_string(text *priv_type_text)
Datum
has_table_privilege_name_name(PG_FUNCTION_ARGS)
{
- Name username = PG_GETARG_NAME(0);
+ Name rolename = PG_GETARG_NAME(0);
text *tablename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1309,16 +1195,16 @@ has_table_privilege_name(PG_FUNCTION_ARGS)
{
text *tablename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
Oid tableoid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
+ aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1334,14 +1220,15 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
Oid tableoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1357,14 +1244,14 @@ has_table_privilege_id(PG_FUNCTION_ARGS)
{
Oid tableoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
+ aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1372,12 +1259,12 @@ has_table_privilege_id(PG_FUNCTION_ARGS)
/*
* has_table_privilege_id_name
* Check user privileges on a table given
- * usesysid, text tablename, and text priv name.
+ * roleid, 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;
@@ -1387,7 +1274,7 @@ has_table_privilege_id_name(PG_FUNCTION_ARGS)
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
+ aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1395,12 +1282,12 @@ has_table_privilege_id_name(PG_FUNCTION_ARGS)
/*
* has_table_privilege_id_id
* Check user privileges on a table given
- * usesysid, table oid, and text priv name.
+ * roleid, 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;
@@ -1408,7 +1295,7 @@ has_table_privilege_id_id(PG_FUNCTION_ARGS)
mode = convert_table_priv_string(priv_type_text);
- aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
+ aclresult = pg_class_aclcheck(tableoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1491,7 +1378,7 @@ convert_table_priv_string(text *priv_type_text)
* 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.
@@ -1508,16 +1395,17 @@ has_database_privilege_name_name(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
text *databasename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1533,16 +1421,16 @@ has_database_privilege_name(PG_FUNCTION_ARGS)
{
text *databasename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
Oid databaseoid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
+ aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1558,14 +1446,15 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
Oid databaseoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1581,14 +1470,14 @@ has_database_privilege_id(PG_FUNCTION_ARGS)
{
Oid databaseoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
+ aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1596,12 +1485,12 @@ has_database_privilege_id(PG_FUNCTION_ARGS)
/*
* has_database_privilege_id_name
* Check user privileges on a database given
- * usesysid, text databasename, and text priv name.
+ * roleid, 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;
@@ -1611,7 +1500,7 @@ has_database_privilege_id_name(PG_FUNCTION_ARGS)
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
+ aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1619,12 +1508,12 @@ has_database_privilege_id_name(PG_FUNCTION_ARGS)
/*
* has_database_privilege_id_id
* Check user privileges on a database given
- * usesysid, database oid, and text priv name.
+ * roleid, 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;
@@ -1632,7 +1521,7 @@ has_database_privilege_id_id(PG_FUNCTION_ARGS)
mode = convert_database_priv_string(priv_type_text);
- aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
+ aclresult = pg_database_aclcheck(databaseoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1703,7 +1592,7 @@ convert_database_priv_string(text *priv_type_text)
* 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.
@@ -1720,16 +1609,17 @@ has_function_privilege_name_name(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
text *functionname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1745,16 +1635,16 @@ has_function_privilege_name(PG_FUNCTION_ARGS)
{
text *functionname = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
Oid functionoid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
+ aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1770,14 +1660,15 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
Oid functionoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1793,14 +1684,14 @@ has_function_privilege_id(PG_FUNCTION_ARGS)
{
Oid functionoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
+ aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1808,12 +1699,12 @@ has_function_privilege_id(PG_FUNCTION_ARGS)
/*
* has_function_privilege_id_name
* Check user privileges on a function given
- * usesysid, text functionname, and text priv name.
+ * roleid, 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;
@@ -1823,7 +1714,7 @@ has_function_privilege_id_name(PG_FUNCTION_ARGS)
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
+ aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1831,12 +1722,12 @@ has_function_privilege_id_name(PG_FUNCTION_ARGS)
/*
* has_function_privilege_id_id
* Check user privileges on a function given
- * usesysid, function oid, and text priv name.
+ * roleid, 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;
@@ -1844,7 +1735,7 @@ has_function_privilege_id_id(PG_FUNCTION_ARGS)
mode = convert_function_priv_string(priv_type_text);
- aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
+ aclresult = pg_proc_aclcheck(functionoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1907,7 +1798,7 @@ convert_function_priv_string(text *priv_type_text)
* 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.
@@ -1924,16 +1815,17 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
text *languagename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_language_aclcheck(languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1949,16 +1841,16 @@ has_language_privilege_name(PG_FUNCTION_ARGS)
{
text *languagename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
Oid languageoid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
+ aclresult = pg_language_aclcheck(languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1974,14 +1866,15 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
Oid languageoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_language_aclcheck(languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -1997,14 +1890,14 @@ has_language_privilege_id(PG_FUNCTION_ARGS)
{
Oid languageoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
+ aclresult = pg_language_aclcheck(languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2012,12 +1905,12 @@ has_language_privilege_id(PG_FUNCTION_ARGS)
/*
* has_language_privilege_id_name
* Check user privileges on a language given
- * usesysid, text languagename, and text priv name.
+ * roleid, 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;
@@ -2027,7 +1920,7 @@ has_language_privilege_id_name(PG_FUNCTION_ARGS)
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
+ aclresult = pg_language_aclcheck(languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2035,12 +1928,12 @@ has_language_privilege_id_name(PG_FUNCTION_ARGS)
/*
* has_language_privilege_id_id
* Check user privileges on a language given
- * usesysid, language oid, and text priv name.
+ * roleid, 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;
@@ -2048,7 +1941,7 @@ has_language_privilege_id_id(PG_FUNCTION_ARGS)
mode = convert_language_priv_string(priv_type_text);
- aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
+ aclresult = pg_language_aclcheck(languageoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2111,7 +2004,7 @@ convert_language_priv_string(text *priv_type_text)
* 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.
@@ -2128,16 +2021,17 @@ has_schema_privilege_name_name(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
text *schemaname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2153,16 +2047,16 @@ has_schema_privilege_name(PG_FUNCTION_ARGS)
{
text *schemaname = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
Oid schemaoid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2178,14 +2072,15 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
Oid schemaoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2201,14 +2096,14 @@ has_schema_privilege_id(PG_FUNCTION_ARGS)
{
Oid schemaoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2216,12 +2111,12 @@ has_schema_privilege_id(PG_FUNCTION_ARGS)
/*
* has_schema_privilege_id_name
* Check user privileges on a schema given
- * usesysid, text schemaname, and text priv name.
+ * roleid, 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;
@@ -2231,7 +2126,7 @@ has_schema_privilege_id_name(PG_FUNCTION_ARGS)
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2239,12 +2134,12 @@ has_schema_privilege_id_name(PG_FUNCTION_ARGS)
/*
* has_schema_privilege_id_id
* Check user privileges on a schema given
- * usesysid, schema oid, and text priv name.
+ * roleid, 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;
@@ -2252,7 +2147,7 @@ has_schema_privilege_id_id(PG_FUNCTION_ARGS)
mode = convert_schema_priv_string(priv_type_text);
- aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
+ aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2319,7 +2214,7 @@ convert_schema_priv_string(text *priv_type_text)
* 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.
@@ -2336,16 +2231,17 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
text *tablespacename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2361,16 +2257,16 @@ has_tablespace_privilege_name(PG_FUNCTION_ARGS)
{
text *tablespacename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
Oid tablespaceoid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2386,14 +2282,15 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
Name username = PG_GETARG_NAME(0);
Oid tablespaceoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
- int32 usesysid;
+ Oid roleid;
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, usesysid, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2409,14 +2306,14 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS)
{
Oid tablespaceoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
- AclId usesysid;
+ Oid roleid;
AclMode mode;
AclResult aclresult;
- usesysid = GetUserId();
+ roleid = GetUserId();
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2424,12 +2321,12 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS)
/*
* has_tablespace_privilege_id_name
* Check user privileges on a tablespace given
- * usesysid, text tablespacename, and text priv name.
+ * roleid, 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;
@@ -2439,7 +2336,7 @@ has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
tablespaceoid = convert_tablespace_name(tablespacename);
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2447,12 +2344,12 @@ has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
/*
* has_tablespace_privilege_id_id
* Check user privileges on a tablespace given
- * usesysid, tablespace oid, and text priv name.
+ * roleid, 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;
@@ -2460,7 +2357,7 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
mode = convert_tablespace_priv_string(priv_type_text);
- aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode);
+ aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
@@ -2515,3 +2412,110 @@ convert_tablespace_priv_string(text *priv_type_text)
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);
+}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 90c8ea695bb..870513fb9d5 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -8,14 +8,13 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.22 2005/05/11 01:41:41 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.23 2005/06/28 05:09:00 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/xact.h"
-#include "catalog/pg_shadow.h"
#include "fmgr.h"
#include "funcapi.h"
#include "miscadmin.h"
@@ -306,7 +305,7 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
if (!OidIsValid(beentry->userid))
PG_RETURN_NULL();
- PG_RETURN_INT32(beentry->userid);
+ PG_RETURN_OID(beentry->userid);
}
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index a0d561f1f0f..8de31643a68 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -17,7 +17,7 @@
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.79 2005/05/30 07:20:58 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.80 2005/06/28 05:09:00 tgl Exp $
*
* ----------
*/
@@ -3036,7 +3036,7 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes,
{
void *qplan;
Relation query_rel;
- AclId save_uid;
+ Oid save_uid;
/*
* The query is always run against the FK table except when this is an
@@ -3089,7 +3089,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan,
Snapshot crosscheck_snapshot;
int limit;
int spi_result;
- AclId save_uid;
+ Oid save_uid;
Datum vals[RI_MAX_NUMKEYS * 2];
char nulls[RI_MAX_NUMKEYS * 2];
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 0bd1d73eae1..cbebd5495c0 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.201 2005/06/26 22:05:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.202 2005/06/28 05:09:01 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -46,13 +46,13 @@
#include "catalog/index.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_index.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_trigger.h"
#include "executor/spi.h"
#include "funcapi.h"
@@ -1194,17 +1194,17 @@ pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags)
/* ----------
- * get_userbyid - Get a user name by usesysid and
- * fallback to 'unknown (UID=n)'
+ * get_userbyid - Get a user name by roleid and
+ * fallback to 'unknown (OID=n)'
* ----------
*/
Datum
pg_get_userbyid(PG_FUNCTION_ARGS)
{
- int32 uid = PG_GETARG_INT32(0);
+ Oid roleid = PG_GETARG_OID(0);
Name result;
- HeapTuple usertup;
- Form_pg_shadow user_rec;
+ HeapTuple roletup;
+ Form_pg_authid role_rec;
/*
* Allocate space for the result
@@ -1213,19 +1213,19 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
memset(NameStr(*result), 0, NAMEDATALEN);
/*
- * Get the pg_shadow entry and print the result
+ * Get the pg_authid entry and print the result
*/
- usertup = SearchSysCache(SHADOWSYSID,
- ObjectIdGetDatum(uid),
+ roletup = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(roleid),
0, 0, 0);
- if (HeapTupleIsValid(usertup))
+ if (HeapTupleIsValid(roletup))
{
- user_rec = (Form_pg_shadow) GETSTRUCT(usertup);
- StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN);
- ReleaseSysCache(usertup);
+ role_rec = (Form_pg_authid) GETSTRUCT(roletup);
+ StrNCpy(NameStr(*result), NameStr(role_rec->rolname), NAMEDATALEN);
+ ReleaseSysCache(roletup);
}
else
- sprintf(NameStr(*result), "unknown (UID=%d)", uid);
+ sprintf(NameStr(*result), "unknown (OID=%u)", roleid);
PG_RETURN_NAME(result);
}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 5390d94462a..ea10f8c8cd3 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.125 2005/05/01 18:56:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.126 2005/06/28 05:09:01 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@@ -24,8 +24,6 @@
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
-#include "catalog/pg_group.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "nodes/makefuncs.h"
@@ -2010,66 +2008,35 @@ get_namespace_name(Oid nspid)
return NULL;
}
-/* ---------- PG_SHADOW CACHE ---------- */
+/* ---------- PG_AUTHID CACHE ---------- */
/*
- * get_usesysid
- *
- * Given a user name, look up the user's sysid.
- * Raises an error if no such user (rather than returning zero,
- * which might possibly be a valid usesysid).
- *
- * Note: the type of usesysid is currently int4, but may change to Oid
- * someday. It'd be reasonable to return zero on failure if we were
- * using Oid ...
+ * get_roleid
+ * Given a role name, look up the role's OID.
+ * Returns InvalidOid if no such role.
*/
-AclId
-get_usesysid(const char *username)
+Oid
+get_roleid(const char *rolname)
{
- AclId userId;
- HeapTuple userTup;
-
- userTup = SearchSysCache(SHADOWNAME,
- PointerGetDatum(username),
- 0, 0, 0);
- if (!HeapTupleIsValid(userTup))
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", username)));
-
- userId = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
-
- ReleaseSysCache(userTup);
-
- return userId;
+ return GetSysCacheOid(AUTHNAME,
+ PointerGetDatum(rolname),
+ 0, 0, 0);
}
/*
- * get_grosysid
- *
- * Given a group name, look up the group's sysid.
- * Raises an error if no such group (rather than returning zero,
- * which might possibly be a valid grosysid).
- *
+ * get_roleid_checked
+ * Given a role name, look up the role's OID.
+ * ereports if no such role.
*/
-AclId
-get_grosysid(char *groname)
+Oid
+get_roleid_checked(const char *rolname)
{
- AclId groupId;
- HeapTuple groupTup;
+ Oid roleid;
- groupTup = SearchSysCache(GRONAME,
- PointerGetDatum(groname),
- 0, 0, 0);
- if (!HeapTupleIsValid(groupTup))
+ roleid = get_roleid(rolname);
+ if (!OidIsValid(roleid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("group \"%s\" does not exist", groname)));
-
- groupId = ((Form_pg_group) GETSTRUCT(groupTup))->grosysid;
-
- ReleaseSysCache(groupTup);
-
- return groupId;
+ errmsg("role \"%s\" does not exist", rolname)));
+ return roleid;
}
-
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index c6cfbc5be24..cd24460857f 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.99 2005/05/11 01:26:02 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.100 2005/06/28 05:09:01 tgl Exp $
*
* NOTES
* These routines allow the parser/planner/executor to perform
@@ -27,9 +27,10 @@
#include "catalog/pg_aggregate.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
+#include "catalog/pg_authid.h"
+#include "catalog/pg_auth_members.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_conversion.h"
-#include "catalog/pg_group.h"
#include "catalog/pg_index.h"
#include "catalog/pg_inherits.h"
#include "catalog/pg_language.h"
@@ -38,7 +39,6 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "utils/catcache.h"
@@ -172,6 +172,46 @@ static const struct cachedesc cacheinfo[] = {
0,
0
}},
+ {AuthMemRelationId, /* AUTHMEMMEMROLE */
+ AuthMemMemRoleIndexId,
+ 0,
+ 2,
+ {
+ Anum_pg_auth_members_member,
+ Anum_pg_auth_members_roleid,
+ 0,
+ 0
+ }},
+ {AuthMemRelationId, /* AUTHMEMROLEMEM */
+ AuthMemRoleMemIndexId,
+ 0,
+ 2,
+ {
+ Anum_pg_auth_members_roleid,
+ Anum_pg_auth_members_member,
+ 0,
+ 0
+ }},
+ {AuthIdRelationId, /* AUTHNAME */
+ AuthIdRolnameIndexId,
+ 0,
+ 1,
+ {
+ Anum_pg_authid_rolname,
+ 0,
+ 0,
+ 0
+ }},
+ {AuthIdRelationId, /* AUTHOID */
+ AuthIdOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ }},
{
CastRelationId, /* CASTSOURCETARGET */
CastSourceTargetIndexId,
@@ -233,26 +273,6 @@ static const struct cachedesc cacheinfo[] = {
0,
0
}},
- {GroupRelationId, /* GRONAME */
- GroupNameIndexId,
- 0,
- 1,
- {
- Anum_pg_group_groname,
- 0,
- 0,
- 0
- }},
- {GroupRelationId, /* GROSYSID */
- GroupSysidIndexId,
- 0,
- 1,
- {
- Anum_pg_group_grosysid,
- 0,
- 0,
- 0
- }},
{IndexRelationId, /* INDEXRELID */
IndexRelidIndexId,
Anum_pg_index_indrelid,
@@ -383,26 +403,6 @@ static const struct cachedesc cacheinfo[] = {
0,
0
}},
- {ShadowRelationId, /* SHADOWNAME */
- ShadowNameIndexId,
- 0,
- 1,
- {
- Anum_pg_shadow_usename,
- 0,
- 0,
- 0
- }},
- {ShadowRelationId, /* SHADOWSYSID */
- ShadowSysidIndexId,
- 0,
- 1,
- {
- Anum_pg_shadow_usesysid,
- 0,
- 0,
- 0
- }},
{StatisticRelationId, /* STATRELATT */
StatisticRelidAttnumIndexId,
Anum_pg_statistic_starelid,
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 0733f190c2b..dd6134ccfd0 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.95 2005/05/29 04:23:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.96 2005/06/28 05:09:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -769,7 +769,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS)
struct fmgr_security_definer_cache
{
FmgrInfo flinfo;
- AclId userid;
+ Oid userid;
};
/*
@@ -786,7 +786,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
Datum result;
FmgrInfo *save_flinfo;
struct fmgr_security_definer_cache * volatile fcache;
- AclId save_userid;
+ Oid save_userid;
HeapTuple tuple;
if (!fcinfo->flinfo->fn_extra)
diff --git a/src/backend/utils/init/flatfiles.c b/src/backend/utils/init/flatfiles.c
index fcbc99189ff..8b129692f45 100644
--- a/src/backend/utils/init/flatfiles.c
+++ b/src/backend/utils/init/flatfiles.c
@@ -4,9 +4,10 @@
* Routines for maintaining "flat file" images of the shared catalogs.
*
* We use flat files so that the postmaster and not-yet-fully-started
- * backends can look at the contents of pg_database, pg_shadow, and pg_group
- * for authentication purposes. This module is responsible for keeping the
- * flat-file images as nearly in sync with database reality as possible.
+ * backends can look at the contents of pg_database, pg_authid, and
+ * pg_auth_members for authentication purposes. This module is
+ * responsible for keeping the flat-file images as nearly in sync with
+ * database reality as possible.
*
* The tricky part of the write_xxx_file() routines in this module is that
* they need to be able to operate in the context of the database startup
@@ -22,7 +23,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.8 2005/06/17 22:32:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.9 2005/06/28 05:09:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,12 +32,14 @@
#include <sys/stat.h>
#include <unistd.h>
+#include "access/genam.h"
#include "access/heapam.h"
#include "access/twophase_rmgr.h"
+#include "catalog/indexing.h"
+#include "catalog/pg_auth_members.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
-#include "catalog/pg_group.h"
#include "catalog/pg_namespace.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
#include "commands/trigger.h"
#include "miscadmin.h"
@@ -45,19 +48,18 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/flatfiles.h"
+#include "utils/fmgroids.h"
#include "utils/resowner.h"
#include "utils/syscache.h"
/* Actual names of the flat files (within $PGDATA/global/) */
#define DATABASE_FLAT_FILE "pg_database"
-#define GROUP_FLAT_FILE "pg_group"
-#define USER_FLAT_FILE "pg_pwd"
+#define AUTH_FLAT_FILE "pg_auth"
/* Info bits in a flatfiles 2PC record */
#define FF_BIT_DATABASE 1
-#define FF_BIT_GROUP 2
-#define FF_BIT_USER 4
+#define FF_BIT_AUTH 2
/*
@@ -73,8 +75,7 @@
* SubTransactionId is seen at top-level commit.
*/
static SubTransactionId database_file_update_subid = InvalidSubTransactionId;
-static SubTransactionId group_file_update_subid = InvalidSubTransactionId;
-static SubTransactionId user_file_update_subid = InvalidSubTransactionId;
+static SubTransactionId auth_file_update_subid = InvalidSubTransactionId;
/*
@@ -88,23 +89,13 @@ database_file_update_needed(void)
}
/*
- * Mark flat group file as needing an update (because pg_group changed)
+ * Mark flat auth file as needing an update (because pg_auth changed)
*/
void
-group_file_update_needed(void)
+auth_file_update_needed(void)
{
- if (group_file_update_subid == InvalidSubTransactionId)
- group_file_update_subid = GetCurrentSubTransactionId();
-}
-
-/*
- * Mark flat user file as needing an update (because pg_shadow changed)
- */
-void
-user_file_update_needed(void)
-{
- if (user_file_update_subid == InvalidSubTransactionId)
- user_file_update_subid = GetCurrentSubTransactionId();
+ if (auth_file_update_subid == InvalidSubTransactionId)
+ auth_file_update_subid = GetCurrentSubTransactionId();
}
@@ -128,39 +119,20 @@ database_getflatfilename(void)
}
/*
- * group_getflatfilename --- get full pathname of group file
- *
- * 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;
}
@@ -189,7 +161,7 @@ fputs_quote(const char *str, FILE *fp)
/*
* name_okay
*
- * We must disallow newlines in user and group names because
+ * We must disallow newlines in role names because
* hba.c's parser won't handle fields split across lines, even if quoted.
*/
static bool
@@ -322,165 +294,81 @@ write_database_file(Relation drel)
/*
- * write_group_file: update the flat group file
+ * Support for write_auth_file
*/
-static void
-write_group_file(Relation grel)
-{
- 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);
@@ -495,39 +383,41 @@ write_user_file(Relation urel)
tempname)));
/*
- * Read pg_shadow and write the file.
+ * Read pg_authid and fill temporary data structures.
*/
- scan = heap_beginscan(urel, SnapshotNow, 0, NULL);
+ totalblocks = RelationGetNumberOfBlocks(rel_auth);
+ totalblocks = totalblocks ? totalblocks : 1;
+ est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_authid)));
+ auth_info = (auth_entry*) palloc(est_rows*sizeof(auth_entry));
+
+ scan = heap_beginscan(rel_auth, SnapshotNow, 0, NULL);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
- Form_pg_shadow pwform = (Form_pg_shadow) GETSTRUCT(tuple);
+ Form_pg_authid pwform = (Form_pg_authid) GETSTRUCT(tuple);
HeapTupleHeader tup = tuple->t_data;
char *tp; /* ptr to tuple data */
long off; /* offset in tuple data */
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
Datum datum;
- char *usename,
- *passwd,
- *valuntil;
- AclId usesysid;
- usename = NameStr(pwform->usename);
- usesysid = pwform->usesysid;
+ auth_info[curr_role].roleid = HeapTupleGetOid(tuple);
+ auth_info[curr_role].rolname = pstrdup(NameStr(pwform->rolname));
+ auth_info[curr_role].roles_names = NIL;
/*
* We can't use heap_getattr() here because during startup we will
- * not have any tupdesc for pg_shadow. Fortunately it's not too
- * hard to work around this. passwd is the first possibly-null
+ * not have any tupdesc for pg_authid. Fortunately it's not too
+ * hard to work around this. rolpassword is the first possibly-null
* field so we can compute its offset directly.
*/
tp = (char *) tup + tup->t_hoff;
- off = offsetof(FormData_pg_shadow, passwd);
+ off = offsetof(FormData_pg_authid, rolpassword);
if (HeapTupleHasNulls(tuple) &&
- att_isnull(Anum_pg_shadow_passwd - 1, bp))
+ att_isnull(Anum_pg_authid_rolpassword - 1, bp))
{
/* passwd is null, emit as an empty string */
- passwd = pstrdup("");
+ auth_info[curr_role].rolpassword = pstrdup("");
}
else
{
@@ -539,59 +429,175 @@ write_user_file(Relation urel)
* if it is, ignore it, since we can't handle that in startup mode.
*/
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)))
- passwd = pstrdup("");
+ auth_info[curr_role].rolpassword = pstrdup("");
else
- passwd = DatumGetCString(DirectFunctionCall1(textout, datum));
+ auth_info[curr_role].rolpassword = DatumGetCString(DirectFunctionCall1(textout, datum));
/* assume passwd has attlen -1 */
off = att_addlength(off, -1, tp + off);
}
if (HeapTupleHasNulls(tuple) &&
- att_isnull(Anum_pg_shadow_valuntil - 1, bp))
+ att_isnull(Anum_pg_authid_rolvaliduntil - 1, bp))
{
- /* valuntil is null, emit as an empty string */
- valuntil = pstrdup("");
+ /* rolvaliduntil is null, emit as an empty string */
+ auth_info[curr_role].rolvaliduntil = pstrdup("");
}
else
{
- /* assume valuntil has attalign 'i' */
- off = att_align(off, 'i');
- /* assume valuntil is pass-by-value, integer size */
- datum = Int32GetDatum(*((int32 *) (tp + off)));
- valuntil = DatumGetCString(DirectFunctionCall1(abstimeout, datum));
+ /*
+ * rolvaliduntil is timestamptz, which we assume is double
+ * alignment and pass-by-reference.
+ */
+ off = att_align(off, 'd');
+ datum = PointerGetDatum(tp + off);
+ auth_info[curr_role].rolvaliduntil = DatumGetCString(DirectFunctionCall1(timestamptz_out, datum));
}
/*
* Check for illegal characters in the user name and password.
*/
- if (!name_okay(usename))
+ if (!name_okay(auth_info[curr_role].rolname))
{
ereport(LOG,
- (errmsg("invalid user name \"%s\"", usename)));
+ (errmsg("invalid role name \"%s\"",
+ auth_info[curr_role].rolname)));
+ pfree(auth_info[curr_role].rolname);
+ pfree(auth_info[curr_role].rolpassword);
+ pfree(auth_info[curr_role].rolvaliduntil);
continue;
}
- if (!name_okay(passwd))
+ if (!name_okay(auth_info[curr_role].rolpassword))
{
ereport(LOG,
- (errmsg("invalid user password \"%s\"", passwd)));
+ (errmsg("invalid role password \"%s\"",
+ auth_info[curr_role].rolpassword)));
+ pfree(auth_info[curr_role].rolname);
+ pfree(auth_info[curr_role].rolpassword);
+ pfree(auth_info[curr_role].rolvaliduntil);
continue;
}
- /*
- * The file format is: "usename" usesysid "passwd" "valuntil"
+ 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(usename, fp);
- fprintf(fp, " %u ", usesysid);
- fputs_quote(passwd, fp);
+ fputs_quote(auth_info[curr_role].rolname, fp);
+ fputs(" ", fp);
+ fputs_quote(auth_info[curr_role].rolpassword, 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,
@@ -609,6 +615,8 @@ write_user_file(Relation urel)
errmsg("could not rename file \"%s\" to \"%s\": %m",
tempname, filename)));
+ pfree(auth_info);
+ pfree(authmem_info);
pfree(tempname);
pfree(filename);
}
@@ -634,7 +642,7 @@ BuildFlatFiles(bool database_only)
{
ResourceOwner owner;
RelFileNode rnode;
- Relation rel;
+ Relation rel, rel_auth, rel_authmem;
/*
* We don't have any hope of running a real relcache, but we can use
@@ -657,21 +665,16 @@ BuildFlatFiles(bool database_only)
if (!database_only)
{
- /* hard-wired path to pg_group */
+ /* hard-wired path to pg_auth */
rnode.spcNode = GLOBALTABLESPACE_OID;
rnode.dbNode = 0;
- rnode.relNode = GroupRelationId;
+ rnode.relNode = AuthIdRelationId;
+ rel_auth = XLogOpenRelation(rnode);
- rel = XLogOpenRelation(rnode);
- write_group_file(rel);
-
- /* hard-wired path to pg_shadow */
rnode.spcNode = GLOBALTABLESPACE_OID;
rnode.dbNode = 0;
- rnode.relNode = ShadowRelationId;
-
- rel = XLogOpenRelation(rnode);
- write_user_file(rel);
+ rnode.relNode = AuthMemRelationId;
+ rel_authmem = XLogOpenRelation(rnode);
}
CurrentResourceOwner = NULL;
@@ -699,19 +702,17 @@ void
AtEOXact_UpdateFlatFiles(bool isCommit)
{
Relation drel = NULL;
- Relation grel = NULL;
- Relation urel = NULL;
+ Relation arel = NULL;
+ Relation mrel = NULL;
if (database_file_update_subid == InvalidSubTransactionId &&
- group_file_update_subid == InvalidSubTransactionId &&
- user_file_update_subid == InvalidSubTransactionId)
+ auth_file_update_subid == InvalidSubTransactionId)
return; /* nothing to do */
if (!isCommit)
{
database_file_update_subid = InvalidSubTransactionId;
- group_file_update_subid = InvalidSubTransactionId;
- user_file_update_subid = InvalidSubTransactionId;
+ auth_file_update_subid = InvalidSubTransactionId;
return;
}
@@ -731,10 +732,10 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
*/
if (database_file_update_subid != InvalidSubTransactionId)
drel = heap_open(DatabaseRelationId, ExclusiveLock);
- if (group_file_update_subid != InvalidSubTransactionId)
- grel = heap_open(GroupRelationId, ExclusiveLock);
- if (user_file_update_subid != InvalidSubTransactionId)
- urel = heap_open(ShadowRelationId, ExclusiveLock);
+ if (auth_file_update_subid != InvalidSubTransactionId) {
+ arel = heap_open(AuthIdRelationId, ExclusiveLock);
+ mrel = heap_open(AuthMemRelationId, ExclusiveLock);
+ }
/* Okay to write the files */
if (database_file_update_subid != InvalidSubTransactionId)
@@ -744,18 +745,12 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
heap_close(drel, NoLock);
}
- if (group_file_update_subid != InvalidSubTransactionId)
- {
- 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);
}
/*
@@ -785,15 +780,10 @@ AtPrepare_UpdateFlatFiles(void)
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,
@@ -817,29 +807,23 @@ AtEOSubXact_UpdateFlatFiles(bool isCommit,
if (database_file_update_subid == mySubid)
database_file_update_subid = parentSubid;
- if (group_file_update_subid == mySubid)
- group_file_update_subid = parentSubid;
-
- if (user_file_update_subid == mySubid)
- user_file_update_subid = parentSubid;
+ if (auth_file_update_subid == mySubid)
+ auth_file_update_subid = parentSubid;
}
else
{
if (database_file_update_subid == mySubid)
database_file_update_subid = InvalidSubTransactionId;
- if (group_file_update_subid == mySubid)
- group_file_update_subid = InvalidSubTransactionId;
-
- if (user_file_update_subid == mySubid)
- user_file_update_subid = InvalidSubTransactionId;
+ if (auth_file_update_subid == mySubid)
+ auth_file_update_subid = InvalidSubTransactionId;
}
}
/*
- * This trigger is fired whenever someone modifies pg_database, pg_shadow
- * or pg_group via general-purpose INSERT/UPDATE/DELETE commands.
+ * This trigger is fired whenever someone modifies pg_database, pg_authid
+ * or pg_auth_members via general-purpose INSERT/UPDATE/DELETE commands.
*
* It is sufficient for this to be a STATEMENT trigger since we don't
* care which individual rows changed. It doesn't much matter whether
@@ -862,11 +846,11 @@ flatfile_update_trigger(PG_FUNCTION_ARGS)
case DatabaseRelationId:
database_file_update_needed();
break;
- case GroupRelationId:
- group_file_update_needed();
+ case AuthIdRelationId:
+ auth_file_update_needed();
break;
- case ShadowRelationId:
- user_file_update_needed();
+ case AuthMemRelationId:
+ auth_file_update_needed();
break;
default:
elog(ERROR, "flatfile_update_trigger was called for wrong table");
@@ -895,8 +879,6 @@ flatfile_twophase_postcommit(TransactionId xid, uint16 info,
*/
if (info & FF_BIT_DATABASE)
database_file_update_needed();
- if (info & FF_BIT_GROUP)
- group_file_update_needed();
- if (info & FF_BIT_USER)
- user_file_update_needed();
+ if (info & FF_BIT_AUTH)
+ auth_file_update_needed();
}
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 508c56e1e03..1db29928996 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.142 2005/06/20 02:17:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.143 2005/06/28 05:09:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,7 +29,7 @@
#include <utime.h>
#endif
-#include "catalog/pg_shadow.h"
+#include "catalog/pg_authid.h"
#include "libpq/libpq-be.h"
#include "miscadmin.h"
#include "storage/fd.h"
@@ -251,7 +251,7 @@ make_absolute_path(const char *path)
/* ----------------------------------------------------------------
- * User ID things
+ * Role ID things
*
* The authenticated user is determined at connection start and never
* changes. The session user can be changed only by SET SESSION
@@ -261,60 +261,60 @@ make_absolute_path(const char *path)
* restore the current user id if you need to change it.
* ----------------------------------------------------------------
*/
-static AclId AuthenticatedUserId = 0;
-static AclId SessionUserId = 0;
-static AclId CurrentUserId = 0;
+static Oid AuthenticatedUserId = InvalidOid;
+static Oid SessionUserId = InvalidOid;
+static Oid CurrentUserId = InvalidOid;
static bool AuthenticatedUserIsSuperuser = false;
/*
* This function is relevant for all privilege checks.
*/
-AclId
+Oid
GetUserId(void)
{
- AssertState(AclIdIsValid(CurrentUserId));
+ AssertState(OidIsValid(CurrentUserId));
return CurrentUserId;
}
void
-SetUserId(AclId newid)
+SetUserId(Oid roleid)
{
- AssertArg(AclIdIsValid(newid));
- CurrentUserId = newid;
+ AssertArg(OidIsValid(roleid));
+ CurrentUserId = roleid;
}
/*
* This value is only relevant for informational purposes.
*/
-AclId
+Oid
GetSessionUserId(void)
{
- AssertState(AclIdIsValid(SessionUserId));
+ AssertState(OidIsValid(SessionUserId));
return SessionUserId;
}
void
-SetSessionUserId(AclId newid)
+SetSessionUserId(Oid roleid)
{
- AssertArg(AclIdIsValid(newid));
- SessionUserId = newid;
+ AssertArg(OidIsValid(roleid));
+ SessionUserId = roleid;
/* Current user defaults to session user. */
- if (!AclIdIsValid(CurrentUserId))
- CurrentUserId = newid;
+ if (!OidIsValid(CurrentUserId))
+ CurrentUserId = roleid;
}
void
-InitializeSessionUserId(const char *username)
+InitializeSessionUserId(const char *rolename)
{
- HeapTuple userTup;
+ HeapTuple roleTup;
Datum datum;
bool isnull;
- AclId usesysid;
+ Oid roleid;
/*
* Don't do scans if we're bootstrapping, none of the system catalogs
@@ -325,23 +325,23 @@ InitializeSessionUserId(const char *username)
/* call only once */
AssertState(!OidIsValid(AuthenticatedUserId));
- userTup = SearchSysCache(SHADOWNAME,
- PointerGetDatum(username),
+ roleTup = SearchSysCache(AUTHNAME,
+ PointerGetDatum(rolename),
0, 0, 0);
- if (!HeapTupleIsValid(userTup))
+ if (!HeapTupleIsValid(roleTup))
ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("user \"%s\" does not exist", username)));
+ errmsg("role \"%s\" does not exist", rolename)));
- usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;
+ roleid = HeapTupleGetOid(roleTup);
- AuthenticatedUserId = usesysid;
- AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper;
+ AuthenticatedUserId = roleid;
+ AuthenticatedUserIsSuperuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
- SetSessionUserId(usesysid); /* sets CurrentUserId too */
+ SetSessionUserId(roleid); /* sets CurrentUserId too */
/* Record username and superuser status as GUC settings too */
- SetConfigOption("session_authorization", username,
+ SetConfigOption("session_authorization", rolename,
PGC_BACKEND, PGC_S_OVERRIDE);
SetConfigOption("is_superuser",
AuthenticatedUserIsSuperuser ? "on" : "off",
@@ -349,11 +349,11 @@ InitializeSessionUserId(const char *username)
/*
* Set up user-specific configuration variables. This is a good place
- * to do it so we don't have to read pg_shadow twice during session
+ * to do it so we don't have to read pg_authid twice during session
* startup.
*/
- datum = SysCacheGetAttr(SHADOWNAME, userTup,
- Anum_pg_shadow_useconfig, &isnull);
+ datum = SysCacheGetAttr(AUTHNAME, roleTup,
+ Anum_pg_authid_rolconfig, &isnull);
if (!isnull)
{
ArrayType *a = DatumGetArrayTypeP(datum);
@@ -361,7 +361,7 @@ InitializeSessionUserId(const char *username)
ProcessGUCArray(a, PGC_S_USER);
}
- ReleaseSysCache(userTup);
+ ReleaseSysCache(roleTup);
}
@@ -374,10 +374,10 @@ InitializeSessionUserIdStandalone(void)
/* call only once */
AssertState(!OidIsValid(AuthenticatedUserId));
- AuthenticatedUserId = BOOTSTRAP_USESYSID;
+ AuthenticatedUserId = BOOTSTRAP_SUPERUSERID;
AuthenticatedUserIsSuperuser = true;
- SetSessionUserId(BOOTSTRAP_USESYSID);
+ SetSessionUserId(BOOTSTRAP_SUPERUSERID);
}
@@ -390,19 +390,19 @@ InitializeSessionUserIdStandalone(void)
* to indicate whether the *current* session userid is a superuser.
*/
void
-SetSessionAuthorization(AclId userid, bool is_superuser)
+SetSessionAuthorization(Oid roleid, bool is_superuser)
{
/* Must have authenticated already, else can't make permission check */
- AssertState(AclIdIsValid(AuthenticatedUserId));
+ AssertState(OidIsValid(AuthenticatedUserId));
- if (userid != AuthenticatedUserId &&
+ if (roleid != AuthenticatedUserId &&
!AuthenticatedUserIsSuperuser)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to set session authorization")));
- SetSessionUserId(userid);
- SetUserId(userid);
+ SetSessionUserId(roleid);
+ SetUserId(roleid);
SetConfigOption("is_superuser",
is_superuser ? "on" : "off",
@@ -411,30 +411,29 @@ SetSessionAuthorization(AclId userid, bool is_superuser)
/*
- * Get user name from user id
+ * Get user name from user oid
*/
char *
-GetUserNameFromId(AclId userid)
+GetUserNameFromId(Oid roleid)
{
HeapTuple tuple;
char *result;
- tuple = SearchSysCache(SHADOWSYSID,
- ObjectIdGetDatum(userid),
+ tuple = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(roleid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("invalid user ID: %d", userid)));
+ errmsg("invalid role OID: %u", roleid)));
- result = pstrdup(NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename));
+ result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname));
ReleaseSysCache(tuple);
return result;
}
-
/*-------------------------------------------------------------------------
* Interlock-file support
*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 1836aee81d7..9baacacfffd 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.149 2005/06/24 01:06:26 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.150 2005/06/28 05:09:02 tgl Exp $
*
*
*-------------------------------------------------------------------------
@@ -20,11 +20,11 @@
#include <math.h>
#include <unistd.h>
-#include "catalog/catalog.h"
#include "access/heapam.h"
+#include "catalog/catalog.h"
#include "catalog/namespace.h"
+#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
#include "libpq/hba.h"
#include "mb/pg_wchar.h"
@@ -37,6 +37,7 @@
#include "storage/procarray.h"
#include "storage/sinval.h"
#include "storage/smgr.h"
+#include "utils/acl.h"
#include "utils/flatfiles.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
@@ -49,7 +50,7 @@ static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace);
static void ReverifyMyDatabase(const char *name);
static void InitCommunication(void);
static void ShutdownPostgres(int code, Datum arg);
-static bool ThereIsAtLeastOneUser(void);
+static bool ThereIsAtLeastOneRole(void);
/*** InitPostgres support ***/
@@ -415,12 +416,12 @@ InitPostgres(const char *dbname, const char *username)
else if (!IsUnderPostmaster)
{
InitializeSessionUserIdStandalone();
- if (!ThereIsAtLeastOneUser())
+ if (!ThereIsAtLeastOneRole())
ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT),
- errmsg("no users are defined in this database system"),
- errhint("You should immediately run CREATE USER \"%s\" WITH SYSID %d CREATEUSER;.",
- username, BOOTSTRAP_USESYSID)));
+ errmsg("no roles are defined in this database system"),
+ errhint("You should immediately run CREATE USER \"%s\" CREATEUSER;.",
+ username)));
}
else
{
@@ -469,6 +470,9 @@ InitPostgres(const char *dbname, const char *username)
/* set default namespace search path */
InitializeSearchPath();
+ /* set up ACL framework (currently just sets RolMemCache callback) */
+ InitializeAcl();
+
/* initialize client encoding */
InitializeClientEncoding();
@@ -530,22 +534,22 @@ ShutdownPostgres(int code, Datum arg)
/*
- * Returns true if at least one user is defined in this database cluster.
+ * Returns true if at least one role is defined in this database cluster.
*/
static bool
-ThereIsAtLeastOneUser(void)
+ThereIsAtLeastOneRole(void)
{
- Relation pg_shadow_rel;
+ Relation pg_authid_rel;
HeapScanDesc scan;
bool result;
- pg_shadow_rel = heap_open(ShadowRelationId, AccessExclusiveLock);
+ pg_authid_rel = heap_open(AuthIdRelationId, AccessExclusiveLock);
- scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL);
+ scan = heap_beginscan(pg_authid_rel, SnapshotNow, 0, NULL);
result = (heap_getnext(scan, ForwardScanDirection) != NULL);
heap_endscan(scan);
- heap_close(pg_shadow_rel, AccessExclusiveLock);
+ heap_close(pg_authid_rel, AccessExclusiveLock);
return result;
}
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 0ab8e742336..84d8085503a 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.270 2005/06/26 19:16:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.271 2005/06/28 05:09:02 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -5108,7 +5108,7 @@ ParseLongOption(const char *string, char **name, char **value)
/*
- * Handle options fetched from pg_database.datconfig or pg_shadow.useconfig.
+ * Handle options fetched from pg_database.datconfig or pg_authid.rolconfig.
* The array parameter must be an array of TEXT (it must not be NULL).
*/
void
@@ -5154,7 +5154,7 @@ ProcessGUCArray(ArrayType *array, GucSource source)
/*
* We process all these options at SUSET level. We assume that
- * the right to insert an option into pg_database or pg_shadow was
+ * the right to insert an option into pg_database or pg_authid was
* checked when it was inserted.
*/
SetConfigOption(name, value, PGC_SUSET, source);
diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c
index 520dc470cdc..9e965b8107f 100644
--- a/src/backend/utils/misc/superuser.c
+++ b/src/backend/utils/misc/superuser.c
@@ -14,29 +14,29 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.31 2005/05/29 20:38:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.32 2005/06/28 05:09:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "catalog/pg_shadow.h"
+#include "catalog/pg_authid.h"
#include "utils/inval.h"
#include "utils/syscache.h"
#include "miscadmin.h"
/*
- * In common cases the same userid (ie, the session or current ID) will
+ * In common cases the same roleid (ie, the session or current ID) will
* be queried repeatedly. So we maintain a simple one-entry cache for
- * the status of the last requested userid. The cache can be flushed
- * at need by watching for cache update events on pg_shadow.
+ * the status of the last requested roleid. The cache can be flushed
+ * at need by watching for cache update events on pg_authid.
*/
-static AclId last_userid = 0; /* 0 == cache not valid */
-static bool last_userid_is_super = false;
-static bool userid_callback_registered = false;
+static Oid last_roleid = InvalidOid; /* InvalidOid == cache not valid */
+static bool last_roleid_is_super = false;
+static bool roleid_callback_registered = false;
-static void UseridCallback(Datum arg, Oid relid);
+static void RoleidCallback(Datum arg, Oid relid);
/*
@@ -50,49 +50,49 @@ superuser(void)
/*
- * The specified userid has Postgres superuser privileges
+ * The specified role has Postgres superuser privileges
*/
bool
-superuser_arg(AclId userid)
+superuser_arg(Oid roleid)
{
bool result;
- HeapTuple utup;
+ HeapTuple rtup;
/* Quick out for cache hit */
- if (AclIdIsValid(last_userid) && last_userid == userid)
- return last_userid_is_super;
+ if (OidIsValid(last_roleid) && last_roleid == roleid)
+ return last_roleid_is_super;
/* Special escape path in case you deleted all your users. */
- if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYSID)
+ if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID)
return true;
- /* OK, look up the information in pg_shadow */
- utup = SearchSysCache(SHADOWSYSID,
- Int32GetDatum(userid),
+ /* OK, look up the information in pg_authid */
+ rtup = SearchSysCache(AUTHOID,
+ ObjectIdGetDatum(roleid),
0, 0, 0);
- if (HeapTupleIsValid(utup))
+ if (HeapTupleIsValid(rtup))
{
- result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
- ReleaseSysCache(utup);
+ result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper;
+ ReleaseSysCache(rtup);
}
else
{
- /* Report "not superuser" for invalid userids */
+ /* Report "not superuser" for invalid roleids */
result = false;
}
/* If first time through, set up callback for cache flushes */
- if (!userid_callback_registered)
+ if (!roleid_callback_registered)
{
- CacheRegisterSyscacheCallback(SHADOWSYSID,
- UseridCallback,
+ CacheRegisterSyscacheCallback(AUTHOID,
+ RoleidCallback,
(Datum) 0);
- userid_callback_registered = true;
+ roleid_callback_registered = true;
}
/* Cache the result for next time */
- last_userid = userid;
- last_userid_is_super = result;
+ last_roleid = roleid;
+ last_roleid_is_super = result;
return result;
}
@@ -102,8 +102,8 @@ superuser_arg(AclId userid)
* Syscache inval callback function
*/
static void
-UseridCallback(Datum arg, Oid relid)
+RoleidCallback(Datum arg, Oid relid)
{
- /* Invalidate our local cache in case user's superuserness changed */
- last_userid = 0;
+ /* Invalidate our local cache in case role's superuserness changed */
+ last_roleid = InvalidOid;
}
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 2442f43ddcf..58fb04860ae 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -42,7 +42,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -169,7 +169,7 @@ static void test_connections(void);
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);
@@ -1316,11 +1316,11 @@ bootstrap_template1(char *short_version)
* 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.
@@ -1328,22 +1328,22 @@ setup_shadow(void)
"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),
@@ -1353,7 +1353,7 @@ setup_shadow(void)
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;
@@ -1461,13 +1461,12 @@ unlimit_systables(void)
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
};
@@ -2624,7 +2623,7 @@ main(int argc, char *argv[])
/* Create the stuff we don't need to use bootstrap mode for */
- setup_shadow();
+ setup_auth();
if (pwprompt || pwfilename)
get_set_pwd();
diff --git a/src/include/access/twophase.h b/src/include/access/twophase.h
index 08f1f9bd9fe..e90b9e304db 100644
--- a/src/include/access/twophase.h
+++ b/src/include/access/twophase.h
@@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -34,7 +34,7 @@ extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid);
extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid,
TimestampTz prepared_at,
- AclId owner, Oid databaseid);
+ Oid owner, Oid databaseid);
extern void StartPrepare(GlobalTransaction gxact);
extern void EndPrepare(GlobalTransaction gxact);
diff --git a/src/include/c.h b/src/include/c.h
index 1a920387747..202e45271e5 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -12,7 +12,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -366,7 +366,7 @@ typedef double float8;
/*
* Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
- * CommandId, AclId
+ * CommandId
*/
/* typedef Oid is in postgres_ext.h */
@@ -394,8 +394,6 @@ typedef uint32 CommandId;
#define FirstCommandId ((CommandId) 0)
-typedef int32 AclId; /* user and group identifiers */
-
/*
* Array indexing support
*/
@@ -507,8 +505,6 @@ typedef NameData *Name;
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
-#define AclIdIsValid(aclId) ((bool) ((aclId) != 0))
-
#define RegProcedureIsValid(p) OidIsValid(p)
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 1e5c7ce0fa0..5a1943723dc 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200506271
+#define CATALOG_VERSION_NO 200506272
#endif
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index 8be3527be2c..757a2095792 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -8,7 +8,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -83,6 +83,16 @@ DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index,2658, on pg_attribute using
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));
@@ -127,11 +137,6 @@ DECLARE_INDEX(pg_depend_reference_index,2674, on pg_depend using btree(refclassi
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
@@ -174,11 +179,6 @@ DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index,2692, on pg_rewrite using btree(oid oi
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
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index ddca993a68a..bda89f44054 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -8,7 +8,7 @@
* 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:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.118 2005/06/28 05:09:04 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -226,7 +226,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
#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 }, \
@@ -250,7 +250,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
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));
@@ -286,7 +286,7 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i 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 }, \
@@ -305,7 +305,7 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 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));
@@ -385,7 +385,7 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i 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 }, \
@@ -411,7 +411,7 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 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));
diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h
new file mode 100644
index 00000000000..e08fd2e6ae1
--- /dev/null
+++ b/src/include/catalog/pg_auth_members.h
@@ -0,0 +1,54 @@
+/*-------------------------------------------------------------------------
+ *
+ * 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 */
diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h
new file mode 100644
index 00000000000..2ea15fea8a1
--- /dev/null
+++ b/src/include/catalog/pg_authid.h
@@ -0,0 +1,94 @@
+/*-------------------------------------------------------------------------
+ *
+ * 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 */
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index e08d6d60d33..b6d8f556b48 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -8,7 +8,7 @@
* 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
@@ -47,7 +47,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP
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 */
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index e9cd3ccca24..eb874446455 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -8,7 +8,7 @@
* 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
@@ -46,7 +46,7 @@ CATALOG(pg_conversion,2607)
{
NameData conname;
Oid connamespace;
- int4 conowner;
+ Oid conowner;
int4 conforencoding;
int4 contoencoding;
regproc conproc;
@@ -86,7 +86,7 @@ typedef FormData_pg_conversion *Form_pg_conversion;
#include "nodes/parsenodes.h"
extern Oid ConversionCreate(const char *conname, Oid connamespace,
- AclId conowner,
+ Oid conowner,
int32 conforencoding, int32 contoencoding,
Oid conproc, bool def);
extern void ConversionDrop(Oid conversionOid, DropBehavior behavior);
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index 69b41e31720..37c57f8508c 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -8,7 +8,7 @@
* 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
@@ -36,7 +36,7 @@
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? */
diff --git a/src/include/catalog/pg_group.h b/src/include/catalog/pg_group.h
deleted file mode 100644
index 216d51a6660..00000000000
--- a/src/include/catalog/pg_group.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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 */
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index f6cb4cf8e5b..c460500578c 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -8,7 +8,7 @@
* 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
@@ -41,7 +41,7 @@
CATALOG(pg_namespace,2615)
{
NameData nspname;
- int4 nspowner;
+ Oid nspowner;
aclitem nspacl[1]; /* VARIABLE LENGTH FIELD */
} FormData_pg_namespace;
@@ -82,6 +82,6 @@ DESCR("Standard public schema");
/*
* prototypes for functions in pg_namespace.c
*/
-extern Oid NamespaceCreate(const char *nspName, int32 ownerSysId);
+extern Oid NamespaceCreate(const char *nspName, Oid ownerId);
#endif /* PG_NAMESPACE_H */
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index 6043fec22d0..23485ff0ebb 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -27,7 +27,7 @@
* 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
@@ -57,7 +57,7 @@ CATALOG(pg_opclass,2616)
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 */
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index f87b6a07383..9de43736eae 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -8,7 +8,7 @@
* 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
@@ -42,7 +42,7 @@ CATALOG(pg_operator,2617)
{
NameData oprname; /* name of operator */
Oid oprnamespace; /* OID of namespace containing this oper */
- int4 oprowner; /* oper owner */
+ Oid oprowner; /* operator 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 */
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 049024ae40c..5326a770592 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
* 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
@@ -41,7 +41,7 @@ CATALOG(pg_proc,1255) BKI_BOOTSTRAP
{
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 */
@@ -1355,7 +1355,7 @@ DATA(insert OID = 1037 ( aclcontains PGNSP PGUID 12 f f t f i 2 16 "1034 103
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");
@@ -2251,8 +2251,8 @@ DATA(insert OID = 1640 ( pg_get_viewdef PGNSP PGUID 12 f f t f s 1 25 "25" _
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 UID (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 OID (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_ ));
@@ -2785,10 +2785,10 @@ DATA(insert OID = 1922 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16
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 usesysid, 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 usesysid, 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 oid, 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 oid, 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_ ));
@@ -2821,7 +2821,7 @@ DATA(insert OID = 1937 ( pg_stat_get_backend_pid PGNSP PGUID 12 f f t f s 1 23
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");
@@ -3171,10 +3171,10 @@ DATA(insert OID = 2250 ( has_database_privilege PGNSP PGUID 12 f f t f s 3
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 usesysid, 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 usesysid, 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 oid, 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 oid, 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_ ));
@@ -3184,10 +3184,10 @@ DATA(insert OID = 2256 ( has_function_privilege PGNSP PGUID 12 f f t f s 3
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 usesysid, 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 usesysid, 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 oid, 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 oid, 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_ ));
@@ -3197,10 +3197,10 @@ DATA(insert OID = 2262 ( has_language_privilege PGNSP PGUID 12 f f t f s 3
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 usesysid, 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 usesysid, 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 oid, 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 oid, 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_ ));
@@ -3210,10 +3210,10 @@ DATA(insert OID = 2268 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16
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 usesysid, 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 usesysid, 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 oid, 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 oid, 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_ ));
@@ -3223,10 +3223,10 @@ DATA(insert OID = 2390 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s
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 usesysid, 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 usesysid, 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 oid, 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 oid, 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_ ));
diff --git a/src/include/catalog/pg_shadow.h b/src/include/catalog/pg_shadow.h
deleted file mode 100644
index 3c24d82d450..00000000000
--- a/src/include/catalog/pg_shadow.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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 */
diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h
index 7c440042746..831e5753d12 100644
--- a/src/include/catalog/pg_tablespace.h
+++ b/src/include/catalog/pg_tablespace.h
@@ -8,7 +8,7 @@
* 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
@@ -36,7 +36,7 @@
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;
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 8a4207e9ea6..44b8cf0cedb 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -8,7 +8,7 @@
* 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
@@ -44,7 +44,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP
{
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
diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h
index 47224831aad..b64b361d27a 100644
--- a/src/include/commands/conversioncmds.h
+++ b/src/include/commands/conversioncmds.h
@@ -7,7 +7,7 @@
* 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 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.10 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -20,6 +20,6 @@
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 newOwnerSysId);
+extern void AlterConversionOwner(List *name, Oid newOwnerId);
#endif /* CONVERSIONCMDS_H */
diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h
index 7ffd7abeb03..1a4fd5123c2 100644
--- a/src/include/commands/dbcommands.h
+++ b/src/include/commands/dbcommands.h
@@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -65,7 +65,7 @@ extern void createdb(const CreatedbStmt *stmt);
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 newOwnerSysId);
+extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId);
extern Oid get_database_oid(const char *dbname);
extern char *get_database_name(Oid dbid);
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 1ae5649c137..10c3438065a 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -50,7 +50,7 @@ extern void RemoveFunctionById(Oid funcOid);
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 newOwnerSysId);
+extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId);
extern void AlterFunction(AlterFunctionStmt *stmt);
extern void CreateCast(CreateCastStmt *stmt);
extern void DropCast(DropCastStmt *stmt);
@@ -61,20 +61,20 @@ extern void DefineOperator(List *names, List *parameters);
extern void RemoveOperator(RemoveOperStmt *stmt);
extern void RemoveOperatorById(Oid operOid);
extern void AlterOperatorOwner(List *name, TypeName *typeName1,
- TypeName *typename2, AclId newOwnerSysId);
+ TypeName *typename2, Oid newOwnerId);
/* 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 newOwnerSysId);
+extern void AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId);
/* 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 newOwnerSysId);
+extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
/* support routines in commands/define.c */
diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h
index 54edffa986c..4528591b3cb 100644
--- a/src/include/commands/schemacmds.h
+++ b/src/include/commands/schemacmds.h
@@ -7,7 +7,7 @@
* 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 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.10 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +23,6 @@ extern void RemoveSchema(List *names, DropBehavior behavior);
extern void RemoveSchemaById(Oid schemaOid);
extern void RenameSchema(const char *oldname, const char *newname);
-extern void AlterSchemaOwner(const char *name, AclId newOwnerSysId);
+extern void AlterSchemaOwner(const char *name, Oid newOwnerId);
#endif /* SCHEMACMDS_H */
diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h
index fe99a191a33..f6c83c952b6 100644
--- a/src/include/commands/tablespace.h
+++ b/src/include/commands/tablespace.h
@@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -36,7 +36,7 @@ typedef struct xl_tblspc_drop_rec
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 newOwnerSysId);
+extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId);
extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);
diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h
index ad5e04cc37a..a940a78f483 100644
--- a/src/include/commands/typecmds.h
+++ b/src/include/commands/typecmds.h
@@ -7,7 +7,7 @@
* 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 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.11 2005/06/28 05:09:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,6 +34,6 @@ extern void AlterDomainDropConstraint(List *names, const char *constrName,
extern List *GetDomainConstraints(Oid typeOid);
-extern void AlterTypeOwner(List *names, AclId newOwnerSysId);
+extern void AlterTypeOwner(List *names, Oid newOwnerId);
#endif /* TYPECMDS_H */
diff --git a/src/include/commands/user.h b/src/include/commands/user.h
index a37f94940a9..ab2829a266b 100644
--- a/src/include/commands/user.h
+++ b/src/include/commands/user.h
@@ -1,10 +1,10 @@
/*-------------------------------------------------------------------------
*
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -14,15 +14,11 @@
#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 */
diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h
index 6798a09ad98..d170f303a43 100644
--- a/src/include/libpq/hba.h
+++ b/src/include/libpq/hba.h
@@ -4,7 +4,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -30,11 +30,10 @@ typedef enum UserAuth
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,
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 3e9b7d912a4..8f6930cd131 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -13,7 +13,7 @@
* 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:34 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.176 2005/06/28 05:09:04 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to other files.
@@ -228,21 +228,21 @@ extern char *DatabasePath;
/* now in utils/init/miscinit.c */
extern void SetDatabasePath(const char *path);
-extern char *GetUserNameFromId(AclId userid);
-extern AclId GetUserId(void);
-extern void SetUserId(AclId userid);
-extern AclId GetSessionUserId(void);
-extern void SetSessionUserId(AclId userid);
-extern void InitializeSessionUserId(const char *username);
+extern char *GetUserNameFromId(Oid roleid);
+extern Oid GetUserId(void);
+extern void SetUserId(Oid roleid);
+extern Oid GetSessionUserId(void);
+extern void SetSessionUserId(Oid roleid);
+extern void InitializeSessionUserId(const char *rolename);
extern void InitializeSessionUserIdStandalone(void);
-extern void SetSessionAuthorization(AclId userid, bool is_superuser);
+extern void SetSessionAuthorization(Oid roleid, 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 */
/*****************************************************************************
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index fd923f72af4..3e623911c70 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -224,6 +224,7 @@ typedef enum NodeTag
T_AlterDomainStmt,
T_SetOperationStmt,
T_GrantStmt,
+ T_GrantRoleStmt,
T_ClosePortalStmt,
T_ClusterStmt,
T_CopyStmt,
@@ -261,19 +262,16 @@ typedef enum NodeTag
T_DropPropertyStmt,
T_CreatePLangStmt,
T_DropPLangStmt,
- T_CreateUserStmt,
- T_AlterUserStmt,
- T_DropUserStmt,
+ T_CreateRoleStmt,
+ T_AlterRoleStmt,
+ T_DropRoleStmt,
T_LockStmt,
T_ConstraintsSetStmt,
- T_CreateGroupStmt,
- T_AlterGroupStmt,
- T_DropGroupStmt,
T_ReindexStmt,
T_CheckPointStmt,
T_CreateSchemaStmt,
T_AlterDatabaseSetStmt,
- T_AlterUserSetStmt,
+ T_AlterRoleSetStmt,
T_CreateConversionStmt,
T_CreateCastStmt,
T_DropCastStmt,
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index e011bb9f978..64acaa72e57 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -544,7 +544,7 @@ typedef struct RangeTblEntry
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;
/*
@@ -749,12 +749,12 @@ typedef enum ObjectType
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,
@@ -762,7 +762,6 @@ typedef enum ObjectType
OBJECT_TABLESPACE,
OBJECT_TRIGGER,
OBJECT_TYPE,
- OBJECT_USER,
OBJECT_VIEW
} ObjectType;
@@ -896,8 +895,7 @@ typedef struct GrantStmt
typedef struct PrivGrantee
{
NodeTag type;
- char *username; /* if both are NULL then PUBLIC */
- char *groupname;
+ char *rolname; /* if NULL then PUBLIC */
} PrivGrantee;
/*
@@ -921,6 +919,23 @@ typedef struct PrivTarget
} 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
* ----------------------
*/
@@ -1123,61 +1138,37 @@ typedef struct DropPLangStmt
} DropPLangStmt;
/* ----------------------
- * Create/Alter/Drop User Statements
+ * Create/Alter/Drop Role Statements
* ----------------------
*/
-typedef struct CreateUserStmt
+typedef struct CreateRoleStmt
{
NodeTag type;
- char *user; /* PostgreSQL user login name */
+ char *role; /* role name */
List *options; /* List of DefElem nodes */
-} CreateUserStmt;
+} CreateRoleStmt;
-typedef struct AlterUserStmt
+typedef struct AlterRoleStmt
{
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 AlterUserSetStmt
+typedef struct AlterRoleSetStmt
{
NodeTag type;
- char *user;
- char *variable;
- List *value;
-} AlterUserSetStmt;
+ char *role; /* role name */
+ char *variable; /* GUC variable name */
+ List *value; /* value for variable, or NIL for Reset */
+} AlterRoleSetStmt;
-typedef struct DropUserStmt
+typedef struct DropRoleStmt
{
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
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 2382ceae936..b6015f536c0 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -5,7 +5,7 @@
*
* 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
@@ -101,7 +101,7 @@ typedef struct PgStat_MsgBestart
{
PgStat_MsgHdr m_hdr;
Oid m_databaseid;
- AclId m_userid;
+ Oid m_userid;
SockAddr m_clientaddr;
} PgStat_MsgBestart;
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h
index ac04945bcd0..f055ac93aa3 100644
--- a/src/include/utils/acl.h
+++ b/src/include/utils/acl.h
@@ -7,7 +7,7 @@
* 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
@@ -29,84 +29,64 @@
/*
- * 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) & 0x7FFF)
+#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16)
+#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 16) & 0xFFFF)
#define ACLITEM_SET_PRIVS(item,privs) \
- ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x7FFF)) | \
- ((AclMode) (privs) & 0x7FFF))
+ ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \
+ ((AclMode) (privs) & 0xFFFF))
#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) 0x7FFF)
-#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0x7FFF << 15)
+#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0xFFFF)
+#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16)
/*
* Definitions for convenient access to Acl (array of AclItem) and IdList
- * (array of AclId). These are standard PostgreSQL arrays, but are restricted
+ * (array of Oid). 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.
*/
@@ -121,13 +101,13 @@ typedef ArrayType Acl;
#define ACL_SIZE(ACL) ARR_SIZE(ACL)
/*
- * IdList a one-dimensional array of AclId
+ * IdList a one-dimensional array of Oid
*/
typedef ArrayType IdList;
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
-#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL))
-#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId)))
+#define IDLIST_DAT(IDL) ((Oid *) ARR_DATA_PTR(IDL))
+#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(Oid)))
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
/*
@@ -221,14 +201,18 @@ typedef enum AclObjectKind
/*
* routines used internally
*/
-extern Acl *acldefault(GrantObjectType objtype, AclId ownerid);
+extern Acl *acldefault(GrantObjectType objtype, Oid ownerId);
extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
- int modechg, AclId ownerid, DropBehavior behavior);
-extern Acl *aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid);
+ int modechg, Oid ownerId, DropBehavior behavior);
+extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId);
-extern AclMode aclmask(const Acl *acl, AclId userid, AclId ownerid,
+extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId,
AclMode mask, AclMaskHow how);
+extern bool is_member_of_role(Oid member, Oid role);
+
+extern void InitializeAcl(void);
+
/*
* SQL functions (from acl.c)
*/
@@ -245,40 +229,39 @@ extern Datum hash_aclitem(PG_FUNCTION_ARGS);
* 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 userid,
+extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_database_aclmask(Oid db_oid, AclId userid,
+extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_proc_aclmask(Oid proc_oid, AclId userid,
+extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_language_aclmask(Oid lang_oid, AclId userid,
+extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_namespace_aclmask(Oid nsp_oid, AclId userid,
+extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclMode pg_tablespace_aclmask(Oid spc_oid, AclId userid,
+extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
AclMode mask, AclMaskHow how);
-extern AclResult pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode);
-extern AclResult pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode);
-extern AclResult pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode);
-extern AclResult pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode);
-extern AclResult pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode);
-extern AclResult pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode);
+extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode);
+extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
+extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
+extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
+extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
+extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, 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 userid);
-extern bool pg_type_ownercheck(Oid type_oid, AclId userid);
-extern bool pg_oper_ownercheck(Oid oper_oid, AclId userid);
-extern bool pg_proc_ownercheck(Oid proc_oid, AclId userid);
-extern bool pg_namespace_ownercheck(Oid nsp_oid, AclId userid);
-extern bool pg_tablespace_ownercheck(Oid spc_oid, AclId userid);
-extern bool pg_opclass_ownercheck(Oid opc_oid, AclId userid);
-extern bool pg_database_ownercheck(Oid db_oid, AclId userid);
-extern bool pg_conversion_ownercheck(Oid conv_oid, AclId userid);
+extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
+extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
+extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
+extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
+extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
+extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
+extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
+extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
+extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
#endif /* ACL_H */
diff --git a/src/include/utils/flatfiles.h b/src/include/utils/flatfiles.h
index 939239aa1b9..5faf35db57b 100644
--- a/src/include/utils/flatfiles.h
+++ b/src/include/utils/flatfiles.h
@@ -4,7 +4,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -14,12 +14,10 @@
#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);
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index b0967edca57..dfd785d5d10 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -6,7 +6,7 @@
* 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 $
*
*-------------------------------------------------------------------------
*/
@@ -104,8 +104,8 @@ extern void free_attstatsslot(Oid atttype,
Datum *values, int nvalues,
float4 *numbers, int nnumbers);
extern char *get_namespace_name(Oid nspid);
-extern AclId get_usesysid(const char *username);
-extern AclId get_grosysid(char *groname);
+extern Oid get_roleid(const char *rolname);
+extern Oid get_roleid_checked(const char *rolname);
#define is_array_type(typid) (get_element_type(typid) != InvalidOid)
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 976788f4057..8a30e08e184 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/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 $
*
*-------------------------------------------------------------------------
*/
@@ -36,29 +36,29 @@
#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 PROCOID 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 OPEROID 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
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 8ac111b5e18..8fa8bb18ce3 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -6,11 +6,12 @@ CREATE USER regressuser2;
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
@@ -275,7 +276,7 @@ DROP FUNCTION testfunc1(int); -- ok
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
---------------------
@@ -283,36 +284,36 @@ select has_table_privilege(NULL,'pg_shadow','select');
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 OID 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
---------------------
@@ -320,21 +321,21 @@ from (select usesysid from pg_user where usename = current_user) as t2;
(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
---------------------
@@ -342,34 +343,34 @@ from (select oid from pg_class where relname = 'pg_shadow') as t1,
(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
@@ -546,8 +547,7 @@ SET SESSION AUTHORIZATION regressuser1;
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
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 384ce37d9c2..47fc262c315 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1277,12 +1277,15 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
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;
@@ -1317,7 +1320,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
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;
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 00abd941ccf..581146bbd70 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -37,6 +37,8 @@ SELECT relname, relhasindex
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
@@ -44,7 +46,6 @@ SELECT relname, relhasindex
pg_database | t
pg_depend | t
pg_description | t
- pg_group | t
pg_index | t
pg_inherits | t
pg_language | t
@@ -54,7 +55,6 @@ SELECT relname, relhasindex
pg_operator | t
pg_proc | t
pg_rewrite | t
- pg_shadow | t
pg_statistic | t
pg_tablespace | t
pg_trigger | t
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 3e224c556a2..aa65bf599d2 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -192,43 +192,43 @@ 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');
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;
@@ -298,7 +298,7 @@ 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
+GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION;
SET SESSION AUTHORIZATION regressuser2;