Replace pg_shadow and pg_group by new role-capable catalogs pg_authid

and pg_auth_members.  There are still many loose ends to finish in this
patch (no documentation, no regression tests, no pg_dump support for
instance).  But I'm going to commit it now anyway so that Alvaro can
make some progress on shared dependencies.  The catalog changes should
be pretty much done.
This commit is contained in:
Tom Lane 2005-06-28 05:09:14 +00:00
parent 977530d8da
commit 7762619e95
96 changed files with 3338 additions and 3240 deletions

View file

@ -1,6 +1,6 @@
<!-- <!--
Documentation of the system catalogs, directed toward PostgreSQL developers 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"> <chapter id="catalogs">
@ -78,6 +78,16 @@
<entry>table columns (<quote>attributes</quote>)</entry> <entry>table columns (<quote>attributes</quote>)</entry>
</row> </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> <row>
<entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry> <entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry>
<entry>casts (data type conversions)</entry> <entry>casts (data type conversions)</entry>
@ -113,11 +123,6 @@
<entry>descriptions or comments on database objects</entry> <entry>descriptions or comments on database objects</entry>
</row> </row>
<row>
<entry><link linkend="catalog-pg-group"><structname>pg_group</structname></link></entry>
<entry>groups of database users</entry>
</row>
<row> <row>
<entry><link linkend="catalog-pg-index"><structname>pg_index</structname></link></entry> <entry><link linkend="catalog-pg-index"><structname>pg_index</structname></link></entry>
<entry>additional index information</entry> <entry>additional index information</entry>
@ -168,11 +173,6 @@
<entry>query rewrite rules</entry> <entry>query rewrite rules</entry>
</row> </row>
<row>
<entry><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link></entry>
<entry>database users</entry>
</row>
<row> <row>
<entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry> <entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry>
<entry>planner statistics</entry> <entry>planner statistics</entry>
@ -902,6 +902,201 @@
</sect1> </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"> <sect1 id="catalog-pg-cast">
<title><structname>pg_cast</structname></title> <title><structname>pg_cast</structname></title>
@ -1065,8 +1260,8 @@
<row> <row>
<entry><structfield>relowner</structfield></entry> <entry><structfield>relowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the relation</entry> <entry>Owner of the relation</entry>
</row> </row>
@ -1492,8 +1687,8 @@
<row> <row>
<entry><structfield>conowner</structfield></entry> <entry><structfield>conowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the conversion</entry> <entry>Owner of the conversion</entry>
</row> </row>
@ -1576,8 +1771,8 @@
<row> <row>
<entry><structfield>datdba</structfield></entry> <entry><structfield>datdba</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></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> <entry>Owner of the database, usually the user who created it</entry>
</row> </row>
@ -1917,69 +2112,6 @@
</sect1> </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"> <sect1 id="catalog-pg-index">
<title><structname>pg_index</structname></title> <title><structname>pg_index</structname></title>
@ -2437,8 +2569,8 @@
<row> <row>
<entry><structfield>nspowner</structfield></entry> <entry><structfield>nspowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the namespace</entry> <entry>Owner of the namespace</entry>
</row> </row>
@ -2517,9 +2649,9 @@
<row> <row>
<entry><structfield>opcowner</structfield></entry> <entry><structfield>opcowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Operator class owner</entry> <entry>Owner of the operator class</entry>
</row> </row>
<row> <row>
@ -2606,8 +2738,8 @@
<row> <row>
<entry><structfield>oprowner</structfield></entry> <entry><structfield>oprowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the operator</entry> <entry>Owner of the operator</entry>
</row> </row>
@ -2786,8 +2918,8 @@
<row> <row>
<entry><structfield>proowner</structfield></entry> <entry><structfield>proowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the function</entry> <entry>Owner of the function</entry>
</row> </row>
@ -3066,114 +3198,6 @@
</sect1> </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"> <sect1 id="catalog-pg-statistic">
<title><structname>pg_statistic</structname></title> <title><structname>pg_statistic</structname></title>
@ -3374,8 +3398,8 @@
<row> <row>
<entry><structfield>spcowner</structfield></entry> <entry><structfield>spcowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></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> <entry>Owner of the tablespace, usually the user who created it</entry>
</row> </row>
@ -3586,8 +3610,8 @@
<row> <row>
<entry><structfield>typowner</structfield></entry> <entry><structfield>typowner</structfield></entry>
<entry><type>int4</type></entry> <entry><type>oid</type></entry>
<entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry>
<entry>Owner of the type</entry> <entry>Owner of the type</entry>
</row> </row>
@ -3922,6 +3946,11 @@
</thead> </thead>
<tbody> <tbody>
<row>
<entry><link linkend="view-pg-group"><structname>pg_group</structname></link></entry>
<entry>groups of database users</entry>
</row>
<row> <row>
<entry><link linkend="view-pg-indexes"><structname>pg_indexes</structname></link></entry> <entry><link linkend="view-pg-indexes"><structname>pg_indexes</structname></link></entry>
<entry>indexes</entry> <entry>indexes</entry>
@ -3937,6 +3966,11 @@
<entry>currently prepared transactions</entry> <entry>currently prepared transactions</entry>
</row> </row>
<row>
<entry><link linkend="view-pg-roles"><structname>pg_roles</structname></link></entry>
<entry>database roles</entry>
</row>
<row> <row>
<entry><link linkend="view-pg-rules"><structname>pg_rules</structname></link></entry> <entry><link linkend="view-pg-rules"><structname>pg_rules</structname></link></entry>
<entry>rules</entry> <entry>rules</entry>
@ -3947,6 +3981,11 @@
<entry>parameter settings</entry> <entry>parameter settings</entry>
</row> </row>
<row>
<entry><link linkend="view-pg-shadow"><structname>pg_shadow</structname></link></entry>
<entry>database users</entry>
</row>
<row> <row>
<entry><link linkend="view-pg-stats"><structname>pg_stats</structname></link></entry> <entry><link linkend="view-pg-stats"><structname>pg_stats</structname></link></entry>
<entry>planner statistics</entry> <entry>planner statistics</entry>
@ -3972,6 +4011,62 @@
</table> </table>
</sect1> </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"> <sect1 id="view-pg-indexes">
<title><structname>pg_indexes</structname></title> <title><structname>pg_indexes</structname></title>
@ -4332,7 +4427,7 @@
<row> <row>
<entry><structfield>owner</structfield></entry> <entry><structfield>owner</structfield></entry>
<entry><type>name</type></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> <entry>
Name of the user that executed the transaction Name of the user that executed the transaction
</entry> </entry>
@ -4361,6 +4456,110 @@
</sect1> </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"> <sect1 id="view-pg-rules">
<title><structname>pg_rules</structname></title> <title><structname>pg_rules</structname></title>
@ -4534,6 +4733,107 @@
</sect1> </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"> <sect1 id="view-pg-stats">
<title><structname>pg_stats</structname></title> <title><structname>pg_stats</structname></title>
@ -4720,7 +5020,7 @@
<row> <row>
<entry><structfield>tableowner</structfield></entry> <entry><structfield>tableowner</structfield></entry>
<entry><type>name</type></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> <entry>name of table's owner</entry>
</row> </row>
<row> <row>
@ -4764,7 +5064,7 @@
The view <structname>pg_user</structname> provides access to The view <structname>pg_user</structname> provides access to
information about database users. This is simply a publicly information about database users. This is simply a publicly
readable view of 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. that blanks out the password field.
</para> </para>
@ -4885,7 +5185,7 @@
<row> <row>
<entry><structfield>viewowner</structfield></entry> <entry><structfield>viewowner</structfield></entry>
<entry><type>name</type></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> <entry>name of view's owner</entry>
</row> </row>
<row> <row>

View file

@ -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 PostgreSQL documentation
--> -->
@ -8443,8 +8443,8 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, ..
<para> <para>
<function>has_table_privilege</function> checks whether a user <function>has_table_privilege</function> checks whether a user
can access a table in a particular way. The user can be can access a table in a particular way. The user can be
specified by name or by ID specified by name or by OID
(<literal>pg_user.usesysid</literal>), or if the argument is (<literal>pg_authid.oid</literal>), or if the argument is
omitted omitted
<function>current_user</function> is assumed. The table can be specified <function>current_user</function> is assumed. The table can be specified
by name or by OID. (Thus, there are actually six variants of 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> in it refer to the relation indicated by the second parameter</entry>
</row> </row>
<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><type>name</type></entry>
<entry>get user name with given ID</entry> <entry>get role name with given ID</entry>
</row> </row>
<row> <row>
<entry><literal><function>pg_get_serial_sequence</function>(<parameter>table_name</parameter>, <parameter>column_name</parameter>)</literal></entry> <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> <para>
<function>pg_get_userbyid</function> <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> <function>pg_get_serial_sequence</function>
fetches the name of the sequence associated with a serial or fetches the name of the sequence associated with a serial or
bigserial column. The name is suitably formatted bigserial column. The name is suitably formatted

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 * NOTES
* Each global transaction is associated with a global transaction * Each global transaction is associated with a global transaction
@ -107,7 +107,7 @@ typedef struct GlobalTransactionData
PGPROC proc; /* dummy proc */ PGPROC proc; /* dummy proc */
TimestampTz prepared_at; /* time of preparation */ TimestampTz prepared_at; /* time of preparation */
XLogRecPtr prepare_lsn; /* XLOG offset of prepare record */ 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 */ TransactionId locking_xid; /* top-level XID of backend working on xact */
bool valid; /* TRUE if fully prepared */ bool valid; /* TRUE if fully prepared */
char gid[GIDSIZE]; /* The GID assigned to the prepared xact */ char gid[GIDSIZE]; /* The GID assigned to the prepared xact */
@ -206,7 +206,7 @@ TwoPhaseShmemInit(void)
*/ */
GlobalTransaction GlobalTransaction
MarkAsPreparing(TransactionId xid, const char *gid, MarkAsPreparing(TransactionId xid, const char *gid,
TimestampTz prepared_at, AclId owner, Oid databaseid) TimestampTz prepared_at, Oid owner, Oid databaseid)
{ {
GlobalTransaction gxact; GlobalTransaction gxact;
int i; int i;
@ -350,7 +350,7 @@ MarkAsPrepared(GlobalTransaction gxact)
* Locate the prepared transaction and mark it busy for COMMIT or PREPARE. * Locate the prepared transaction and mark it busy for COMMIT or PREPARE.
*/ */
static GlobalTransaction static GlobalTransaction
LockGXact(const char *gid, AclId user) LockGXact(const char *gid, Oid user)
{ {
int i; int i;
@ -559,7 +559,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared", TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
TIMESTAMPTZOID, -1, 0); TIMESTAMPTZOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid", TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
INT4OID, -1, 0); OIDOID, -1, 0);
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid", TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
OIDOID, -1, 0); OIDOID, -1, 0);
@ -601,7 +601,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
values[0] = TransactionIdGetDatum(gxact->proc.xid); values[0] = TransactionIdGetDatum(gxact->proc.xid);
values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid)); values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid));
values[2] = TimestampTzGetDatum(gxact->prepared_at); values[2] = TimestampTzGetDatum(gxact->prepared_at);
values[3] = Int32GetDatum(gxact->owner); values[3] = ObjectIdGetDatum(gxact->owner);
values[4] = ObjectIdGetDatum(gxact->proc.databaseId); values[4] = ObjectIdGetDatum(gxact->proc.databaseId);
tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
@ -690,7 +690,7 @@ typedef struct TwoPhaseFileHeader
TransactionId xid; /* original transaction XID */ TransactionId xid; /* original transaction XID */
Oid database; /* OID of database it was in */ Oid database; /* OID of database it was in */
TimestampTz prepared_at; /* time of preparation */ 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 nsubxacts; /* number of following subxact XIDs */
int32 ncommitrels; /* number of delete-on-commit rels */ int32 ncommitrels; /* number of delete-on-commit rels */
int32 nabortrels; /* number of delete-on-abort rels */ int32 nabortrels; /* number of delete-on-abort rels */

View file

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 */ * context */
ResourceOwner curTransactionOwner; /* my query resources */ ResourceOwner curTransactionOwner; /* my query resources */
List *childXids; /* subcommitted child XIDs */ 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 */ bool prevXactReadOnly; /* entry-time xact r/o state */
struct TransactionStateData *parent; /* back link to parent */ struct TransactionStateData *parent; /* back link to parent */
} TransactionStateData; } TransactionStateData;
@ -1488,8 +1488,10 @@ CommitTransaction(void)
/* NOTIFY commit must come before lower-level cleanup */ /* NOTIFY commit must come before lower-level cleanup */
AtCommit_Notify(); 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); AtEOXact_UpdateFlatFiles(true);
/* Prevent cancel/die interrupt while cleaning up */ /* Prevent cancel/die interrupt while cleaning up */
@ -3847,7 +3849,7 @@ PushTransaction(void)
{ {
TransactionState p = CurrentTransactionState; TransactionState p = CurrentTransactionState;
TransactionState s; TransactionState s;
AclId currentUser; Oid currentUser;
/* /*
* At present, GetUserId cannot fail, but let's not assume that. Get * At present, GetUserId cannot fail, but let's not assume that. Get

View file

@ -2,7 +2,7 @@
# #
# Makefile for backend/catalog # 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_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_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_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_namespace.h pg_conversion.h pg_database.h \
pg_tablespace.h pg_depend.h indexing.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) pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
@ -21,15 +21,15 @@
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_conversion.h" #include "catalog/pg_conversion.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_group.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -76,10 +76,10 @@ dumpacl(Acl *acl)
* all granted privileges appear to flow from the object owner, and there * all granted privileges appear to flow from the object owner, and there
* are never multiple "original sources" of a privilege. * are never multiple "original sources" of a privilege.
*/ */
static AclId static Oid
select_grantor(AclId ownerId) select_grantor(Oid ownerId)
{ {
AclId grantorId; Oid grantorId;
grantorId = GetUserId(); grantorId = GetUserId();
@ -105,7 +105,7 @@ static Acl *
merge_acl_with_grant(Acl *old_acl, bool is_grant, merge_acl_with_grant(Acl *old_acl, bool is_grant,
bool grant_option, DropBehavior behavior, bool grant_option, DropBehavior behavior,
List *grantees, AclMode privileges, List *grantees, AclMode privileges,
AclId grantor_uid, AclId owner_uid) Oid grantorId, Oid ownerId)
{ {
unsigned modechg; unsigned modechg;
ListCell *j; ListCell *j;
@ -122,41 +122,25 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
{ {
PrivGrantee *grantee = (PrivGrantee *) lfirst(j); PrivGrantee *grantee = (PrivGrantee *) lfirst(j);
AclItem aclitem; AclItem aclitem;
uint32 idtype;
Acl *newer_acl; Acl *newer_acl;
if (grantee->username) if (grantee->rolname)
{ aclitem.ai_grantee = get_roleid_checked(grantee->rolname);
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;
}
else else
{ aclitem.ai_grantee = ACL_ID_PUBLIC;
aclitem. ai_grantee = ACL_ID_WORLD;
idtype = ACL_IDTYPE_WORLD;
}
/* /*
* Grant options can only be granted to individual users, not * Grant options can only be granted to individual roles, not PUBLIC.
* groups or public. The reason is that if a user would re-grant * The reason is that if a user would re-grant a privilege that he
* a privilege that he held through a group having a grant option, * held through PUBLIC, and later the user is removed, the situation
* and later the user is removed from the group, the situation is * is impossible to clean up.
* 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, ereport(ERROR,
(errcode(ERRCODE_INVALID_GRANT_OPERATION), (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 * 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 * and its grant option, while REVOKE GRANT OPTION revokes only
* the option. * 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,
(!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS, (!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS);
idtype);
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 */ /* avoid memory leak when there are many grantees */
pfree(new_acl); pfree(new_acl);
@ -261,8 +244,8 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
AclMode this_privileges; AclMode this_privileges;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
AclId grantorId; Oid grantorId;
AclId ownerId; Oid ownerId;
HeapTuple newtuple; HeapTuple newtuple;
Datum values[Natts_pg_class]; Datum values[Natts_pg_class];
char nulls[Natts_pg_class]; char nulls[Natts_pg_class];
@ -430,8 +413,8 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
AclMode this_privileges; AclMode this_privileges;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
AclId grantorId; Oid grantorId;
AclId ownerId; Oid ownerId;
HeapTuple newtuple; HeapTuple newtuple;
Datum values[Natts_pg_database]; Datum values[Natts_pg_database];
char nulls[Natts_pg_database]; char nulls[Natts_pg_database];
@ -587,8 +570,8 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
AclMode this_privileges; AclMode this_privileges;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
AclId grantorId; Oid grantorId;
AclId ownerId; Oid ownerId;
HeapTuple newtuple; HeapTuple newtuple;
Datum values[Natts_pg_proc]; Datum values[Natts_pg_proc];
char nulls[Natts_pg_proc]; char nulls[Natts_pg_proc];
@ -740,8 +723,8 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
AclMode this_privileges; AclMode this_privileges;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
AclId grantorId; Oid grantorId;
AclId ownerId; Oid ownerId;
HeapTuple newtuple; HeapTuple newtuple;
Datum values[Natts_pg_language]; Datum values[Natts_pg_language];
char nulls[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 * Note: for now, languages are treated as owned by the bootstrap
* user. We should add an owner column to pg_language instead. * user. We should add an owner column to pg_language instead.
*/ */
ownerId = BOOTSTRAP_USESYSID; ownerId = BOOTSTRAP_SUPERUSERID;
grantorId = select_grantor(ownerId); grantorId = select_grantor(ownerId);
/* /*
@ -903,8 +886,8 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
AclMode this_privileges; AclMode this_privileges;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
AclId grantorId; Oid grantorId;
AclId ownerId; Oid ownerId;
HeapTuple newtuple; HeapTuple newtuple;
Datum values[Natts_pg_namespace]; Datum values[Natts_pg_namespace];
char nulls[Natts_pg_namespace]; char nulls[Natts_pg_namespace];
@ -1059,8 +1042,8 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
AclMode this_privileges; AclMode this_privileges;
Acl *old_acl; Acl *old_acl;
Acl *new_acl; Acl *new_acl;
AclId grantorId; Oid grantorId;
AclId ownerId; Oid ownerId;
HeapTuple newtuple; HeapTuple newtuple;
Datum values[Natts_pg_tablespace]; Datum values[Natts_pg_tablespace];
char nulls[Natts_pg_tablespace]; char nulls[Natts_pg_tablespace];
@ -1207,27 +1190,6 @@ privilege_to_string(AclMode privilege)
return NULL; /* appease compiler */ return NULL; /* appease compiler */
} }
/*
* Convert group ID to name, or return NULL if group can't be found
*/
char *
get_groname(AclId grosysid)
{
HeapTuple tuple;
char *name = NULL;
tuple = SearchSysCache(GROSYSID,
ObjectIdGetDatum(grosysid),
0, 0, 0);
if (HeapTupleIsValid(tuple))
{
name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname));
ReleaseSysCache(tuple);
}
return name;
}
/* /*
* Standardized reporting of aclcheck permissions failures. * Standardized reporting of aclcheck permissions failures.
* *
@ -1310,26 +1272,26 @@ aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
} }
/* Check if given userid has usecatupd privilege according to pg_shadow */ /* Check if given user has rolcatupdate privilege according to pg_authid */
static bool static bool
has_usecatupd(AclId userid) has_rolcatupdate(Oid roleid)
{ {
bool usecatupd; bool rolcatupdate;
HeapTuple tuple; HeapTuple tuple;
tuple = SearchSysCache(SHADOWSYSID, tuple = SearchSysCache(AUTHOID,
ObjectIdGetDatum(userid), ObjectIdGetDatum(roleid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (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); ReleaseSysCache(tuple);
return usecatupd; return rolcatupdate;
} }
@ -1344,7 +1306,7 @@ has_usecatupd(AclId userid)
* below. * below.
*/ */
AclMode AclMode
pg_class_aclmask(Oid table_oid, AclId userid, pg_class_aclmask(Oid table_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
@ -1353,7 +1315,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
AclId ownerId; Oid ownerId;
/* /*
* Must get the relation's tuple from pg_class * 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 * 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 * themselves from themselves.) Also allow it if
* allowSystemTableMods. * allowSystemTableMods.
* *
@ -1381,7 +1343,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) && if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
IsSystemClass(classForm) && IsSystemClass(classForm) &&
classForm->relkind != RELKIND_VIEW && classForm->relkind != RELKIND_VIEW &&
!has_usecatupd(userid) && !has_rolcatupdate(roleid) &&
!allowSystemTableMods) !allowSystemTableMods)
{ {
#ifdef ACLDEBUG #ifdef ACLDEBUG
@ -1393,10 +1355,10 @@ pg_class_aclmask(Oid table_oid, AclId userid,
/* /*
* Otherwise, superusers bypass all permission-checking. * Otherwise, superusers bypass all permission-checking.
*/ */
if (superuser_arg(userid)) if (superuser_arg(roleid))
{ {
#ifdef ACLDEBUG #ifdef ACLDEBUG
elog(DEBUG2, "%u is superuser, home free", userid); elog(DEBUG2, "OID %u is superuser, home free", roleid);
#endif #endif
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
return mask; return mask;
@ -1421,7 +1383,7 @@ pg_class_aclmask(Oid table_oid, AclId userid,
acl = DatumGetAclP(aclDatum); 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 we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) 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 * Exported routine for examining a user's privileges for a database
*/ */
AclMode AclMode
pg_database_aclmask(Oid db_oid, AclId userid, pg_database_aclmask(Oid db_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
@ -1447,10 +1409,10 @@ pg_database_aclmask(Oid db_oid, AclId userid,
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
AclId ownerId; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return mask; return mask;
/* /*
@ -1487,7 +1449,7 @@ pg_database_aclmask(Oid db_oid, AclId userid,
acl = DatumGetAclP(aclDatum); 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 we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) 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 * Exported routine for examining a user's privileges for a function
*/ */
AclMode AclMode
pg_proc_aclmask(Oid proc_oid, AclId userid, pg_proc_aclmask(Oid proc_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
@ -1511,10 +1473,10 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
AclId ownerId; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return mask; return mask;
/* /*
@ -1544,7 +1506,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid,
acl = DatumGetAclP(aclDatum); 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 we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) 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 * Exported routine for examining a user's privileges for a language
*/ */
AclMode AclMode
pg_language_aclmask(Oid lang_oid, AclId userid, pg_language_aclmask(Oid lang_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
@ -1567,10 +1529,10 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
AclId ownerId; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return mask; return mask;
/* /*
@ -1585,7 +1547,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
errmsg("language with OID %u does not exist", lang_oid))); errmsg("language with OID %u does not exist", lang_oid)));
/* XXX pg_language should have an owner column, but doesn't */ /* 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, aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl,
&isNull); &isNull);
@ -1601,7 +1563,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid,
acl = DatumGetAclP(aclDatum); 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 we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) 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 * Exported routine for examining a user's privileges for a namespace
*/ */
AclMode AclMode
pg_namespace_aclmask(Oid nsp_oid, AclId userid, pg_namespace_aclmask(Oid nsp_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
@ -1624,10 +1586,10 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
AclId ownerId; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return mask; return mask;
/* /*
@ -1685,7 +1647,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid,
acl = DatumGetAclP(aclDatum); 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 we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) 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 * Exported routine for examining a user's privileges for a tablespace
*/ */
AclMode AclMode
pg_tablespace_aclmask(Oid spc_oid, AclId userid, pg_tablespace_aclmask(Oid spc_oid, Oid roleid,
AclMode mask, AclMaskHow how) AclMode mask, AclMaskHow how)
{ {
AclMode result; AclMode result;
@ -1711,7 +1673,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
Datum aclDatum; Datum aclDatum;
bool isNull; bool isNull;
Acl *acl; Acl *acl;
AclId ownerId; Oid ownerId;
/* /*
* Only shared relations can be stored in global space; don't let even * 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; return 0;
/* Otherwise, superusers bypass all permission checking. */ /* Otherwise, superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return mask; return mask;
/* /*
@ -1758,7 +1720,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
acl = DatumGetAclP(aclDatum); 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 we have a detoasted copy, free it */
if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
@ -1779,9 +1741,9 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid,
* ACLCHECK_NO_PRIV). * ACLCHECK_NO_PRIV).
*/ */
AclResult 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; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; 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 * Exported routine for checking a user's access privileges to a database
*/ */
AclResult 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; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; 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 * Exported routine for checking a user's access privileges to a function
*/ */
AclResult 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; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; 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 * Exported routine for checking a user's access privileges to a language
*/ */
AclResult 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; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; 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 * Exported routine for checking a user's access privileges to a namespace
*/ */
AclResult 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; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; 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 * Exported routine for checking a user's access privileges to a tablespace
*/ */
AclResult 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; return ACLCHECK_OK;
else else
return ACLCHECK_NO_PRIV; 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). * Ownership check for a relation (specified by OID).
*/ */
bool bool
pg_class_ownercheck(Oid class_oid, AclId userid) pg_class_ownercheck(Oid class_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(RELOID, tuple = SearchSysCache(RELOID,
@ -1869,24 +1831,24 @@ pg_class_ownercheck(Oid class_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_TABLE), (errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation with OID %u does not exist", class_oid))); 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); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }
/* /*
* Ownership check for a type (specified by OID). * Ownership check for a type (specified by OID).
*/ */
bool bool
pg_type_ownercheck(Oid type_oid, AclId userid) pg_type_ownercheck(Oid type_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(TYPEOID, tuple = SearchSysCache(TYPEOID,
@ -1897,24 +1859,24 @@ pg_type_ownercheck(Oid type_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type with OID %u does not exist", type_oid))); 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); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }
/* /*
* Ownership check for an operator (specified by OID). * Ownership check for an operator (specified by OID).
*/ */
bool bool
pg_oper_ownercheck(Oid oper_oid, AclId userid) pg_oper_ownercheck(Oid oper_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(OPEROID, tuple = SearchSysCache(OPEROID,
@ -1925,24 +1887,24 @@ pg_oper_ownercheck(Oid oper_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_FUNCTION), (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("operator with OID %u does not exist", oper_oid))); 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); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }
/* /*
* Ownership check for a function (specified by OID). * Ownership check for a function (specified by OID).
*/ */
bool bool
pg_proc_ownercheck(Oid proc_oid, AclId userid) pg_proc_ownercheck(Oid proc_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(PROCOID, tuple = SearchSysCache(PROCOID,
@ -1953,24 +1915,24 @@ pg_proc_ownercheck(Oid proc_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_FUNCTION), (errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function with OID %u does not exist", proc_oid))); 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); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }
/* /*
* Ownership check for a namespace (specified by OID). * Ownership check for a namespace (specified by OID).
*/ */
bool bool
pg_namespace_ownercheck(Oid nsp_oid, AclId userid) pg_namespace_ownercheck(Oid nsp_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(NAMESPACEOID, tuple = SearchSysCache(NAMESPACEOID,
@ -1981,27 +1943,27 @@ pg_namespace_ownercheck(Oid nsp_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_SCHEMA), (errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("schema with OID %u does not exist", nsp_oid))); 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); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }
/* /*
* Ownership check for a tablespace (specified by OID). * Ownership check for a tablespace (specified by OID).
*/ */
bool bool
pg_tablespace_ownercheck(Oid spc_oid, AclId userid) pg_tablespace_ownercheck(Oid spc_oid, Oid roleid)
{ {
Relation pg_tablespace; Relation pg_tablespace;
ScanKeyData entry[1]; ScanKeyData entry[1];
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple spctuple; HeapTuple spctuple;
int32 spcowner; Oid spcowner;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
/* There's no syscache for pg_tablespace, so must look the hard way */ /* 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_endscan(scan);
heap_close(pg_tablespace, AccessShareLock); heap_close(pg_tablespace, AccessShareLock);
return userid == spcowner; return is_member_of_role(roleid, spcowner);
} }
/* /*
* Ownership check for an operator class (specified by OID). * Ownership check for an operator class (specified by OID).
*/ */
bool bool
pg_opclass_ownercheck(Oid opc_oid, AclId userid) pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(CLAOID, tuple = SearchSysCache(CLAOID,
@ -2049,27 +2011,27 @@ pg_opclass_ownercheck(Oid opc_oid, AclId userid)
errmsg("operator class with OID %u does not exist", errmsg("operator class with OID %u does not exist",
opc_oid))); opc_oid)));
owner_id = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner;
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }
/* /*
* Ownership check for a database (specified by OID). * Ownership check for a database (specified by OID).
*/ */
bool bool
pg_database_ownercheck(Oid db_oid, AclId userid) pg_database_ownercheck(Oid db_oid, Oid roleid)
{ {
Relation pg_database; Relation pg_database;
ScanKeyData entry[1]; ScanKeyData entry[1];
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple dbtuple; HeapTuple dbtuple;
int32 dba; Oid dba;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
/* There's no syscache for pg_database, so must look the hard way */ /* 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_endscan(scan);
heap_close(pg_database, AccessShareLock); heap_close(pg_database, AccessShareLock);
return userid == dba; return is_member_of_role(roleid, dba);
} }
/* /*
* Ownership check for a conversion (specified by OID). * Ownership check for a conversion (specified by OID).
*/ */
bool bool
pg_conversion_ownercheck(Oid conv_oid, AclId userid) pg_conversion_ownercheck(Oid conv_oid, Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
AclId owner_id; Oid ownerId;
/* Superusers bypass all permission checking. */ /* Superusers bypass all permission checking. */
if (superuser_arg(userid)) if (superuser_arg(roleid))
return true; return true;
tuple = SearchSysCache(CONOID, tuple = SearchSysCache(CONOID,
@ -2116,9 +2078,9 @@ pg_conversion_ownercheck(Oid conv_oid, AclId userid)
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("conversion with OID %u does not exist", conv_oid))); 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); ReleaseSysCache(tuple);
return userid == owner_id; return is_member_of_role(roleid, ownerId);
} }

View file

@ -11,7 +11,7 @@
# #
# #
# IDENTIFICATION # 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 # NOTES
# non-essential whitespace is removed from the generated file. # non-essential whitespace is removed from the generated file.
@ -114,6 +114,14 @@ for dir in $INCLUDE_DIRS; do
fi fi
done 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 # Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h
for dir in $INCLUDE_DIRS; do for dir in $INCLUDE_DIRS; do
if [ -f "$dir/catalog/pg_namespace.h" ]; then 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/^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/NAMEDATALEN/$NAMEDATALEN/g" \
-e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \ -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \
| $AWK ' | $AWK '

View file

@ -4,7 +4,7 @@
* *
* Copyright (c) 2003-2005, PostgreSQL Global Development Group * 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 CREATE VIEW applicable_roles AS
SELECT CAST(current_user AS sql_identifier) AS grantee, SELECT CAST(current_user AS sql_identifier) AS grantee,
CAST(g.groname AS sql_identifier) AS role_name, CAST(a.rolname AS sql_identifier) AS role_name,
CAST('NO' AS character_data) AS is_grantable 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) WHERE b.rolname = current_user;
AND u.usename = current_user;
GRANT SELECT ON applicable_roles TO PUBLIC; GRANT SELECT ON applicable_roles TO PUBLIC;
@ -282,7 +282,7 @@ GRANT SELECT ON column_domain_usage TO PUBLIC;
*/ */
CREATE VIEW column_privileges AS 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(grantee.name AS sql_identifier) AS grantee,
CAST(current_database() AS sql_identifier) AS table_catalog, CAST(current_database() AS sql_identifier) AS table_catalog,
CAST(nc.nspname AS sql_identifier) AS table_schema, 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(pr.type AS character_data) AS privilege_type,
CAST( CAST(
CASE WHEN aclcontains(c.relacl, 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 THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_attribute a, FROM pg_attribute a,
pg_class c, pg_class c,
pg_namespace nc, pg_namespace nc,
pg_user u_grantor, pg_authid u_grantor,
( (
SELECT usesysid, 0, usename FROM pg_user SELECT oid, rolname FROM pg_authid
UNION ALL UNION ALL
SELECT 0, grosysid, groname FROM pg_group SELECT 0, 'PUBLIC'
UNION ALL ) AS grantee (oid, name),
SELECT 0, 0, 'PUBLIC'
) AS grantee (usesysid, grosysid, name),
(SELECT 'SELECT' UNION ALL (SELECT 'SELECT' UNION ALL
SELECT 'INSERT' UNION ALL SELECT 'INSERT' UNION ALL
SELECT 'UPDATE' UNION ALL SELECT 'UPDATE' UNION ALL
@ -316,8 +314,8 @@ CREATE VIEW column_privileges AS
AND NOT a.attisdropped AND NOT a.attisdropped
AND c.relkind IN ('r', 'v') AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl, AND aclcontains(c.relacl,
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false)) makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
AND (u_grantor.usename = current_user AND (u_grantor.rolname = current_user
OR grantee.name = current_user OR grantee.name = current_user
OR grantee.name = 'PUBLIC'); OR grantee.name = 'PUBLIC');
@ -693,10 +691,10 @@ GRANT SELECT ON domains TO PUBLIC;
*/ */
CREATE VIEW enabled_roles AS CREATE VIEW enabled_roles AS
SELECT CAST(g.groname AS sql_identifier) AS role_name SELECT CAST(a.rolname AS sql_identifier) AS role_name
FROM pg_group g, pg_user u FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid))
WHERE u.usesysid = ANY (g.grolist) join pg_authid b ON (m.member = b.oid))
AND u.usename = current_user; WHERE b.rolname = current_user;
GRANT SELECT ON enabled_roles TO PUBLIC; 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(pr.type AS character_data) AS privilege_type,
CAST( CAST(
CASE WHEN aclcontains(c.relacl, 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 THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_attribute a, FROM pg_attribute a,
@ -884,7 +882,7 @@ CREATE VIEW role_column_grants AS
AND NOT a.attisdropped AND NOT a.attisdropped
AND c.relkind IN ('r', 'v') AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl, 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); AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
GRANT SELECT ON role_column_grants TO PUBLIC; 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('EXECUTE' AS character_data) AS privilege_type,
CAST( CAST(
CASE WHEN aclcontains(p.proacl, 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 THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_proc p, FROM pg_proc p,
@ -917,7 +915,7 @@ CREATE VIEW role_routine_grants AS
WHERE p.pronamespace = n.oid WHERE p.pronamespace = n.oid
AND aclcontains(p.proacl, 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); AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
GRANT SELECT ON role_routine_grants TO PUBLIC; 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(pr.type AS character_data) AS privilege_type,
CAST( CAST(
CASE WHEN aclcontains(c.relacl, 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, THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
CAST('NO' AS character_data) AS with_hierarchy CAST('NO' AS character_data) AS with_hierarchy
@ -956,7 +954,7 @@ CREATE VIEW role_table_grants AS
WHERE c.relnamespace = nc.oid WHERE c.relnamespace = nc.oid
AND c.relkind IN ('r', 'v') AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl, 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); AND g_grantee.groname IN (SELECT role_name FROM enabled_roles);
GRANT SELECT ON role_table_grants TO PUBLIC; 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 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(grantee.name AS sql_identifier) AS grantee,
CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(current_database() AS sql_identifier) AS specific_catalog,
CAST(n.nspname AS sql_identifier) AS specific_schema, 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('EXECUTE' AS character_data) AS privilege_type,
CAST( CAST(
CASE WHEN aclcontains(p.proacl, 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 THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable
FROM pg_proc p, FROM pg_proc p,
pg_namespace n, pg_namespace n,
pg_user u_grantor, pg_authid u_grantor,
( (
SELECT usesysid, 0, usename FROM pg_user SELECT oid, rolname FROM pg_authid
UNION ALL UNION ALL
SELECT 0, grosysid, groname FROM pg_group SELECT 0, 'PUBLIC'
UNION ALL ) AS grantee (oid, name)
SELECT 0, 0, 'PUBLIC'
) AS grantee (usesysid, grosysid, name)
WHERE p.pronamespace = n.oid WHERE p.pronamespace = n.oid
AND aclcontains(p.proacl, AND aclcontains(p.proacl,
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false)) makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', false))
AND (u_grantor.usename = current_user AND (u_grantor.rolname = current_user
OR grantee.name = current_user OR grantee.name = current_user
OR grantee.name = 'PUBLIC'); OR grantee.name = 'PUBLIC');
@ -1338,7 +1334,7 @@ GRANT SELECT ON table_constraints TO PUBLIC;
*/ */
CREATE VIEW table_privileges AS 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(grantee.name AS sql_identifier) AS grantee,
CAST(current_database() AS sql_identifier) AS table_catalog, CAST(current_database() AS sql_identifier) AS table_catalog,
CAST(nc.nspname AS sql_identifier) AS table_schema, 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(pr.type AS character_data) AS privilege_type,
CAST( CAST(
CASE WHEN aclcontains(c.relacl, 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, THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable,
CAST('NO' AS character_data) AS with_hierarchy CAST('NO' AS character_data) AS with_hierarchy
FROM pg_class c, FROM pg_class c,
pg_namespace nc, pg_namespace nc,
pg_user u_grantor, pg_authid u_grantor,
( (
SELECT usesysid, 0, usename FROM pg_user SELECT oid, rolname FROM pg_authid
UNION ALL UNION ALL
SELECT 0, grosysid, groname FROM pg_group SELECT 0, 'PUBLIC'
UNION ALL ) AS grantee (oid, name),
SELECT 0, 0, 'PUBLIC'
) AS grantee (usesysid, grosysid, name),
(SELECT 'SELECT' UNION ALL (SELECT 'SELECT' UNION ALL
SELECT 'DELETE' UNION ALL SELECT 'DELETE' UNION ALL
SELECT 'INSERT' UNION ALL SELECT 'INSERT' UNION ALL
@ -1371,8 +1365,8 @@ CREATE VIEW table_privileges AS
WHERE c.relnamespace = nc.oid WHERE c.relnamespace = nc.oid
AND c.relkind IN ('r', 'v') AND c.relkind IN ('r', 'v')
AND aclcontains(c.relacl, AND aclcontains(c.relacl,
makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false)) makeaclitem(grantee.oid, u_grantor.oid, pr.type, false))
AND (u_grantor.usename = current_user AND (u_grantor.rolname = current_user
OR grantee.name = current_user OR grantee.name = current_user
OR grantee.name = 'PUBLIC'); OR grantee.name = 'PUBLIC');

View file

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 "access/xact.h"
#include "catalog/dependency.h" #include "catalog/dependency.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_conversion.h" #include "catalog/pg_conversion.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
@ -1499,7 +1499,7 @@ FindDefaultConversionProc(int4 for_encoding, int4 to_encoding)
static void static void
recomputeNamespacePath(void) recomputeNamespacePath(void)
{ {
AclId userId = GetUserId(); Oid roleid = GetUserId();
char *rawname; char *rawname;
List *namelist; List *namelist;
List *oidlist; List *oidlist;
@ -1511,7 +1511,7 @@ recomputeNamespacePath(void)
/* /*
* Do nothing if path is already valid. * Do nothing if path is already valid.
*/ */
if (namespaceSearchPathValid && namespaceUser == userId) if (namespaceSearchPathValid && namespaceUser == roleid)
return; return;
/* Need a modifiable copy of namespace_search_path string */ /* Need a modifiable copy of namespace_search_path string */
@ -1542,21 +1542,21 @@ recomputeNamespacePath(void)
/* $user --- substitute namespace matching user name, if any */ /* $user --- substitute namespace matching user name, if any */
HeapTuple tuple; HeapTuple tuple;
tuple = SearchSysCache(SHADOWSYSID, tuple = SearchSysCache(AUTHOID,
ObjectIdGetDatum(userId), ObjectIdGetDatum(roleid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(tuple)) 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, namespaceId = GetSysCacheOid(NAMESPACENAME,
CStringGetDatum(uname), CStringGetDatum(rname),
0, 0, 0); 0, 0, 0);
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
if (OidIsValid(namespaceId) && if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) && !list_member_oid(oidlist, namespaceId) &&
pg_namespace_aclcheck(namespaceId, userId, pg_namespace_aclcheck(namespaceId, roleid,
ACL_USAGE) == ACLCHECK_OK) ACL_USAGE) == ACLCHECK_OK)
oidlist = lappend_oid(oidlist, namespaceId); oidlist = lappend_oid(oidlist, namespaceId);
} }
@ -1569,7 +1569,7 @@ recomputeNamespacePath(void)
0, 0, 0); 0, 0, 0);
if (OidIsValid(namespaceId) && if (OidIsValid(namespaceId) &&
!list_member_oid(oidlist, namespaceId) && !list_member_oid(oidlist, namespaceId) &&
pg_namespace_aclcheck(namespaceId, userId, pg_namespace_aclcheck(namespaceId, roleid,
ACL_USAGE) == ACLCHECK_OK) ACL_USAGE) == ACLCHECK_OK)
oidlist = lappend_oid(oidlist, namespaceId); oidlist = lappend_oid(oidlist, namespaceId);
} }
@ -1622,7 +1622,7 @@ recomputeNamespacePath(void)
/* Mark the path valid. */ /* Mark the path valid. */
namespaceSearchPathValid = true; namespaceSearchPathValid = true;
namespaceUser = userId; namespaceUser = roleid;
/* Clean up. */ /* Clean up. */
pfree(rawname); pfree(rawname);
@ -1674,7 +1674,7 @@ InitTempTableNamespace(void)
* that access the temp namespace for my own backend skip * that access the temp namespace for my own backend skip
* permissions checks on it. * permissions checks on it.
*/ */
namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID); namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID);
/* Advance command counter to make namespace visible */ /* Advance command counter to make namespace visible */
CommandCounterIncrement(); CommandCounterIncrement();
} }

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 Oid
ConversionCreate(const char *conname, Oid connamespace, ConversionCreate(const char *conname, Oid connamespace,
AclId conowner, Oid conowner,
int32 conforencoding, int32 contoencoding, int32 conforencoding, int32 contoencoding,
Oid conproc, bool def) Oid conproc, bool def)
{ {
@ -95,7 +95,7 @@ ConversionCreate(const char *conname, Oid connamespace,
namestrcpy(&cname, conname); namestrcpy(&cname, conname);
values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname); values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname);
values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace); 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_conforencoding - 1] = Int32GetDatum(conforencoding);
values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding); values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding);
values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc); values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc);

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 Oid
NamespaceCreate(const char *nspName, int32 ownerSysId) NamespaceCreate(const char *nspName, Oid ownerId)
{ {
Relation nspdesc; Relation nspdesc;
HeapTuple tup; HeapTuple tup;
@ -57,7 +57,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId)
} }
namestrcpy(&nname, nspName); namestrcpy(&nname, nspName);
values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname); 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'; nulls[Anum_pg_namespace_nspacl - 1] = 'n';
nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock); nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* these routines moved here from commands/define.c and somewhat cleaned up. * these routines moved here from commands/define.c and somewhat cleaned up.
@ -235,7 +235,7 @@ OperatorShellMake(const char *operatorName,
namestrcpy(&oname, operatorName); namestrcpy(&oname, operatorName);
values[i++] = NameGetDatum(&oname); /* oprname */ values[i++] = NameGetDatum(&oname); /* oprname */
values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */ 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++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */
values[i++] = BoolGetDatum(false); /* oprcanhash */ values[i++] = BoolGetDatum(false); /* oprcanhash */
values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */ values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */
@ -519,7 +519,7 @@ OperatorCreate(const char *operatorName,
namestrcpy(&oname, operatorName); namestrcpy(&oname, operatorName);
values[i++] = NameGetDatum(&oname); /* oprname */ values[i++] = NameGetDatum(&oname); /* oprname */
values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */ 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++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */
values[i++] = BoolGetDatum(canHash); /* oprcanhash */ values[i++] = BoolGetDatum(canHash); /* oprcanhash */
values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */ values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); namestrcpy(&procname, procedureName);
values[Anum_pg_proc_proname - 1] = NameGetDatum(&procname); values[Anum_pg_proc_proname - 1] = NameGetDatum(&procname);
values[Anum_pg_proc_pronamespace - 1] = ObjectIdGetDatum(procNamespace); 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_prolang - 1] = ObjectIdGetDatum(languageObjectId);
values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg); values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg);
values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer); values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer);

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); namestrcpy(&name, typeName);
values[i++] = NameGetDatum(&name); /* typname */ values[i++] = NameGetDatum(&name); /* typname */
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */ values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
values[i++] = Int32GetDatum(GetUserId()); /* typowner */ values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */
values[i++] = Int16GetDatum(internalSize); /* typlen */ values[i++] = Int16GetDatum(internalSize); /* typlen */
values[i++] = BoolGetDatum(passedByValue); /* typbyval */ values[i++] = BoolGetDatum(passedByValue); /* typbyval */
values[i++] = CharGetDatum(typeType); /* typtype */ values[i++] = CharGetDatum(typeType); /* typtype */

View file

@ -3,9 +3,45 @@
* *
* Copyright (c) 1996-2005, PostgreSQL Global Development Group * 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 CREATE VIEW pg_user AS
SELECT SELECT
usename, usename,
@ -111,10 +147,10 @@ CREATE VIEW pg_locks AS
CREATE VIEW pg_prepared_xacts AS CREATE VIEW pg_prepared_xacts AS
SELECT P.transaction, P.gid, P.prepared, 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 FROM pg_prepared_xact() AS P
(transaction xid, gid text, prepared timestamptz, ownerid int4, dbid oid) (transaction xid, gid text, prepared timestamptz, ownerid oid, dbid oid)
LEFT JOIN pg_shadow U ON P.ownerid = U.usesysid LEFT JOIN pg_authid U ON P.ownerid = U.oid
LEFT JOIN pg_database D ON P.dbid = D.oid; LEFT JOIN pg_database D ON P.dbid = D.oid;
CREATE VIEW pg_settings AS CREATE VIEW pg_settings AS
@ -269,7 +305,7 @@ CREATE VIEW pg_stat_activity AS
D.datname AS datname, D.datname AS datname,
pg_stat_get_backend_pid(S.backendid) AS procpid, pg_stat_get_backend_pid(S.backendid) AS procpid,
pg_stat_get_backend_userid(S.backendid) AS usesysid, 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(S.backendid) AS current_query,
pg_stat_get_backend_activity_start(S.backendid) AS query_start, 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_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 pg_stat_get_backend_client_port(S.backendid) AS client_port
FROM pg_database D, FROM pg_database D,
(SELECT pg_stat_get_backend_idset() AS backendid) AS S, (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 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 CREATE VIEW pg_stat_database AS
SELECT SELECT

View file

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * 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 * Change aggregate owner
*/ */
void void
AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId)
{ {
Oid basetypeOid; Oid basetypeOid;
Oid procOid; 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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * 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 */ /* Otherwise, must be superuser to change object ownership */
if (!superuser()) 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 * Modify the owner --- okay to scribble on tup because it's a
* copy * copy
*/ */
procForm->proowner = newOwnerSysId; procForm->proowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup); CatalogUpdateIndexes(rel, tup);

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); RenameFunction(stmt->object, stmt->objarg, stmt->newname);
break; break;
case OBJECT_GROUP:
RenameGroup(stmt->subname, stmt->newname);
break;
case OBJECT_LANGUAGE: case OBJECT_LANGUAGE:
RenameLanguage(stmt->subname, stmt->newname); RenameLanguage(stmt->subname, stmt->newname);
break; break;
@ -76,6 +72,10 @@ ExecRenameStmt(RenameStmt *stmt)
RenameOpClass(stmt->object, stmt->subname, stmt->newname); RenameOpClass(stmt->object, stmt->subname, stmt->newname);
break; break;
case OBJECT_ROLE:
RenameRole(stmt->subname, stmt->newname);
break;
case OBJECT_SCHEMA: case OBJECT_SCHEMA:
RenameSchema(stmt->subname, stmt->newname); RenameSchema(stmt->subname, stmt->newname);
break; break;
@ -84,10 +84,6 @@ ExecRenameStmt(RenameStmt *stmt)
RenameTableSpace(stmt->subname, stmt->newname); RenameTableSpace(stmt->subname, stmt->newname);
break; break;
case OBJECT_USER:
RenameUser(stmt->subname, stmt->newname);
break;
case OBJECT_TABLE: case OBJECT_TABLE:
case OBJECT_INDEX: case OBJECT_INDEX:
case OBJECT_COLUMN: case OBJECT_COLUMN:
@ -153,7 +149,7 @@ ExecRenameStmt(RenameStmt *stmt)
void void
ExecAlterOwnerStmt(AlterOwnerStmt *stmt) ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
{ {
AclId newowner = get_usesysid(stmt->newowner); Oid newowner = get_roleid_checked(stmt->newowner);
switch (stmt->objectType) switch (stmt->objectType)
{ {

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * Change conversion owner
*/ */
void void
AlterConversionOwner(List *name, AclId newOwnerSysId) AlterConversionOwner(List *name, Oid newOwnerId)
{ {
Oid conversionOid; Oid conversionOid;
HeapTuple tup; HeapTuple tup;
@ -203,7 +203,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * 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 */ /* Otherwise, must be superuser to change object ownership */
if (!superuser()) if (!superuser())
@ -215,7 +215,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId)
* Modify the owner --- okay to scribble on tup because it's a * Modify the owner --- okay to scribble on tup because it's a
* copy * copy
*/ */
convForm->conowner = newOwnerSysId; convForm->conowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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/index.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/copy.h" #include "commands/copy.h"
#include "commands/trigger.h" #include "commands/trigger.h"

View file

@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * 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/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
#include "catalog/pg_tablespace.h"
#include "commands/comment.h" #include "commands/comment.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
#include "commands/tablespace.h" #include "commands/tablespace.h"
@ -52,7 +52,7 @@
/* non-export function prototypes */ /* 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, int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP, TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
@ -70,7 +70,7 @@ createdb(const CreatedbStmt *stmt)
HeapScanDesc scan; HeapScanDesc scan;
Relation rel; Relation rel;
Oid src_dboid; Oid src_dboid;
AclId src_owner; Oid src_owner;
int src_encoding; int src_encoding;
bool src_istemplate; bool src_istemplate;
bool src_allowconn; bool src_allowconn;
@ -85,7 +85,7 @@ createdb(const CreatedbStmt *stmt)
Datum new_record[Natts_pg_database]; Datum new_record[Natts_pg_database];
char new_record_nulls[Natts_pg_database]; char new_record_nulls[Natts_pg_database];
Oid dboid; Oid dboid;
AclId datdba; Oid datdba;
ListCell *option; ListCell *option;
DefElem *dtablespacename = NULL; DefElem *dtablespacename = NULL;
DefElem *downer = NULL; DefElem *downer = NULL;
@ -186,13 +186,13 @@ createdb(const CreatedbStmt *stmt)
nodeTag(dencoding->arg)); nodeTag(dencoding->arg));
} }
/* obtain sysid of proposed owner */ /* obtain OID of proposed owner */
if (dbowner) if (dbowner)
datdba = get_usesysid(dbowner); /* will ereport if no such user */ datdba = get_roleid_checked(dbowner);
else else
datdba = GetUserId(); datdba = GetUserId();
if (datdba == GetUserId()) if (is_member_of_role(GetUserId(), datdba))
{ {
/* creating database for self: can be superuser or createdb */ /* creating database for self: can be superuser or createdb */
if (!superuser() && !have_createdb_privilege()) if (!superuser() && !have_createdb_privilege())
@ -243,7 +243,7 @@ createdb(const CreatedbStmt *stmt)
*/ */
if (!src_istemplate) if (!src_istemplate)
{ {
if (!superuser() && GetUserId() != src_owner) if (!pg_database_ownercheck(src_dboid, GetUserId()))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to copy database \"%s\"", errmsg("permission denied to copy database \"%s\"",
@ -483,7 +483,7 @@ createdb(const CreatedbStmt *stmt)
new_record[Anum_pg_database_datname - 1] = new_record[Anum_pg_database_datname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(dbname)); 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_encoding - 1] = Int32GetDatum(encoding);
new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false); new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true); new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
@ -557,9 +557,8 @@ createdb(const CreatedbStmt *stmt)
void void
dropdb(const char *dbname) dropdb(const char *dbname)
{ {
int4 db_owner;
bool db_istemplate;
Oid db_id; Oid db_id;
bool db_istemplate;
Relation pgdbrel; Relation pgdbrel;
SysScanDesc pgdbscan; SysScanDesc pgdbscan;
ScanKeyData key; ScanKeyData key;
@ -588,13 +587,13 @@ dropdb(const char *dbname)
*/ */
pgdbrel = heap_open(DatabaseRelationId, ExclusiveLock); 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)) &db_istemplate, NULL, NULL, NULL, NULL, NULL))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", dbname))); 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, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
dbname); dbname);
@ -818,8 +817,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
(errcode(ERRCODE_UNDEFINED_DATABASE), (errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", stmt->dbname))); errmsg("database \"%s\" does not exist", stmt->dbname)));
if (!(superuser() if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
|| ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE,
stmt->dbname); stmt->dbname);
@ -878,7 +876,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
* ALTER DATABASE name OWNER TO newowner * ALTER DATABASE name OWNER TO newowner
*/ */
void void
AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
{ {
HeapTuple tuple; HeapTuple tuple;
Relation rel; Relation rel;
@ -910,7 +908,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
* command to have succeeded. This is to be consistent with other * command to have succeeded. This is to be consistent with other
* objects. * objects.
*/ */
if (datForm->datdba != newOwnerSysId) if (datForm->datdba != newOwnerId)
{ {
Datum repl_val[Natts_pg_database]; Datum repl_val[Natts_pg_database];
char repl_null[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)); memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_database_datdba - 1] = 'r'; 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 * Determine the modified ACL for the new owner. This is only
@ -943,7 +941,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
if (!isNull) if (!isNull)
{ {
newAcl = aclnewowner(DatumGetAclP(aclDatum), newAcl = aclnewowner(DatumGetAclP(aclDatum),
datForm->datdba, newOwnerSysId); datForm->datdba, newOwnerId);
repl_repl[Anum_pg_database_datacl - 1] = 'r'; repl_repl[Anum_pg_database_datacl - 1] = 'r';
repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl); repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl);
} }
@ -972,7 +970,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId)
*/ */
static bool 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, int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP, Oid *dbLastSysOidP,
TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP, TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP,
@ -1007,7 +1005,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
/* oid of the database */ /* oid of the database */
if (dbIdP) if (dbIdP)
*dbIdP = HeapTupleGetOid(tuple); *dbIdP = HeapTupleGetOid(tuple);
/* sysid of the owner */ /* oid of the owner */
if (ownerIdP) if (ownerIdP)
*ownerIdP = dbform->datdba; *ownerIdP = dbform->datdba;
/* character encoding */ /* character encoding */
@ -1046,12 +1044,12 @@ have_createdb_privilege(void)
bool result = false; bool result = false;
HeapTuple utup; HeapTuple utup;
utup = SearchSysCache(SHADOWSYSID, utup = SearchSysCache(AUTHOID,
Int32GetDatum(GetUserId()), ObjectIdGetDatum(GetUserId()),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(utup)) if (HeapTupleIsValid(utup))
{ {
result = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb; result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreatedb;
ReleaseSysCache(utup); ReleaseSysCache(utup);
} }
return result; return result;

View file

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* These routines take the parse tree and pick out the * 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 * Change function owner
*/ */
void void
AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId) AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
{ {
Oid procOid; Oid procOid;
HeapTuple tup; 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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * command to have succeeded. This is for dump restoration purposes.
*/ */
if (procForm->proowner != newOwnerSysId) if (procForm->proowner != newOwnerId)
{ {
Datum repl_val[Natts_pg_proc]; Datum repl_val[Natts_pg_proc];
char repl_null[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)); memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_proc_proowner - 1] = 'r'; 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 * Determine the modified ACL for the new owner. This is only
@ -914,7 +914,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId)
if (!isNull) if (!isNull)
{ {
newAcl = aclnewowner(DatumGetAclP(aclDatum), newAcl = aclnewowner(DatumGetAclP(aclDatum),
procForm->proowner, newOwnerSysId); procForm->proowner, newOwnerId);
repl_repl[Anum_pg_proc_proacl - 1] = 'r'; repl_repl[Anum_pg_proc_proacl - 1] = 'r';
repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl); repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl);
} }

View file

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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); namestrcpy(&opcName, opcname);
values[i++] = NameGetDatum(&opcName); /* opcname */ values[i++] = NameGetDatum(&opcName); /* opcname */
values[i++] = ObjectIdGetDatum(namespaceoid); /* opcnamespace */ values[i++] = ObjectIdGetDatum(namespaceoid); /* opcnamespace */
values[i++] = Int32GetDatum(GetUserId()); /* opcowner */ values[i++] = ObjectIdGetDatum(GetUserId()); /* opcowner */
values[i++] = ObjectIdGetDatum(typeoid); /* opcintype */ values[i++] = ObjectIdGetDatum(typeoid); /* opcintype */
values[i++] = BoolGetDatum(stmt->isDefault); /* opcdefault */ values[i++] = BoolGetDatum(stmt->isDefault); /* opcdefault */
values[i++] = ObjectIdGetDatum(storageoid); /* opckeytype */ values[i++] = ObjectIdGetDatum(storageoid); /* opckeytype */
@ -880,7 +880,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
* Change opclass owner * Change opclass owner
*/ */
void void
AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId) AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
{ {
Oid opcOid; Oid opcOid;
Oid amOid; 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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * 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 */ /* Otherwise, must be superuser to change object ownership */
if (!superuser()) 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 * Modify the owner --- okay to scribble on tup because it's a
* copy * copy
*/ */
opcForm->opcowner = newOwnerSysId; opcForm->opcowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);

View file

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -269,7 +269,7 @@ RemoveOperatorById(Oid operOid)
*/ */
void void
AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
AclId newOwnerSysId) Oid newOwnerId)
{ {
Oid operOid; Oid operOid;
HeapTuple tup; 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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * 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 */ /* Otherwise, must be superuser to change object ownership */
if (!superuser()) 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 * Modify the owner --- okay to scribble on tup because it's a
* copy * copy
*/ */
oprForm->oprowner = newOwnerSysId; oprForm->oprowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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; Oid namespaceId;
List *parsetree_list; List *parsetree_list;
ListCell *parsetree_item; ListCell *parsetree_item;
AclId owner_userid; Oid owner_uid;
AclId saved_userid; Oid saved_uid;
AclResult aclresult; AclResult aclresult;
saved_userid = GetUserId(); saved_uid = GetUserId();
/* /*
* Figure out user identities. * Figure out user identities.
@ -54,12 +54,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
if (!authId) if (!authId)
{ {
owner_userid = saved_userid; owner_uid = saved_uid;
} }
else if (superuser()) else if (superuser())
{ {
/* The following will error out if user does not exist */ owner_uid = get_roleid_checked(authId);
owner_userid = get_usesysid(authId);
/* /*
* Set the current user to the requested authorization so that * 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 will revert to session user on error or at the end of
* this routine.) * this routine.)
*/ */
SetUserId(owner_userid); SetUserId(owner_uid);
} }
else else
{ {
const char *owner_name; const char *owner_name;
/* not superuser */ /* not superuser */
owner_userid = saved_userid; owner_uid = saved_uid;
owner_name = GetUserNameFromId(owner_userid); owner_name = GetUserNameFromId(owner_uid);
if (strcmp(authId, owner_name) != 0) if (strcmp(authId, owner_name) != 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@ -87,7 +86,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
/* /*
* Permissions checks. * Permissions checks.
*/ */
aclresult = pg_database_aclcheck(MyDatabaseId, saved_userid, ACL_CREATE); aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
if (aclresult != ACLCHECK_OK) if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_DATABASE, aclcheck_error(aclresult, ACL_KIND_DATABASE,
get_database_name(MyDatabaseId)); get_database_name(MyDatabaseId));
@ -99,7 +98,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
errdetail("The prefix \"pg_\" is reserved for system schemas."))); errdetail("The prefix \"pg_\" is reserved for system schemas.")));
/* Create the schema's namespace */ /* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_userid); namespaceId = NamespaceCreate(schemaName, owner_uid);
/* Advance cmd counter to make the namespace visible */ /* Advance cmd counter to make the namespace visible */
CommandCounterIncrement(); CommandCounterIncrement();
@ -149,7 +148,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
PopSpecialNamespace(namespaceId); PopSpecialNamespace(namespaceId);
/* Reset current user */ /* Reset current user */
SetUserId(saved_userid); SetUserId(saved_uid);
} }
@ -279,7 +278,7 @@ RenameSchema(const char *oldname, const char *newname)
* Change schema owner * Change schema owner
*/ */
void void
AlterSchemaOwner(const char *name, AclId newOwnerSysId) AlterSchemaOwner(const char *name, Oid newOwnerId)
{ {
HeapTuple tup; HeapTuple tup;
Relation rel; 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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * command to have succeeded. This is for dump restoration purposes.
*/ */
if (nspForm->nspowner != newOwnerSysId) if (nspForm->nspowner != newOwnerId)
{ {
Datum repl_val[Natts_pg_namespace]; Datum repl_val[Natts_pg_namespace];
char repl_null[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)); memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_namespace_nspowner - 1] = 'r'; 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 * Determine the modified ACL for the new owner. This is only
@ -332,7 +331,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId)
if (!isNull) if (!isNull)
{ {
newAcl = aclnewowner(DatumGetAclP(aclDatum), newAcl = aclnewowner(DatumGetAclP(aclDatum),
nspForm->nspowner, newOwnerSysId); nspForm->nspowner, newOwnerId);
repl_repl[Anum_pg_namespace_nspacl - 1] = 'r'; repl_repl[Anum_pg_namespace_nspacl - 1] = 'r';
repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl); repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl);
} }

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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); const char *colName, TypeName *typename);
static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab); static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab);
static void ATPostAlterTypeParse(char *cmd, List **wqueue); 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, static void change_owner_recurse_to_sequences(Oid relationOid,
int32 newOwnerSysId); Oid newOwnerId);
static void ATExecClusterOn(Relation rel, const char *indexName); static void ATExecClusterOn(Relation rel, const char *indexName);
static void ATExecDropCluster(Relation rel); static void ATExecDropCluster(Relation rel);
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
@ -2133,8 +2133,8 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
AlterTableCreateToastTable(RelationGetRelid(rel), false); AlterTableCreateToastTable(RelationGetRelid(rel), false);
break; break;
case AT_ChangeOwner: /* ALTER OWNER */ case AT_ChangeOwner: /* ALTER OWNER */
/* get_usesysid raises an error if no such user */ ATExecChangeOwner(RelationGetRelid(rel),
ATExecChangeOwner(RelationGetRelid(rel), get_usesysid(cmd->name)); get_roleid_checked(cmd->name));
break; break;
case AT_ClusterOn: /* CLUSTER ON */ case AT_ClusterOn: /* CLUSTER ON */
ATExecClusterOn(rel, cmd->name); ATExecClusterOn(rel, cmd->name);
@ -5233,7 +5233,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
* ALTER TABLE OWNER * ALTER TABLE OWNER
*/ */
static void static void
ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) ATExecChangeOwner(Oid relationOid, Oid newOwnerId)
{ {
Relation target_rel; Relation target_rel;
Relation class_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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * 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]; Datum repl_val[Natts_pg_class];
char repl_null[Natts_pg_class]; char repl_null[Natts_pg_class];
@ -5297,7 +5297,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
memset(repl_repl, ' ', sizeof(repl_repl)); memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_class_relowner - 1] = 'r'; 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 * Determine the modified ACL for the new owner. This is only
@ -5309,7 +5309,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId)
if (!isNull) if (!isNull)
{ {
newAcl = aclnewowner(DatumGetAclP(aclDatum), newAcl = aclnewowner(DatumGetAclP(aclDatum),
tuple_class->relowner, newOwnerSysId); tuple_class->relowner, newOwnerId);
repl_repl[Anum_pg_class_relacl - 1] = 'r'; repl_repl[Anum_pg_class_relacl - 1] = 'r';
repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl); 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 */ /* For each index, recursively change its ownership */
foreach(i, index_oid_list) foreach(i, index_oid_list)
ATExecChangeOwner(lfirst_oid(i), newOwnerSysId); ATExecChangeOwner(lfirst_oid(i), newOwnerId);
list_free(index_oid_list); 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 it has a toast table, recurse to change its ownership */
if (tuple_class->reltoastrelid != InvalidOid) 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 */ /* 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. * ownership.
*/ */
static void static void
change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId) change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId)
{ {
Relation depRel; Relation depRel;
SysScanDesc scan; 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. */ /* 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. */ /* Now we can close it. Keep the lock till end of transaction. */
relation_close(seqRel, NoLock); relation_close(seqRel, NoLock);

View file

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * 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; Oid tablespaceoid;
char *location; char *location;
char *linkloc; char *linkloc;
AclId ownerid; Oid ownerId;
/* validate */ /* validate */
@ -225,12 +225,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
/* However, the eventual owner of the tablespace need not be */ /* However, the eventual owner of the tablespace need not be */
if (stmt->owner) if (stmt->owner)
{ ownerId = get_roleid_checked(stmt->owner);
/* No need to check result, get_usesysid() does that */
ownerid = get_usesysid(stmt->owner);
}
else else
ownerid = GetUserId(); ownerId = GetUserId();
/* Unix-ify the offered path, and strip any trailing slashes */ /* Unix-ify the offered path, and strip any trailing slashes */
location = pstrdup(stmt->location); location = pstrdup(stmt->location);
@ -297,7 +294,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
values[Anum_pg_tablespace_spcname - 1] = values[Anum_pg_tablespace_spcname - 1] =
DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename)); DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
values[Anum_pg_tablespace_spcowner - 1] = values[Anum_pg_tablespace_spcowner - 1] =
Int32GetDatum(ownerid); ObjectIdGetDatum(ownerId);
values[Anum_pg_tablespace_spclocation - 1] = values[Anum_pg_tablespace_spclocation - 1] =
DirectFunctionCall1(textin, CStringGetDatum(location)); DirectFunctionCall1(textin, CStringGetDatum(location));
nulls[Anum_pg_tablespace_spcacl - 1] = 'n'; nulls[Anum_pg_tablespace_spcacl - 1] = 'n';
@ -426,9 +423,8 @@ DropTableSpace(DropTableSpaceStmt *stmt)
tablespaceoid = HeapTupleGetOid(tuple); tablespaceoid = HeapTupleGetOid(tuple);
/* Must be superuser or owner */ /* Must be tablespace owner */
if (GetUserId() != ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner && if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId()))
!superuser())
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE,
tablespacename); tablespacename);
@ -711,8 +707,8 @@ RenameTableSpace(const char *oldname, const char *newname)
heap_endscan(scan); heap_endscan(scan);
/* Must be owner or superuser */ /* Must be owner */
if (newform->spcowner != GetUserId() && !superuser()) if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId()))
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname); aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname);
/* Validate new name */ /* Validate new name */
@ -750,7 +746,7 @@ RenameTableSpace(const char *oldname, const char *newname)
* Change tablespace owner * Change tablespace owner
*/ */
void void
AlterTableSpaceOwner(const char *name, AclId newOwnerSysId) AlterTableSpaceOwner(const char *name, Oid newOwnerId)
{ {
Relation rel; Relation rel;
ScanKeyData entry[1]; 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 * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * command to have succeeded. This is for dump restoration purposes.
*/ */
if (spcForm->spcowner != newOwnerSysId) if (spcForm->spcowner != newOwnerId)
{ {
Datum repl_val[Natts_pg_tablespace]; Datum repl_val[Natts_pg_tablespace];
char repl_null[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)); memset(repl_repl, ' ', sizeof(repl_repl));
repl_repl[Anum_pg_tablespace_spcowner - 1] = 'r'; 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 * Determine the modified ACL for the new owner. This is only
@ -811,7 +807,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId)
if (!isNull) if (!isNull)
{ {
newAcl = aclnewowner(DatumGetAclP(aclDatum), newAcl = aclnewowner(DatumGetAclP(aclDatum),
spcForm->spcowner, newOwnerSysId); spcForm->spcowner, newOwnerId);
repl_repl[Anum_pg_tablespace_spcacl - 1] = 'r'; repl_repl[Anum_pg_tablespace_spcacl - 1] = 'r';
repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl); repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl);
} }

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the * The "DefineFoo" routines take the parse tree and pick out the
@ -2016,7 +2016,7 @@ GetDomainConstraints(Oid typeOid)
* Change the owner of a type. * Change the owner of a type.
*/ */
void void
AlterTypeOwner(List *names, AclId newOwnerSysId) AlterTypeOwner(List *names, Oid newOwnerId)
{ {
TypeName *typename; TypeName *typename;
Oid typeOid; Oid typeOid;
@ -2063,7 +2063,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId)
* If the new owner is the same as the existing owner, consider the * If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is for dump restoration purposes. * 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 */ /* Otherwise, must be superuser to change object ownership */
if (!superuser()) if (!superuser())
@ -2075,7 +2075,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId)
* Modify the owner --- okay to scribble on typTup because it's a * Modify the owner --- okay to scribble on typTup because it's a
* copy * copy
*/ */
typTup->typowner = newOwnerSysId; typTup->typowner = newOwnerId;
simple_heap_update(rel, &tup->t_self, tup); simple_heap_update(rel, &tup->t_self, tup);

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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 <ctype.h>
#include "access/xact.h" #include "access/xact.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_authid.h"
#include "commands/variable.h" #include "commands/variable.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "parser/scansup.h" #include "parser/scansup.h"
@ -567,46 +567,46 @@ assign_client_encoding(const char *value, bool doit, GucSource source)
* SET SESSION AUTHORIZATION * SET SESSION AUTHORIZATION
* *
* When resetting session auth after an error, we can't expect to do catalog * 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 * 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 * 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. * by the numeric oid, followed by a comma, followed by the role name.
* This cannot be confused with a plain user name because of the NAMEDATALEN * 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 * 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 */ extern char *session_authorization_string; /* in guc.c */
const char * const char *
assign_session_authorization(const char *value, bool doit, GucSource source) assign_session_authorization(const char *value, bool doit, GucSource source)
{ {
AclId usesysid = 0; Oid roleid = InvalidOid;
bool is_superuser = false; bool is_superuser = false;
const char *actual_username = NULL; const char *actual_rolename = NULL;
char *result; char *result;
if (strspn(value, "x") == NAMEDATALEN && if (strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F')) (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F'))
{ {
/* might be a saved userid string */ /* might be a saved userid string */
AclId savedsysid; Oid savedoid;
char *endptr; char *endptr;
savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10); savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10);
if (endptr != value + NAMEDATALEN + 1 && *endptr == ',') if (endptr != value + NAMEDATALEN + 1 && *endptr == ',')
{ {
/* syntactically valid, so break out the data */ /* syntactically valid, so break out the data */
usesysid = savedsysid; roleid = savedoid;
is_superuser = (value[NAMEDATALEN] == 'T'); 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 */ /* not a saved ID, so look it up */
HeapTuple userTup; HeapTuple roleTup;
if (!IsTransactionState()) if (!IsTransactionState())
{ {
@ -618,38 +618,38 @@ assign_session_authorization(const char *value, bool doit, GucSource source)
return NULL; return NULL;
} }
userTup = SearchSysCache(SHADOWNAME, roleTup = SearchSysCache(AUTHNAME,
PointerGetDatum(value), PointerGetDatum(value),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(userTup)) if (!HeapTupleIsValid(roleTup))
{ {
if (source >= PGC_S_INTERACTIVE) if (source >= PGC_S_INTERACTIVE)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("user \"%s\" does not exist", value))); errmsg("role \"%s\" does not exist", value)));
return NULL; return NULL;
} }
usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; roleid = HeapTupleGetOid(roleTup);
is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
actual_username = value; actual_rolename = value;
ReleaseSysCache(userTup); ReleaseSysCache(roleTup);
} }
if (doit) 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) if (!result)
return NULL; return NULL;
memset(result, 'x', NAMEDATALEN); memset(result, 'x', NAMEDATALEN);
sprintf(result + NAMEDATALEN, "%c%lu,%s", sprintf(result + NAMEDATALEN, "%c%u,%s",
is_superuser ? 'T' : 'F', is_superuser ? 'T' : 'F',
(unsigned long) usesysid, roleid,
actual_username); actual_rolename);
return result; return result;
} }
@ -662,13 +662,13 @@ show_session_authorization(void)
* assign_session_authorization * assign_session_authorization
*/ */
const char *value = session_authorization_string; const char *value = session_authorization_string;
AclId savedsysid; Oid savedoid;
char *endptr; char *endptr;
Assert(strspn(value, "x") == NAMEDATALEN && Assert(strspn(value, "x") == NAMEDATALEN &&
(value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F')); (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 == ','); Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ',');

View file

@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * 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; AclMode requiredPerms;
Oid relOid; Oid relOid;
AclId userid; Oid userid;
/* /*
* Only plain-relation RTEs need to be checked here. Subquery RTEs * Only plain-relation RTEs need to be checked here. Subquery RTEs

View file

@ -61,7 +61,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 */ /* Check that aggregate owner has permission to call component fns */
{ {
HeapTuple procTuple; HeapTuple procTuple;
AclId aggOwner; Oid aggOwner;
procTuple = SearchSysCache(PROCOID, procTuple = SearchSysCache(PROCOID,
ObjectIdGetDatum(aggref->aggfnoid), ObjectIdGetDatum(aggref->aggfnoid),

View file

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 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, char *shadow_pass = NULL,
*valuntil = NULL, *valuntil = NULL,
@ -39,13 +39,11 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
ListCell *token; ListCell *token;
char *crypt_client_pass = client_pass; char *crypt_client_pass = client_pass;
if ((line = get_user_line(user)) == NULL) if ((line = get_role_line(role)) == NULL)
return STATUS_ERROR; return STATUS_ERROR;
/* Skip over username and usesysid */ /* Skip over rolename */
token = list_head(*line); token = list_head(*line);
if (token)
token = lnext(token);
if (token) if (token)
token = lnext(token); token = lnext(token);
if (token) if (token)
@ -146,17 +144,28 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
/* /*
* Password OK, now check to be sure we are not past valuntil * Password OK, now check to be sure we are not past valuntil
*/ */
AbsoluteTime vuntil;
if (valuntil == NULL || *valuntil == '\0') 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; 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) if (port->auth_method == uaMD5)

View file

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 * 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 * 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 * first item is an integer line number (so we can give somewhat-useful
* location info in error messages). Remaining items are palloc'd strings, * 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_lines = NIL;
static List *ident_line_nums = NIL; static List *ident_line_nums = NIL;
/* pre-parsed content of group file and corresponding line #s */ /* pre-parsed content of flat auth file and corresponding line #s */
static List *group_lines = NIL; static List *role_lines = NIL;
static List *group_line_nums = NIL; static List *role_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;
/* sorted entries so we can do binary search lookups */ /* sorted entries so we can do binary search lookups */
static List **user_sorted = NULL; /* sorted user list, for bsearch() */ static List **role_sorted = NULL; /* sorted role list, for bsearch() */
static List **group_sorted = NULL; /* sorted group list, for static int role_length;
* bsearch() */
static int user_length;
static int group_length;
static void tokenize_file(const char *filename, FILE *file, static void tokenize_file(const char *filename, FILE *file,
List **lines, List **line_nums); 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 * return empty string as *buf and position the file to the beginning
* of the next line or EOF, whichever comes first. Allow spaces in * of the next line or EOF, whichever comes first. Allow spaces in
* quoted strings. Terminate on unquoted commas. Handle * 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. * database names specially, by appending a newline to them.
*/ */
static void static void
@ -199,7 +193,8 @@ next_token(FILE *fp, char *buf, int bufsz)
if (!saw_quote && if (!saw_quote &&
(strcmp(start_buf, "all") == 0 || (strcmp(start_buf, "all") == 0 ||
strcmp(start_buf, "sameuser") == 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 */ /* append newline to a magical keyword */
*buf++ = '\n'; *buf++ = '\n';
@ -434,94 +429,58 @@ tokenize_file(const char *filename, FILE *file,
} }
} }
/* /*
* Compare two lines based on their user/group names. * Compare two lines based on their role/member 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.
* *
* Used for bsearch() lookup. * Used for bsearch() lookup.
*/ */
static int 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 ** List **
get_group_line(const char *group) get_role_line(const char *role)
{ {
/* On some versions of Solaris, bsearch of zero items dumps core */ /* On some versions of Solaris, bsearch of zero items dumps core */
if (group_length == 0) if (role_length == 0)
return NULL; return NULL;
return (List **) bsearch((void *) group, return (List **) bsearch((void *) role,
(void *) group_sorted, (void *) role_sorted,
group_length, role_length,
sizeof(List *), sizeof(List *),
user_group_bsearch_cmp); role_bsearch_cmp);
} }
/* /*
* Lookup a user name in the pg_shadow file * Does member belong to role?
*/
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?
*/ */
static bool static bool
check_group(char *group, char *user) check_member(const char *role, const char *member)
{ {
List **line; List **line;
List **line2;
ListCell *line_item; ListCell *line_item;
char *usesysid;
if ((line = get_user_line(user)) == NULL) if ((line = get_role_line(member)) == NULL)
return false; /* if user not exist, say "no" */ return false; /* if member not exist, say "no" */
/* Skip over username to get usesysid */
usesysid = (char *) lsecond(*line);
if ((line = get_group_line(group)) == NULL) if ((line2 = get_role_line(role)) == NULL)
return false; /* if group not exist, say "no" */ return false; /* if role not exist, say "no" */
/* skip over the group name, examine all the member usesysid's */ /* skip over the role name, password, valuntil, examine all the members */
for_each_cell(line_item, lnext(list_head(*line))) 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; 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 static bool
check_user(char *user, char *param_str) check_role(char *role, char *param_str)
{ {
char *tok; char *tok;
@ -540,10 +499,10 @@ check_user(char *user, char *param_str)
{ {
if (tok[0] == '+') if (tok[0] == '+')
{ {
if (check_group(tok + 1, user)) if (check_member(tok + 1, role))
return true; return true;
} }
else if (strcmp(tok, user) == 0 || else if (strcmp(tok, role) == 0 ||
strcmp(tok, "all\n") == 0) strcmp(tok, "all\n") == 0)
return true; 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 static bool
check_db(char *dbname, char *user, char *param_str) check_db(char *dbname, char *role, char *param_str)
{ {
char *tok; char *tok;
@ -565,12 +524,13 @@ check_db(char *dbname, char *user, char *param_str)
return true; return true;
else if (strcmp(tok, "sameuser\n") == 0) else if (strcmp(tok, "sameuser\n") == 0)
{ {
if (strcmp(dbname, user) == 0) if (strcmp(dbname, role) == 0)
return true; 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; return true;
} }
else if (strcmp(tok, dbname) == 0) else if (strcmp(tok, dbname) == 0)
@ -655,7 +615,7 @@ parse_hba(List *line, int line_num, hbaPort *port,
{ {
char *token; char *token;
char *db; char *db;
char *user; char *role;
struct addrinfo *gai_result; struct addrinfo *gai_result;
struct addrinfo hints; struct addrinfo hints;
int ret; int ret;
@ -675,11 +635,11 @@ parse_hba(List *line, int line_num, hbaPort *port,
goto hba_syntax; goto hba_syntax;
db = lfirst(line_item); db = lfirst(line_item);
/* Get the user. */ /* Get the role. */
line_item = lnext(line_item); line_item = lnext(line_item);
if (!line_item) if (!line_item)
goto hba_syntax; goto hba_syntax;
user = lfirst(line_item); role = lfirst(line_item);
line_item = lnext(line_item); line_item = lnext(line_item);
if (!line_item) if (!line_item)
@ -735,11 +695,11 @@ parse_hba(List *line, int line_num, hbaPort *port,
goto hba_syntax; goto hba_syntax;
db = lfirst(line_item); db = lfirst(line_item);
/* Get the user. */ /* Get the role. */
line_item = lnext(line_item); line_item = lnext(line_item);
if (!line_item) if (!line_item)
goto hba_syntax; goto hba_syntax;
user = lfirst(line_item); role = lfirst(line_item);
/* Read the IP address field. (with or without CIDR netmask) */ /* Read the IP address field. (with or without CIDR netmask) */
line_item = lnext(line_item); line_item = lnext(line_item);
@ -861,10 +821,10 @@ parse_hba(List *line, int line_num, hbaPort *port,
else else
goto hba_syntax; 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)) if (!check_db(port->database_name, port->user_name, db))
return; return;
if (!check_user(port->user_name, user)) if (!check_role(port->user_name, role))
return; return;
/* Success */ /* Success */
@ -923,27 +883,27 @@ check_hba(hbaPort *port)
/* /*
* Load group/user name mapping file * Load role/password mapping file
*/ */
void void
load_group(void) load_role(void)
{ {
char *filename; char *filename;
FILE *group_file; FILE *role_file;
/* Discard any old data */ /* Discard any old data */
if (group_lines || group_line_nums) if (role_lines || role_line_nums)
free_lines(&group_lines, &group_line_nums); free_lines(&role_lines, &role_line_nums);
if (group_sorted) if (role_sorted)
pfree(group_sorted); pfree(role_sorted);
group_sorted = NULL; role_sorted = NULL;
group_length = 0; role_length = 0;
/* Read in the file contents */ /* Read in the file contents */
filename = group_getflatfilename(); filename = auth_getflatfilename();
group_file = AllocateFile(filename, "r"); role_file = AllocateFile(filename, "r");
if (group_file == NULL) if (role_file == NULL)
{ {
/* no complaint if not there */ /* no complaint if not there */
if (errno != ENOENT) if (errno != ENOENT)
@ -954,84 +914,25 @@ load_group(void)
return; 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); pfree(filename);
/* create sorted lines for binary searching */ /* create array for binary searching */
group_length = list_length(group_lines); role_length = list_length(role_lines);
if (group_length) if (role_length)
{ {
int i = 0; int i = 0;
ListCell *line; ListCell *line;
group_sorted = palloc(group_length * sizeof(List *)); role_sorted = palloc(role_length * sizeof(List *));
foreach(line, role_lines)
{
role_sorted[i++] = lfirst(line);
}
foreach(line, group_lines) /* We assume the flat file was written already-sorted */
group_sorted[i++] = lfirst(line);
qsort((void *) group_sorted,
group_length,
sizeof(List *),
user_group_qsort_cmp);
}
}
/*
* Load user/password mapping file
*/
void
load_user(void)
{
char *filename;
FILE *user_file;
/* Discard any old data */
if (user_lines || user_line_nums)
free_lines(&user_lines, &user_line_nums);
if (user_sorted)
pfree(user_sorted);
user_sorted = NULL;
user_length = 0;
/* Read in the file contents */
filename = user_getflatfilename();
user_file = AllocateFile(filename, "r");
if (user_file == NULL)
{
/* no complaint if not there */
if (errno != ENOENT)
ereport(LOG,
(errcode_for_file_access(),
errmsg("could not open file \"%s\": %m", filename)));
pfree(filename);
return;
}
tokenize_file(filename, user_file, &user_lines, &user_line_nums);
FreeFile(user_file);
pfree(filename);
/* create sorted lines for binary searching */
user_length = list_length(user_lines);
if (user_length)
{
int i = 0;
ListCell *line;
user_sorted = palloc(user_length * sizeof(List *));
foreach(line, user_lines)
user_sorted[i++] = lfirst(line);
qsort((void *) user_sorted,
user_length,
sizeof(List *),
user_group_qsort_cmp);
} }
} }
@ -1108,18 +1009,18 @@ read_pg_database_line(FILE *fp, char *dbname,
/* /*
* Process one line from the ident config file. * 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. * *found_p and *error_p are set according to our results.
*/ */
static void static void
parse_ident_usermap(List *line, int line_number, const char *usermap_name, 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) bool *found_p, bool *error_p)
{ {
ListCell *line_item; ListCell *line_item;
char *token; char *token;
char *file_map; char *file_map;
char *file_pguser; char *file_pgrole;
char *file_ident_user; char *file_ident_user;
*found_p = false; *found_p = false;
@ -1139,16 +1040,16 @@ parse_ident_usermap(List *line, int line_number, const char *usermap_name,
token = lfirst(line_item); token = lfirst(line_item);
file_ident_user = token; file_ident_user = token;
/* Get the PG username token */ /* Get the PG rolename token */
line_item = lnext(line_item); line_item = lnext(line_item);
if (!line_item) if (!line_item)
goto ident_syntax; goto ident_syntax;
token = lfirst(line_item); token = lfirst(line_item);
file_pguser = token; file_pgrole = token;
/* Match? */ /* Match? */
if (strcmp(file_map, usermap_name) == 0 && 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) strcmp(file_ident_user, ident_user) == 0)
*found_p = true; *found_p = true;
@ -1167,17 +1068,17 @@ ident_syntax:
* Scan the (pre-parsed) ident usermap file line by line, looking for a match * 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 * 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 * Special case: For usermap "samerole", don't look in the usermap
* file. That's an implied map where "pguser" must be identical to * file. That's an implied map where "pgrole" must be identical to
* "ident_user" in order to be authorized. * "ident_user" in order to be authorized.
* *
* Iff authorized, return true. * Iff authorized, return true.
*/ */
static bool static bool
check_ident_usermap(const char *usermap_name, check_ident_usermap(const char *usermap_name,
const char *pg_user, const char *pg_role,
const char *ident_user) const char *ident_user)
{ {
bool found_entry = false, bool found_entry = false,
@ -1190,9 +1091,10 @@ check_ident_usermap(const char *usermap_name,
errmsg("cannot use Ident authentication without usermap field"))); errmsg("cannot use Ident authentication without usermap field")));
found_entry = false; 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; found_entry = true;
else else
found_entry = false; found_entry = false;
@ -1205,7 +1107,7 @@ check_ident_usermap(const char *usermap_name,
forboth(line_cell, ident_lines, num_cell, ident_line_nums) forboth(line_cell, ident_lines, num_cell, ident_line_nums)
{ {
parse_ident_usermap(lfirst(line_cell), lfirst_int(num_cell), 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); &found_entry, &error);
if (found_entry || error) if (found_entry || error)
break; break;

View file

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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); PrivGrantee *newnode = makeNode(PrivGrantee);
COPY_STRING_FIELD(username); COPY_STRING_FIELD(rolname);
COPY_STRING_FIELD(groupname);
return newnode; return newnode;
} }
@ -1778,6 +1777,21 @@ _copyFuncWithArgs(FuncWithArgs *from)
return newnode; return newnode;
} }
static GrantRoleStmt *
_copyGrantRoleStmt(GrantRoleStmt *from)
{
GrantRoleStmt *newnode = makeNode(GrantRoleStmt);
COPY_NODE_FIELD(granted_roles);
COPY_NODE_FIELD(grantee_roles);
COPY_SCALAR_FIELD(is_grant);
COPY_SCALAR_FIELD(admin_opt);
COPY_STRING_FIELD(grantor);
COPY_SCALAR_FIELD(behavior);
return newnode;
}
static DeclareCursorStmt * static DeclareCursorStmt *
_copyDeclareCursorStmt(DeclareCursorStmt *from) _copyDeclareCursorStmt(DeclareCursorStmt *from)
{ {
@ -2374,46 +2388,47 @@ _copyDropPLangStmt(DropPLangStmt *from)
return newnode; return newnode;
} }
static CreateUserStmt * static CreateRoleStmt *
_copyCreateUserStmt(CreateUserStmt *from) _copyCreateRoleStmt(CreateRoleStmt *from)
{ {
CreateUserStmt *newnode = makeNode(CreateUserStmt); CreateRoleStmt *newnode = makeNode(CreateRoleStmt);
COPY_STRING_FIELD(user); COPY_STRING_FIELD(role);
COPY_NODE_FIELD(options); COPY_NODE_FIELD(options);
return newnode; return newnode;
} }
static AlterUserStmt * static AlterRoleStmt *
_copyAlterUserStmt(AlterUserStmt *from) _copyAlterRoleStmt(AlterRoleStmt *from)
{ {
AlterUserStmt *newnode = makeNode(AlterUserStmt); AlterRoleStmt *newnode = makeNode(AlterRoleStmt);
COPY_STRING_FIELD(user); COPY_STRING_FIELD(role);
COPY_NODE_FIELD(options); COPY_NODE_FIELD(options);
COPY_SCALAR_FIELD(action);
return newnode; return newnode;
} }
static AlterUserSetStmt * static AlterRoleSetStmt *
_copyAlterUserSetStmt(AlterUserSetStmt *from) _copyAlterRoleSetStmt(AlterRoleSetStmt *from)
{ {
AlterUserSetStmt *newnode = makeNode(AlterUserSetStmt); AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt);
COPY_STRING_FIELD(user); COPY_STRING_FIELD(role);
COPY_STRING_FIELD(variable); COPY_STRING_FIELD(variable);
COPY_NODE_FIELD(value); COPY_NODE_FIELD(value);
return newnode; return newnode;
} }
static DropUserStmt * static DropRoleStmt *
_copyDropUserStmt(DropUserStmt *from) _copyDropRoleStmt(DropRoleStmt *from)
{ {
DropUserStmt *newnode = makeNode(DropUserStmt); DropRoleStmt *newnode = makeNode(DropRoleStmt);
COPY_NODE_FIELD(users); COPY_NODE_FIELD(roles);
return newnode; return newnode;
} }
@ -2441,39 +2456,6 @@ _copyConstraintsSetStmt(ConstraintsSetStmt *from)
return newnode; return newnode;
} }
static CreateGroupStmt *
_copyCreateGroupStmt(CreateGroupStmt *from)
{
CreateGroupStmt *newnode = makeNode(CreateGroupStmt);
COPY_STRING_FIELD(name);
COPY_NODE_FIELD(options);
return newnode;
}
static AlterGroupStmt *
_copyAlterGroupStmt(AlterGroupStmt *from)
{
AlterGroupStmt *newnode = makeNode(AlterGroupStmt);
COPY_STRING_FIELD(name);
COPY_SCALAR_FIELD(action);
COPY_NODE_FIELD(listUsers);
return newnode;
}
static DropGroupStmt *
_copyDropGroupStmt(DropGroupStmt *from)
{
DropGroupStmt *newnode = makeNode(DropGroupStmt);
COPY_STRING_FIELD(name);
return newnode;
}
static ReindexStmt * static ReindexStmt *
_copyReindexStmt(ReindexStmt *from) _copyReindexStmt(ReindexStmt *from)
{ {
@ -2927,6 +2909,9 @@ copyObject(void *from)
case T_GrantStmt: case T_GrantStmt:
retval = _copyGrantStmt(from); retval = _copyGrantStmt(from);
break; break;
case T_GrantRoleStmt:
retval = _copyGrantRoleStmt(from);
break;
case T_DeclareCursorStmt: case T_DeclareCursorStmt:
retval = _copyDeclareCursorStmt(from); retval = _copyDeclareCursorStmt(from);
break; break;
@ -3071,17 +3056,17 @@ copyObject(void *from)
case T_DropPLangStmt: case T_DropPLangStmt:
retval = _copyDropPLangStmt(from); retval = _copyDropPLangStmt(from);
break; break;
case T_CreateUserStmt: case T_CreateRoleStmt:
retval = _copyCreateUserStmt(from); retval = _copyCreateRoleStmt(from);
break; break;
case T_AlterUserStmt: case T_AlterRoleStmt:
retval = _copyAlterUserStmt(from); retval = _copyAlterRoleStmt(from);
break; break;
case T_AlterUserSetStmt: case T_AlterRoleSetStmt:
retval = _copyAlterUserSetStmt(from); retval = _copyAlterRoleSetStmt(from);
break; break;
case T_DropUserStmt: case T_DropRoleStmt:
retval = _copyDropUserStmt(from); retval = _copyDropRoleStmt(from);
break; break;
case T_LockStmt: case T_LockStmt:
retval = _copyLockStmt(from); retval = _copyLockStmt(from);
@ -3089,15 +3074,6 @@ copyObject(void *from)
case T_ConstraintsSetStmt: case T_ConstraintsSetStmt:
retval = _copyConstraintsSetStmt(from); retval = _copyConstraintsSetStmt(from);
break; 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: case T_ReindexStmt:
retval = _copyReindexStmt(from); retval = _copyReindexStmt(from);
break; break;

View file

@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 static bool
_equalPrivGrantee(PrivGrantee *a, PrivGrantee *b) _equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
{ {
COMPARE_STRING_FIELD(username); COMPARE_STRING_FIELD(rolname);
COMPARE_STRING_FIELD(groupname);
return true; return true;
} }
@ -793,6 +792,19 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
return true; return true;
} }
static bool
_equalGrantRoleStmt(GrantRoleStmt *a, GrantRoleStmt *b)
{
COMPARE_NODE_FIELD(granted_roles);
COMPARE_NODE_FIELD(grantee_roles);
COMPARE_SCALAR_FIELD(is_grant);
COMPARE_SCALAR_FIELD(admin_opt);
COMPARE_STRING_FIELD(grantor);
COMPARE_SCALAR_FIELD(behavior);
return true;
}
static bool static bool
_equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b) _equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
{ {
@ -1295,27 +1307,28 @@ _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
} }
static bool static bool
_equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b) _equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
{ {
COMPARE_STRING_FIELD(user); COMPARE_STRING_FIELD(role);
COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(options);
return true; return true;
} }
static bool 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_NODE_FIELD(options);
COMPARE_SCALAR_FIELD(action);
return true; return true;
} }
static bool 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_STRING_FIELD(variable);
COMPARE_NODE_FIELD(value); COMPARE_NODE_FIELD(value);
@ -1323,9 +1336,9 @@ _equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
} }
static bool static bool
_equalDropUserStmt(DropUserStmt *a, DropUserStmt *b) _equalDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b)
{ {
COMPARE_NODE_FIELD(users); COMPARE_NODE_FIELD(roles);
return true; return true;
} }
@ -1349,33 +1362,6 @@ _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
return true; return true;
} }
static bool
_equalCreateGroupStmt(CreateGroupStmt *a, CreateGroupStmt *b)
{
COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(options);
return true;
}
static bool
_equalAlterGroupStmt(AlterGroupStmt *a, AlterGroupStmt *b)
{
COMPARE_STRING_FIELD(name);
COMPARE_SCALAR_FIELD(action);
COMPARE_NODE_FIELD(listUsers);
return true;
}
static bool
_equalDropGroupStmt(DropGroupStmt *a, DropGroupStmt *b)
{
COMPARE_STRING_FIELD(name);
return true;
}
static bool static bool
_equalReindexStmt(ReindexStmt *a, ReindexStmt *b) _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
{ {
@ -1971,6 +1957,9 @@ equal(void *a, void *b)
case T_GrantStmt: case T_GrantStmt:
retval = _equalGrantStmt(a, b); retval = _equalGrantStmt(a, b);
break; break;
case T_GrantRoleStmt:
retval = _equalGrantRoleStmt(a, b);
break;
case T_DeclareCursorStmt: case T_DeclareCursorStmt:
retval = _equalDeclareCursorStmt(a, b); retval = _equalDeclareCursorStmt(a, b);
break; break;
@ -2115,17 +2104,17 @@ equal(void *a, void *b)
case T_DropPLangStmt: case T_DropPLangStmt:
retval = _equalDropPLangStmt(a, b); retval = _equalDropPLangStmt(a, b);
break; break;
case T_CreateUserStmt: case T_CreateRoleStmt:
retval = _equalCreateUserStmt(a, b); retval = _equalCreateRoleStmt(a, b);
break; break;
case T_AlterUserStmt: case T_AlterRoleStmt:
retval = _equalAlterUserStmt(a, b); retval = _equalAlterRoleStmt(a, b);
break; break;
case T_AlterUserSetStmt: case T_AlterRoleSetStmt:
retval = _equalAlterUserSetStmt(a, b); retval = _equalAlterRoleSetStmt(a, b);
break; break;
case T_DropUserStmt: case T_DropRoleStmt:
retval = _equalDropUserStmt(a, b); retval = _equalDropRoleStmt(a, b);
break; break;
case T_LockStmt: case T_LockStmt:
retval = _equalLockStmt(a, b); retval = _equalLockStmt(a, b);
@ -2133,15 +2122,6 @@ equal(void *a, void *b)
case T_ConstraintsSetStmt: case T_ConstraintsSetStmt:
retval = _equalConstraintsSetStmt(a, b); retval = _equalConstraintsSetStmt(a, b);
break; 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: case T_ReindexStmt:
retval = _equalReindexStmt(a, b); retval = _equalReindexStmt(a, b);
break; break;

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Every node type that can appear in stored rules' parsetrees *must* * 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(inh);
WRITE_BOOL_FIELD(inFromCl); WRITE_BOOL_FIELD(inFromCl);
WRITE_UINT_FIELD(requiredPerms); WRITE_UINT_FIELD(requiredPerms);
WRITE_UINT_FIELD(checkAsUser); WRITE_OID_FIELD(checkAsUser);
} }
static void static void

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* Path and Plan nodes do not have any readfuncs support, because we * 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(inh);
READ_BOOL_FIELD(inFromCl); READ_BOOL_FIELD(inFromCl);
READ_UINT_FIELD(requiredPerms); READ_UINT_FIELD(requiredPerms);
READ_UINT_FIELD(checkAsUser); READ_OID_FIELD(checkAsUser);
READ_DONE(); READ_DONE();
} }

View file

@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -133,19 +133,20 @@ static void doNegateFloat(Value *v);
%type <node> stmt schema_stmt %type <node> stmt schema_stmt
AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt AlterOwnerStmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt AlterOwnerStmt
AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserSetStmt AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserSetStmt
AlterRoleStmt AlterRoleSetStmt
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt GrantRoleStmt GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt
LockStmt NotifyStmt ExplainableStmt PreparableStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RemoveFuncStmt RemoveOperStmt RenameStmt RevokeRoleStmt RevokeStmt
RuleActionStmt RuleActionStmtOrEmpty RuleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt
SelectStmt TransactionStmt TruncateStmt SelectStmt TransactionStmt TruncateStmt
UnlistenStmt UpdateStmt VacuumStmt UnlistenStmt UpdateStmt VacuumStmt
@ -170,17 +171,16 @@ static void doNegateFloat(Value *v);
%type <ival> opt_lock lock_type cast_context %type <ival> opt_lock lock_type cast_context
%type <boolean> opt_force opt_or_replace %type <boolean> opt_force opt_or_replace
opt_grant_grant_option opt_revoke_grant_option opt_grant_grant_option opt_revoke_grant_option
opt_alter_admin_option
opt_grant_admin_option opt_revoke_admin_option
opt_nowait opt_nowait
%type <boolean> like_including_defaults %type <boolean> like_including_defaults
%type <list> user_list %type <list> role_list
%type <list> OptGroupList %type <list> OptRoleList
%type <defelt> OptGroupElem %type <defelt> OptRoleElem
%type <list> OptUserList
%type <defelt> OptUserElem
%type <str> OptSchemaName %type <str> OptSchemaName
%type <list> OptSchemaEltList %type <list> OptSchemaEltList
@ -308,7 +308,7 @@ static void doNegateFloat(Value *v);
%type <ival> Iconst %type <ival> Iconst
%type <str> Sconst comment_text %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 <list> var_list var_list_or_default
%type <str> ColId ColLabel var_name type_name param_name %type <str> ColId ColLabel var_name type_name param_name
%type <node> var_value zone_value %type <node> var_value zone_value
@ -336,7 +336,7 @@ static void doNegateFloat(Value *v);
*/ */
/* ordinary key words in alphabetical order */ /* 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 AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
@ -347,8 +347,8 @@ static void doNegateFloat(Value *v);
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE CURRENT_TIMESTAMP CURRENT_ROLE CURRENT_USER CURSOR CYCLE
DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS 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 FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
FREEZE FROM FULL FUNCTION FREEZE FROM FULL FUNCTION
GLOBAL GRANT GREATEST GROUP_P GLOBAL GRANT GRANTED GREATEST GROUP_P
HANDLER HAVING HEADER HOLD HOUR_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 LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
LOCK_P LOCK_P LOGIN
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NOCREATEROLE NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P
NULLIF NUMERIC NULLIF NUMERIC NOLOGIN
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER 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 READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT 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 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 SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYMMETRIC STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYMMETRIC
SYSID SYSTEM_P SYSID SYSTEM_P
@ -497,6 +497,8 @@ stmt :
| AlterOwnerStmt | AlterOwnerStmt
| AlterSeqStmt | AlterSeqStmt
| AlterTableStmt | AlterTableStmt
| AlterRoleSetStmt
| AlterRoleStmt
| AlterUserSetStmt | AlterUserSetStmt
| AlterUserStmt | AlterUserStmt
| AnalyzeStmt | AnalyzeStmt
@ -520,6 +522,7 @@ stmt :
| CreateStmt | CreateStmt
| CreateTableSpaceStmt | CreateTableSpaceStmt
| CreateTrigStmt | CreateTrigStmt
| CreateRoleStmt
| CreateUserStmt | CreateUserStmt
| CreatedbStmt | CreatedbStmt
| DeallocateStmt | DeallocateStmt
@ -535,11 +538,13 @@ stmt :
| DropStmt | DropStmt
| DropTableSpaceStmt | DropTableSpaceStmt
| DropTrigStmt | DropTrigStmt
| DropRoleStmt
| DropUserStmt | DropUserStmt
| DropdbStmt | DropdbStmt
| ExecuteStmt | ExecuteStmt
| ExplainStmt | ExplainStmt
| FetchStmt | FetchStmt
| GrantRoleStmt
| GrantStmt | GrantStmt
| IndexStmt | IndexStmt
| InsertStmt | InsertStmt
@ -553,6 +558,7 @@ stmt :
| RemoveFuncStmt | RemoveFuncStmt
| RemoveOperStmt | RemoveOperStmt
| RenameStmt | RenameStmt
| RevokeRoleStmt
| RevokeStmt | RevokeStmt
| RuleStmt | RuleStmt
| SelectStmt | SelectStmt
@ -571,16 +577,16 @@ stmt :
/***************************************************************************** /*****************************************************************************
* *
* Create a new Postgres DBMS user * Create a new Postgres DBMS role
* *
* *
*****************************************************************************/ *****************************************************************************/
CreateUserStmt: CreateRoleStmt:
CREATE USER UserId opt_with OptUserList CREATE ROLE RoleId opt_with OptRoleList
{ {
CreateUserStmt *n = makeNode(CreateUserStmt); CreateRoleStmt *n = makeNode(CreateRoleStmt);
n->user = $3; n->role = $3;
n->options = $5; n->options = $5;
$$ = (Node *)n; $$ = (Node *)n;
} }
@ -591,6 +597,80 @@ opt_with: WITH {}
| /*EMPTY*/ {} | /*EMPTY*/ {}
; ;
/*****************************************************************************
*
* Create a new Postgres DBMS user (role with implied login ability)
*
*
*****************************************************************************/
CreateUserStmt:
CREATE USER RoleId opt_with OptRoleList
{
CreateRoleStmt *n = makeNode(CreateRoleStmt);
n->role = $3;
n->options = $5;
n->options = lappend(n->options,makeDefElem("canlogin", (Node *)makeInteger(TRUE)));
$$ = (Node *)n;
}
;
/*****************************************************************************
*
* Alter a postgresql DBMS role
*
*
*****************************************************************************/
AlterRoleStmt:
ALTER ROLE RoleId opt_with OptRoleList
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
n->options = $5;
$$ = (Node *)n;
}
| ALTER ROLE RoleId add_drop ROLE role_list opt_alter_admin_option
{
AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->role = $3;
n->action = $4;
n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6));
n->options = lappend(n->options,makeDefElem("adminopt", (Node *)makeInteger($7)));
$$ = (Node *)n;
}
;
add_drop: ADD { $$ = +1; }
| DROP { $$ = -1; }
;
opt_alter_admin_option:
ADMIN OPTION { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
AlterRoleSetStmt:
ALTER ROLE RoleId SET set_rest
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
n->variable = $5->name;
n->value = $5->args;
$$ = (Node *)n;
}
| ALTER ROLE RoleId VariableResetStmt
{
AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->role = $3;
n->variable = ((VariableResetStmt *)$4)->name;
n->value = NIL;
$$ = (Node *)n;
}
;
/***************************************************************************** /*****************************************************************************
* *
* Alter a postgresql DBMS user * Alter a postgresql DBMS user
@ -599,10 +679,10 @@ opt_with: WITH {}
*****************************************************************************/ *****************************************************************************/
AlterUserStmt: AlterUserStmt:
ALTER USER UserId opt_with OptUserList ALTER USER RoleId opt_with OptRoleList
{ {
AlterUserStmt *n = makeNode(AlterUserStmt); AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->user = $3; n->role = $3;
n->options = $5; n->options = $5;
$$ = (Node *)n; $$ = (Node *)n;
} }
@ -610,18 +690,18 @@ AlterUserStmt:
AlterUserSetStmt: AlterUserSetStmt:
ALTER USER UserId SET set_rest ALTER USER RoleId SET set_rest
{ {
AlterUserSetStmt *n = makeNode(AlterUserSetStmt); AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->user = $3; n->role = $3;
n->variable = $5->name; n->variable = $5->name;
n->value = $5->args; n->value = $5->args;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER USER UserId VariableResetStmt | ALTER USER RoleId VariableResetStmt
{ {
AlterUserSetStmt *n = makeNode(AlterUserSetStmt); AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt);
n->user = $3; n->role = $3;
n->variable = ((VariableResetStmt *)$4)->name; n->variable = ((VariableResetStmt *)$4)->name;
n->value = NIL; n->value = NIL;
$$ = (Node *)n; $$ = (Node *)n;
@ -629,6 +709,24 @@ AlterUserSetStmt:
; ;
/*****************************************************************************
*
* Drop a postgresql DBMS role
*
* XXX Ideally this would have CASCADE/RESTRICT options, but since a role
* might own objects in multiple databases, there is presently no way to
* implement either cascading or restricting. Caveat DBA.
*****************************************************************************/
DropRoleStmt:
DROP ROLE role_list
{
DropRoleStmt *n = makeNode(DropRoleStmt);
n->roles = $3;
$$ = (Node *)n;
}
;
/***************************************************************************** /*****************************************************************************
* *
* Drop a postgresql DBMS user * Drop a postgresql DBMS user
@ -639,23 +737,23 @@ AlterUserSetStmt:
*****************************************************************************/ *****************************************************************************/
DropUserStmt: DropUserStmt:
DROP USER user_list DROP USER role_list
{ {
DropUserStmt *n = makeNode(DropUserStmt); DropRoleStmt *n = makeNode(DropRoleStmt);
n->users = $3; n->roles = $3;
$$ = (Node *)n; $$ = (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: OptRoleList:
OptUserList OptUserElem { $$ = lappend($1, $2); } OptRoleList OptRoleElem { $$ = lappend($1, $2); }
| /* EMPTY */ { $$ = NIL; } | /* EMPTY */ { $$ = NIL; }
; ;
OptUserElem: OptRoleElem:
PASSWORD Sconst PASSWORD Sconst
{ {
$$ = makeDefElem("password", (Node *)makeString($2)); $$ = makeDefElem("password", (Node *)makeString($2));
@ -680,66 +778,75 @@ OptUserElem:
{ {
$$ = makeDefElem("createdb", (Node *)makeInteger(FALSE)); $$ = makeDefElem("createdb", (Node *)makeInteger(FALSE));
} }
| CREATEROLE
{
$$ = makeDefElem("createrole", (Node *)makeInteger(TRUE));
}
| CREATEUSER | CREATEUSER
{ {
$$ = makeDefElem("createuser", (Node *)makeInteger(TRUE)); $$ = makeDefElem("createrole", (Node *)makeInteger(TRUE));
}
| LOGIN
{
$$ = makeDefElem("canlogin", (Node *)makeInteger(TRUE));
}
| NOCREATEROLE
{
$$ = makeDefElem("createrole", (Node *)makeInteger(FALSE));
} }
| NOCREATEUSER | 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 | VALID UNTIL Sconst
{ {
$$ = makeDefElem("validUntil", (Node *)makeString($3)); $$ = 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)); } role_list: role_list ',' RoleId { $$ = lappend($1, makeString($3)); }
| UserId { $$ = list_make1(makeString($1)); } | RoleId { $$ = list_make1(makeString($1)); }
; ;
/***************************************************************************** /*****************************************************************************
* *
* Create a postgresql group * Create a postgresql group (role without login ability)
* *
* *
*****************************************************************************/ *****************************************************************************/
CreateGroupStmt: CreateGroupStmt:
CREATE GROUP_P UserId opt_with OptGroupList CREATE GROUP_P RoleId opt_with OptRoleList
{ {
CreateGroupStmt *n = makeNode(CreateGroupStmt); CreateRoleStmt *n = makeNode(CreateRoleStmt);
n->name = $3; n->role = $3;
n->options = $5; n->options = $5;
$$ = (Node *)n; $$ = (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: AlterGroupStmt:
ALTER GROUP_P UserId add_drop USER user_list ALTER GROUP_P RoleId add_drop USER role_list
{ {
AlterGroupStmt *n = makeNode(AlterGroupStmt); AlterRoleStmt *n = makeNode(AlterRoleStmt);
n->name = $3; n->role = $3;
n->action = $4; n->action = $4;
n->listUsers = $6; n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6));
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
add_drop: ADD { $$ = +1; }
| DROP { $$ = -1; }
;
/***************************************************************************** /*****************************************************************************
* *
@ -772,10 +875,10 @@ add_drop: ADD { $$ = +1; }
*****************************************************************************/ *****************************************************************************/
DropGroupStmt: DropGroupStmt:
DROP GROUP_P UserId DROP GROUP_P role_list
{ {
DropGroupStmt *n = makeNode(DropGroupStmt); DropRoleStmt *n = makeNode(DropRoleStmt);
n->name = $3; n->roles = $3;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
@ -788,7 +891,7 @@ DropGroupStmt:
*****************************************************************************/ *****************************************************************************/
CreateSchemaStmt: CreateSchemaStmt:
CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
{ {
CreateSchemaStmt *n = makeNode(CreateSchemaStmt); CreateSchemaStmt *n = makeNode(CreateSchemaStmt);
/* One can omit the schema name or the authorization id. */ /* 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 */ /* Subcommands that are for ALTER TABLE or ALTER INDEX */
alter_rel_cmd: alter_rel_cmd:
/* ALTER [TABLE|INDEX] <name> OWNER TO UserId */ /* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
OWNER TO UserId OWNER TO RoleId
{ {
AlterTableCmd *n = makeNode(AlterTableCmd); AlterTableCmd *n = makeNode(AlterTableCmd);
n->subtype = AT_ChangeOwner; n->subtype = AT_ChangeOwner;
@ -3013,6 +3116,36 @@ from_in: FROM {}
; ;
/*****************************************************************************
*
* GRANT and REVOKE ROLE statements
*
*****************************************************************************/
GrantRoleStmt: GRANT ROLE role_list TO role_list opt_grant_admin_option
opt_granted_by
{
GrantRoleStmt *n = makeNode(GrantRoleStmt);
n->granted_roles = $3;
n->grantee_roles = $5;
n->is_grant = true;
n->admin_opt = $6;
n->grantor = $7;
$$ = (Node*)n;
}
RevokeRoleStmt: REVOKE ROLE opt_revoke_admin_option role_list FROM role_list
opt_drop_behavior
{
GrantRoleStmt *n = makeNode(GrantRoleStmt);
n->granted_roles = $4;
n->grantee_roles = $6;
n->is_grant = false;
n->admin_opt = $3;
n->behavior = $7;
$$ = (Node*)n;
}
/***************************************************************************** /*****************************************************************************
* *
* GRANT and REVOKE statements * GRANT and REVOKE statements
@ -3139,26 +3272,24 @@ grantee_list:
| grantee_list ',' grantee { $$ = lappend($1, $3); } | grantee_list ',' grantee { $$ = lappend($1, $3); }
; ;
grantee: ColId grantee: RoleId
{ {
PrivGrantee *n = makeNode(PrivGrantee); PrivGrantee *n = makeNode(PrivGrantee);
/* This hack lets us avoid reserving PUBLIC as a keyword*/ /* This hack lets us avoid reserving PUBLIC as a keyword*/
if (strcmp($1, "public") == 0) if (strcmp($1, "public") == 0)
n->username = NULL; n->rolname = NULL;
else else
n->username = $1; n->rolname = $1;
n->groupname = NULL;
$$ = (Node *)n; $$ = (Node *)n;
} }
| GROUP_P ColId | GROUP_P RoleId
{ {
PrivGrantee *n = makeNode(PrivGrantee); PrivGrantee *n = makeNode(PrivGrantee);
/* Treat GROUP PUBLIC as a synonym for PUBLIC */ /* Treat GROUP PUBLIC as a synonym for PUBLIC */
if (strcmp($2, "public") == 0) if (strcmp($2, "public") == 0)
n->groupname = NULL; n->rolname = NULL;
else else
n->groupname = $2; n->rolname = $2;
n->username = NULL;
$$ = (Node *)n; $$ = (Node *)n;
} }
; ;
@ -3169,11 +3300,26 @@ opt_grant_grant_option:
| /*EMPTY*/ { $$ = FALSE; } | /*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: opt_revoke_grant_option:
GRANT OPTION FOR { $$ = TRUE; } GRANT OPTION FOR { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; }
; ;
opt_revoke_admin_option:
ADMIN OPTION FOR { $$ = TRUE; }
| /*EMPTY*/ { $$ = FALSE; }
;
function_with_argtypes_list: function_with_argtypes_list:
function_with_argtypes { $$ = list_make1($1); } function_with_argtypes { $$ = list_make1($1); }
@ -3727,10 +3873,10 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
n->newname = $7; n->newname = $7;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER GROUP_P UserId RENAME TO UserId | ALTER GROUP_P RoleId RENAME TO RoleId
{ {
RenameStmt *n = makeNode(RenameStmt); RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_GROUP; n->renameType = OBJECT_ROLE;
n->subname = $3; n->subname = $3;
n->newname = $6; n->newname = $6;
$$ = (Node *)n; $$ = (Node *)n;
@ -3796,10 +3942,18 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
n->renameType = OBJECT_TRIGGER; n->renameType = OBJECT_TRIGGER;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER USER UserId RENAME TO UserId | ALTER ROLE RoleId RENAME TO RoleId
{ {
RenameStmt *n = makeNode(RenameStmt); 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->subname = $3;
n->newname = $6; n->newname = $6;
$$ = (Node *)n; $$ = (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); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_AGGREGATE; n->objectType = OBJECT_AGGREGATE;
@ -3834,7 +3988,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $9; n->newowner = $9;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER CONVERSION_P any_name OWNER TO UserId | ALTER CONVERSION_P any_name OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_CONVERSION; n->objectType = OBJECT_CONVERSION;
@ -3842,7 +3996,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6; n->newowner = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER DATABASE database_name OWNER TO UserId | ALTER DATABASE database_name OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DATABASE; n->objectType = OBJECT_DATABASE;
@ -3850,7 +4004,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6; n->newowner = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER DOMAIN_P any_name OWNER TO UserId | ALTER DOMAIN_P any_name OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_DOMAIN; n->objectType = OBJECT_DOMAIN;
@ -3858,7 +4012,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6; n->newowner = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER FUNCTION func_name func_args OWNER TO UserId | ALTER FUNCTION func_name func_args OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_FUNCTION; n->objectType = OBJECT_FUNCTION;
@ -3867,7 +4021,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $7; n->newowner = $7;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO UserId | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPERATOR; n->objectType = OBJECT_OPERATOR;
@ -3876,7 +4030,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $9; n->newowner = $9;
$$ = (Node *)n; $$ = (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); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_OPCLASS; n->objectType = OBJECT_OPCLASS;
@ -3885,7 +4039,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $9; n->newowner = $9;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER SCHEMA name OWNER TO UserId | ALTER SCHEMA name OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_SCHEMA; n->objectType = OBJECT_SCHEMA;
@ -3893,7 +4047,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6; n->newowner = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER TYPE_P any_name OWNER TO UserId | ALTER TYPE_P any_name OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TYPE; n->objectType = OBJECT_TYPE;
@ -3901,7 +4055,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId
n->newowner = $6; n->newowner = $6;
$$ = (Node *)n; $$ = (Node *)n;
} }
| ALTER TABLESPACE name OWNER TO UserId | ALTER TABLESPACE name OWNER TO RoleId
{ {
AlterOwnerStmt *n = makeNode(AlterOwnerStmt); AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
n->objectType = OBJECT_TABLESPACE; n->objectType = OBJECT_TABLESPACE;
@ -6903,6 +7057,33 @@ func_expr: func_name '(' ')'
$$ = (Node *)makeTypeCast((Node *)s, d); $$ = (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 | CURRENT_USER
{ {
FuncCall *n = makeNode(FuncCall); FuncCall *n = makeNode(FuncCall);
@ -7685,7 +7866,7 @@ AexprConst: Iconst
Iconst: ICONST { $$ = $1; }; Iconst: ICONST { $$ = $1; };
Sconst: SCONST { $$ = $1; }; Sconst: SCONST { $$ = $1; };
UserId: ColId { $$ = $1; }; RoleId: ColId { $$ = $1; };
/* /*
* Name classification hierarchy. * Name classification hierarchy.
@ -7774,6 +7955,7 @@ unreserved_keyword:
| CONVERSION_P | CONVERSION_P
| COPY | COPY
| CREATEDB | CREATEDB
| CREATEROLE
| CREATEUSER | CREATEUSER
| CSV | CSV
| CURSOR | CURSOR
@ -7834,6 +8016,7 @@ unreserved_keyword:
| LOCAL | LOCAL
| LOCATION | LOCATION
| LOCK_P | LOCK_P
| LOGIN
| MATCH | MATCH
| MAXVALUE | MAXVALUE
| MINUTE_P | MINUTE_P
@ -7845,7 +8028,9 @@ unreserved_keyword:
| NEXT | NEXT
| NO | NO
| NOCREATEDB | NOCREATEDB
| NOCREATEROLE
| NOCREATEUSER | NOCREATEUSER
| NOLOGIN
| NOTHING | NOTHING
| NOTIFY | NOTIFY
| NOWAIT | NOWAIT
@ -8045,6 +8230,7 @@ reserved_keyword:
| CURRENT_DATE | CURRENT_DATE
| CURRENT_TIME | CURRENT_TIME
| CURRENT_TIMESTAMP | CURRENT_TIMESTAMP
| CURRENT_ROLE
| CURRENT_USER | CURRENT_USER
| DEFAULT | DEFAULT
| DEFERRABLE | DEFERRABLE
@ -8083,6 +8269,7 @@ reserved_keyword:
| PRIMARY | PRIMARY
| REFERENCES | REFERENCES
| SELECT | SELECT
| SESSION_ROLE
| SESSION_USER | SESSION_USER
| SOME | SOME
| SYMMETRIC | SYMMETRIC
@ -8093,6 +8280,7 @@ reserved_keyword:
| TRUE_P | TRUE_P
| UNION | UNION
| UNIQUE | UNIQUE
| ROLE
| USER | USER
| USING | USING
| WHEN | WHEN

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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}, {"returns", RETURNS},
{"revoke", REVOKE}, {"revoke", REVOKE},
{"right", RIGHT}, {"right", RIGHT},
{"role", ROLE},
{"rollback", ROLLBACK}, {"rollback", ROLLBACK},
{"row", ROW}, {"row", ROW},
{"rows", ROWS}, {"rows", ROWS},

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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->inFromCl = inFromCl;
rte->requiredPerms = ACL_SELECT; 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 * Add completed RTE to pstate's range table list, but not to join
@ -620,7 +620,7 @@ addRangeTableEntryForRelation(ParseState *pstate,
rte->inFromCl = inFromCl; rte->inFromCl = inFromCl;
rte->requiredPerms = ACL_SELECT; 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 * Add completed RTE to pstate's range table list, but not to join
@ -698,7 +698,7 @@ addRangeTableEntryForSubquery(ParseState *pstate,
rte->inFromCl = inFromCl; rte->inFromCl = inFromCl;
rte->requiredPerms = 0; rte->requiredPerms = 0;
rte->checkAsUser = 0; rte->checkAsUser = InvalidOid;
/* /*
* Add completed RTE to pstate's range table list, but not to join * Add completed RTE to pstate's range table list, but not to join
@ -823,7 +823,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
rte->inFromCl = inFromCl; rte->inFromCl = inFromCl;
rte->requiredPerms = 0; rte->requiredPerms = 0;
rte->checkAsUser = 0; rte->checkAsUser = InvalidOid;
/* /*
* Add completed RTE to pstate's range table list, but not to join * Add completed RTE to pstate's range table list, but not to join
@ -882,7 +882,7 @@ addRangeTableEntryForJoin(ParseState *pstate,
rte->inFromCl = inFromCl; rte->inFromCl = inFromCl;
rte->requiredPerms = 0; rte->requiredPerms = 0;
rte->checkAsUser = 0; rte->checkAsUser = InvalidOid;
/* /*
* Add completed RTE to pstate's range table list, but not to join * Add completed RTE to pstate's range table list, but not to join

View file

@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2005, PostgreSQL Global Development Group * Copyright (c) 2001-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.96 2005/06/25 23:58:57 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.97 2005/06/28 05:08:59 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
@ -34,7 +34,6 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "libpq/libpq.h" #include "libpq/libpq.h"
#include "libpq/pqsignal.h" #include "libpq/pqsignal.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"

View file

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* *
@ -2032,12 +2032,11 @@ reaper(SIGNAL_ARGS)
FatalError = false; FatalError = false;
/* /*
* Load the flat user/group files into postmaster's caches. * Load the flat authorization file into postmaster's cache.
* The startup process has recomputed these from the database * The startup process has recomputed this from the database
* contents, so we wait till it finishes before loading them. * contents, so we wait till it finishes before loading it.
*/ */
load_user(); load_role();
load_group();
/* /*
* Crank up the background writer. It doesn't matter if this * Crank up the background writer. It doesn't matter if this
@ -2664,8 +2663,7 @@ BackendRun(Port *port)
load_hba(); load_hba();
load_ident(); load_ident();
load_user(); load_role();
load_group();
#endif #endif
/* /*
@ -3290,10 +3288,9 @@ sigusr1_handler(SIGNAL_ARGS)
if (CheckPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE)) if (CheckPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE))
{ {
/* /*
* Password or group file has changed. * Authorization file has changed.
*/ */
load_user(); load_role();
load_group();
} }
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN)) if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN))

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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" #include "utils/syscache.h"
static void setRuleCheckAsUser_Query(Query *qry, AclId userid); static void setRuleCheckAsUser_Query(Query *qry, Oid userid);
static void setRuleCheckAsUser_Expr(Node *node, AclId userid); static void setRuleCheckAsUser_Expr(Node *node, Oid userid);
static bool setRuleCheckAsUser_walker(Node *node, AclId *context); static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
/* /*
@ -505,7 +505,7 @@ DefineQueryRewrite(RuleStmt *stmt)
* them always. * them always.
*/ */
static void static void
setRuleCheckAsUser_Query(Query *qry, AclId userid) setRuleCheckAsUser_Query(Query *qry, Oid userid)
{ {
ListCell *l; ListCell *l;
@ -534,13 +534,13 @@ setRuleCheckAsUser_Query(Query *qry, AclId userid)
* Expression-tree walker to find sublink queries * Expression-tree walker to find sublink queries
*/ */
static void static void
setRuleCheckAsUser_Expr(Node *node, AclId userid) setRuleCheckAsUser_Expr(Node *node, Oid userid)
{ {
(void) setRuleCheckAsUser_walker(node, &userid); (void) setRuleCheckAsUser_walker(node, &userid);
} }
static bool static bool
setRuleCheckAsUser_walker(Node *node, AclId *context) setRuleCheckAsUser_walker(Node *node, Oid *context)
{ {
if (node == NULL) if (node == NULL)
return false; return false;

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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; subrte->checkAsUser = rte->checkAsUser;
rte->requiredPerms = 0; /* no permission check on subquery itself */ rte->requiredPerms = 0; /* no permission check on subquery itself */
rte->checkAsUser = 0; rte->checkAsUser = InvalidOid;
/* /*
* FOR UPDATE/SHARE of view? * FOR UPDATE/SHARE of view?

View file

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * 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 "access/twophase.h"
#include "catalog/catalog.h" #include "catalog/catalog.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_shadow.h"
#include "commands/alter.h" #include "commands/alter.h"
#include "commands/async.h" #include "commands/async.h"
#include "commands/cluster.h" #include "commands/cluster.h"
@ -279,12 +278,11 @@ check_xact_readonly(Node *parsetree)
case T_AlterDatabaseSetStmt: case T_AlterDatabaseSetStmt:
case T_AlterDomainStmt: case T_AlterDomainStmt:
case T_AlterFunctionStmt: case T_AlterFunctionStmt:
case T_AlterGroupStmt: case T_AlterRoleStmt:
case T_AlterRoleSetStmt:
case T_AlterOwnerStmt: case T_AlterOwnerStmt:
case T_AlterSeqStmt: case T_AlterSeqStmt:
case T_AlterTableStmt: case T_AlterTableStmt:
case T_AlterUserStmt:
case T_AlterUserSetStmt:
case T_RenameStmt: case T_RenameStmt:
case T_CommentStmt: case T_CommentStmt:
case T_DefineStmt: case T_DefineStmt:
@ -293,7 +291,7 @@ check_xact_readonly(Node *parsetree)
case T_CreatedbStmt: case T_CreatedbStmt:
case T_CreateDomainStmt: case T_CreateDomainStmt:
case T_CreateFunctionStmt: case T_CreateFunctionStmt:
case T_CreateGroupStmt: case T_CreateRoleStmt:
case T_IndexStmt: case T_IndexStmt:
case T_CreatePLangStmt: case T_CreatePLangStmt:
case T_CreateOpClassStmt: case T_CreateOpClassStmt:
@ -304,7 +302,6 @@ check_xact_readonly(Node *parsetree)
case T_CreateTableSpaceStmt: case T_CreateTableSpaceStmt:
case T_CreateTrigStmt: case T_CreateTrigStmt:
case T_CompositeTypeStmt: case T_CompositeTypeStmt:
case T_CreateUserStmt:
case T_ViewStmt: case T_ViewStmt:
case T_RemoveAggrStmt: case T_RemoveAggrStmt:
case T_DropCastStmt: case T_DropCastStmt:
@ -312,13 +309,13 @@ check_xact_readonly(Node *parsetree)
case T_DropdbStmt: case T_DropdbStmt:
case T_DropTableSpaceStmt: case T_DropTableSpaceStmt:
case T_RemoveFuncStmt: case T_RemoveFuncStmt:
case T_DropGroupStmt: case T_DropRoleStmt:
case T_DropPLangStmt: case T_DropPLangStmt:
case T_RemoveOperStmt: case T_RemoveOperStmt:
case T_RemoveOpClassStmt: case T_RemoveOpClassStmt:
case T_DropPropertyStmt: case T_DropPropertyStmt:
case T_DropUserStmt:
case T_GrantStmt: case T_GrantStmt:
case T_GrantRoleStmt:
case T_TruncateStmt: case T_TruncateStmt:
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
@ -679,11 +676,14 @@ ProcessUtility(Node *parsetree,
} }
break; break;
case T_GrantStmt: case T_GrantStmt:
ExecuteGrantStmt((GrantStmt *) parsetree); ExecuteGrantStmt((GrantStmt *) parsetree);
break; break;
case T_GrantRoleStmt:
GrantRole((GrantRoleStmt *) parsetree);
break;
/* /*
* ******************************** object creation / * ******************************** object creation /
* destruction ******************************** * destruction ********************************
@ -958,22 +958,22 @@ ProcessUtility(Node *parsetree,
break; break;
/* /*
* ******************************** USER statements **** * ******************************** ROLE statements ****
*/ */
case T_CreateUserStmt: case T_CreateRoleStmt:
CreateUser((CreateUserStmt *) parsetree); CreateRole((CreateRoleStmt *) parsetree);
break; break;
case T_AlterUserStmt: case T_AlterRoleStmt:
AlterUser((AlterUserStmt *) parsetree); AlterRole((AlterRoleStmt *) parsetree);
break; break;
case T_AlterUserSetStmt: case T_AlterRoleSetStmt:
AlterUserSet((AlterUserSetStmt *) parsetree); AlterRoleSet((AlterRoleSetStmt *) parsetree);
break; break;
case T_DropUserStmt: case T_DropRoleStmt:
DropUser((DropUserStmt *) parsetree); DropRole((DropRoleStmt *) parsetree);
break; break;
case T_LockStmt: case T_LockStmt:
@ -984,18 +984,6 @@ ProcessUtility(Node *parsetree,
AfterTriggerSetState((ConstraintsSetStmt *) parsetree); AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
break; 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: case T_CheckPointStmt:
if (!superuser()) if (!superuser())
ereport(ERROR, ereport(ERROR,
@ -1350,9 +1338,6 @@ CreateCommandTag(Node *parsetree)
case OBJECT_FUNCTION: case OBJECT_FUNCTION:
tag = "ALTER FUNCTION"; tag = "ALTER FUNCTION";
break; break;
case OBJECT_GROUP:
tag = "ALTER GROUP";
break;
case OBJECT_INDEX: case OBJECT_INDEX:
tag = "ALTER INDEX"; tag = "ALTER INDEX";
break; break;
@ -1362,6 +1347,9 @@ CreateCommandTag(Node *parsetree)
case OBJECT_OPCLASS: case OBJECT_OPCLASS:
tag = "ALTER OPERATOR CLASS"; tag = "ALTER OPERATOR CLASS";
break; break;
case OBJECT_ROLE:
tag = "ALTER ROLE";
break;
case OBJECT_SCHEMA: case OBJECT_SCHEMA:
tag = "ALTER SCHEMA"; tag = "ALTER SCHEMA";
break; break;
@ -1371,9 +1359,6 @@ CreateCommandTag(Node *parsetree)
case OBJECT_TRIGGER: case OBJECT_TRIGGER:
tag = "ALTER TRIGGER"; tag = "ALTER TRIGGER";
break; break;
case OBJECT_USER:
tag = "ALTER USER";
break;
default: default:
tag = "ALTER TABLE"; tag = "ALTER TABLE";
} }
@ -1450,6 +1435,14 @@ CreateCommandTag(Node *parsetree)
} }
break; break;
case T_GrantRoleStmt:
{
GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
}
break;
case T_DefineStmt: case T_DefineStmt:
switch (((DefineStmt *) parsetree)->kind) switch (((DefineStmt *) parsetree)->kind)
{ {
@ -1588,20 +1581,20 @@ CreateCommandTag(Node *parsetree)
tag = "DROP LANGUAGE"; tag = "DROP LANGUAGE";
break; break;
case T_CreateUserStmt: case T_CreateRoleStmt:
tag = "CREATE USER"; tag = "CREATE ROLE";
break; break;
case T_AlterUserStmt: case T_AlterRoleStmt:
tag = "ALTER USER"; tag = "ALTER ROLE";
break; break;
case T_AlterUserSetStmt: case T_AlterRoleSetStmt:
tag = "ALTER USER"; tag = "ALTER ROLE";
break; break;
case T_DropUserStmt: case T_DropRoleStmt:
tag = "DROP USER"; tag = "DROP ROLE";
break; break;
case T_LockStmt: case T_LockStmt:
@ -1612,18 +1605,6 @@ CreateCommandTag(Node *parsetree)
tag = "SET CONSTRAINTS"; tag = "SET CONSTRAINTS";
break; 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: case T_CheckPointStmt:
tag = "CHECKPOINT"; tag = "CHECKPOINT";
break; break;

File diff suppressed because it is too large Load diff

View file

@ -8,14 +8,13 @@
* *
* *
* IDENTIFICATION * 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 "postgres.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/pg_shadow.h"
#include "fmgr.h" #include "fmgr.h"
#include "funcapi.h" #include "funcapi.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -306,7 +305,7 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
if (!OidIsValid(beentry->userid)) if (!OidIsValid(beentry->userid))
PG_RETURN_NULL(); PG_RETURN_NULL();
PG_RETURN_INT32(beentry->userid); PG_RETURN_OID(beentry->userid);
} }

View file

@ -17,7 +17,7 @@
* *
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * 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; void *qplan;
Relation query_rel; Relation query_rel;
AclId save_uid; Oid save_uid;
/* /*
* The query is always run against the FK table except when this is an * 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; Snapshot crosscheck_snapshot;
int limit; int limit;
int spi_result; int spi_result;
AclId save_uid; Oid save_uid;
Datum vals[RI_MAX_NUMKEYS * 2]; Datum vals[RI_MAX_NUMKEYS * 2];
char nulls[RI_MAX_NUMKEYS * 2]; char nulls[RI_MAX_NUMKEYS * 2];

View file

@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * 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. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -46,13 +46,13 @@
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h" #include "catalog/pg_cast.h"
#include "catalog/pg_constraint.h" #include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h" #include "catalog/pg_depend.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_trigger.h" #include "catalog/pg_trigger.h"
#include "executor/spi.h" #include "executor/spi.h"
#include "funcapi.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 * get_userbyid - Get a user name by roleid and
* fallback to 'unknown (UID=n)' * fallback to 'unknown (OID=n)'
* ---------- * ----------
*/ */
Datum Datum
pg_get_userbyid(PG_FUNCTION_ARGS) pg_get_userbyid(PG_FUNCTION_ARGS)
{ {
int32 uid = PG_GETARG_INT32(0); Oid roleid = PG_GETARG_OID(0);
Name result; Name result;
HeapTuple usertup; HeapTuple roletup;
Form_pg_shadow user_rec; Form_pg_authid role_rec;
/* /*
* Allocate space for the result * Allocate space for the result
@ -1213,19 +1213,19 @@ pg_get_userbyid(PG_FUNCTION_ARGS)
memset(NameStr(*result), 0, NAMEDATALEN); 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, roletup = SearchSysCache(AUTHOID,
ObjectIdGetDatum(uid), ObjectIdGetDatum(roleid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(usertup)) if (HeapTupleIsValid(roletup))
{ {
user_rec = (Form_pg_shadow) GETSTRUCT(usertup); role_rec = (Form_pg_authid) GETSTRUCT(roletup);
StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN); StrNCpy(NameStr(*result), NameStr(role_rec->rolname), NAMEDATALEN);
ReleaseSysCache(usertup); ReleaseSysCache(roletup);
} }
else else
sprintf(NameStr(*result), "unknown (UID=%d)", uid); sprintf(NameStr(*result), "unknown (OID=%u)", roleid);
PG_RETURN_NAME(result); PG_RETURN_NAME(result);
} }

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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 * NOTES
* Eventually, the index information should go through here, too. * Eventually, the index information should go through here, too.
@ -24,8 +24,6 @@
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_group.h"
#include "catalog/pg_statistic.h" #include "catalog/pg_statistic.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "nodes/makefuncs.h" #include "nodes/makefuncs.h"
@ -2010,66 +2008,35 @@ get_namespace_name(Oid nspid)
return NULL; return NULL;
} }
/* ---------- PG_SHADOW CACHE ---------- */ /* ---------- PG_AUTHID CACHE ---------- */
/* /*
* get_usesysid * get_roleid
* * Given a role name, look up the role's OID.
* Given a user name, look up the user's sysid. * Returns InvalidOid if no such role.
* 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 ...
*/ */
AclId Oid
get_usesysid(const char *username) get_roleid(const char *rolname)
{ {
AclId userId; return GetSysCacheOid(AUTHNAME,
HeapTuple userTup; PointerGetDatum(rolname),
0, 0, 0);
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;
} }
/* /*
* get_grosysid * get_roleid_checked
* * Given a role name, look up the role's OID.
* Given a group name, look up the group's sysid. * ereports if no such role.
* Raises an error if no such group (rather than returning zero,
* which might possibly be a valid grosysid).
*
*/ */
AclId Oid
get_grosysid(char *groname) get_roleid_checked(const char *rolname)
{ {
AclId groupId; Oid roleid;
HeapTuple groupTup;
groupTup = SearchSysCache(GRONAME, roleid = get_roleid(rolname);
PointerGetDatum(groname), if (!OidIsValid(roleid))
0, 0, 0);
if (!HeapTupleIsValid(groupTup))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("group \"%s\" does not exist", groname))); errmsg("role \"%s\" does not exist", rolname)));
return roleid;
groupId = ((Form_pg_group) GETSTRUCT(groupTup))->grosysid;
ReleaseSysCache(groupTup);
return groupId;
} }

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
@ -27,9 +27,10 @@
#include "catalog/pg_aggregate.h" #include "catalog/pg_aggregate.h"
#include "catalog/pg_amop.h" #include "catalog/pg_amop.h"
#include "catalog/pg_amproc.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_cast.h"
#include "catalog/pg_conversion.h" #include "catalog/pg_conversion.h"
#include "catalog/pg_group.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_inherits.h" #include "catalog/pg_inherits.h"
#include "catalog/pg_language.h" #include "catalog/pg_language.h"
@ -38,7 +39,6 @@
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h" #include "catalog/pg_rewrite.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_statistic.h" #include "catalog/pg_statistic.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "utils/catcache.h" #include "utils/catcache.h"
@ -172,6 +172,46 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
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 */ CastRelationId, /* CASTSOURCETARGET */
CastSourceTargetIndexId, CastSourceTargetIndexId,
@ -233,26 +273,6 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
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 */ {IndexRelationId, /* INDEXRELID */
IndexRelidIndexId, IndexRelidIndexId,
Anum_pg_index_indrelid, Anum_pg_index_indrelid,
@ -383,26 +403,6 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
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 */ {StatisticRelationId, /* STATRELATT */
StatisticRelidAttnumIndexId, StatisticRelidAttnumIndexId,
Anum_pg_statistic_starelid, Anum_pg_statistic_starelid,

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 struct fmgr_security_definer_cache
{ {
FmgrInfo flinfo; FmgrInfo flinfo;
AclId userid; Oid userid;
}; };
/* /*
@ -786,7 +786,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS)
Datum result; Datum result;
FmgrInfo *save_flinfo; FmgrInfo *save_flinfo;
struct fmgr_security_definer_cache * volatile fcache; struct fmgr_security_definer_cache * volatile fcache;
AclId save_userid; Oid save_userid;
HeapTuple tuple; HeapTuple tuple;
if (!fcinfo->flinfo->fn_extra) if (!fcinfo->flinfo->fn_extra)

View file

@ -4,9 +4,10 @@
* Routines for maintaining "flat file" images of the shared catalogs. * Routines for maintaining "flat file" images of the shared catalogs.
* *
* We use flat files so that the postmaster and not-yet-fully-started * 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 * backends can look at the contents of pg_database, pg_authid, and
* for authentication purposes. This module is responsible for keeping the * pg_auth_members for authentication purposes. This module is
* flat-file images as nearly in sync with database reality as possible. * 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 * 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 * 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) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "access/twophase_rmgr.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_database.h"
#include "catalog/pg_group.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "commands/trigger.h" #include "commands/trigger.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -45,19 +48,18 @@
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/flatfiles.h" #include "utils/flatfiles.h"
#include "utils/fmgroids.h"
#include "utils/resowner.h" #include "utils/resowner.h"
#include "utils/syscache.h" #include "utils/syscache.h"
/* Actual names of the flat files (within $PGDATA/global/) */ /* Actual names of the flat files (within $PGDATA/global/) */
#define DATABASE_FLAT_FILE "pg_database" #define DATABASE_FLAT_FILE "pg_database"
#define GROUP_FLAT_FILE "pg_group" #define AUTH_FLAT_FILE "pg_auth"
#define USER_FLAT_FILE "pg_pwd"
/* Info bits in a flatfiles 2PC record */ /* Info bits in a flatfiles 2PC record */
#define FF_BIT_DATABASE 1 #define FF_BIT_DATABASE 1
#define FF_BIT_GROUP 2 #define FF_BIT_AUTH 2
#define FF_BIT_USER 4
/* /*
@ -73,8 +75,7 @@
* SubTransactionId is seen at top-level commit. * SubTransactionId is seen at top-level commit.
*/ */
static SubTransactionId database_file_update_subid = InvalidSubTransactionId; static SubTransactionId database_file_update_subid = InvalidSubTransactionId;
static SubTransactionId group_file_update_subid = InvalidSubTransactionId; static SubTransactionId auth_file_update_subid = InvalidSubTransactionId;
static SubTransactionId user_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 void
group_file_update_needed(void) auth_file_update_needed(void)
{ {
if (group_file_update_subid == InvalidSubTransactionId) if (auth_file_update_subid == InvalidSubTransactionId)
group_file_update_subid = GetCurrentSubTransactionId(); auth_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();
} }
@ -128,39 +119,20 @@ database_getflatfilename(void)
} }
/* /*
* group_getflatfilename --- get full pathname of group file * Get full pathname of auth file.
* *
* Note that result string is palloc'd, and should be freed by the caller. * Note that result string is palloc'd, and should be freed by the caller.
*/ */
char * char *
group_getflatfilename(void) auth_getflatfilename(void)
{ {
int bufsize; int bufsize;
char *pfnam; char *pfnam;
bufsize = strlen(DataDir) + strlen("/global/") + bufsize = strlen(DataDir) + strlen("/global/") +
strlen(GROUP_FLAT_FILE) + 1; strlen(AUTH_FLAT_FILE) + 1;
pfnam = (char *) palloc(bufsize); pfnam = (char *) palloc(bufsize);
snprintf(pfnam, bufsize, "%s/global/%s", DataDir, GROUP_FLAT_FILE); snprintf(pfnam, bufsize, "%s/global/%s", DataDir, AUTH_FLAT_FILE);
return pfnam;
}
/*
* Get full pathname of password file.
*
* Note that result string is palloc'd, and should be freed by the caller.
*/
char *
user_getflatfilename(void)
{
int bufsize;
char *pfnam;
bufsize = strlen(DataDir) + strlen("/global/") +
strlen(USER_FLAT_FILE) + 1;
pfnam = (char *) palloc(bufsize);
snprintf(pfnam, bufsize, "%s/global/%s", DataDir, USER_FLAT_FILE);
return pfnam; return pfnam;
} }
@ -189,7 +161,7 @@ fputs_quote(const char *str, FILE *fp)
/* /*
* name_okay * 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. * hba.c's parser won't handle fields split across lines, even if quoted.
*/ */
static bool static bool
@ -322,165 +294,81 @@ write_database_file(Relation drel)
/* /*
* write_group_file: update the flat group file * Support for write_auth_file
*/ */
static void
write_group_file(Relation grel) typedef struct {
Oid roleid;
char* rolname;
char* rolpassword;
char* rolvaliduntil;
List* roles_names;
} auth_entry;
typedef struct {
Oid roleid;
Oid memberid;
} authmem_entry;
static int
oid_compar(const void *a, const void *b)
{ {
char *filename, const auth_entry *a_auth = (const auth_entry*) a;
*tempname; const auth_entry *b_auth = (const auth_entry*) b;
int bufsize;
FILE *fp;
mode_t oumask;
HeapScanDesc scan;
HeapTuple tuple;
/* if (a_auth->roleid < b_auth->roleid) return -1;
* Create a temporary filename to be renamed later. This prevents the if (a_auth->roleid > b_auth->roleid) return 1;
* backend from clobbering the flat file while the postmaster return 0;
* might be reading from it.
*/
filename = group_getflatfilename();
bufsize = strlen(filename) + 12;
tempname = (char *) palloc(bufsize);
snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
oumask = umask((mode_t) 077);
fp = AllocateFile(tempname, "w");
umask(oumask);
if (fp == NULL)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to temporary file \"%s\": %m",
tempname)));
/*
* Read pg_group and write the file.
*/
scan = heap_beginscan(grel, SnapshotNow, 0, NULL);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
Form_pg_group grpform = (Form_pg_group) GETSTRUCT(tuple);
HeapTupleHeader tup = tuple->t_data;
char *tp; /* ptr to tuple data */
long off; /* offset in tuple data */
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
Datum datum;
char *groname;
IdList *grolist_p;
AclId *aidp;
int i,
num;
groname = NameStr(grpform->groname);
/*
* Check for illegal characters in the group name.
*/
if (!name_okay(groname))
{
ereport(LOG,
(errmsg("invalid group name \"%s\"", groname)));
continue;
}
/*
* We can't use heap_getattr() here because during startup we will
* not have any tupdesc for pg_group. Fortunately it's not too
* hard to work around this. grolist is the first possibly-null
* field so we can compute its offset directly.
*/
tp = (char *) tup + tup->t_hoff;
off = offsetof(FormData_pg_group, grolist);
if (HeapTupleHasNulls(tuple) &&
att_isnull(Anum_pg_group_grolist - 1, bp))
{
/* grolist is null, so we can ignore this group */
continue;
}
/* assume grolist is pass-by-ref */
datum = PointerGetDatum(tp + off);
/*
* We can't currently support out-of-line toasted group lists in
* startup mode (the tuptoaster won't work). This sucks, but it
* should be something of a corner case. Live with it until we
* can redesign pg_group.
*
* Detect startup mode by noting whether we got a tupdesc.
*/
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)) &&
RelationGetDescr(grel) == NULL)
continue;
/* be sure the IdList is not toasted */
grolist_p = DatumGetIdListP(datum);
/*
* The file format is: "groupname" usesysid1 usesysid2 ...
*
* We ignore groups that have no members.
*/
aidp = IDLIST_DAT(grolist_p);
num = IDLIST_NUM(grolist_p);
if (num > 0)
{
fputs_quote(groname, fp);
fprintf(fp, "\t%u", aidp[0]);
for (i = 1; i < num; ++i)
fprintf(fp, " %u", aidp[i]);
fputs("\n", fp);
}
/* if IdList was toasted, free detoasted copy */
if ((Pointer) grolist_p != DatumGetPointer(datum))
pfree(grolist_p);
}
heap_endscan(scan);
if (FreeFile(fp))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write to temporary file \"%s\": %m",
tempname)));
/*
* Rename the temp file to its final name, deleting the old flat file.
* We expect that rename(2) is an atomic action.
*/
if (rename(tempname, filename))
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not rename file \"%s\" to \"%s\": %m",
tempname, filename)));
pfree(tempname);
pfree(filename);
} }
static int
name_compar(const void *a, const void *b)
{
const auth_entry *a_auth = (const auth_entry*) a;
const auth_entry *b_auth = (const auth_entry*) b;
return strcmp(a_auth->rolname,b_auth->rolname);
}
static int
mem_compar(const void *a, const void *b)
{
const authmem_entry *a_auth = (const authmem_entry*) a;
const authmem_entry *b_auth = (const authmem_entry*) b;
if (a_auth->memberid < b_auth->memberid) return -1;
if (a_auth->memberid > b_auth->memberid) return 1;
return 0;
}
/* /*
* write_user_file: update the flat password file * write_auth_file: update the flat auth file
*/ */
static void static void
write_user_file(Relation urel) write_auth_file(Relation rel_auth, Relation rel_authmem, bool startup)
{ {
char *filename, char *filename,
*tempname; *tempname;
int bufsize; int bufsize;
BlockNumber totalblocks;
FILE *fp; FILE *fp;
mode_t oumask; mode_t oumask;
HeapScanDesc scan; HeapScanDesc scan;
HeapTuple tuple; 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 * 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. * be reading from it.
*/ */
filename = user_getflatfilename(); filename = auth_getflatfilename();
bufsize = strlen(filename) + 12; bufsize = strlen(filename) + 12;
tempname = (char *) palloc(bufsize); tempname = (char *) palloc(bufsize);
snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid); snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
@ -495,39 +383,41 @@ write_user_file(Relation urel)
tempname))); 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) 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; HeapTupleHeader tup = tuple->t_data;
char *tp; /* ptr to tuple data */ char *tp; /* ptr to tuple data */
long off; /* offset in tuple data */ long off; /* offset in tuple data */
bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */ bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */
Datum datum; Datum datum;
char *usename,
*passwd,
*valuntil;
AclId usesysid;
usename = NameStr(pwform->usename); auth_info[curr_role].roleid = HeapTupleGetOid(tuple);
usesysid = pwform->usesysid; 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 * We can't use heap_getattr() here because during startup we will
* not have any tupdesc for pg_shadow. Fortunately it's not too * not have any tupdesc for pg_authid. Fortunately it's not too
* hard to work around this. passwd is the first possibly-null * hard to work around this. rolpassword is the first possibly-null
* field so we can compute its offset directly. * field so we can compute its offset directly.
*/ */
tp = (char *) tup + tup->t_hoff; tp = (char *) tup + tup->t_hoff;
off = offsetof(FormData_pg_shadow, passwd); off = offsetof(FormData_pg_authid, rolpassword);
if (HeapTupleHasNulls(tuple) && 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 is null, emit as an empty string */
passwd = pstrdup(""); auth_info[curr_role].rolpassword = pstrdup("");
} }
else else
{ {
@ -539,60 +429,176 @@ write_user_file(Relation urel)
* if it is, ignore it, since we can't handle that in startup mode. * if it is, ignore it, since we can't handle that in startup mode.
*/ */
if (VARATT_IS_EXTERNAL(DatumGetPointer(datum))) if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)))
passwd = pstrdup(""); auth_info[curr_role].rolpassword = pstrdup("");
else else
passwd = DatumGetCString(DirectFunctionCall1(textout, datum)); auth_info[curr_role].rolpassword = DatumGetCString(DirectFunctionCall1(textout, datum));
/* assume passwd has attlen -1 */ /* assume passwd has attlen -1 */
off = att_addlength(off, -1, tp + off); off = att_addlength(off, -1, tp + off);
} }
if (HeapTupleHasNulls(tuple) && 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 */ /* rolvaliduntil is null, emit as an empty string */
valuntil = pstrdup(""); auth_info[curr_role].rolvaliduntil = pstrdup("");
} }
else else
{ {
/* assume valuntil has attalign 'i' */ /*
off = att_align(off, 'i'); * rolvaliduntil is timestamptz, which we assume is double
/* assume valuntil is pass-by-value, integer size */ * alignment and pass-by-reference.
datum = Int32GetDatum(*((int32 *) (tp + off))); */
valuntil = DatumGetCString(DirectFunctionCall1(abstimeout, datum)); 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. * Check for illegal characters in the user name and password.
*/ */
if (!name_okay(usename)) if (!name_okay(auth_info[curr_role].rolname))
{ {
ereport(LOG, 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; continue;
} }
if (!name_okay(passwd)) if (!name_okay(auth_info[curr_role].rolpassword))
{ {
ereport(LOG, 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; continue;
} }
/* curr_role++;
* The file format is: "usename" usesysid "passwd" "valuntil" total_roles++;
*/
fputs_quote(usename, fp);
fprintf(fp, " %u ", usesysid);
fputs_quote(passwd, fp);
fputs(" ", fp);
fputs_quote(valuntil, fp);
fputs("\n", fp);
pfree(passwd);
pfree(valuntil);
} }
heap_endscan(scan); heap_endscan(scan);
Assert(total_roles <= est_rows);
qsort(auth_info, total_roles, sizeof(auth_entry), oid_compar);
/*
* Read pg_auth_members into temporary data structure, too
*/
totalblocks = RelationGetNumberOfBlocks(rel_authmem);
totalblocks = totalblocks ? totalblocks : 1;
est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_auth_members)));
authmem_info = (authmem_entry*) palloc(est_rows*sizeof(authmem_entry));
scan = heap_beginscan(rel_authmem, SnapshotNow, 0, NULL);
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
{
Form_pg_auth_members memform = (Form_pg_auth_members) GETSTRUCT(tuple);
authmem_info[curr_mem].roleid = memform->roleid;
authmem_info[curr_mem].memberid = memform->member;
curr_mem++;
total_mem++;
}
heap_endscan(scan);
Assert(total_mem <= est_rows);
qsort(authmem_info, total_mem, sizeof(authmem_entry), mem_compar);
for (curr_role = 0; curr_role < total_roles; curr_role++)
{
int first_found, last_found, curr_mem;
List *roles_list_hunt = NIL;
List *roles_list = NIL;
ListCell *mem = NULL;
auth_entry *found_role = NULL, key_auth;
authmem_entry key;
authmem_entry *found_mem = NULL;
roles_list_hunt = lappend_oid(roles_list_hunt,
auth_info[curr_role].roleid);
while (roles_list_hunt)
{
key.memberid = linitial_oid(roles_list_hunt);
roles_list_hunt = list_delete_first(roles_list_hunt);
if (total_mem)
found_mem = bsearch(&key, authmem_info, total_mem,
sizeof(authmem_entry), mem_compar);
if (found_mem)
{
/*
* bsearch found a match for us; but if there were multiple
* matches it could have found any one of them.
*/
first_found = last_found = (found_mem - authmem_info);
while (first_found > 0 &&
mem_compar(&key, &authmem_info[first_found - 1]) == 0)
first_found--;
while (last_found + 1 < total_mem &&
mem_compar(&key, &authmem_info[last_found + 1]) == 0)
last_found++;
for (curr_mem = first_found; curr_mem <= last_found; curr_mem++)
{
Oid otherrole = authmem_info[curr_mem].roleid;
if (!list_member_oid(roles_list, otherrole))
{
roles_list = lappend_oid(roles_list,
otherrole);
roles_list_hunt = lappend_oid(roles_list_hunt,
otherrole);
}
}
}
}
foreach(mem, roles_list)
{
key_auth.roleid = lfirst_oid(mem);
found_role = bsearch(&key_auth, auth_info, total_roles, sizeof(auth_entry), oid_compar);
auth_info[curr_role].roles_names = lappend(auth_info[curr_role].roles_names,found_role->rolname);
}
}
qsort(auth_info, total_roles, sizeof(auth_entry), name_compar);
for (curr_role = 0; curr_role < total_roles; curr_role++)
{
ListCell *mem = NULL;
/*----------
* The file format is:
* "rolename" "password" "validuntil" "member" "member" ...
* where lines are expected to be in order by rolename
*----------
*/
fputs_quote(auth_info[curr_role].rolname, fp);
fputs(" ", fp);
fputs_quote(auth_info[curr_role].rolpassword, fp);
fputs(" ", fp);
fputs_quote(auth_info[curr_role].rolvaliduntil, fp);
foreach(mem, auth_info[curr_role].roles_names)
{
fputs(" ", fp);
fputs_quote(lfirst(mem), fp);
}
fputs("\n", fp);
pfree(auth_info[curr_role].rolname);
pfree(auth_info[curr_role].rolpassword);
pfree(auth_info[curr_role].rolvaliduntil);
}
if (FreeFile(fp)) if (FreeFile(fp))
ereport(ERROR, ereport(ERROR,
(errcode_for_file_access(), (errcode_for_file_access(),
@ -609,6 +615,8 @@ write_user_file(Relation urel)
errmsg("could not rename file \"%s\" to \"%s\": %m", errmsg("could not rename file \"%s\" to \"%s\": %m",
tempname, filename))); tempname, filename)));
pfree(auth_info);
pfree(authmem_info);
pfree(tempname); pfree(tempname);
pfree(filename); pfree(filename);
} }
@ -634,7 +642,7 @@ BuildFlatFiles(bool database_only)
{ {
ResourceOwner owner; ResourceOwner owner;
RelFileNode rnode; 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 * 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) if (!database_only)
{ {
/* hard-wired path to pg_group */ /* hard-wired path to pg_auth */
rnode.spcNode = GLOBALTABLESPACE_OID; rnode.spcNode = GLOBALTABLESPACE_OID;
rnode.dbNode = 0; 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.spcNode = GLOBALTABLESPACE_OID;
rnode.dbNode = 0; rnode.dbNode = 0;
rnode.relNode = ShadowRelationId; rnode.relNode = AuthMemRelationId;
rel_authmem = XLogOpenRelation(rnode);
rel = XLogOpenRelation(rnode);
write_user_file(rel);
} }
CurrentResourceOwner = NULL; CurrentResourceOwner = NULL;
@ -699,19 +702,17 @@ void
AtEOXact_UpdateFlatFiles(bool isCommit) AtEOXact_UpdateFlatFiles(bool isCommit)
{ {
Relation drel = NULL; Relation drel = NULL;
Relation grel = NULL; Relation arel = NULL;
Relation urel = NULL; Relation mrel = NULL;
if (database_file_update_subid == InvalidSubTransactionId && if (database_file_update_subid == InvalidSubTransactionId &&
group_file_update_subid == InvalidSubTransactionId && auth_file_update_subid == InvalidSubTransactionId)
user_file_update_subid == InvalidSubTransactionId)
return; /* nothing to do */ return; /* nothing to do */
if (!isCommit) if (!isCommit)
{ {
database_file_update_subid = InvalidSubTransactionId; database_file_update_subid = InvalidSubTransactionId;
group_file_update_subid = InvalidSubTransactionId; auth_file_update_subid = InvalidSubTransactionId;
user_file_update_subid = InvalidSubTransactionId;
return; return;
} }
@ -731,10 +732,10 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
*/ */
if (database_file_update_subid != InvalidSubTransactionId) if (database_file_update_subid != InvalidSubTransactionId)
drel = heap_open(DatabaseRelationId, ExclusiveLock); drel = heap_open(DatabaseRelationId, ExclusiveLock);
if (group_file_update_subid != InvalidSubTransactionId) if (auth_file_update_subid != InvalidSubTransactionId) {
grel = heap_open(GroupRelationId, ExclusiveLock); arel = heap_open(AuthIdRelationId, ExclusiveLock);
if (user_file_update_subid != InvalidSubTransactionId) mrel = heap_open(AuthMemRelationId, ExclusiveLock);
urel = heap_open(ShadowRelationId, ExclusiveLock); }
/* Okay to write the files */ /* Okay to write the files */
if (database_file_update_subid != InvalidSubTransactionId) if (database_file_update_subid != InvalidSubTransactionId)
@ -744,18 +745,12 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
heap_close(drel, NoLock); heap_close(drel, NoLock);
} }
if (group_file_update_subid != InvalidSubTransactionId) if (auth_file_update_subid != InvalidSubTransactionId)
{ {
group_file_update_subid = InvalidSubTransactionId; auth_file_update_subid = InvalidSubTransactionId;
write_group_file(grel); write_auth_file(arel, mrel, false);
heap_close(grel, NoLock); heap_close(arel, NoLock);
} heap_close(mrel, NoLock);
if (user_file_update_subid != InvalidSubTransactionId)
{
user_file_update_subid = InvalidSubTransactionId;
write_user_file(urel);
heap_close(urel, NoLock);
} }
/* /*
@ -785,15 +780,10 @@ AtPrepare_UpdateFlatFiles(void)
database_file_update_subid = InvalidSubTransactionId; database_file_update_subid = InvalidSubTransactionId;
info |= FF_BIT_DATABASE; info |= FF_BIT_DATABASE;
} }
if (group_file_update_subid != InvalidSubTransactionId) if (auth_file_update_subid != InvalidSubTransactionId)
{ {
group_file_update_subid = InvalidSubTransactionId; auth_file_update_subid = InvalidSubTransactionId;
info |= FF_BIT_GROUP; info |= FF_BIT_AUTH;
}
if (user_file_update_subid != InvalidSubTransactionId)
{
user_file_update_subid = InvalidSubTransactionId;
info |= FF_BIT_USER;
} }
if (info != 0) if (info != 0)
RegisterTwoPhaseRecord(TWOPHASE_RM_FLATFILES_ID, info, RegisterTwoPhaseRecord(TWOPHASE_RM_FLATFILES_ID, info,
@ -817,29 +807,23 @@ AtEOSubXact_UpdateFlatFiles(bool isCommit,
if (database_file_update_subid == mySubid) if (database_file_update_subid == mySubid)
database_file_update_subid = parentSubid; database_file_update_subid = parentSubid;
if (group_file_update_subid == mySubid) if (auth_file_update_subid == mySubid)
group_file_update_subid = parentSubid; auth_file_update_subid = parentSubid;
if (user_file_update_subid == mySubid)
user_file_update_subid = parentSubid;
} }
else else
{ {
if (database_file_update_subid == mySubid) if (database_file_update_subid == mySubid)
database_file_update_subid = InvalidSubTransactionId; database_file_update_subid = InvalidSubTransactionId;
if (group_file_update_subid == mySubid) if (auth_file_update_subid == mySubid)
group_file_update_subid = InvalidSubTransactionId; auth_file_update_subid = InvalidSubTransactionId;
if (user_file_update_subid == mySubid)
user_file_update_subid = InvalidSubTransactionId;
} }
} }
/* /*
* This trigger is fired whenever someone modifies pg_database, pg_shadow * This trigger is fired whenever someone modifies pg_database, pg_authid
* or pg_group via general-purpose INSERT/UPDATE/DELETE commands. * 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 * 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 * care which individual rows changed. It doesn't much matter whether
@ -862,11 +846,11 @@ flatfile_update_trigger(PG_FUNCTION_ARGS)
case DatabaseRelationId: case DatabaseRelationId:
database_file_update_needed(); database_file_update_needed();
break; break;
case GroupRelationId: case AuthIdRelationId:
group_file_update_needed(); auth_file_update_needed();
break; break;
case ShadowRelationId: case AuthMemRelationId:
user_file_update_needed(); auth_file_update_needed();
break; break;
default: default:
elog(ERROR, "flatfile_update_trigger was called for wrong table"); 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) if (info & FF_BIT_DATABASE)
database_file_update_needed(); database_file_update_needed();
if (info & FF_BIT_GROUP) if (info & FF_BIT_AUTH)
group_file_update_needed(); auth_file_update_needed();
if (info & FF_BIT_USER)
user_file_update_needed();
} }

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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> #include <utime.h>
#endif #endif
#include "catalog/pg_shadow.h" #include "catalog/pg_authid.h"
#include "libpq/libpq-be.h" #include "libpq/libpq-be.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "storage/fd.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 * The authenticated user is determined at connection start and never
* changes. The session user can be changed only by SET SESSION * 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. * restore the current user id if you need to change it.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
static AclId AuthenticatedUserId = 0; static Oid AuthenticatedUserId = InvalidOid;
static AclId SessionUserId = 0; static Oid SessionUserId = InvalidOid;
static AclId CurrentUserId = 0; static Oid CurrentUserId = InvalidOid;
static bool AuthenticatedUserIsSuperuser = false; static bool AuthenticatedUserIsSuperuser = false;
/* /*
* This function is relevant for all privilege checks. * This function is relevant for all privilege checks.
*/ */
AclId Oid
GetUserId(void) GetUserId(void)
{ {
AssertState(AclIdIsValid(CurrentUserId)); AssertState(OidIsValid(CurrentUserId));
return CurrentUserId; return CurrentUserId;
} }
void void
SetUserId(AclId newid) SetUserId(Oid roleid)
{ {
AssertArg(AclIdIsValid(newid)); AssertArg(OidIsValid(roleid));
CurrentUserId = newid; CurrentUserId = roleid;
} }
/* /*
* This value is only relevant for informational purposes. * This value is only relevant for informational purposes.
*/ */
AclId Oid
GetSessionUserId(void) GetSessionUserId(void)
{ {
AssertState(AclIdIsValid(SessionUserId)); AssertState(OidIsValid(SessionUserId));
return SessionUserId; return SessionUserId;
} }
void void
SetSessionUserId(AclId newid) SetSessionUserId(Oid roleid)
{ {
AssertArg(AclIdIsValid(newid)); AssertArg(OidIsValid(roleid));
SessionUserId = newid; SessionUserId = roleid;
/* Current user defaults to session user. */ /* Current user defaults to session user. */
if (!AclIdIsValid(CurrentUserId)) if (!OidIsValid(CurrentUserId))
CurrentUserId = newid; CurrentUserId = roleid;
} }
void void
InitializeSessionUserId(const char *username) InitializeSessionUserId(const char *rolename)
{ {
HeapTuple userTup; HeapTuple roleTup;
Datum datum; Datum datum;
bool isnull; bool isnull;
AclId usesysid; Oid roleid;
/* /*
* Don't do scans if we're bootstrapping, none of the system catalogs * Don't do scans if we're bootstrapping, none of the system catalogs
@ -325,23 +325,23 @@ InitializeSessionUserId(const char *username)
/* call only once */ /* call only once */
AssertState(!OidIsValid(AuthenticatedUserId)); AssertState(!OidIsValid(AuthenticatedUserId));
userTup = SearchSysCache(SHADOWNAME, roleTup = SearchSysCache(AUTHNAME,
PointerGetDatum(username), PointerGetDatum(rolename),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(userTup)) if (!HeapTupleIsValid(roleTup))
ereport(FATAL, ereport(FATAL,
(errcode(ERRCODE_UNDEFINED_OBJECT), (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; AuthenticatedUserId = roleid;
AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; 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 */ /* Record username and superuser status as GUC settings too */
SetConfigOption("session_authorization", username, SetConfigOption("session_authorization", rolename,
PGC_BACKEND, PGC_S_OVERRIDE); PGC_BACKEND, PGC_S_OVERRIDE);
SetConfigOption("is_superuser", SetConfigOption("is_superuser",
AuthenticatedUserIsSuperuser ? "on" : "off", AuthenticatedUserIsSuperuser ? "on" : "off",
@ -349,11 +349,11 @@ InitializeSessionUserId(const char *username)
/* /*
* Set up user-specific configuration variables. This is a good place * 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. * startup.
*/ */
datum = SysCacheGetAttr(SHADOWNAME, userTup, datum = SysCacheGetAttr(AUTHNAME, roleTup,
Anum_pg_shadow_useconfig, &isnull); Anum_pg_authid_rolconfig, &isnull);
if (!isnull) if (!isnull)
{ {
ArrayType *a = DatumGetArrayTypeP(datum); ArrayType *a = DatumGetArrayTypeP(datum);
@ -361,7 +361,7 @@ InitializeSessionUserId(const char *username)
ProcessGUCArray(a, PGC_S_USER); ProcessGUCArray(a, PGC_S_USER);
} }
ReleaseSysCache(userTup); ReleaseSysCache(roleTup);
} }
@ -374,10 +374,10 @@ InitializeSessionUserIdStandalone(void)
/* call only once */ /* call only once */
AssertState(!OidIsValid(AuthenticatedUserId)); AssertState(!OidIsValid(AuthenticatedUserId));
AuthenticatedUserId = BOOTSTRAP_USESYSID; AuthenticatedUserId = BOOTSTRAP_SUPERUSERID;
AuthenticatedUserIsSuperuser = true; AuthenticatedUserIsSuperuser = true;
SetSessionUserId(BOOTSTRAP_USESYSID); SetSessionUserId(BOOTSTRAP_SUPERUSERID);
} }
@ -390,19 +390,19 @@ InitializeSessionUserIdStandalone(void)
* to indicate whether the *current* session userid is a superuser. * to indicate whether the *current* session userid is a superuser.
*/ */
void void
SetSessionAuthorization(AclId userid, bool is_superuser) SetSessionAuthorization(Oid roleid, bool is_superuser)
{ {
/* Must have authenticated already, else can't make permission check */ /* Must have authenticated already, else can't make permission check */
AssertState(AclIdIsValid(AuthenticatedUserId)); AssertState(OidIsValid(AuthenticatedUserId));
if (userid != AuthenticatedUserId && if (roleid != AuthenticatedUserId &&
!AuthenticatedUserIsSuperuser) !AuthenticatedUserIsSuperuser)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied to set session authorization"))); errmsg("permission denied to set session authorization")));
SetSessionUserId(userid); SetSessionUserId(roleid);
SetUserId(userid); SetUserId(roleid);
SetConfigOption("is_superuser", SetConfigOption("is_superuser",
is_superuser ? "on" : "off", 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 * char *
GetUserNameFromId(AclId userid) GetUserNameFromId(Oid roleid)
{ {
HeapTuple tuple; HeapTuple tuple;
char *result; char *result;
tuple = SearchSysCache(SHADOWSYSID, tuple = SearchSysCache(AUTHOID,
ObjectIdGetDatum(userid), ObjectIdGetDatum(roleid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT), (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); ReleaseSysCache(tuple);
return result; return result;
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* Interlock-file support * Interlock-file support
* *

View file

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 <math.h>
#include <unistd.h> #include <unistd.h>
#include "catalog/catalog.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h" #include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_tablespace.h" #include "catalog/pg_tablespace.h"
#include "libpq/hba.h" #include "libpq/hba.h"
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
@ -37,6 +37,7 @@
#include "storage/procarray.h" #include "storage/procarray.h"
#include "storage/sinval.h" #include "storage/sinval.h"
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/acl.h"
#include "utils/flatfiles.h" #include "utils/flatfiles.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/guc.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 ReverifyMyDatabase(const char *name);
static void InitCommunication(void); static void InitCommunication(void);
static void ShutdownPostgres(int code, Datum arg); static void ShutdownPostgres(int code, Datum arg);
static bool ThereIsAtLeastOneUser(void); static bool ThereIsAtLeastOneRole(void);
/*** InitPostgres support ***/ /*** InitPostgres support ***/
@ -415,12 +416,12 @@ InitPostgres(const char *dbname, const char *username)
else if (!IsUnderPostmaster) else if (!IsUnderPostmaster)
{ {
InitializeSessionUserIdStandalone(); InitializeSessionUserIdStandalone();
if (!ThereIsAtLeastOneUser()) if (!ThereIsAtLeastOneRole())
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_UNDEFINED_OBJECT), (errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("no users are defined in this database system"), errmsg("no roles are defined in this database system"),
errhint("You should immediately run CREATE USER \"%s\" WITH SYSID %d CREATEUSER;.", errhint("You should immediately run CREATE USER \"%s\" CREATEUSER;.",
username, BOOTSTRAP_USESYSID))); username)));
} }
else else
{ {
@ -469,6 +470,9 @@ InitPostgres(const char *dbname, const char *username)
/* set default namespace search path */ /* set default namespace search path */
InitializeSearchPath(); InitializeSearchPath();
/* set up ACL framework (currently just sets RolMemCache callback) */
InitializeAcl();
/* initialize client encoding */ /* initialize client encoding */
InitializeClientEncoding(); 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 static bool
ThereIsAtLeastOneUser(void) ThereIsAtLeastOneRole(void)
{ {
Relation pg_shadow_rel; Relation pg_authid_rel;
HeapScanDesc scan; HeapScanDesc scan;
bool result; 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); result = (heap_getnext(scan, ForwardScanDirection) != NULL);
heap_endscan(scan); heap_endscan(scan);
heap_close(pg_shadow_rel, AccessExclusiveLock); heap_close(pg_authid_rel, AccessExclusiveLock);
return result; return result;
} }

View file

@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * 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). * The array parameter must be an array of TEXT (it must not be NULL).
*/ */
void void
@ -5154,7 +5154,7 @@ ProcessGUCArray(ArrayType *array, GucSource source)
/* /*
* We process all these options at SUSET level. We assume that * 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. * checked when it was inserted.
*/ */
SetConfigOption(name, value, PGC_SUSET, source); SetConfigOption(name, value, PGC_SUSET, source);

View file

@ -14,29 +14,29 @@
* *
* *
* IDENTIFICATION * 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 "postgres.h"
#include "catalog/pg_shadow.h" #include "catalog/pg_authid.h"
#include "utils/inval.h" #include "utils/inval.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "miscadmin.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 * be queried repeatedly. So we maintain a simple one-entry cache for
* the status of the last requested userid. The cache can be flushed * the status of the last requested roleid. The cache can be flushed
* at need by watching for cache update events on pg_shadow. * at need by watching for cache update events on pg_authid.
*/ */
static AclId last_userid = 0; /* 0 == cache not valid */ static Oid last_roleid = InvalidOid; /* InvalidOid == cache not valid */
static bool last_userid_is_super = false; static bool last_roleid_is_super = false;
static bool userid_callback_registered = 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 bool
superuser_arg(AclId userid) superuser_arg(Oid roleid)
{ {
bool result; bool result;
HeapTuple utup; HeapTuple rtup;
/* Quick out for cache hit */ /* Quick out for cache hit */
if (AclIdIsValid(last_userid) && last_userid == userid) if (OidIsValid(last_roleid) && last_roleid == roleid)
return last_userid_is_super; return last_roleid_is_super;
/* Special escape path in case you deleted all your users. */ /* Special escape path in case you deleted all your users. */
if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYSID) if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID)
return true; return true;
/* OK, look up the information in pg_shadow */ /* OK, look up the information in pg_authid */
utup = SearchSysCache(SHADOWSYSID, rtup = SearchSysCache(AUTHOID,
Int32GetDatum(userid), ObjectIdGetDatum(roleid),
0, 0, 0); 0, 0, 0);
if (HeapTupleIsValid(utup)) if (HeapTupleIsValid(rtup))
{ {
result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper;
ReleaseSysCache(utup); ReleaseSysCache(rtup);
} }
else else
{ {
/* Report "not superuser" for invalid userids */ /* Report "not superuser" for invalid roleids */
result = false; result = false;
} }
/* If first time through, set up callback for cache flushes */ /* If first time through, set up callback for cache flushes */
if (!userid_callback_registered) if (!roleid_callback_registered)
{ {
CacheRegisterSyscacheCallback(SHADOWSYSID, CacheRegisterSyscacheCallback(AUTHOID,
UseridCallback, RoleidCallback,
(Datum) 0); (Datum) 0);
userid_callback_registered = true; roleid_callback_registered = true;
} }
/* Cache the result for next time */ /* Cache the result for next time */
last_userid = userid; last_roleid = roleid;
last_userid_is_super = result; last_roleid_is_super = result;
return result; return result;
} }
@ -102,8 +102,8 @@ superuser_arg(AclId userid)
* Syscache inval callback function * Syscache inval callback function
*/ */
static void static void
UseridCallback(Datum arg, Oid relid) RoleidCallback(Datum arg, Oid relid)
{ {
/* Invalidate our local cache in case user's superuserness changed */ /* Invalidate our local cache in case role's superuserness changed */
last_userid = 0; last_roleid = InvalidOid;
} }

View file

@ -42,7 +42,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* Portions taken from FreeBSD. * 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 test_buffers(void);
static void setup_config(void); static void setup_config(void);
static void bootstrap_template1(char *short_version); 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 get_set_pwd(void);
static void unlimit_systables(void); static void unlimit_systables(void);
static void setup_depend(void); static void setup_depend(void);
@ -1316,11 +1316,11 @@ bootstrap_template1(char *short_version)
* set up the shadow password table * set up the shadow password table
*/ */
static void static void
setup_shadow(void) setup_auth(void)
{ {
PG_CMD_DECL; PG_CMD_DECL;
char **line; char **line;
static char *pg_shadow_setup[] = { static char *pg_authid_setup[] = {
/* /*
* Create triggers to ensure manual updates to shared catalogs * Create triggers to ensure manual updates to shared catalogs
* will be reflected into their "flat file" copies. * will be reflected into their "flat file" copies.
@ -1328,22 +1328,22 @@ setup_shadow(void)
"CREATE TRIGGER pg_sync_pg_database " "CREATE TRIGGER pg_sync_pg_database "
" AFTER INSERT OR UPDATE OR DELETE ON pg_database " " AFTER INSERT OR UPDATE OR DELETE ON pg_database "
" FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
"CREATE TRIGGER pg_sync_pg_group " "CREATE TRIGGER pg_sync_pg_authid "
" AFTER INSERT OR UPDATE OR DELETE ON pg_group " " AFTER INSERT OR UPDATE OR DELETE ON pg_authid "
" FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
"CREATE TRIGGER pg_sync_pg_pwd " "CREATE TRIGGER pg_sync_pg_auth_members "
" AFTER INSERT OR UPDATE OR DELETE ON pg_shadow " " AFTER INSERT OR UPDATE OR DELETE ON pg_auth_members "
" FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
/* /*
* needs to be done before alter user, because alter user checks * The authid table shouldn't be readable except through views,
* that pg_shadow is secure ... * to ensure passwords are not publicly visible.
*/ */
"REVOKE ALL on pg_shadow FROM public;\n", "REVOKE ALL on pg_authid FROM public;\n",
NULL NULL
}; };
fputs(_("initializing pg_shadow ... "), stdout); fputs(_("initializing pg_authid ... "), stdout);
fflush(stdout); fflush(stdout);
snprintf(cmd, sizeof(cmd), snprintf(cmd, sizeof(cmd),
@ -1353,7 +1353,7 @@ setup_shadow(void)
PG_CMD_OPEN; 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_PUTS(*line);
PG_CMD_CLOSE; PG_CMD_CLOSE;
@ -1461,13 +1461,12 @@ unlimit_systables(void)
char **line; char **line;
static char *systables_setup[] = { static char *systables_setup[] = {
"ALTER TABLE pg_attrdef CREATE TOAST TABLE;\n", "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_constraint CREATE TOAST TABLE;\n",
"ALTER TABLE pg_database CREATE TOAST TABLE;\n", "ALTER TABLE pg_database CREATE TOAST TABLE;\n",
"ALTER TABLE pg_description 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_proc CREATE TOAST TABLE;\n",
"ALTER TABLE pg_rewrite 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", "ALTER TABLE pg_statistic CREATE TOAST TABLE;\n",
NULL NULL
}; };
@ -2624,7 +2623,7 @@ main(int argc, char *argv[])
/* Create the stuff we don't need to use bootstrap mode for */ /* Create the stuff we don't need to use bootstrap mode for */
setup_shadow(); setup_auth();
if (pwprompt || pwfilename) if (pwprompt || pwfilename)
get_set_pwd(); get_set_pwd();

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid,
TimestampTz prepared_at, TimestampTz prepared_at,
AclId owner, Oid databaseid); Oid owner, Oid databaseid);
extern void StartPrepare(GlobalTransaction gxact); extern void StartPrepare(GlobalTransaction gxact);
extern void EndPrepare(GlobalTransaction gxact); extern void EndPrepare(GlobalTransaction gxact);

View file

@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId,
* CommandId, AclId * CommandId
*/ */
/* typedef Oid is in postgres_ext.h */ /* typedef Oid is in postgres_ext.h */
@ -394,8 +394,6 @@ typedef uint32 CommandId;
#define FirstCommandId ((CommandId) 0) #define FirstCommandId ((CommandId) 0)
typedef int32 AclId; /* user and group identifiers */
/* /*
* Array indexing support * Array indexing support
*/ */
@ -507,8 +505,6 @@ typedef NameData *Name;
#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid))
#define AclIdIsValid(aclId) ((bool) ((aclId) != 0))
#define RegProcedureIsValid(p) OidIsValid(p) #define RegProcedureIsValid(p) OidIsValid(p)

View file

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200506271 #define CATALOG_VERSION_NO 200506272
#endif #endif

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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)); DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index,2659, on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
#define AttributeRelidNumIndexId 2659 #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)); DECLARE_UNIQUE_INDEX(pg_cast_oid_index,2660, on pg_cast using btree(oid oid_ops));
#define CastOidIndexId 2660 #define CastOidIndexId 2660
DECLARE_UNIQUE_INDEX(pg_cast_source_target_index,2661, on pg_cast using btree(castsource oid_ops, casttarget oid_ops)); DECLARE_UNIQUE_INDEX(pg_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)); 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 #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 */ /* 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)); DECLARE_INDEX(pg_index_indrelid_index,2678, on pg_index using btree(indrelid oid_ops));
#define IndexIndrelidIndexId 2678 #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)); DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index,2693, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
#define RewriteRelRulenameIndexId 2693 #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)); DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index,2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
#define StatisticRelidAttnumIndexId 2696 #define StatisticRelidAttnumIndexId 2696

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 \ #define Schema_pg_type \
{ 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \ { 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, {"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, {"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, {"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 }, \ { 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 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 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 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 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)); 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 \ #define Schema_pg_proc \
{ 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \ { 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, {"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, {"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, {"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 }, \ { 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 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 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 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 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)); 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, {"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, {"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, {"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, {"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, {"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 }, \ { 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 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 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 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 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 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)); DATA(insert ( 1259 reltablespace 26 -1 4 7 0 -1 -1 t p i t f f t 0));

View file

@ -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 */

View file

@ -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 */

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -47,7 +47,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP
NameData relname; /* class name */ NameData relname; /* class name */
Oid relnamespace; /* OID of namespace containing this class */ Oid relnamespace; /* OID of namespace containing this class */
Oid reltype; /* OID of associated entry in pg_type */ 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 relam; /* index access method; 0 if not an index */
Oid relfilenode; /* identifier of physical storage file */ Oid relfilenode; /* identifier of physical storage file */
Oid reltablespace; /* identifier of table space for relation */ Oid reltablespace; /* identifier of table space for relation */

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -46,7 +46,7 @@ CATALOG(pg_conversion,2607)
{ {
NameData conname; NameData conname;
Oid connamespace; Oid connamespace;
int4 conowner; Oid conowner;
int4 conforencoding; int4 conforencoding;
int4 contoencoding; int4 contoencoding;
regproc conproc; regproc conproc;
@ -86,7 +86,7 @@ typedef FormData_pg_conversion *Form_pg_conversion;
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
extern Oid ConversionCreate(const char *conname, Oid connamespace, extern Oid ConversionCreate(const char *conname, Oid connamespace,
AclId conowner, Oid conowner,
int32 conforencoding, int32 contoencoding, int32 conforencoding, int32 contoencoding,
Oid conproc, bool def); Oid conproc, bool def);
extern void ConversionDrop(Oid conversionOid, DropBehavior behavior); extern void ConversionDrop(Oid conversionOid, DropBehavior behavior);

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -36,7 +36,7 @@
CATALOG(pg_database,1262) BKI_SHARED_RELATION CATALOG(pg_database,1262) BKI_SHARED_RELATION
{ {
NameData datname; /* database name */ NameData datname; /* database name */
int4 datdba; /* sysid of owner */ Oid datdba; /* owner of database */
int4 encoding; /* character encoding */ int4 encoding; /* character encoding */
bool datistemplate; /* allowed as CREATE DATABASE template? */ bool datistemplate; /* allowed as CREATE DATABASE template? */
bool datallowconn; /* new connections allowed? */ bool datallowconn; /* new connections allowed? */

View file

@ -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 */

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -41,7 +41,7 @@
CATALOG(pg_namespace,2615) CATALOG(pg_namespace,2615)
{ {
NameData nspname; NameData nspname;
int4 nspowner; Oid nspowner;
aclitem nspacl[1]; /* VARIABLE LENGTH FIELD */ aclitem nspacl[1]; /* VARIABLE LENGTH FIELD */
} FormData_pg_namespace; } FormData_pg_namespace;
@ -82,6 +82,6 @@ DESCR("Standard public schema");
/* /*
* prototypes for functions in pg_namespace.c * 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 */ #endif /* PG_NAMESPACE_H */

View file

@ -27,7 +27,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 */ Oid opcamid; /* index access method opclass is for */
NameData opcname; /* name of this opclass */ NameData opcname; /* name of this opclass */
Oid opcnamespace; /* namespace 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 */ Oid opcintype; /* type of data indexed by opclass */
bool opcdefault; /* T if opclass is default for opcintype */ bool opcdefault; /* T if opclass is default for opcintype */
Oid opckeytype; /* type of data in index, or InvalidOid */ Oid opckeytype; /* type of data in index, or InvalidOid */

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -42,7 +42,7 @@ CATALOG(pg_operator,2617)
{ {
NameData oprname; /* name of operator */ NameData oprname; /* name of operator */
Oid oprnamespace; /* OID of namespace containing this oper */ Oid oprnamespace; /* OID of namespace containing this oper */
int4 oprowner; /* oper owner */ Oid oprowner; /* operator owner */
char oprkind; /* 'l', 'r', or 'b' */ char oprkind; /* 'l', 'r', or 'b' */
bool oprcanhash; /* can be used in hash join? */ bool oprcanhash; /* can be used in hash join? */
Oid oprleft; /* left arg type, or 0 if 'l' oprkind */ Oid oprleft; /* left arg type, or 0 if 'l' oprkind */

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * 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 */ NameData proname; /* procedure name */
Oid pronamespace; /* OID of namespace containing this proc */ Oid pronamespace; /* OID of namespace containing this proc */
int4 proowner; /* proc owner */ Oid proowner; /* procedure owner */
Oid prolang; /* OID of pg_language entry */ Oid prolang; /* OID of pg_language entry */
bool proisagg; /* is it an aggregate? */ bool proisagg; /* is it an aggregate? */
bool prosecdef; /* security definer */ 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?"); 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_ )); 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"); 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"); 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_ )); DATA(insert OID = 1044 ( bpcharin PGNSP PGUID 12 f f t f i 3 1042 "2275 26 23" _null_ _null_ _null_ bpcharin - _null_ ));
DESCR("I/O"); DESCR("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"); 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_ )); 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"); 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_ )); 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("user name by UID (with fallback)"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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 usesysid, rel name"); 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 "23 26 25" _null_ _null_ _null_ has_table_privilege_id_id - _null_ )); 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 usesysid, rel oid"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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"); 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"); 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_ )); DATA(insert OID = 1940 ( pg_stat_get_backend_activity PGNSP PGUID 12 f f t f s 1 25 "23" _null_ _null_ _null_ pg_stat_get_backend_activity - _null_ ));
DESCR("Statistics: Current query of backend"); DESCR("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"); 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_ )); 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"); 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_ )); 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 usesysid, database name"); 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 "23 26 25" _null_ _null_ _null_ has_database_privilege_id_id - _null_ )); 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 usesysid, database oid"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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 usesysid, function name"); 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 "23 26 25" _null_ _null_ _null_ has_function_privilege_id_id - _null_ )); 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 usesysid, function oid"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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 usesysid, language name"); 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 "23 26 25" _null_ _null_ _null_ has_language_privilege_id_id - _null_ )); 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 usesysid, language oid"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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 usesysid, schema name"); 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 "23 26 25" _null_ _null_ _null_ has_schema_privilege_id_id - _null_ )); 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 usesysid, schema oid"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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"); 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_ )); 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 usesysid, tablespace name"); 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 "23 26 25" _null_ _null_ _null_ has_tablespace_privilege_id_id - _null_ )); 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 usesysid, tablespace oid"); 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_ )); 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"); 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_ )); 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_ ));

View file

@ -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 */

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -36,7 +36,7 @@
CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION
{ {
NameData spcname; /* tablespace name */ NameData spcname; /* tablespace name */
int4 spcowner; /* sysid of owner */ Oid spcowner; /* owner of tablespace */
text spclocation; /* physical location (VAR LENGTH) */ text spclocation; /* physical location (VAR LENGTH) */
aclitem spcacl[1]; /* access permissions (VAR LENGTH) */ aclitem spcacl[1]; /* access permissions (VAR LENGTH) */
} FormData_pg_tablespace; } FormData_pg_tablespace;

View file

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -44,7 +44,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP
{ {
NameData typname; /* type name */ NameData typname; /* type name */
Oid typnamespace; /* OID of namespace containing this type */ 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 * For a fixed-size type, typlen is the number of bytes we use to

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 CreateConversionCommand(CreateConversionStmt *parsetree);
extern void DropConversionCommand(List *conversion_name, DropBehavior behavior); extern void DropConversionCommand(List *conversion_name, DropBehavior behavior);
extern void RenameConversion(List *name, const char *newname); 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 */ #endif /* CONVERSIONCMDS_H */

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 dropdb(const char *dbname);
extern void RenameDatabase(const char *oldname, const char *newname); extern void RenameDatabase(const char *oldname, const char *newname);
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); 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 Oid get_database_oid(const char *dbname);
extern char *get_database_name(Oid dbid); extern char *get_database_name(Oid dbid);

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 SetFunctionReturnType(Oid funcOid, Oid newRetType);
extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType); extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType);
extern void RenameFunction(List *name, List *argtypes, const char *newname); 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 AlterFunction(AlterFunctionStmt *stmt);
extern void CreateCast(CreateCastStmt *stmt); extern void CreateCast(CreateCastStmt *stmt);
extern void DropCast(DropCastStmt *stmt); extern void DropCast(DropCastStmt *stmt);
@ -61,20 +61,20 @@ extern void DefineOperator(List *names, List *parameters);
extern void RemoveOperator(RemoveOperStmt *stmt); extern void RemoveOperator(RemoveOperStmt *stmt);
extern void RemoveOperatorById(Oid operOid); extern void RemoveOperatorById(Oid operOid);
extern void AlterOperatorOwner(List *name, TypeName *typeName1, extern void AlterOperatorOwner(List *name, TypeName *typeName1,
TypeName *typename2, AclId newOwnerSysId); TypeName *typename2, Oid newOwnerId);
/* commands/aggregatecmds.c */ /* commands/aggregatecmds.c */
extern void DefineAggregate(List *names, List *parameters); extern void DefineAggregate(List *names, List *parameters);
extern void RemoveAggregate(RemoveAggrStmt *stmt); extern void RemoveAggregate(RemoveAggrStmt *stmt);
extern void RenameAggregate(List *name, TypeName *basetype, const char *newname); 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 */ /* commands/opclasscmds.c */
extern void DefineOpClass(CreateOpClassStmt *stmt); extern void DefineOpClass(CreateOpClassStmt *stmt);
extern void RemoveOpClass(RemoveOpClassStmt *stmt); extern void RemoveOpClass(RemoveOpClassStmt *stmt);
extern void RemoveOpClassById(Oid opclassOid); extern void RemoveOpClassById(Oid opclassOid);
extern void RenameOpClass(List *name, const char *access_method, const char *newname); 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 */ /* support routines in commands/define.c */

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 RemoveSchemaById(Oid schemaOid);
extern void RenameSchema(const char *oldname, const char *newname); 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 */ #endif /* SCHEMACMDS_H */

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 CreateTableSpace(CreateTableSpaceStmt *stmt);
extern void DropTableSpace(DropTableSpaceStmt *stmt); extern void DropTableSpace(DropTableSpaceStmt *stmt);
extern void RenameTableSpace(const char *oldname, const char *newname); 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); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo);

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 List *GetDomainConstraints(Oid typeOid);
extern void AlterTypeOwner(List *names, AclId newOwnerSysId); extern void AlterTypeOwner(List *names, Oid newOwnerId);
#endif /* TYPECMDS_H */ #endif /* TYPECMDS_H */

View file

@ -1,10 +1,10 @@
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* user.h * user.h
* Commands for manipulating users and groups. * Commands for manipulating roles (formerly called users).
* *
* *
* $PostgreSQL: pgsql/src/include/commands/user.h,v 1.26 2005/02/20 02:22:05 tgl Exp $ * $PostgreSQL: pgsql/src/include/commands/user.h,v 1.27 2005/06/28 05:09:12 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -14,15 +14,11 @@
#include "nodes/parsenodes.h" #include "nodes/parsenodes.h"
extern void CreateUser(CreateUserStmt *stmt); extern void CreateRole(CreateRoleStmt *stmt);
extern void AlterUser(AlterUserStmt *stmt); extern void AlterRole(AlterRoleStmt *stmt);
extern void AlterUserSet(AlterUserSetStmt *stmt); extern void AlterRoleSet(AlterRoleSetStmt *stmt);
extern void DropUser(DropUserStmt *stmt); extern void DropRole(DropRoleStmt *stmt);
extern void RenameUser(const char *oldname, const char *newname); extern void GrantRole(GrantRoleStmt *stmt);
extern void RenameRole(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);
#endif /* USER_H */ #endif /* USER_H */

View file

@ -4,7 +4,7 @@
* Interface to hba.c * 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; 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_hba(void);
extern void load_ident(void); extern void load_ident(void);
extern void load_user(void); extern void load_role(void);
extern void load_group(void);
extern int hba_getauthmethod(hbaPort *port); extern int hba_getauthmethod(hbaPort *port);
extern int authident(hbaPort *port); extern int authident(hbaPort *port);
extern bool read_pg_database_line(FILE *fp, char *dbname, extern bool read_pg_database_line(FILE *fp, char *dbname,

View file

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* some of the information in this file should be moved to other files. * 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 */ /* now in utils/init/miscinit.c */
extern void SetDatabasePath(const char *path); extern void SetDatabasePath(const char *path);
extern char *GetUserNameFromId(AclId userid); extern char *GetUserNameFromId(Oid roleid);
extern AclId GetUserId(void); extern Oid GetUserId(void);
extern void SetUserId(AclId userid); extern void SetUserId(Oid roleid);
extern AclId GetSessionUserId(void); extern Oid GetSessionUserId(void);
extern void SetSessionUserId(AclId userid); extern void SetSessionUserId(Oid roleid);
extern void InitializeSessionUserId(const char *username); extern void InitializeSessionUserId(const char *rolename);
extern void InitializeSessionUserIdStandalone(void); 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 void SetDataDir(const char *dir);
extern char *make_absolute_path(const char *path); extern char *make_absolute_path(const char *path);
/* in utils/misc/superuser.c */ /* in utils/misc/superuser.c */
extern bool superuser(void); /* current user is superuser */ 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 */
/***************************************************************************** /*****************************************************************************

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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_AlterDomainStmt,
T_SetOperationStmt, T_SetOperationStmt,
T_GrantStmt, T_GrantStmt,
T_GrantRoleStmt,
T_ClosePortalStmt, T_ClosePortalStmt,
T_ClusterStmt, T_ClusterStmt,
T_CopyStmt, T_CopyStmt,
@ -261,19 +262,16 @@ typedef enum NodeTag
T_DropPropertyStmt, T_DropPropertyStmt,
T_CreatePLangStmt, T_CreatePLangStmt,
T_DropPLangStmt, T_DropPLangStmt,
T_CreateUserStmt, T_CreateRoleStmt,
T_AlterUserStmt, T_AlterRoleStmt,
T_DropUserStmt, T_DropRoleStmt,
T_LockStmt, T_LockStmt,
T_ConstraintsSetStmt, T_ConstraintsSetStmt,
T_CreateGroupStmt,
T_AlterGroupStmt,
T_DropGroupStmt,
T_ReindexStmt, T_ReindexStmt,
T_CheckPointStmt, T_CheckPointStmt,
T_CreateSchemaStmt, T_CreateSchemaStmt,
T_AlterDatabaseSetStmt, T_AlterDatabaseSetStmt,
T_AlterUserSetStmt, T_AlterRoleSetStmt,
T_CreateConversionStmt, T_CreateConversionStmt,
T_CreateCastStmt, T_CreateCastStmt,
T_DropCastStmt, T_DropCastStmt,

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 inh; /* inheritance requested? */
bool inFromCl; /* present in FROM clause? */ bool inFromCl; /* present in FROM clause? */
AclMode requiredPerms; /* bitmask of required access permissions */ 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; } RangeTblEntry;
/* /*
@ -749,12 +749,12 @@ typedef enum ObjectType
OBJECT_DATABASE, OBJECT_DATABASE,
OBJECT_DOMAIN, OBJECT_DOMAIN,
OBJECT_FUNCTION, OBJECT_FUNCTION,
OBJECT_GROUP,
OBJECT_INDEX, OBJECT_INDEX,
OBJECT_LANGUAGE, OBJECT_LANGUAGE,
OBJECT_LARGEOBJECT, OBJECT_LARGEOBJECT,
OBJECT_OPCLASS, OBJECT_OPCLASS,
OBJECT_OPERATOR, OBJECT_OPERATOR,
OBJECT_ROLE,
OBJECT_RULE, OBJECT_RULE,
OBJECT_SCHEMA, OBJECT_SCHEMA,
OBJECT_SEQUENCE, OBJECT_SEQUENCE,
@ -762,7 +762,6 @@ typedef enum ObjectType
OBJECT_TABLESPACE, OBJECT_TABLESPACE,
OBJECT_TRIGGER, OBJECT_TRIGGER,
OBJECT_TYPE, OBJECT_TYPE,
OBJECT_USER,
OBJECT_VIEW OBJECT_VIEW
} ObjectType; } ObjectType;
@ -896,8 +895,7 @@ typedef struct GrantStmt
typedef struct PrivGrantee typedef struct PrivGrantee
{ {
NodeTag type; NodeTag type;
char *username; /* if both are NULL then PUBLIC */ char *rolname; /* if NULL then PUBLIC */
char *groupname;
} PrivGrantee; } PrivGrantee;
/* /*
@ -920,6 +918,23 @@ typedef struct PrivTarget
List *objs; List *objs;
} 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 * Copy Statement
* ---------------------- * ----------------------
@ -1123,61 +1138,37 @@ typedef struct DropPLangStmt
} DropPLangStmt; } DropPLangStmt;
/* ---------------------- /* ----------------------
* Create/Alter/Drop User Statements * Create/Alter/Drop Role Statements
* ---------------------- * ----------------------
*/ */
typedef struct CreateUserStmt typedef struct CreateRoleStmt
{ {
NodeTag type; NodeTag type;
char *user; /* PostgreSQL user login name */ char *role; /* role name */
List *options; /* List of DefElem nodes */ List *options; /* List of DefElem nodes */
} CreateUserStmt; } CreateRoleStmt;
typedef struct AlterUserStmt typedef struct AlterRoleStmt
{ {
NodeTag type; NodeTag type;
char *user; /* PostgreSQL user login name */ char *role; /* role name */
List *options; /* List of DefElem nodes */ List *options; /* List of DefElem nodes */
} AlterUserStmt; int action; /* +1 = add members, -1 = drop members */
} AlterRoleStmt;
typedef struct AlterUserSetStmt typedef struct AlterRoleSetStmt
{ {
NodeTag type; NodeTag type;
char *user; char *role; /* role name */
char *variable; char *variable; /* GUC variable name */
List *value; List *value; /* value for variable, or NIL for Reset */
} AlterUserSetStmt; } AlterRoleSetStmt;
typedef struct DropUserStmt typedef struct DropRoleStmt
{ {
NodeTag type; NodeTag type;
List *users; /* List of users to remove */ List *roles; /* List of roles to remove */
} DropUserStmt; } DropRoleStmt;
/* ----------------------
* 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;
/* ---------------------- /* ----------------------
* {Create|Alter} SEQUENCE Statement * {Create|Alter} SEQUENCE Statement

View file

@ -5,7 +5,7 @@
* *
* Copyright (c) 2001-2005, PostgreSQL Global Development Group * 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 #ifndef PGSTAT_H
@ -101,7 +101,7 @@ typedef struct PgStat_MsgBestart
{ {
PgStat_MsgHdr m_hdr; PgStat_MsgHdr m_hdr;
Oid m_databaseid; Oid m_databaseid;
AclId m_userid; Oid m_userid;
SockAddr m_clientaddr; SockAddr m_clientaddr;
} PgStat_MsgBestart; } PgStat_MsgBestart;

View file

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* An ACL array is simply an array of AclItems, representing the union * 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 * typedef AclMode is declared in parsenodes.h, also the individual privilege
* bit meanings are defined there * bit meanings are defined there
*/ */
#define ACL_ID_WORLD 0 /* placeholder for id in a WORLD acl item */ #define ACL_ID_PUBLIC 0 /* placeholder for id in a PUBLIC 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 */
/* /*
* AclItem * 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 * Note: must be same size on all platforms, because the size is hardcoded
* in the pg_type.h entry for aclitem. * in the pg_type.h entry for aclitem.
*/ */
typedef struct AclItem typedef struct AclItem
{ {
AclId ai_grantee; /* ID that this item grants privs to */ Oid ai_grantee; /* ID that this item grants privs to */
AclId ai_grantor; /* grantor of privs (always a user id) */ Oid ai_grantor; /* grantor of privs */
AclMode ai_privs; /* AclIdType plus privilege bits */ AclMode ai_privs; /* privilege bits */
} AclItem; } AclItem;
/* /*
* The AclIdType is stored in the top two bits of the ai_privs field * The upper 16 bits of the ai_privs field of an AclItem are the grant option
* of an AclItem. The middle 15 bits are the grant option markers, * bits, and the lower 16 bits are the actual privileges. We use "rights"
* and the lower 15 bits are the actual privileges. We use "rights"
* to mean the combined grant option and privilege bits fields. * to mean the combined grant option and privilege bits fields.
*/ */
#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0x7FFF) #define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0xFFFF)
#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 15) & 0x7FFF) #define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 16) & 0xFFFF)
#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs & 0x3FFFFFFF) #define ACLITEM_GET_RIGHTS(item) ((item).ai_privs)
#define ACLITEM_GET_IDTYPE(item) ((item).ai_privs >> 30)
#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0x7FFF) << 15) #define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16)
#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 15) & 0x7FFF) #define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 16) & 0xFFFF)
#define ACLITEM_SET_PRIVS(item,privs) \ #define ACLITEM_SET_PRIVS(item,privs) \
((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x7FFF)) | \ ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \
((AclMode) (privs) & 0x7FFF)) ((AclMode) (privs) & 0xFFFF))
#define ACLITEM_SET_GOPTIONS(item,goptions) \ #define ACLITEM_SET_GOPTIONS(item,goptions) \
((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0x7FFF) << 15)) | \ ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFF) << 16)) | \
(((AclMode) (goptions) & 0x7FFF) << 15)) (((AclMode) (goptions) & 0xFFFF) << 16))
#define ACLITEM_SET_RIGHTS(item,rights) \ #define ACLITEM_SET_RIGHTS(item,rights) \
((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x3FFFFFFF)) | \ ((item).ai_privs = (AclMode) (rights))
((AclMode) (rights) & 0x3FFFFFFF))
#define ACLITEM_SET_IDTYPE(item,idtype) \
((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0x03) << 30)) | \
(((AclMode) (idtype) & 0x03) << 30))
#define ACLITEM_SET_PRIVS_IDTYPE(item,privs,goption,idtype) \ #define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \
((item).ai_privs = ((AclMode) (privs) & 0x7FFF) | \ ((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \
(((AclMode) (goption) & 0x7FFF) << 15) | \ (((AclMode) (goptions) & 0xFFFF) << 16))
((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 * 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, * to have one dimension. We also ignore the lower bound when reading,
* and set it to one when writing. * and set it to one when writing.
* *
* CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all
* other array types). Therefore, be careful to detoast them with the * other array types). Therefore, be careful to detoast them with the
* macros provided, unless you know for certain that a particular array * macros provided, unless you know for certain that a particular array
* can't have been toasted. Presently, we do not provide toast tables for * can't have been toasted.
* pg_class or pg_group, so the entries in those tables won't have been
* stored externally --- but they could have been compressed!
*/ */
@ -121,13 +101,13 @@ typedef ArrayType Acl;
#define ACL_SIZE(ACL) ARR_SIZE(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; typedef ArrayType IdList;
#define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0]) #define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0])
#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL)) #define IDLIST_DAT(IDL) ((Oid *) ARR_DATA_PTR(IDL))
#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId))) #define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(Oid)))
#define IDLIST_SIZE(IDL) ARR_SIZE(IDL) #define IDLIST_SIZE(IDL) ARR_SIZE(IDL)
/* /*
@ -221,14 +201,18 @@ typedef enum AclObjectKind
/* /*
* routines used internally * 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, extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip,
int modechg, AclId ownerid, DropBehavior behavior); int modechg, Oid ownerId, DropBehavior behavior);
extern Acl *aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid); 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); AclMode mask, AclMaskHow how);
extern bool is_member_of_role(Oid member, Oid role);
extern void InitializeAcl(void);
/* /*
* SQL functions (from acl.c) * SQL functions (from acl.c)
*/ */
@ -245,40 +229,39 @@ extern Datum hash_aclitem(PG_FUNCTION_ARGS);
* prototypes for functions in aclchk.c * prototypes for functions in aclchk.c
*/ */
extern void ExecuteGrantStmt(GrantStmt *stmt); 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); 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); 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); 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); 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); 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); AclMode mask, AclMaskHow how);
extern AclResult pg_class_aclcheck(Oid table_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, AclId userid, AclMode mode); extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode);
extern AclResult pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode); extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode);
extern AclResult pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode); extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode);
extern AclResult pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode); extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode);
extern AclResult pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode); extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode);
extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind,
const char *objectname); const char *objectname);
/* ownercheck routines just return true (owner) or false (not) */ /* ownercheck routines just return true (owner) or false (not) */
extern bool pg_class_ownercheck(Oid class_oid, AclId userid); extern bool pg_class_ownercheck(Oid class_oid, Oid roleid);
extern bool pg_type_ownercheck(Oid type_oid, AclId userid); extern bool pg_type_ownercheck(Oid type_oid, Oid roleid);
extern bool pg_oper_ownercheck(Oid oper_oid, AclId userid); extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid);
extern bool pg_proc_ownercheck(Oid proc_oid, AclId userid); extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
extern bool pg_namespace_ownercheck(Oid nsp_oid, AclId userid); extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
extern bool pg_tablespace_ownercheck(Oid spc_oid, AclId userid); extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
extern bool pg_opclass_ownercheck(Oid opc_oid, AclId userid); extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
extern bool pg_database_ownercheck(Oid db_oid, AclId userid); extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
extern bool pg_conversion_ownercheck(Oid conv_oid, AclId userid); extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
#endif /* ACL_H */ #endif /* ACL_H */

View file

@ -4,7 +4,7 @@
* Routines for maintaining "flat file" images of the shared catalogs. * 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" #include "fmgr.h"
extern void database_file_update_needed(void); extern void database_file_update_needed(void);
extern void group_file_update_needed(void); extern void auth_file_update_needed(void);
extern void user_file_update_needed(void);
extern char *database_getflatfilename(void); extern char *database_getflatfilename(void);
extern char *group_getflatfilename(void); extern char *auth_getflatfilename(void);
extern char *user_getflatfilename(void);
extern void BuildFlatFiles(bool database_only); extern void BuildFlatFiles(bool database_only);

View file

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, Datum *values, int nvalues,
float4 *numbers, int nnumbers); float4 *numbers, int nnumbers);
extern char *get_namespace_name(Oid nspid); extern char *get_namespace_name(Oid nspid);
extern AclId get_usesysid(const char *username); extern Oid get_roleid(const char *rolname);
extern AclId get_grosysid(char *groname); extern Oid get_roleid_checked(const char *rolname);
#define is_array_type(typid) (get_element_type(typid) != InvalidOid) #define is_array_type(typid) (get_element_type(typid) != InvalidOid)

View file

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 AMPROCNUM 5
#define ATTNAME 6 #define ATTNAME 6
#define ATTNUM 7 #define ATTNUM 7
#define CASTSOURCETARGET 8 #define AUTHMEMMEMROLE 8
#define CLAAMNAMENSP 9 #define AUTHMEMROLEMEM 9
#define CLAOID 10 #define AUTHNAME 10
#define CONDEFAULT 11 #define AUTHOID 11
#define CONNAMENSP 12 #define CASTSOURCETARGET 12
#define CONOID 13 #define CLAAMNAMENSP 13
#define GRONAME 14 #define CLAOID 14
#define GROSYSID 15 #define CONDEFAULT 15
#define INDEXRELID 16 #define CONNAMENSP 16
#define INHRELID 17 #define CONOID 17
#define LANGNAME 18 #define INDEXRELID 18
#define LANGOID 19 #define INHRELID 19
#define NAMESPACENAME 20 #define LANGNAME 20
#define NAMESPACEOID 21 #define LANGOID 21
#define OPERNAMENSP 22 #define NAMESPACENAME 22
#define OPEROID 23 #define NAMESPACEOID 23
#define PROCNAMEARGSNSP 24 #define OPERNAMENSP 24
#define PROCOID 25 #define OPEROID 25
#define RELNAMENSP 26 #define PROCNAMEARGSNSP 26
#define RELOID 27 #define PROCOID 27
#define RULERELNAME 28 #define RELNAMENSP 28
#define SHADOWNAME 29 #define RELOID 29
#define SHADOWSYSID 30 #define RULERELNAME 30
#define STATRELATT 31 #define STATRELATT 31
#define TYPENAMENSP 32 #define TYPENAMENSP 32
#define TYPEOID 33 #define TYPEOID 33

View file

@ -6,11 +6,12 @@ CREATE USER regressuser2;
CREATE USER regressuser3; CREATE USER regressuser3;
CREATE USER regressuser4; CREATE USER regressuser4;
CREATE USER regressuser4; -- duplicate CREATE USER regressuser4; -- duplicate
ERROR: user "regressuser4" already exists ERROR: role "regressuser4" already exists
CREATE GROUP regressgroup1; CREATE GROUP regressgroup1;
CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2;
ALTER GROUP regressgroup1 ADD USER regressuser4; ALTER GROUP regressgroup1 ADD USER regressuser4;
ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate 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 DROP USER regressuser2;
ALTER GROUP regressgroup2 ADD USER regressuser4; ALTER GROUP regressgroup2 ADD USER regressuser4;
-- test owner privileges -- test owner privileges
@ -275,7 +276,7 @@ DROP FUNCTION testfunc1(int); -- ok
GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
-- has_table_privilege function -- has_table_privilege function
-- bad-input checks -- bad-input checks
select has_table_privilege(NULL,'pg_shadow','select'); select has_table_privilege(NULL,'pg_authid','select');
has_table_privilege has_table_privilege
--------------------- ---------------------
@ -283,36 +284,36 @@ select has_table_privilege(NULL,'pg_shadow','select');
select has_table_privilege('pg_shad','select'); select has_table_privilege('pg_shad','select');
ERROR: relation "pg_shad" does not exist ERROR: relation "pg_shad" does not exist
select has_table_privilege('nosuchuser','pg_shadow','select'); select has_table_privilege('nosuchuser','pg_authid','select');
ERROR: user "nosuchuser" does not exist ERROR: role "nosuchuser" does not exist
select has_table_privilege('pg_shadow','sel'); select has_table_privilege('pg_authid','sel');
ERROR: unrecognized privilege type: "sel" ERROR: unrecognized privilege type: "sel"
select has_table_privilege(-999999,'pg_shadow','update'); select has_table_privilege(-999999,'pg_authid','update');
ERROR: user with ID 4293967297 does not exist ERROR: role with OID 4293967297 does not exist
select has_table_privilege(1,'rule'); select has_table_privilege(1,'rule');
ERROR: relation with OID 1 does not exist ERROR: relation with OID 1 does not exist
-- superuser -- superuser
\c - \c -
select has_table_privilege(current_user,'pg_shadow','select'); select has_table_privilege(current_user,'pg_authid','select');
has_table_privilege has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege(current_user,'pg_shadow','insert'); select has_table_privilege(current_user,'pg_authid','insert');
has_table_privilege has_table_privilege
--------------------- ---------------------
t t
(1 row) (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; from (select usesysid from pg_user where usename = current_user) as t2;
has_table_privilege has_table_privilege
--------------------- ---------------------
t t
(1 row) (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; from (select usesysid from pg_user where usename = current_user) as t2;
has_table_privilege has_table_privilege
--------------------- ---------------------
@ -320,21 +321,21 @@ from (select usesysid from pg_user where usename = current_user) as t2;
(1 row) (1 row)
select has_table_privilege(current_user,t1.oid,'rule') 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 has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege(current_user,t1.oid,'references') 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 has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege(t2.usesysid,t1.oid,'select') 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 usesysid from pg_user where usename = current_user) as t2;
has_table_privilege has_table_privilege
--------------------- ---------------------
@ -342,34 +343,34 @@ from (select oid from pg_class where relname = 'pg_shadow') as t1,
(1 row) (1 row)
select has_table_privilege(t2.usesysid,t1.oid,'insert') 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 usesysid from pg_user where usename = current_user) as t2;
has_table_privilege has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege('pg_shadow','update'); select has_table_privilege('pg_authid','update');
has_table_privilege has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege('pg_shadow','delete'); select has_table_privilege('pg_authid','delete');
has_table_privilege has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege(t1.oid,'select') 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 has_table_privilege
--------------------- ---------------------
t t
(1 row) (1 row)
select has_table_privilege(t1.oid,'trigger') 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 has_table_privilege
--------------------- ---------------------
t t
@ -546,8 +547,7 @@ SET SESSION AUTHORIZATION regressuser1;
CREATE TABLE atest4 (a int); CREATE TABLE atest4 (a int);
GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION; GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regressuser2; 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;
ERROR: grant options can only be granted to individual users
SET SESSION AUTHORIZATION regressuser2; SET SESSION AUTHORIZATION regressuser2;
GRANT SELECT ON atest4 TO regressuser3; GRANT SELECT ON atest4 TO regressuser3;
GRANT UPDATE ON atest4 TO regressuser3; -- fail GRANT UPDATE ON atest4 TO regressuser3; -- fail

View file

@ -1277,12 +1277,15 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem
viewname | definition 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); 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_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_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_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_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_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_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; 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)))); 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); 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; 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 SELECT tablename, rulename, definition FROM pg_rules
ORDER BY tablename, rulename; ORDER BY tablename, rulename;

View file

@ -37,6 +37,8 @@ SELECT relname, relhasindex
pg_amproc | t pg_amproc | t
pg_attrdef | t pg_attrdef | t
pg_attribute | t pg_attribute | t
pg_auth_members | t
pg_authid | t
pg_cast | t pg_cast | t
pg_class | t pg_class | t
pg_constraint | t pg_constraint | t
@ -44,7 +46,6 @@ SELECT relname, relhasindex
pg_database | t pg_database | t
pg_depend | t pg_depend | t
pg_description | t pg_description | t
pg_group | t
pg_index | t pg_index | t
pg_inherits | t pg_inherits | t
pg_language | t pg_language | t
@ -54,7 +55,6 @@ SELECT relname, relhasindex
pg_operator | t pg_operator | t
pg_proc | t pg_proc | t
pg_rewrite | t pg_rewrite | t
pg_shadow | t
pg_statistic | t pg_statistic | t
pg_tablespace | t pg_tablespace | t
pg_trigger | t pg_trigger | t

View file

@ -192,43 +192,43 @@ GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC;
-- has_table_privilege function -- has_table_privilege function
-- bad-input checks -- 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('pg_shad','select');
select has_table_privilege('nosuchuser','pg_shadow','select'); select has_table_privilege('nosuchuser','pg_authid','select');
select has_table_privilege('pg_shadow','sel'); select has_table_privilege('pg_authid','sel');
select has_table_privilege(-999999,'pg_shadow','update'); select has_table_privilege(-999999,'pg_authid','update');
select has_table_privilege(1,'rule'); select has_table_privilege(1,'rule');
-- superuser -- superuser
\c - \c -
select has_table_privilege(current_user,'pg_shadow','select'); select has_table_privilege(current_user,'pg_authid','select');
select has_table_privilege(current_user,'pg_shadow','insert'); 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; 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; from (select usesysid from pg_user where usename = current_user) as t2;
select has_table_privilege(current_user,t1.oid,'rule') 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') 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') 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 usesysid from pg_user where usename = current_user) as t2;
select has_table_privilege(t2.usesysid,t1.oid,'insert') 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 usesysid from pg_user where usename = current_user) as t2;
select has_table_privilege('pg_shadow','update'); select has_table_privilege('pg_authid','update');
select has_table_privilege('pg_shadow','delete'); select has_table_privilege('pg_authid','delete');
select has_table_privilege(t1.oid,'select') 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') 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 -- non-superuser
SET SESSION AUTHORIZATION regressuser3; SET SESSION AUTHORIZATION regressuser3;
@ -298,7 +298,7 @@ CREATE TABLE atest4 (a int);
GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION; GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION;
GRANT UPDATE ON atest4 TO regressuser2; 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; SET SESSION AUTHORIZATION regressuser2;