diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 2b1318b05e4f87b6832063ff1ae491e3ae200696..7358dfb5122e3b44d6c01635bb10df404cb1d792 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -1,6 +1,6 @@ <!-- Documentation of the system catalogs, directed toward PostgreSQL developers - $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.105 2005/06/18 19:33:41 tgl Exp $ + $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.106 2005/06/28 05:08:50 tgl Exp $ --> <chapter id="catalogs"> @@ -78,6 +78,16 @@ <entry>table columns (<quote>attributes</quote>)</entry> </row> + <row> + <entry><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link></entry> + <entry>authorization identifiers (roles)</entry> + </row> + + <row> + <entry><link linkend="catalog-pg-auth-members"><structname>pg_auth_members</structname></link></entry> + <entry>authorization identifier membership relationships</entry> + </row> + <row> <entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry> <entry>casts (data type conversions)</entry> @@ -113,11 +123,6 @@ <entry>descriptions or comments on database objects</entry> </row> - <row> - <entry><link linkend="catalog-pg-group"><structname>pg_group</structname></link></entry> - <entry>groups of database users</entry> - </row> - <row> <entry><link linkend="catalog-pg-index"><structname>pg_index</structname></link></entry> <entry>additional index information</entry> @@ -168,11 +173,6 @@ <entry>query rewrite rules</entry> </row> - <row> - <entry><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link></entry> - <entry>database users</entry> - </row> - <row> <entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry> <entry>planner statistics</entry> @@ -902,6 +902,201 @@ </sect1> + <sect1 id="catalog-pg-authid"> + <title><structname>pg_authid</structname></title> + + <indexterm zone="catalog-pg-authid"> + <primary>pg_authid</primary> + </indexterm> + + <para> + The catalog <structname>pg_authid</structname> contains information about + database authorization identifiers (roles). A role subsumes the concepts + of <quote>users</> and <quote>groups</>. A user is essentially just a + role with the <structfield>rolcanlogin</> flag set. Any role (with or + without <structfield>rolcanlogin</>) may have other roles as members; see + <link linkend="catalog-pg-auth-members"><structname>pg_auth_members</structname></link>. + </para> + + <para> + Since this catalog contains passwords, it must not be publicly readable. + <link linkend="view-pg-roles"><structname>pg_roles</structname></link> + is a publicly readable view on + <structname>pg_authid</structname> that blanks out the password field. + </para> + + <para> + <xref linkend="user-manag"> contains detailed information about user and + privilege management. + </para> + + <para> + Because user identities are cluster-wide, + <structname>pg_authid</structname> + is shared across all databases of a cluster: there is only one + copy of <structname>pg_authid</structname> per cluster, not + one per database. + </para> + + <table> + <title><structname>pg_authid</> Columns</title> + + <tgroup cols=4> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>References</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>rolname</structfield></entry> + <entry><type>name</type></entry> + <entry></entry> + <entry>Role name</entry> + </row> + + <row> + <entry><structfield>rolsuper</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>Role has superuser privileges</entry> + </row> + + <row> + <entry><structfield>rolcreaterole</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>Role may create more roles</entry> + </row> + + <row> + <entry><structfield>rolcreatedb</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>Role may create databases</entry> + </row> + + <row> + <entry><structfield>rolcatupdate</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry> + Role may update system catalogs directly. (Even a superuser may not do + this unless this column is true.) + </entry> + </row> + + <row> + <entry><structfield>rolcanlogin</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry> + Role may log in, that is, this role can be given as the initial + session authorization identifier. + </entry> + </row> + + <row> + <entry><structfield>rolpassword</structfield></entry> + <entry><type>text</type></entry> + <entry></entry> + <entry>Password (possibly encrypted); NULL if none</entry> + </row> + + <row> + <entry><structfield>rolvaliduntil</structfield></entry> + <entry><type>timestamptz</type></entry> + <entry></entry> + <entry>Password expiry time (only used for password authentication); + NULL if no expiration</entry> + </row> + + <row> + <entry><structfield>rolconfig</structfield></entry> + <entry><type>text[]</type></entry> + <entry></entry> + <entry>Session defaults for run-time configuration variables</entry> + </row> + </tbody> + </tgroup> + </table> + + </sect1> + + + <sect1 id="catalog-pg-auth-members"> + <title><structname>pg_auth_members</structname></title> + + <indexterm zone="catalog-pg-auth-members"> + <primary>pg_auth_members</primary> + </indexterm> + + <para> + The catalog <structname>pg_auth_members</structname> shows the membership + relations between roles. Any non-circular set of relationships is allowed. + </para> + + <para> + Because user identities are cluster-wide, + <structname>pg_auth_members</structname> + is shared across all databases of a cluster: there is only one + copy of <structname>pg_auth_members</structname> per cluster, not + one per database. + </para> + + <table> + <title><structname>pg_auth_members</> Columns</title> + + <tgroup cols=4> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>References</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>roleid</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>ID of a role that has a member</entry> + </row> + + <row> + <entry><structfield>member</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>ID of a role that is a member of <structfield>roleid</></entry> + </row> + + <row> + <entry><structfield>grantor</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>ID of the role that granted this membership</entry> + </row> + + <row> + <entry><structfield>admin_option</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>True if <structfield>member</> may grant membership in + <structfield>roleid</> to others</entry> + </row> + </tbody> + </tgroup> + </table> + + </sect1> + + <sect1 id="catalog-pg-cast"> <title><structname>pg_cast</structname></title> @@ -1065,8 +1260,8 @@ <row> <entry><structfield>relowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the relation</entry> </row> @@ -1492,8 +1687,8 @@ <row> <entry><structfield>conowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the conversion</entry> </row> @@ -1576,8 +1771,8 @@ <row> <entry><structfield>datdba</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the database, usually the user who created it</entry> </row> @@ -1917,69 +2112,6 @@ </sect1> - <sect1 id="catalog-pg-group"> - <title><structname>pg_group</structname></title> - - <indexterm zone="catalog-pg-group"> - <primary>pg_group</primary> - </indexterm> - - <para> - The catalog <structname>pg_group</structname> defines groups and stores what users belong to what - groups. Groups are created with the <command>CREATE - GROUP</command> command. Consult <xref linkend="user-manag"> for information - about user privilege management. - </para> - - <para> - Because user and group identities are cluster-wide, - <structname>pg_group</structname> - is shared across all databases of a cluster: there is only one - copy of <structname>pg_group</structname> per cluster, not - one per database. - </para> - - <table> - <title><structname>pg_group</> Columns</title> - - <tgroup cols=4> - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>References</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - <row> - <entry><structfield>groname</structfield></entry> - <entry><type>name</type></entry> - <entry></entry> - <entry>Name of the group</entry> - </row> - - <row> - <entry><structfield>grosysid</structfield></entry> - <entry><type>int4</type></entry> - <entry></entry> - <entry>An arbitrary number to identify this group</entry> - </row> - - <row> - <entry><structfield>grolist</structfield></entry> - <entry><type>int4[]</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> - <entry>An array containing the IDs of the users in this group</entry> - </row> - </tbody> - </tgroup> - </table> - - </sect1> - - <sect1 id="catalog-pg-index"> <title><structname>pg_index</structname></title> @@ -2437,8 +2569,8 @@ <row> <entry><structfield>nspowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the namespace</entry> </row> @@ -2517,9 +2649,9 @@ <row> <entry><structfield>opcowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> - <entry>Operator class owner</entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>Owner of the operator class</entry> </row> <row> @@ -2606,8 +2738,8 @@ <row> <entry><structfield>oprowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the operator</entry> </row> @@ -2786,8 +2918,8 @@ <row> <entry><structfield>proowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the function</entry> </row> @@ -3066,149 +3198,41 @@ </sect1> - <sect1 id="catalog-pg-shadow"> - <title><structname>pg_shadow</structname></title> + <sect1 id="catalog-pg-statistic"> + <title><structname>pg_statistic</structname></title> - <indexterm zone="catalog-pg-shadow"> - <primary>pg_shadow</primary> + <indexterm zone="catalog-pg-statistic"> + <primary>pg_statistic</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. + The catalog <structname>pg_statistic</structname> stores statistical data + about the contents of the database. Entries are created by + <command>ANALYZE</command> and subsequently used by the query planner. + There is one entry for each table column that has been analyzed. + Note that all the statistical data is inherently approximate, + even assuming that it is up-to-date. </para> <para> - <xref linkend="user-manag"> contains detailed information about user and - privilege management. + <structname>pg_statistic</structname> also stores statistical data about + the values of index expressions. These are described as if they were + actual data columns; in particular, <structfield>starelid</structfield> + references the index. No entry is made for an ordinary non-expression + index column, however, since it would be redundant with the entry + for the underlying table column. </para> <para> - Because user identities are cluster-wide, - <structname>pg_shadow</structname> - is shared across all databases of a cluster: there is only one - copy of <structname>pg_shadow</structname> per cluster, not - one per database. - </para> - - <table> - <title><structname>pg_shadow</> Columns</title> - - <tgroup cols=4> - <thead> - <row> - <entry>Name</entry> - <entry>Type</entry> - <entry>References</entry> - <entry>Description</entry> - </row> - </thead> - - <tbody> - <row> - <entry><structfield>usename</structfield></entry> - <entry><type>name</type></entry> - <entry></entry> - <entry>User name</entry> - </row> - - <row> - <entry><structfield>usesysid</structfield></entry> - <entry><type>int4</type></entry> - <entry></entry> - <entry>User ID (arbitrary number used to reference this user)</entry> - </row> - - <row> - <entry><structfield>usecreatedb</structfield></entry> - <entry><type>bool</type></entry> - <entry></entry> - <entry>User may create databases</entry> - </row> - - <row> - <entry><structfield>usesuper</structfield></entry> - <entry><type>bool</type></entry> - <entry></entry> - <entry>User is a superuser</entry> - </row> - - <row> - <entry><structfield>usecatupd</structfield></entry> - <entry><type>bool</type></entry> - <entry></entry> - <entry> - User may update system catalogs. (Even a superuser may not do - this unless this column is true.) - </entry> - </row> - - <row> - <entry><structfield>passwd</structfield></entry> - <entry><type>text</type></entry> - <entry></entry> - <entry>Password (possibly encrypted)</entry> - </row> - - <row> - <entry><structfield>valuntil</structfield></entry> - <entry><type>abstime</type></entry> - <entry></entry> - <entry>Password expiry time (only used for password authentication)</entry> - </row> - - <row> - <entry><structfield>useconfig</structfield></entry> - <entry><type>text[]</type></entry> - <entry></entry> - <entry>Session defaults for run-time configuration variables</entry> - </row> - </tbody> - </tgroup> - </table> - - </sect1> - - - <sect1 id="catalog-pg-statistic"> - <title><structname>pg_statistic</structname></title> - - <indexterm zone="catalog-pg-statistic"> - <primary>pg_statistic</primary> - </indexterm> - - <para> - The catalog <structname>pg_statistic</structname> stores statistical data - about the contents of the database. Entries are created by - <command>ANALYZE</command> and subsequently used by the query planner. - There is one entry for each table column that has been analyzed. - Note that all the statistical data is inherently approximate, - even assuming that it is up-to-date. - </para> - - <para> - <structname>pg_statistic</structname> also stores statistical data about - the values of index expressions. These are described as if they were - actual data columns; in particular, <structfield>starelid</structfield> - references the index. No entry is made for an ordinary non-expression - index column, however, since it would be redundant with the entry - for the underlying table column. - </para> - - <para> - Since different kinds of statistics may be appropriate for different - kinds of data, <structname>pg_statistic</structname> is designed not - to assume very much about what sort of statistics it stores. Only - extremely general statistics (such as nullness) are given dedicated - columns in <structname>pg_statistic</structname>. Everything else - is stored in <quote>slots</quote>, which are groups of associated columns - whose content is identified by a code number in one of the slot's columns. - For more information see - <filename>src/include/catalog/pg_statistic.h</filename>. + Since different kinds of statistics may be appropriate for different + kinds of data, <structname>pg_statistic</structname> is designed not + to assume very much about what sort of statistics it stores. Only + extremely general statistics (such as nullness) are given dedicated + columns in <structname>pg_statistic</structname>. Everything else + is stored in <quote>slots</quote>, which are groups of associated columns + whose content is identified by a code number in one of the slot's columns. + For more information see + <filename>src/include/catalog/pg_statistic.h</filename>. </para> <para> @@ -3374,8 +3398,8 @@ <row> <entry><structfield>spcowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the tablespace, usually the user who created it</entry> </row> @@ -3586,8 +3610,8 @@ <row> <entry><structfield>typowner</structfield></entry> - <entry><type>int4</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usesysid</literal></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> <entry>Owner of the type</entry> </row> @@ -3922,6 +3946,11 @@ </thead> <tbody> + <row> + <entry><link linkend="view-pg-group"><structname>pg_group</structname></link></entry> + <entry>groups of database users</entry> + </row> + <row> <entry><link linkend="view-pg-indexes"><structname>pg_indexes</structname></link></entry> <entry>indexes</entry> @@ -3937,6 +3966,11 @@ <entry>currently prepared transactions</entry> </row> + <row> + <entry><link linkend="view-pg-roles"><structname>pg_roles</structname></link></entry> + <entry>database roles</entry> + </row> + <row> <entry><link linkend="view-pg-rules"><structname>pg_rules</structname></link></entry> <entry>rules</entry> @@ -3947,6 +3981,11 @@ <entry>parameter settings</entry> </row> + <row> + <entry><link linkend="view-pg-shadow"><structname>pg_shadow</structname></link></entry> + <entry>database users</entry> + </row> + <row> <entry><link linkend="view-pg-stats"><structname>pg_stats</structname></link></entry> <entry>planner statistics</entry> @@ -3972,6 +4011,62 @@ </table> </sect1> + <sect1 id="view-pg-group"> + <title><structname>pg_group</structname></title> + + <indexterm zone="view-pg-group"> + <primary>pg_group</primary> + </indexterm> + + <para> + The view <structname>pg_group</structname> exists for backwards + compatibility: it emulates a catalog that existed in + <productname>PostgreSQL</productname> before version 8.1. + It shows the names and members of all roles that are marked as not + <structfield>rolcanlogin</>, which is an approximation to the set + of roles that are being used as groups. + </para> + + <table> + <title><structname>pg_group</> Columns</title> + + <tgroup cols=4> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>References</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>groname</structfield></entry> + <entry><type>name</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry> + <entry>Name of the group</entry> + </row> + + <row> + <entry><structfield>grosysid</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>ID of this group</entry> + </row> + + <row> + <entry><structfield>grolist</structfield></entry> + <entry><type>oid[]</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>An array containing the IDs of the roles in this group</entry> + </row> + </tbody> + </tgroup> + </table> + + </sect1> + <sect1 id="view-pg-indexes"> <title><structname>pg_indexes</structname></title> @@ -4332,7 +4427,7 @@ <row> <entry><structfield>owner</structfield></entry> <entry><type>name</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usename</literal></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry> <entry> Name of the user that executed the transaction </entry> @@ -4361,6 +4456,110 @@ </sect1> + <sect1 id="view-pg-roles"> + <title><structname>pg_roles</structname></title> + + <indexterm zone="view-pg-roles"> + <primary>pg_roles</primary> + </indexterm> + + <para> + The view <structname>pg_roles</structname> provides access to + information about database roles. This is simply a publicly + readable view of + <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link> + that blanks out the password field. + </para> + + <table> + <title><structname>pg_roles</> Columns</title> + + <tgroup cols=4> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>References</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>rolname</structfield></entry> + <entry><type>name</type></entry> + <entry></entry> + <entry>Role name</entry> + </row> + + <row> + <entry><structfield>rolsuper</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>Role has superuser privileges</entry> + </row> + + <row> + <entry><structfield>rolcreaterole</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>Role may create more roles</entry> + </row> + + <row> + <entry><structfield>rolcreatedb</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>Role may create databases</entry> + </row> + + <row> + <entry><structfield>rolcatupdate</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry> + Role may update system catalogs directly. (Even a superuser may not do + this unless this column is true.) + </entry> + </row> + + <row> + <entry><structfield>rolcanlogin</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry> + Role may log in, that is, this role can be given as the initial + session authorization identifier. + </entry> + </row> + + <row> + <entry><structfield>rolpassword</structfield></entry> + <entry><type>text</type></entry> + <entry></entry> + <entry>Not the password (always reads as <literal>********</>)</entry> + </row> + + <row> + <entry><structfield>rolvaliduntil</structfield></entry> + <entry><type>timestamptz</type></entry> + <entry></entry> + <entry>Password expiry time (only used for password authentication); + NULL if no expiration</entry> + </row> + + <row> + <entry><structfield>rolconfig</structfield></entry> + <entry><type>text[]</type></entry> + <entry></entry> + <entry>Session defaults for run-time configuration variables</entry> + </row> + </tbody> + </tgroup> + </table> + + </sect1> + <sect1 id="view-pg-rules"> <title><structname>pg_rules</structname></title> @@ -4534,6 +4733,107 @@ </sect1> + <sect1 id="view-pg-shadow"> + <title><structname>pg_shadow</structname></title> + + <indexterm zone="view-pg-shadow"> + <primary>pg_shadow</primary> + </indexterm> + + <para> + The view <structname>pg_shadow</structname> exists for backwards + compatibility: it emulates a catalog that existed in + <productname>PostgreSQL</productname> before version 8.1. + It shows properties of all roles that are marked as + <structfield>rolcanlogin</>. + </para> + + <para> + The name stems from the fact that this table + should not be readable by the public since it contains passwords. + <link linkend="view-pg-user"><structname>pg_user</structname></link> + is a publicly readable view on + <structname>pg_shadow</structname> that blanks out the password field. + </para> + + <table> + <title><structname>pg_shadow</> Columns</title> + + <tgroup cols=4> + <thead> + <row> + <entry>Name</entry> + <entry>Type</entry> + <entry>References</entry> + <entry>Description</entry> + </row> + </thead> + + <tbody> + <row> + <entry><structfield>usename</structfield></entry> + <entry><type>name</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry> + <entry>User name</entry> + </row> + + <row> + <entry><structfield>usesysid</structfield></entry> + <entry><type>oid</type></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.oid</literal></entry> + <entry>ID of this user</entry> + </row> + + <row> + <entry><structfield>usecreatedb</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>User may create databases</entry> + </row> + + <row> + <entry><structfield>usesuper</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry>User is a superuser</entry> + </row> + + <row> + <entry><structfield>usecatupd</structfield></entry> + <entry><type>bool</type></entry> + <entry></entry> + <entry> + User may update system catalogs. (Even a superuser may not do + this unless this column is true.) + </entry> + </row> + + <row> + <entry><structfield>passwd</structfield></entry> + <entry><type>text</type></entry> + <entry></entry> + <entry>Password (possibly encrypted)</entry> + </row> + + <row> + <entry><structfield>valuntil</structfield></entry> + <entry><type>abstime</type></entry> + <entry></entry> + <entry>Password expiry time (only used for password authentication)</entry> + </row> + + <row> + <entry><structfield>useconfig</structfield></entry> + <entry><type>text[]</type></entry> + <entry></entry> + <entry>Session defaults for run-time configuration variables</entry> + </row> + </tbody> + </tgroup> + </table> + + </sect1> + <sect1 id="view-pg-stats"> <title><structname>pg_stats</structname></title> @@ -4720,7 +5020,7 @@ <row> <entry><structfield>tableowner</structfield></entry> <entry><type>name</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usename</literal></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry> <entry>name of table's owner</entry> </row> <row> @@ -4764,7 +5064,7 @@ The view <structname>pg_user</structname> provides access to information about database users. This is simply a publicly readable view of - <link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link> + <link linkend="view-pg-shadow"><structname>pg_shadow</structname></link> that blanks out the password field. </para> @@ -4885,7 +5185,7 @@ <row> <entry><structfield>viewowner</structfield></entry> <entry><type>name</type></entry> - <entry><literal><link linkend="catalog-pg-shadow"><structname>pg_shadow</structname></link>.usename</literal></entry> + <entry><literal><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.rolname</literal></entry> <entry>name of view's owner</entry> </row> <row> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index d7430f1ccf8053623d8d15eecfabd4e42b31e051..734686bf4a4317e50e5beb14c40874cbd3679f0c 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.260 2005/06/26 22:05:35 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.261 2005/06/28 05:08:50 tgl Exp $ PostgreSQL documentation --> @@ -8443,8 +8443,8 @@ SET search_path TO <replaceable>schema</> <optional>, <replaceable>schema</>, .. <para> <function>has_table_privilege</function> checks whether a user can access a table in a particular way. The user can be - specified by name or by ID - (<literal>pg_user.usesysid</literal>), or if the argument is + specified by name or by OID + (<literal>pg_authid.oid</literal>), or if the argument is omitted <function>current_user</function> is assumed. The table can be specified by name or by OID. (Thus, there are actually six variants of @@ -8756,9 +8756,9 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); in it refer to the relation indicated by the second parameter</entry> </row> <row> - <entry><literal><function>pg_get_userbyid</function>(<parameter>userid</parameter>)</literal></entry> + <entry><literal><function>pg_get_userbyid</function>(<parameter>roleid</parameter>)</literal></entry> <entry><type>name</type></entry> - <entry>get user name with given ID</entry> + <entry>get role name with given ID</entry> </row> <row> <entry><literal><function>pg_get_serial_sequence</function>(<parameter>table_name</parameter>, <parameter>column_name</parameter>)</literal></entry> @@ -8805,7 +8805,7 @@ SELECT pg_type_is_visible('myschema.widget'::regtype); <para> <function>pg_get_userbyid</function> - extracts a user's name given a user ID number. + extracts a role's name given its OID. <function>pg_get_serial_sequence</function> fetches the name of the sequence associated with a serial or bigserial column. The name is suitably formatted diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index 7c8102d87c92d4db9ff825074233442f5d0dd6db..ccd8b802157ad16bebd4a067fab19cf72a755fe9 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.6 2005/06/19 22:34:56 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.7 2005/06/28 05:08:51 tgl Exp $ * * NOTES * Each global transaction is associated with a global transaction @@ -107,7 +107,7 @@ typedef struct GlobalTransactionData PGPROC proc; /* dummy proc */ TimestampTz prepared_at; /* time of preparation */ XLogRecPtr prepare_lsn; /* XLOG offset of prepare record */ - AclId owner; /* ID of user that executed the xact */ + Oid owner; /* ID of user that executed the xact */ TransactionId locking_xid; /* top-level XID of backend working on xact */ bool valid; /* TRUE if fully prepared */ char gid[GIDSIZE]; /* The GID assigned to the prepared xact */ @@ -206,7 +206,7 @@ TwoPhaseShmemInit(void) */ GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, - TimestampTz prepared_at, AclId owner, Oid databaseid) + TimestampTz prepared_at, Oid owner, Oid databaseid) { GlobalTransaction gxact; int i; @@ -350,7 +350,7 @@ MarkAsPrepared(GlobalTransaction gxact) * Locate the prepared transaction and mark it busy for COMMIT or PREPARE. */ static GlobalTransaction -LockGXact(const char *gid, AclId user) +LockGXact(const char *gid, Oid user) { int i; @@ -559,7 +559,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS) TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared", TIMESTAMPTZOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid", - INT4OID, -1, 0); + OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid", OIDOID, -1, 0); @@ -601,7 +601,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS) values[0] = TransactionIdGetDatum(gxact->proc.xid); values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid)); values[2] = TimestampTzGetDatum(gxact->prepared_at); - values[3] = Int32GetDatum(gxact->owner); + values[3] = ObjectIdGetDatum(gxact->owner); values[4] = ObjectIdGetDatum(gxact->proc.databaseId); tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); @@ -690,7 +690,7 @@ typedef struct TwoPhaseFileHeader TransactionId xid; /* original transaction XID */ Oid database; /* OID of database it was in */ TimestampTz prepared_at; /* time of preparation */ - AclId owner; /* user running the transaction */ + Oid owner; /* user running the transaction */ int32 nsubxacts; /* number of following subxact XIDs */ int32 ncommitrels; /* number of delete-on-commit rels */ int32 nabortrels; /* number of delete-on-abort rels */ diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 98e56c400202c45514c291f659a47470df1360b0..a5d53d3e1457381b140677ead6d89cadc6b646a0 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.207 2005/06/19 20:00:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.208 2005/06/28 05:08:51 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -121,7 +121,7 @@ typedef struct TransactionStateData * context */ ResourceOwner curTransactionOwner; /* my query resources */ List *childXids; /* subcommitted child XIDs */ - AclId currentUser; /* subxact start current_user */ + Oid currentUser; /* subxact start current_user */ bool prevXactReadOnly; /* entry-time xact r/o state */ struct TransactionStateData *parent; /* back link to parent */ } TransactionStateData; @@ -1488,8 +1488,10 @@ CommitTransaction(void) /* NOTIFY commit must come before lower-level cleanup */ AtCommit_Notify(); - /* Update flat files if we changed pg_database, pg_shadow or pg_group */ - /* This should be the last step before commit */ + /* + * Update flat files if we changed pg_database, pg_authid or + * pg_auth_members. This should be the last step before commit. + */ AtEOXact_UpdateFlatFiles(true); /* Prevent cancel/die interrupt while cleaning up */ @@ -3847,7 +3849,7 @@ PushTransaction(void) { TransactionState p = CurrentTransactionState; TransactionState s; - AclId currentUser; + Oid currentUser; /* * At present, GetUserId cannot fail, but let's not assume that. Get diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index a77b41b441ff6b6ba4acb7768e9fb1589a8f8ee1..09addc4af1cb3968404c52af58ad290b6b5cd93e 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/catalog # -# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.53 2004/07/21 20:34:45 momjian Exp $ +# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.54 2005/06/28 05:08:52 tgl Exp $ # #------------------------------------------------------------------------- @@ -31,8 +31,9 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \ pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \ - pg_namespace.h pg_conversion.h pg_database.h pg_shadow.h pg_group.h \ - pg_tablespace.h pg_depend.h indexing.h \ + pg_namespace.h pg_conversion.h pg_database.h \ + pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \ + indexing.h \ ) pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 5eba84f995fddcd497abc477c622e756334afc9e..6ff89eb0425b52c87eed91aa6cc7fbfb1fe781ca 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.112 2005/05/29 23:38:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.113 2005/06/28 05:08:52 tgl Exp $ * * NOTES * See acl.h. @@ -21,15 +21,15 @@ #include "catalog/catalog.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_auth_members.h" +#include "catalog/pg_authid.h" #include "catalog/pg_conversion.h" #include "catalog/pg_database.h" -#include "catalog/pg_group.h" #include "catalog/pg_language.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" #include "miscadmin.h" @@ -76,10 +76,10 @@ dumpacl(Acl *acl) * all granted privileges appear to flow from the object owner, and there * are never multiple "original sources" of a privilege. */ -static AclId -select_grantor(AclId ownerId) +static Oid +select_grantor(Oid ownerId) { - AclId grantorId; + Oid grantorId; grantorId = GetUserId(); @@ -105,7 +105,7 @@ static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, - AclId grantor_uid, AclId owner_uid) + Oid grantorId, Oid ownerId) { unsigned modechg; ListCell *j; @@ -122,41 +122,25 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant, { PrivGrantee *grantee = (PrivGrantee *) lfirst(j); AclItem aclitem; - uint32 idtype; Acl *newer_acl; - if (grantee->username) - { - aclitem. ai_grantee = get_usesysid(grantee->username); - - idtype = ACL_IDTYPE_UID; - } - else if (grantee->groupname) - { - aclitem. ai_grantee = get_grosysid(grantee->groupname); - - idtype = ACL_IDTYPE_GID; - } + if (grantee->rolname) + aclitem.ai_grantee = get_roleid_checked(grantee->rolname); else - { - aclitem. ai_grantee = ACL_ID_WORLD; - - idtype = ACL_IDTYPE_WORLD; - } + aclitem.ai_grantee = ACL_ID_PUBLIC; /* - * Grant options can only be granted to individual users, not - * groups or public. The reason is that if a user would re-grant - * a privilege that he held through a group having a grant option, - * and later the user is removed from the group, the situation is - * impossible to clean up. + * Grant options can only be granted to individual roles, not PUBLIC. + * The reason is that if a user would re-grant a privilege that he + * held through PUBLIC, and later the user is removed, the situation + * is impossible to clean up. */ - if (is_grant && grant_option && idtype != ACL_IDTYPE_UID) + if (is_grant && grant_option && aclitem.ai_grantee == ACL_ID_PUBLIC) ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), - errmsg("grant options can only be granted to individual users"))); + errmsg("grant options can only be granted to roles"))); - aclitem. ai_grantor = grantor_uid; + aclitem.ai_grantor = grantorId; /* * The asymmetry in the conditions here comes from the spec. In @@ -166,12 +150,11 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant, * and its grant option, while REVOKE GRANT OPTION revokes only * the option. */ - ACLITEM_SET_PRIVS_IDTYPE(aclitem, + ACLITEM_SET_PRIVS_GOPTIONS(aclitem, (is_grant || !grant_option) ? privileges : ACL_NO_RIGHTS, - (!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS, - idtype); + (!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS); - newer_acl = aclupdate(new_acl, &aclitem, modechg, owner_uid, behavior); + newer_acl = aclupdate(new_acl, &aclitem, modechg, ownerId, behavior); /* avoid memory leak when there are many grantees */ pfree(new_acl); @@ -261,8 +244,8 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt) AclMode this_privileges; Acl *old_acl; Acl *new_acl; - AclId grantorId; - AclId ownerId; + Oid grantorId; + Oid ownerId; HeapTuple newtuple; Datum values[Natts_pg_class]; char nulls[Natts_pg_class]; @@ -430,8 +413,8 @@ ExecuteGrantStmt_Database(GrantStmt *stmt) AclMode this_privileges; Acl *old_acl; Acl *new_acl; - AclId grantorId; - AclId ownerId; + Oid grantorId; + Oid ownerId; HeapTuple newtuple; Datum values[Natts_pg_database]; char nulls[Natts_pg_database]; @@ -587,8 +570,8 @@ ExecuteGrantStmt_Function(GrantStmt *stmt) AclMode this_privileges; Acl *old_acl; Acl *new_acl; - AclId grantorId; - AclId ownerId; + Oid grantorId; + Oid ownerId; HeapTuple newtuple; Datum values[Natts_pg_proc]; char nulls[Natts_pg_proc]; @@ -740,8 +723,8 @@ ExecuteGrantStmt_Language(GrantStmt *stmt) AclMode this_privileges; Acl *old_acl; Acl *new_acl; - AclId grantorId; - AclId ownerId; + Oid grantorId; + Oid ownerId; HeapTuple newtuple; Datum values[Natts_pg_language]; char nulls[Natts_pg_language]; @@ -767,7 +750,7 @@ ExecuteGrantStmt_Language(GrantStmt *stmt) * Note: for now, languages are treated as owned by the bootstrap * user. We should add an owner column to pg_language instead. */ - ownerId = BOOTSTRAP_USESYSID; + ownerId = BOOTSTRAP_SUPERUSERID; grantorId = select_grantor(ownerId); /* @@ -903,8 +886,8 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt) AclMode this_privileges; Acl *old_acl; Acl *new_acl; - AclId grantorId; - AclId ownerId; + Oid grantorId; + Oid ownerId; HeapTuple newtuple; Datum values[Natts_pg_namespace]; char nulls[Natts_pg_namespace]; @@ -1059,8 +1042,8 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt) AclMode this_privileges; Acl *old_acl; Acl *new_acl; - AclId grantorId; - AclId ownerId; + Oid grantorId; + Oid ownerId; HeapTuple newtuple; Datum values[Natts_pg_tablespace]; char nulls[Natts_pg_tablespace]; @@ -1207,27 +1190,6 @@ privilege_to_string(AclMode privilege) return NULL; /* appease compiler */ } -/* - * Convert group ID to name, or return NULL if group can't be found - */ -char * -get_groname(AclId grosysid) -{ - HeapTuple tuple; - char *name = NULL; - - tuple = SearchSysCache(GROSYSID, - ObjectIdGetDatum(grosysid), - 0, 0, 0); - if (HeapTupleIsValid(tuple)) - { - name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname)); - ReleaseSysCache(tuple); - } - return name; -} - - /* * Standardized reporting of aclcheck permissions failures. * @@ -1310,26 +1272,26 @@ aclcheck_error(AclResult aclerr, AclObjectKind objectkind, } -/* Check if given userid has usecatupd privilege according to pg_shadow */ +/* Check if given user has rolcatupdate privilege according to pg_authid */ static bool -has_usecatupd(AclId userid) +has_rolcatupdate(Oid roleid) { - bool usecatupd; + bool rolcatupdate; HeapTuple tuple; - tuple = SearchSysCache(SHADOWSYSID, - ObjectIdGetDatum(userid), + tuple = SearchSysCache(AUTHOID, + ObjectIdGetDatum(roleid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user with ID %u does not exist", userid))); + errmsg("role with OID %u does not exist", roleid))); - usecatupd = ((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd; + rolcatupdate = ((Form_pg_authid) GETSTRUCT(tuple))->rolcatupdate; ReleaseSysCache(tuple); - return usecatupd; + return rolcatupdate; } @@ -1344,7 +1306,7 @@ has_usecatupd(AclId userid) * below. */ AclMode -pg_class_aclmask(Oid table_oid, AclId userid, +pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how) { AclMode result; @@ -1353,7 +1315,7 @@ pg_class_aclmask(Oid table_oid, AclId userid, Datum aclDatum; bool isNull; Acl *acl; - AclId ownerId; + Oid ownerId; /* * Must get the relation's tuple from pg_class @@ -1370,7 +1332,7 @@ pg_class_aclmask(Oid table_oid, AclId userid, /* * Deny anyone permission to update a system catalog unless - * pg_shadow.usecatupd is set. (This is to let superusers protect + * pg_authid.rolcatupdate is set. (This is to let superusers protect * themselves from themselves.) Also allow it if * allowSystemTableMods. * @@ -1381,7 +1343,7 @@ pg_class_aclmask(Oid table_oid, AclId userid, if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) && IsSystemClass(classForm) && classForm->relkind != RELKIND_VIEW && - !has_usecatupd(userid) && + !has_rolcatupdate(roleid) && !allowSystemTableMods) { #ifdef ACLDEBUG @@ -1393,10 +1355,10 @@ pg_class_aclmask(Oid table_oid, AclId userid, /* * Otherwise, superusers bypass all permission-checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) { #ifdef ACLDEBUG - elog(DEBUG2, "%u is superuser, home free", userid); + elog(DEBUG2, "OID %u is superuser, home free", roleid); #endif ReleaseSysCache(tuple); return mask; @@ -1421,7 +1383,7 @@ pg_class_aclmask(Oid table_oid, AclId userid, acl = DatumGetAclP(aclDatum); } - result = aclmask(acl, userid, ownerId, mask, how); + result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) @@ -1436,7 +1398,7 @@ pg_class_aclmask(Oid table_oid, AclId userid, * Exported routine for examining a user's privileges for a database */ AclMode -pg_database_aclmask(Oid db_oid, AclId userid, +pg_database_aclmask(Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how) { AclMode result; @@ -1447,10 +1409,10 @@ pg_database_aclmask(Oid db_oid, AclId userid, Datum aclDatum; bool isNull; Acl *acl; - AclId ownerId; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return mask; /* @@ -1487,7 +1449,7 @@ pg_database_aclmask(Oid db_oid, AclId userid, acl = DatumGetAclP(aclDatum); } - result = aclmask(acl, userid, ownerId, mask, how); + result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) @@ -1503,7 +1465,7 @@ pg_database_aclmask(Oid db_oid, AclId userid, * Exported routine for examining a user's privileges for a function */ AclMode -pg_proc_aclmask(Oid proc_oid, AclId userid, +pg_proc_aclmask(Oid proc_oid, Oid roleid, AclMode mask, AclMaskHow how) { AclMode result; @@ -1511,10 +1473,10 @@ pg_proc_aclmask(Oid proc_oid, AclId userid, Datum aclDatum; bool isNull; Acl *acl; - AclId ownerId; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return mask; /* @@ -1544,7 +1506,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid, acl = DatumGetAclP(aclDatum); } - result = aclmask(acl, userid, ownerId, mask, how); + result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) @@ -1559,7 +1521,7 @@ pg_proc_aclmask(Oid proc_oid, AclId userid, * Exported routine for examining a user's privileges for a language */ AclMode -pg_language_aclmask(Oid lang_oid, AclId userid, +pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how) { AclMode result; @@ -1567,10 +1529,10 @@ pg_language_aclmask(Oid lang_oid, AclId userid, Datum aclDatum; bool isNull; Acl *acl; - AclId ownerId; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return mask; /* @@ -1585,7 +1547,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid, errmsg("language with OID %u does not exist", lang_oid))); /* XXX pg_language should have an owner column, but doesn't */ - ownerId = BOOTSTRAP_USESYSID; + ownerId = BOOTSTRAP_SUPERUSERID; aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl, &isNull); @@ -1601,7 +1563,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid, acl = DatumGetAclP(aclDatum); } - result = aclmask(acl, userid, ownerId, mask, how); + result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) @@ -1616,7 +1578,7 @@ pg_language_aclmask(Oid lang_oid, AclId userid, * Exported routine for examining a user's privileges for a namespace */ AclMode -pg_namespace_aclmask(Oid nsp_oid, AclId userid, +pg_namespace_aclmask(Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how) { AclMode result; @@ -1624,10 +1586,10 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid, Datum aclDatum; bool isNull; Acl *acl; - AclId ownerId; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return mask; /* @@ -1685,7 +1647,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid, acl = DatumGetAclP(aclDatum); } - result = aclmask(acl, userid, ownerId, mask, how); + result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) @@ -1700,7 +1662,7 @@ pg_namespace_aclmask(Oid nsp_oid, AclId userid, * Exported routine for examining a user's privileges for a tablespace */ AclMode -pg_tablespace_aclmask(Oid spc_oid, AclId userid, +pg_tablespace_aclmask(Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow how) { AclMode result; @@ -1711,7 +1673,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid, Datum aclDatum; bool isNull; Acl *acl; - AclId ownerId; + Oid ownerId; /* * Only shared relations can be stored in global space; don't let even @@ -1721,7 +1683,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid, return 0; /* Otherwise, superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return mask; /* @@ -1758,7 +1720,7 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid, acl = DatumGetAclP(aclDatum); } - result = aclmask(acl, userid, ownerId, mask, how); + result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) @@ -1779,9 +1741,9 @@ pg_tablespace_aclmask(Oid spc_oid, AclId userid, * ACLCHECK_NO_PRIV). */ AclResult -pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode) +pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode) { - if (pg_class_aclmask(table_oid, userid, mode, ACLMASK_ANY) != 0) + if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -1791,9 +1753,9 @@ pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode) * Exported routine for checking a user's access privileges to a database */ AclResult -pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode) +pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode) { - if (pg_database_aclmask(db_oid, userid, mode, ACLMASK_ANY) != 0) + if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -1803,9 +1765,9 @@ pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode) * Exported routine for checking a user's access privileges to a function */ AclResult -pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode) +pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode) { - if (pg_proc_aclmask(proc_oid, userid, mode, ACLMASK_ANY) != 0) + if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -1815,9 +1777,9 @@ pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode) * Exported routine for checking a user's access privileges to a language */ AclResult -pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode) +pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode) { - if (pg_language_aclmask(lang_oid, userid, mode, ACLMASK_ANY) != 0) + if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -1827,9 +1789,9 @@ pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode) * Exported routine for checking a user's access privileges to a namespace */ AclResult -pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode) +pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode) { - if (pg_namespace_aclmask(nsp_oid, userid, mode, ACLMASK_ANY) != 0) + if (pg_namespace_aclmask(nsp_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -1839,9 +1801,9 @@ pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode) * Exported routine for checking a user's access privileges to a tablespace */ AclResult -pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode) +pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode) { - if (pg_tablespace_aclmask(spc_oid, userid, mode, ACLMASK_ANY) != 0) + if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -1852,13 +1814,13 @@ pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode) * Ownership check for a relation (specified by OID). */ bool -pg_class_ownercheck(Oid class_oid, AclId userid) +pg_class_ownercheck(Oid class_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(RELOID, @@ -1869,24 +1831,24 @@ pg_class_ownercheck(Oid class_oid, AclId userid) (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation with OID %u does not exist", class_oid))); - owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner; + ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } /* * Ownership check for a type (specified by OID). */ bool -pg_type_ownercheck(Oid type_oid, AclId userid) +pg_type_ownercheck(Oid type_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(TYPEOID, @@ -1897,24 +1859,24 @@ pg_type_ownercheck(Oid type_oid, AclId userid) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type with OID %u does not exist", type_oid))); - owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner; + ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } /* * Ownership check for an operator (specified by OID). */ bool -pg_oper_ownercheck(Oid oper_oid, AclId userid) +pg_oper_ownercheck(Oid oper_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(OPEROID, @@ -1925,24 +1887,24 @@ pg_oper_ownercheck(Oid oper_oid, AclId userid) (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("operator with OID %u does not exist", oper_oid))); - owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner; + ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } /* * Ownership check for a function (specified by OID). */ bool -pg_proc_ownercheck(Oid proc_oid, AclId userid) +pg_proc_ownercheck(Oid proc_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(PROCOID, @@ -1953,24 +1915,24 @@ pg_proc_ownercheck(Oid proc_oid, AclId userid) (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function with OID %u does not exist", proc_oid))); - owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; + ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } /* * Ownership check for a namespace (specified by OID). */ bool -pg_namespace_ownercheck(Oid nsp_oid, AclId userid) +pg_namespace_ownercheck(Oid nsp_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(NAMESPACEOID, @@ -1981,27 +1943,27 @@ pg_namespace_ownercheck(Oid nsp_oid, AclId userid) (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema with OID %u does not exist", nsp_oid))); - owner_id = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; + ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } /* * Ownership check for a tablespace (specified by OID). */ bool -pg_tablespace_ownercheck(Oid spc_oid, AclId userid) +pg_tablespace_ownercheck(Oid spc_oid, Oid roleid) { Relation pg_tablespace; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple spctuple; - int32 spcowner; + Oid spcowner; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; /* There's no syscache for pg_tablespace, so must look the hard way */ @@ -2024,20 +1986,20 @@ pg_tablespace_ownercheck(Oid spc_oid, AclId userid) heap_endscan(scan); heap_close(pg_tablespace, AccessShareLock); - return userid == spcowner; + return is_member_of_role(roleid, spcowner); } /* * Ownership check for an operator class (specified by OID). */ bool -pg_opclass_ownercheck(Oid opc_oid, AclId userid) +pg_opclass_ownercheck(Oid opc_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(CLAOID, @@ -2049,27 +2011,27 @@ pg_opclass_ownercheck(Oid opc_oid, AclId userid) errmsg("operator class with OID %u does not exist", opc_oid))); - owner_id = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; + ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } /* * Ownership check for a database (specified by OID). */ bool -pg_database_ownercheck(Oid db_oid, AclId userid) +pg_database_ownercheck(Oid db_oid, Oid roleid) { Relation pg_database; ScanKeyData entry[1]; HeapScanDesc scan; HeapTuple dbtuple; - int32 dba; + Oid dba; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; /* There's no syscache for pg_database, so must look the hard way */ @@ -2092,20 +2054,20 @@ pg_database_ownercheck(Oid db_oid, AclId userid) heap_endscan(scan); heap_close(pg_database, AccessShareLock); - return userid == dba; + return is_member_of_role(roleid, dba); } /* * Ownership check for a conversion (specified by OID). */ bool -pg_conversion_ownercheck(Oid conv_oid, AclId userid) +pg_conversion_ownercheck(Oid conv_oid, Oid roleid) { HeapTuple tuple; - AclId owner_id; + Oid ownerId; /* Superusers bypass all permission checking. */ - if (superuser_arg(userid)) + if (superuser_arg(roleid)) return true; tuple = SearchSysCache(CONOID, @@ -2116,9 +2078,9 @@ pg_conversion_ownercheck(Oid conv_oid, AclId userid) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion with OID %u does not exist", conv_oid))); - owner_id = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner; + ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner; ReleaseSysCache(tuple); - return userid == owner_id; + return is_member_of_role(roleid, ownerId); } diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh index 92a3ac5eeccca31c364c33a88ce7c22ae0ad3afa..9d9b75bde58aadc4af39c123b44fa962df302549 100644 --- a/src/backend/catalog/genbki.sh +++ b/src/backend/catalog/genbki.sh @@ -11,7 +11,7 @@ # # # IDENTIFICATION -# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.36 2005/04/14 20:03:23 tgl Exp $ +# $PostgreSQL: pgsql/src/backend/catalog/genbki.sh,v 1.37 2005/06/28 05:08:52 tgl Exp $ # # NOTES # non-essential whitespace is removed from the generated file. @@ -114,6 +114,14 @@ for dir in $INCLUDE_DIRS; do fi done +# Get BOOTSTRAP_SUPERUSERID from catalog/pg_authid.h +for dir in $INCLUDE_DIRS; do + if [ -f "$dir/catalog/pg_authid.h" ]; then + BOOTSTRAP_SUPERUSERID=`grep '^#define[ ]*BOOTSTRAP_SUPERUSERID' $dir/catalog/pg_authid.h | $AWK '{ print $3 }'` + break + fi +done + # Get PG_CATALOG_NAMESPACE from catalog/pg_namespace.h for dir in $INCLUDE_DIRS; do if [ -f "$dir/catalog/pg_namespace.h" ]; then @@ -153,7 +161,7 @@ sed -e "s/;[ ]*$//g" \ -e "s/[ ]TransactionId/ xid/g" \ -e "s/^TransactionId/xid/g" \ -e "s/(TransactionId/(xid/g" \ - -e "s/PGUID/1/g" \ + -e "s/PGUID/$BOOTSTRAP_SUPERUSERID/g" \ -e "s/NAMEDATALEN/$NAMEDATALEN/g" \ -e "s/PGNSP/$PG_CATALOG_NAMESPACE/g" \ | $AWK ' diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 83e6fa82b0f2976c449fd23d37e3866dcfd5b39a..6d90887ba6c2a8391a3c952103bf8a47358d558f 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -4,7 +4,7 @@ * * Copyright (c) 2003-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.28 2005/05/31 03:36:24 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/information_schema.sql,v 1.29 2005/06/28 05:08:52 tgl Exp $ */ /* @@ -210,13 +210,13 @@ CREATE DOMAIN time_stamp AS timestamp(2) CREATE VIEW applicable_roles AS SELECT CAST(current_user AS sql_identifier) AS grantee, - CAST(g.groname AS sql_identifier) AS role_name, - CAST('NO' AS character_data) AS is_grantable + CAST(a.rolname AS sql_identifier) AS role_name, + CAST(CASE WHEN m.admin_option = 'true' THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable - FROM pg_group g, pg_user u + FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid)) + join pg_authid b ON (m.member = b.oid)) - WHERE u.usesysid = ANY (g.grolist) - AND u.usename = current_user; + WHERE b.rolname = current_user; GRANT SELECT ON applicable_roles TO PUBLIC; @@ -282,7 +282,7 @@ GRANT SELECT ON column_domain_usage TO PUBLIC; */ CREATE VIEW column_privileges AS - SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor, + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, CAST(grantee.name AS sql_identifier) AS grantee, CAST(current_database() AS sql_identifier) AS table_catalog, CAST(nc.nspname AS sql_identifier) AS table_schema, @@ -291,20 +291,18 @@ CREATE VIEW column_privileges AS CAST(pr.type AS character_data) AS privilege_type, CAST( CASE WHEN aclcontains(c.relacl, - makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, true)) + makeaclitem(grantee.oid, u_grantor.oid, pr.type, true)) THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable FROM pg_attribute a, pg_class c, pg_namespace nc, - pg_user u_grantor, + pg_authid u_grantor, ( - SELECT usesysid, 0, usename FROM pg_user - UNION ALL - SELECT 0, grosysid, groname FROM pg_group + SELECT oid, rolname FROM pg_authid UNION ALL - SELECT 0, 0, 'PUBLIC' - ) AS grantee (usesysid, grosysid, name), + SELECT 0, 'PUBLIC' + ) AS grantee (oid, name), (SELECT 'SELECT' UNION ALL SELECT 'INSERT' UNION ALL SELECT 'UPDATE' UNION ALL @@ -316,8 +314,8 @@ CREATE VIEW column_privileges AS AND NOT a.attisdropped AND c.relkind IN ('r', 'v') AND aclcontains(c.relacl, - makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false)) - AND (u_grantor.usename = current_user + makeaclitem(grantee.oid, u_grantor.oid, pr.type, false)) + AND (u_grantor.rolname = current_user OR grantee.name = current_user OR grantee.name = 'PUBLIC'); @@ -693,10 +691,10 @@ GRANT SELECT ON domains TO PUBLIC; */ CREATE VIEW enabled_roles AS - SELECT CAST(g.groname AS sql_identifier) AS role_name - FROM pg_group g, pg_user u - WHERE u.usesysid = ANY (g.grolist) - AND u.usename = current_user; + SELECT CAST(a.rolname AS sql_identifier) AS role_name + FROM ((pg_auth_members m join pg_authid a ON (m.roleid = a.oid)) + join pg_authid b ON (m.member = b.oid)) + WHERE b.rolname = current_user; GRANT SELECT ON enabled_roles TO PUBLIC; @@ -865,7 +863,7 @@ CREATE VIEW role_column_grants AS CAST(pr.type AS character_data) AS privilege_type, CAST( CASE WHEN aclcontains(c.relacl, - makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, true)) + makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, true)) THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable FROM pg_attribute a, @@ -884,7 +882,7 @@ CREATE VIEW role_column_grants AS AND NOT a.attisdropped AND c.relkind IN ('r', 'v') AND aclcontains(c.relacl, - makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, false)) + makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, false)) AND g_grantee.groname IN (SELECT role_name FROM enabled_roles); GRANT SELECT ON role_column_grants TO PUBLIC; @@ -907,7 +905,7 @@ CREATE VIEW role_routine_grants AS CAST('EXECUTE' AS character_data) AS privilege_type, CAST( CASE WHEN aclcontains(p.proacl, - makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true)) + makeaclitem(g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true)) THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable FROM pg_proc p, @@ -917,7 +915,7 @@ CREATE VIEW role_routine_grants AS WHERE p.pronamespace = n.oid AND aclcontains(p.proacl, - makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false)) + makeaclitem(g_grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false)) AND g_grantee.groname IN (SELECT role_name FROM enabled_roles); GRANT SELECT ON role_routine_grants TO PUBLIC; @@ -937,7 +935,7 @@ CREATE VIEW role_table_grants AS CAST(pr.type AS character_data) AS privilege_type, CAST( CASE WHEN aclcontains(c.relacl, - makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, true)) + makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, true)) THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable, CAST('NO' AS character_data) AS with_hierarchy @@ -956,7 +954,7 @@ CREATE VIEW role_table_grants AS WHERE c.relnamespace = nc.oid AND c.relkind IN ('r', 'v') AND aclcontains(c.relacl, - makeaclitem(0, g_grantee.grosysid, u_grantor.usesysid, pr.type, false)) + makeaclitem(g_grantee.grosysid, u_grantor.usesysid, pr.type, false)) AND g_grantee.groname IN (SELECT role_name FROM enabled_roles); GRANT SELECT ON role_table_grants TO PUBLIC; @@ -990,7 +988,7 @@ GRANT SELECT ON role_usage_grants TO PUBLIC; */ CREATE VIEW routine_privileges AS - SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor, + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, CAST(grantee.name AS sql_identifier) AS grantee, CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(n.nspname AS sql_identifier) AS specific_schema, @@ -1001,24 +999,22 @@ CREATE VIEW routine_privileges AS CAST('EXECUTE' AS character_data) AS privilege_type, CAST( CASE WHEN aclcontains(p.proacl, - makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', true)) + makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', true)) THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable FROM pg_proc p, pg_namespace n, - pg_user u_grantor, + pg_authid u_grantor, ( - SELECT usesysid, 0, usename FROM pg_user - UNION ALL - SELECT 0, grosysid, groname FROM pg_group + SELECT oid, rolname FROM pg_authid UNION ALL - SELECT 0, 0, 'PUBLIC' - ) AS grantee (usesysid, grosysid, name) + SELECT 0, 'PUBLIC' + ) AS grantee (oid, name) WHERE p.pronamespace = n.oid AND aclcontains(p.proacl, - makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, 'EXECUTE', false)) - AND (u_grantor.usename = current_user + makeaclitem(grantee.oid, u_grantor.oid, 'EXECUTE', false)) + AND (u_grantor.rolname = current_user OR grantee.name = current_user OR grantee.name = 'PUBLIC'); @@ -1338,7 +1334,7 @@ GRANT SELECT ON table_constraints TO PUBLIC; */ CREATE VIEW table_privileges AS - SELECT CAST(u_grantor.usename AS sql_identifier) AS grantor, + SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, CAST(grantee.name AS sql_identifier) AS grantee, CAST(current_database() AS sql_identifier) AS table_catalog, CAST(nc.nspname AS sql_identifier) AS table_schema, @@ -1346,20 +1342,18 @@ CREATE VIEW table_privileges AS CAST(pr.type AS character_data) AS privilege_type, CAST( CASE WHEN aclcontains(c.relacl, - makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, true)) + makeaclitem(grantee.oid, u_grantor.oid, pr.type, true)) THEN 'YES' ELSE 'NO' END AS character_data) AS is_grantable, CAST('NO' AS character_data) AS with_hierarchy FROM pg_class c, pg_namespace nc, - pg_user u_grantor, + pg_authid u_grantor, ( - SELECT usesysid, 0, usename FROM pg_user - UNION ALL - SELECT 0, grosysid, groname FROM pg_group + SELECT oid, rolname FROM pg_authid UNION ALL - SELECT 0, 0, 'PUBLIC' - ) AS grantee (usesysid, grosysid, name), + SELECT 0, 'PUBLIC' + ) AS grantee (oid, name), (SELECT 'SELECT' UNION ALL SELECT 'DELETE' UNION ALL SELECT 'INSERT' UNION ALL @@ -1371,8 +1365,8 @@ CREATE VIEW table_privileges AS WHERE c.relnamespace = nc.oid AND c.relkind IN ('r', 'v') AND aclcontains(c.relacl, - makeaclitem(grantee.usesysid, grantee.grosysid, u_grantor.usesysid, pr.type, false)) - AND (u_grantor.usename = current_user + makeaclitem(grantee.oid, u_grantor.oid, pr.type, false)) + AND (u_grantor.rolname = current_user OR grantee.name = current_user OR grantee.name = 'PUBLIC'); diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 3cfcc6f9b46b97f2e8d5b7aeb5e49b0a52d5d925..6b12bda661548e6f59e72866a6a07627788823eb 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -13,7 +13,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.75 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/namespace.c,v 1.76 2005/06/28 05:08:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,12 +22,12 @@ #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/namespace.h" +#include "catalog/pg_authid.h" #include "catalog/pg_conversion.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" #include "lib/stringinfo.h" @@ -1499,7 +1499,7 @@ FindDefaultConversionProc(int4 for_encoding, int4 to_encoding) static void recomputeNamespacePath(void) { - AclId userId = GetUserId(); + Oid roleid = GetUserId(); char *rawname; List *namelist; List *oidlist; @@ -1511,7 +1511,7 @@ recomputeNamespacePath(void) /* * Do nothing if path is already valid. */ - if (namespaceSearchPathValid && namespaceUser == userId) + if (namespaceSearchPathValid && namespaceUser == roleid) return; /* Need a modifiable copy of namespace_search_path string */ @@ -1542,21 +1542,21 @@ recomputeNamespacePath(void) /* $user --- substitute namespace matching user name, if any */ HeapTuple tuple; - tuple = SearchSysCache(SHADOWSYSID, - ObjectIdGetDatum(userId), + tuple = SearchSysCache(AUTHOID, + ObjectIdGetDatum(roleid), 0, 0, 0); if (HeapTupleIsValid(tuple)) { - char *uname; + char *rname; - uname = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename); + rname = NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname); namespaceId = GetSysCacheOid(NAMESPACENAME, - CStringGetDatum(uname), + CStringGetDatum(rname), 0, 0, 0); ReleaseSysCache(tuple); if (OidIsValid(namespaceId) && !list_member_oid(oidlist, namespaceId) && - pg_namespace_aclcheck(namespaceId, userId, + pg_namespace_aclcheck(namespaceId, roleid, ACL_USAGE) == ACLCHECK_OK) oidlist = lappend_oid(oidlist, namespaceId); } @@ -1569,7 +1569,7 @@ recomputeNamespacePath(void) 0, 0, 0); if (OidIsValid(namespaceId) && !list_member_oid(oidlist, namespaceId) && - pg_namespace_aclcheck(namespaceId, userId, + pg_namespace_aclcheck(namespaceId, roleid, ACL_USAGE) == ACLCHECK_OK) oidlist = lappend_oid(oidlist, namespaceId); } @@ -1622,7 +1622,7 @@ recomputeNamespacePath(void) /* Mark the path valid. */ namespaceSearchPathValid = true; - namespaceUser = userId; + namespaceUser = roleid; /* Clean up. */ pfree(rawname); @@ -1674,7 +1674,7 @@ InitTempTableNamespace(void) * that access the temp namespace for my own backend skip * permissions checks on it. */ - namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_USESYSID); + namespaceId = NamespaceCreate(namespaceName, BOOTSTRAP_SUPERUSERID); /* Advance command counter to make namespace visible */ CommandCounterIncrement(); } diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index 797583f6c04a51701857651fe1742e3c07e0d500..61a1a53902ab998e6eef43b77165e883b64b0fff 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.23 2005/05/27 00:57:49 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.24 2005/06/28 05:08:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ */ Oid ConversionCreate(const char *conname, Oid connamespace, - AclId conowner, + Oid conowner, int32 conforencoding, int32 contoencoding, Oid conproc, bool def) { @@ -95,7 +95,7 @@ ConversionCreate(const char *conname, Oid connamespace, namestrcpy(&cname, conname); values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname); values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace); - values[Anum_pg_conversion_conowner - 1] = Int32GetDatum(conowner); + values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner); values[Anum_pg_conversion_conforencoding - 1] = Int32GetDatum(conforencoding); values[Anum_pg_conversion_contoencoding - 1] = Int32GetDatum(contoencoding); values[Anum_pg_conversion_conproc - 1] = ObjectIdGetDatum(conproc); diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c index c2266f22d4dfa4fbbcd9d331dc2d138527aded4f..8144d64136b5c2bef83fe94294353ec02f91239c 100644 --- a/src/backend/catalog/pg_namespace.c +++ b/src/backend/catalog/pg_namespace.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.13 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.14 2005/06/28 05:08:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -26,7 +26,7 @@ * --------------- */ Oid -NamespaceCreate(const char *nspName, int32 ownerSysId) +NamespaceCreate(const char *nspName, Oid ownerId) { Relation nspdesc; HeapTuple tup; @@ -57,7 +57,7 @@ NamespaceCreate(const char *nspName, int32 ownerSysId) } namestrcpy(&nname, nspName); values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname); - values[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(ownerSysId); + values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId); nulls[Anum_pg_namespace_nspacl - 1] = 'n'; nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock); diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 6f50e4dabddb969fa3b5a9836cbbf437896e9887..55fa9e127cf14d2d7e91456ef8cd1a718663a0c6 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.91 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.92 2005/06/28 05:08:52 tgl Exp $ * * NOTES * these routines moved here from commands/define.c and somewhat cleaned up. @@ -235,7 +235,7 @@ OperatorShellMake(const char *operatorName, namestrcpy(&oname, operatorName); values[i++] = NameGetDatum(&oname); /* oprname */ values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */ - values[i++] = Int32GetDatum(GetUserId()); /* oprowner */ + values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */ values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */ values[i++] = BoolGetDatum(false); /* oprcanhash */ values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */ @@ -519,7 +519,7 @@ OperatorCreate(const char *operatorName, namestrcpy(&oname, operatorName); values[i++] = NameGetDatum(&oname); /* oprname */ values[i++] = ObjectIdGetDatum(operatorNamespace); /* oprnamespace */ - values[i++] = Int32GetDatum(GetUserId()); /* oprowner */ + values[i++] = ObjectIdGetDatum(GetUserId()); /* oprowner */ values[i++] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); /* oprkind */ values[i++] = BoolGetDatum(canHash); /* oprcanhash */ values[i++] = ObjectIdGetDatum(leftTypeId); /* oprleft */ diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 12f6c64634f0e874a00e3d17f34939c99e146a6e..7d1384ed382be8530fb1e9a3fa66073e1edab905 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.129 2005/05/03 16:51:00 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.130 2005/06/28 05:08:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -217,7 +217,7 @@ ProcedureCreate(const char *procedureName, namestrcpy(&procname, procedureName); values[Anum_pg_proc_proname - 1] = NameGetDatum(&procname); values[Anum_pg_proc_pronamespace - 1] = ObjectIdGetDatum(procNamespace); - values[Anum_pg_proc_proowner - 1] = Int32GetDatum(GetUserId()); + values[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(GetUserId()); values[Anum_pg_proc_prolang - 1] = ObjectIdGetDatum(languageObjectId); values[Anum_pg_proc_proisagg - 1] = BoolGetDatum(isAgg); values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer); diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index acadded40d782de1006cf62477726233dc57fdee..fa4068bf9f60b6cdf6f165cdae0c113935fc0929 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.100 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.101 2005/06/28 05:08:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -227,7 +227,7 @@ TypeCreate(const char *typeName, namestrcpy(&name, typeName); values[i++] = NameGetDatum(&name); /* typname */ values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */ - values[i++] = Int32GetDatum(GetUserId()); /* typowner */ + values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */ values[i++] = Int16GetDatum(internalSize); /* typlen */ values[i++] = BoolGetDatum(passedByValue); /* typbyval */ values[i++] = CharGetDatum(typeType); /* typtype */ diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index f757e21039d716e0a5aaef9739355e3e754868f2..d20a3b6d7f21c673620757d25d816a2bdaf448ae 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -3,9 +3,45 @@ * * Copyright (c) 1996-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.15 2005/06/18 19:33:42 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/system_views.sql,v 1.16 2005/06/28 05:08:52 tgl Exp $ */ +CREATE VIEW pg_roles AS + SELECT + rolname, + rolsuper, + rolcreaterole, + rolcreatedb, + rolcatupdate, + rolcanlogin, + '********'::text as rolpassword, + rolvaliduntil, + rolconfig + FROM pg_authid; + +CREATE VIEW pg_shadow AS + SELECT + rolname AS usename, + oid AS usesysid, + rolcreatedb AS usecreatedb, + rolsuper AS usesuper, + rolcatupdate AS usecatupd, + rolpassword AS passwd, + rolvaliduntil::abstime AS valuntil, + rolconfig AS useconfig + FROM pg_authid + WHERE rolcanlogin; + +REVOKE ALL on pg_shadow FROM public; + +CREATE VIEW pg_group AS + SELECT + rolname AS groname, + oid AS grosysid, + ARRAY(SELECT member FROM pg_auth_members WHERE roleid = oid) AS grolist + FROM pg_authid + WHERE NOT rolcanlogin; + CREATE VIEW pg_user AS SELECT usename, @@ -111,10 +147,10 @@ CREATE VIEW pg_locks AS CREATE VIEW pg_prepared_xacts AS SELECT P.transaction, P.gid, P.prepared, - U.usename AS owner, D.datname AS database + U.rolname AS owner, D.datname AS database FROM pg_prepared_xact() AS P - (transaction xid, gid text, prepared timestamptz, ownerid int4, dbid oid) - LEFT JOIN pg_shadow U ON P.ownerid = U.usesysid + (transaction xid, gid text, prepared timestamptz, ownerid oid, dbid oid) + LEFT JOIN pg_authid U ON P.ownerid = U.oid LEFT JOIN pg_database D ON P.dbid = D.oid; CREATE VIEW pg_settings AS @@ -269,7 +305,7 @@ CREATE VIEW pg_stat_activity AS D.datname AS datname, pg_stat_get_backend_pid(S.backendid) AS procpid, pg_stat_get_backend_userid(S.backendid) AS usesysid, - U.usename AS usename, + U.rolname AS usename, pg_stat_get_backend_activity(S.backendid) AS current_query, pg_stat_get_backend_activity_start(S.backendid) AS query_start, pg_stat_get_backend_start(S.backendid) AS backend_start, @@ -277,9 +313,9 @@ CREATE VIEW pg_stat_activity AS pg_stat_get_backend_client_port(S.backendid) AS client_port FROM pg_database D, (SELECT pg_stat_get_backend_idset() AS backendid) AS S, - pg_shadow U + pg_authid U WHERE pg_stat_get_backend_dbid(S.backendid) = D.oid AND - pg_stat_get_backend_userid(S.backendid) = U.usesysid; + pg_stat_get_backend_userid(S.backendid) = U.oid; CREATE VIEW pg_stat_database AS SELECT diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 9833937b705ec6189d2d744cdd000abd4bc78598..6335757981ec32eb50cee43498cab6e56393ebf1 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.26 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/aggregatecmds.c,v 1.27 2005/06/28 05:08:53 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -295,7 +295,7 @@ RenameAggregate(List *name, TypeName *basetype, const char *newname) * Change aggregate owner */ void -AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) +AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId) { Oid basetypeOid; Oid procOid; @@ -329,7 +329,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (procForm->proowner != newOwnerSysId) + if (procForm->proowner != newOwnerId) { /* Otherwise, must be superuser to change object ownership */ if (!superuser()) @@ -341,7 +341,7 @@ AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId) * Modify the owner --- okay to scribble on tup because it's a * copy */ - procForm->proowner = newOwnerSysId; + procForm->proowner = newOwnerId; simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 9bb40f351649531450827925231dc0d3b1220745..a19b500152da82fb2666c0f1964da076a75fae8e 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.12 2004/12/31 21:59:41 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.13 2005/06/28 05:08:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -64,10 +64,6 @@ ExecRenameStmt(RenameStmt *stmt) RenameFunction(stmt->object, stmt->objarg, stmt->newname); break; - case OBJECT_GROUP: - RenameGroup(stmt->subname, stmt->newname); - break; - case OBJECT_LANGUAGE: RenameLanguage(stmt->subname, stmt->newname); break; @@ -76,6 +72,10 @@ ExecRenameStmt(RenameStmt *stmt) RenameOpClass(stmt->object, stmt->subname, stmt->newname); break; + case OBJECT_ROLE: + RenameRole(stmt->subname, stmt->newname); + break; + case OBJECT_SCHEMA: RenameSchema(stmt->subname, stmt->newname); break; @@ -84,10 +84,6 @@ ExecRenameStmt(RenameStmt *stmt) RenameTableSpace(stmt->subname, stmt->newname); break; - case OBJECT_USER: - RenameUser(stmt->subname, stmt->newname); - break; - case OBJECT_TABLE: case OBJECT_INDEX: case OBJECT_COLUMN: @@ -153,7 +149,7 @@ ExecRenameStmt(RenameStmt *stmt) void ExecAlterOwnerStmt(AlterOwnerStmt *stmt) { - AclId newowner = get_usesysid(stmt->newowner); + Oid newowner = get_roleid_checked(stmt->newowner); switch (stmt->objectType) { diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index fb71bf59f92f6660910d49f6105390d7d7656fa5..c2aa48614e6afbab43ae6febb0963db42f42149a 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.18 2005/05/03 19:17:59 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.19 2005/06/28 05:08:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -175,7 +175,7 @@ RenameConversion(List *name, const char *newname) * Change conversion owner */ void -AlterConversionOwner(List *name, AclId newOwnerSysId) +AlterConversionOwner(List *name, Oid newOwnerId) { Oid conversionOid; HeapTuple tup; @@ -203,7 +203,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (convForm->conowner != newOwnerSysId) + if (convForm->conowner != newOwnerId) { /* Otherwise, must be superuser to change object ownership */ if (!superuser()) @@ -215,7 +215,7 @@ AlterConversionOwner(List *name, AclId newOwnerSysId) * Modify the owner --- okay to scribble on tup because it's a * copy */ - convForm->conowner = newOwnerSysId; + convForm->conowner = newOwnerId; simple_heap_update(rel, &tup->t_self, tup); diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 30eeefded8e4e1d6deeafb72a59208e64d644ecf..10e68684b8e6e62f3e141b6a05da72f4eb8e1637 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.245 2005/06/02 01:21:22 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.246 2005/06/28 05:08:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -25,7 +25,6 @@ #include "catalog/index.h" #include "catalog/namespace.h" #include "catalog/pg_index.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_type.h" #include "commands/copy.h" #include "commands/trigger.h" diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 6fa6aa5b44bacc07063b7772b7ae73952c7a70bd..1dac14ead2e6ad0285ca51adc84d8c8907adae9a 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -15,7 +15,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.161 2005/06/25 22:47:29 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.162 2005/06/28 05:08:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -28,10 +28,10 @@ #include "access/genam.h" #include "access/heapam.h" #include "catalog/catalog.h" +#include "catalog/indexing.h" +#include "catalog/pg_authid.h" #include "catalog/pg_database.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_tablespace.h" -#include "catalog/indexing.h" #include "commands/comment.h" #include "commands/dbcommands.h" #include "commands/tablespace.h" @@ -52,7 +52,7 @@ /* non-export function prototypes */ -static bool get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, +static bool get_db_info(const char *name, Oid *dbIdP, Oid *ownerIdP, int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, Oid *dbLastSysOidP, TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP, @@ -70,7 +70,7 @@ createdb(const CreatedbStmt *stmt) HeapScanDesc scan; Relation rel; Oid src_dboid; - AclId src_owner; + Oid src_owner; int src_encoding; bool src_istemplate; bool src_allowconn; @@ -85,7 +85,7 @@ createdb(const CreatedbStmt *stmt) Datum new_record[Natts_pg_database]; char new_record_nulls[Natts_pg_database]; Oid dboid; - AclId datdba; + Oid datdba; ListCell *option; DefElem *dtablespacename = NULL; DefElem *downer = NULL; @@ -186,13 +186,13 @@ createdb(const CreatedbStmt *stmt) nodeTag(dencoding->arg)); } - /* obtain sysid of proposed owner */ + /* obtain OID of proposed owner */ if (dbowner) - datdba = get_usesysid(dbowner); /* will ereport if no such user */ + datdba = get_roleid_checked(dbowner); else datdba = GetUserId(); - if (datdba == GetUserId()) + if (is_member_of_role(GetUserId(), datdba)) { /* creating database for self: can be superuser or createdb */ if (!superuser() && !have_createdb_privilege()) @@ -243,7 +243,7 @@ createdb(const CreatedbStmt *stmt) */ if (!src_istemplate) { - if (!superuser() && GetUserId() != src_owner) + if (!pg_database_ownercheck(src_dboid, GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to copy database \"%s\"", @@ -483,7 +483,7 @@ createdb(const CreatedbStmt *stmt) new_record[Anum_pg_database_datname - 1] = DirectFunctionCall1(namein, CStringGetDatum(dbname)); - new_record[Anum_pg_database_datdba - 1] = Int32GetDatum(datdba); + new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba); new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding); new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false); new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true); @@ -557,9 +557,8 @@ createdb(const CreatedbStmt *stmt) void dropdb(const char *dbname) { - int4 db_owner; - bool db_istemplate; Oid db_id; + bool db_istemplate; Relation pgdbrel; SysScanDesc pgdbscan; ScanKeyData key; @@ -588,13 +587,13 @@ dropdb(const char *dbname) */ pgdbrel = heap_open(DatabaseRelationId, ExclusiveLock); - if (!get_db_info(dbname, &db_id, &db_owner, NULL, + if (!get_db_info(dbname, &db_id, NULL, NULL, &db_istemplate, NULL, NULL, NULL, NULL, NULL)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", dbname))); - if (GetUserId() != db_owner && !superuser()) + if (!pg_database_ownercheck(db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, dbname); @@ -818,8 +817,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", stmt->dbname))); - if (!(superuser() - || ((Form_pg_database) GETSTRUCT(tuple))->datdba == GetUserId())) + if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, stmt->dbname); @@ -878,7 +876,7 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt) * ALTER DATABASE name OWNER TO newowner */ void -AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) +AlterDatabaseOwner(const char *dbname, Oid newOwnerId) { HeapTuple tuple; Relation rel; @@ -910,7 +908,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) * command to have succeeded. This is to be consistent with other * objects. */ - if (datForm->datdba != newOwnerSysId) + if (datForm->datdba != newOwnerId) { Datum repl_val[Natts_pg_database]; char repl_null[Natts_pg_database]; @@ -930,7 +928,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) memset(repl_repl, ' ', sizeof(repl_repl)); repl_repl[Anum_pg_database_datdba - 1] = 'r'; - repl_val[Anum_pg_database_datdba - 1] = Int32GetDatum(newOwnerSysId); + repl_val[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(newOwnerId); /* * Determine the modified ACL for the new owner. This is only @@ -943,7 +941,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) if (!isNull) { newAcl = aclnewowner(DatumGetAclP(aclDatum), - datForm->datdba, newOwnerSysId); + datForm->datdba, newOwnerId); repl_repl[Anum_pg_database_datacl - 1] = 'r'; repl_val[Anum_pg_database_datacl - 1] = PointerGetDatum(newAcl); } @@ -972,7 +970,7 @@ AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId) */ static bool -get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, +get_db_info(const char *name, Oid *dbIdP, Oid *ownerIdP, int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, Oid *dbLastSysOidP, TransactionId *dbVacuumXidP, TransactionId *dbFrozenXidP, @@ -1007,7 +1005,7 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP, /* oid of the database */ if (dbIdP) *dbIdP = HeapTupleGetOid(tuple); - /* sysid of the owner */ + /* oid of the owner */ if (ownerIdP) *ownerIdP = dbform->datdba; /* character encoding */ @@ -1046,12 +1044,12 @@ have_createdb_privilege(void) bool result = false; HeapTuple utup; - utup = SearchSysCache(SHADOWSYSID, - Int32GetDatum(GetUserId()), + utup = SearchSysCache(AUTHOID, + ObjectIdGetDatum(GetUserId()), 0, 0, 0); if (HeapTupleIsValid(utup)) { - result = ((Form_pg_shadow) GETSTRUCT(utup))->usecreatedb; + result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreatedb; ReleaseSysCache(utup); } return result; diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index ea3c381183713a8745a50cbe0567dbd0f32f46e1..3329822fe623e6a8df678a264d0f86c07d1fc62e 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.61 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.62 2005/06/28 05:08:53 tgl Exp $ * * DESCRIPTION * These routines take the parse tree and pick out the @@ -853,7 +853,7 @@ RenameFunction(List *name, List *argtypes, const char *newname) * Change function owner */ void -AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId) +AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) { Oid procOid; HeapTuple tup; @@ -882,7 +882,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (procForm->proowner != newOwnerSysId) + if (procForm->proowner != newOwnerId) { Datum repl_val[Natts_pg_proc]; char repl_null[Natts_pg_proc]; @@ -902,7 +902,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId) memset(repl_repl, ' ', sizeof(repl_repl)); repl_repl[Anum_pg_proc_proowner - 1] = 'r'; - repl_val[Anum_pg_proc_proowner - 1] = Int32GetDatum(newOwnerSysId); + repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwnerId); /* * Determine the modified ACL for the new owner. This is only @@ -914,7 +914,7 @@ AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId) if (!isNull) { newAcl = aclnewowner(DatumGetAclP(aclDatum), - procForm->proowner, newOwnerSysId); + procForm->proowner, newOwnerId); repl_repl[Anum_pg_proc_proacl - 1] = 'r'; repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl); } diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index e64924c43a7385b31fc54fcd9e6c368d4bc7f9f9..3610269644a47eebede50bff8072a749b7194771 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.32 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.33 2005/06/28 05:08:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -321,7 +321,7 @@ DefineOpClass(CreateOpClassStmt *stmt) namestrcpy(&opcName, opcname); values[i++] = NameGetDatum(&opcName); /* opcname */ values[i++] = ObjectIdGetDatum(namespaceoid); /* opcnamespace */ - values[i++] = Int32GetDatum(GetUserId()); /* opcowner */ + values[i++] = ObjectIdGetDatum(GetUserId()); /* opcowner */ values[i++] = ObjectIdGetDatum(typeoid); /* opcintype */ values[i++] = BoolGetDatum(stmt->isDefault); /* opcdefault */ values[i++] = ObjectIdGetDatum(storageoid); /* opckeytype */ @@ -880,7 +880,7 @@ RenameOpClass(List *name, const char *access_method, const char *newname) * Change opclass owner */ void -AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId) +AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId) { Oid opcOid; Oid amOid; @@ -945,7 +945,7 @@ AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (opcForm->opcowner != newOwnerSysId) + if (opcForm->opcowner != newOwnerId) { /* Otherwise, must be superuser to change object ownership */ if (!superuser()) @@ -957,7 +957,7 @@ AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId) * Modify the owner --- okay to scribble on tup because it's a * copy */ - opcForm->opcowner = newOwnerSysId; + opcForm->opcowner = newOwnerId; simple_heap_update(rel, &tup->t_self, tup); diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 45dc1eafeaa427a58f7f60b89a0e2cc53cf3baf4..adea1b2b5d737a41694b1ecb1c7ca9e60304bfb2 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.21 2005/04/14 20:03:24 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.22 2005/06/28 05:08:54 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -269,7 +269,7 @@ RemoveOperatorById(Oid operOid) */ void AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, - AclId newOwnerSysId) + Oid newOwnerId) { Oid operOid; HeapTuple tup; @@ -293,7 +293,7 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (oprForm->oprowner != newOwnerSysId) + if (oprForm->oprowner != newOwnerId) { /* Otherwise, must be superuser to change object ownership */ if (!superuser()) @@ -305,7 +305,7 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, * Modify the owner --- okay to scribble on tup because it's a * copy */ - oprForm->oprowner = newOwnerSysId; + oprForm->oprowner = newOwnerId; simple_heap_update(rel, &tup->t_self, tup); diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 5754c1dfcb4f8da5d3d0baf87d9908b89d15c8cf..d92812f1fcfc4994a8170795799fc5ffcebd0fb9 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.30 2005/06/21 00:58:15 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.31 2005/06/28 05:08:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -42,11 +42,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) Oid namespaceId; List *parsetree_list; ListCell *parsetree_item; - AclId owner_userid; - AclId saved_userid; + Oid owner_uid; + Oid saved_uid; AclResult aclresult; - saved_userid = GetUserId(); + saved_uid = GetUserId(); /* * Figure out user identities. @@ -54,12 +54,11 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) if (!authId) { - owner_userid = saved_userid; + owner_uid = saved_uid; } else if (superuser()) { - /* The following will error out if user does not exist */ - owner_userid = get_usesysid(authId); + owner_uid = get_roleid_checked(authId); /* * Set the current user to the requested authorization so that @@ -67,15 +66,15 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) * (This will revert to session user on error or at the end of * this routine.) */ - SetUserId(owner_userid); + SetUserId(owner_uid); } else { const char *owner_name; /* not superuser */ - owner_userid = saved_userid; - owner_name = GetUserNameFromId(owner_userid); + owner_uid = saved_uid; + owner_name = GetUserNameFromId(owner_uid); if (strcmp(authId, owner_name) != 0) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), @@ -87,7 +86,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) /* * Permissions checks. */ - aclresult = pg_database_aclcheck(MyDatabaseId, saved_userid, ACL_CREATE); + aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_DATABASE, get_database_name(MyDatabaseId)); @@ -99,7 +98,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) errdetail("The prefix \"pg_\" is reserved for system schemas."))); /* Create the schema's namespace */ - namespaceId = NamespaceCreate(schemaName, owner_userid); + namespaceId = NamespaceCreate(schemaName, owner_uid); /* Advance cmd counter to make the namespace visible */ CommandCounterIncrement(); @@ -149,7 +148,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt) PopSpecialNamespace(namespaceId); /* Reset current user */ - SetUserId(saved_userid); + SetUserId(saved_uid); } @@ -279,7 +278,7 @@ RenameSchema(const char *oldname, const char *newname) * Change schema owner */ void -AlterSchemaOwner(const char *name, AclId newOwnerSysId) +AlterSchemaOwner(const char *name, Oid newOwnerId) { HeapTuple tup; Relation rel; @@ -300,7 +299,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (nspForm->nspowner != newOwnerSysId) + if (nspForm->nspowner != newOwnerId) { Datum repl_val[Natts_pg_namespace]; char repl_null[Natts_pg_namespace]; @@ -320,7 +319,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId) memset(repl_repl, ' ', sizeof(repl_repl)); repl_repl[Anum_pg_namespace_nspowner - 1] = 'r'; - repl_val[Anum_pg_namespace_nspowner - 1] = Int32GetDatum(newOwnerSysId); + repl_val[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(newOwnerId); /* * Determine the modified ACL for the new owner. This is only @@ -332,7 +331,7 @@ AlterSchemaOwner(const char *name, AclId newOwnerSysId) if (!isNull) { newAcl = aclnewowner(DatumGetAclP(aclDatum), - nspForm->nspowner, newOwnerSysId); + nspForm->nspowner, newOwnerId); repl_repl[Anum_pg_namespace_nspacl - 1] = 'r'; repl_val[Anum_pg_namespace_nspacl - 1] = PointerGetDatum(newAcl); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 9981129c0ebf579b7d3441c77aab25e39b30ca4a..dda9532baf857b6721cafcecdc6581f75bd9488c 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.161 2005/06/06 20:22:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.162 2005/06/28 05:08:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -231,9 +231,9 @@ static void ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, const char *colName, TypeName *typename); static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab); static void ATPostAlterTypeParse(char *cmd, List **wqueue); -static void ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId); +static void ATExecChangeOwner(Oid relationOid, Oid newOwnerId); static void change_owner_recurse_to_sequences(Oid relationOid, - int32 newOwnerSysId); + Oid newOwnerId); static void ATExecClusterOn(Relation rel, const char *indexName); static void ATExecDropCluster(Relation rel); static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, @@ -2133,8 +2133,8 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd) AlterTableCreateToastTable(RelationGetRelid(rel), false); break; case AT_ChangeOwner: /* ALTER OWNER */ - /* get_usesysid raises an error if no such user */ - ATExecChangeOwner(RelationGetRelid(rel), get_usesysid(cmd->name)); + ATExecChangeOwner(RelationGetRelid(rel), + get_roleid_checked(cmd->name)); break; case AT_ClusterOn: /* CLUSTER ON */ ATExecClusterOn(rel, cmd->name); @@ -5233,7 +5233,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue) * ALTER TABLE OWNER */ static void -ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) +ATExecChangeOwner(Oid relationOid, Oid newOwnerId) { Relation target_rel; Relation class_rel; @@ -5277,7 +5277,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (tuple_class->relowner != newOwnerSysId) + if (tuple_class->relowner != newOwnerId) { Datum repl_val[Natts_pg_class]; char repl_null[Natts_pg_class]; @@ -5297,7 +5297,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) memset(repl_repl, ' ', sizeof(repl_repl)); repl_repl[Anum_pg_class_relowner - 1] = 'r'; - repl_val[Anum_pg_class_relowner - 1] = Int32GetDatum(newOwnerSysId); + repl_val[Anum_pg_class_relowner - 1] = ObjectIdGetDatum(newOwnerId); /* * Determine the modified ACL for the new owner. This is only @@ -5309,7 +5309,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) if (!isNull) { newAcl = aclnewowner(DatumGetAclP(aclDatum), - tuple_class->relowner, newOwnerSysId); + tuple_class->relowner, newOwnerId); repl_repl[Anum_pg_class_relacl - 1] = 'r'; repl_val[Anum_pg_class_relacl - 1] = PointerGetDatum(newAcl); } @@ -5337,7 +5337,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) /* For each index, recursively change its ownership */ foreach(i, index_oid_list) - ATExecChangeOwner(lfirst_oid(i), newOwnerSysId); + ATExecChangeOwner(lfirst_oid(i), newOwnerId); list_free(index_oid_list); } @@ -5346,10 +5346,10 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) { /* If it has a toast table, recurse to change its ownership */ if (tuple_class->reltoastrelid != InvalidOid) - ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerSysId); + ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId); /* If it has dependent sequences, recurse to change them too */ - change_owner_recurse_to_sequences(relationOid, newOwnerSysId); + change_owner_recurse_to_sequences(relationOid, newOwnerId); } } @@ -5366,7 +5366,7 @@ ATExecChangeOwner(Oid relationOid, int32 newOwnerSysId) * ownership. */ static void -change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId) +change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId) { Relation depRel; SysScanDesc scan; @@ -5416,7 +5416,7 @@ change_owner_recurse_to_sequences(Oid relationOid, int32 newOwnerSysId) } /* We don't need to close the sequence while we alter it. */ - ATExecChangeOwner(depForm->objid, newOwnerSysId); + ATExecChangeOwner(depForm->objid, newOwnerId); /* Now we can close it. Keep the lock till end of transaction. */ relation_close(seqRel, NoLock); diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index a469a8fa349ff43bb726eb19625b22aa7964bb9d..15a263b8efd2a7aaad5718979d4b0ce54719e66a 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.22 2005/06/19 21:34:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.23 2005/06/28 05:08:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -208,7 +208,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) Oid tablespaceoid; char *location; char *linkloc; - AclId ownerid; + Oid ownerId; /* validate */ @@ -225,12 +225,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) /* However, the eventual owner of the tablespace need not be */ if (stmt->owner) - { - /* No need to check result, get_usesysid() does that */ - ownerid = get_usesysid(stmt->owner); - } + ownerId = get_roleid_checked(stmt->owner); else - ownerid = GetUserId(); + ownerId = GetUserId(); /* Unix-ify the offered path, and strip any trailing slashes */ location = pstrdup(stmt->location); @@ -297,7 +294,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) values[Anum_pg_tablespace_spcname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename)); values[Anum_pg_tablespace_spcowner - 1] = - Int32GetDatum(ownerid); + ObjectIdGetDatum(ownerId); values[Anum_pg_tablespace_spclocation - 1] = DirectFunctionCall1(textin, CStringGetDatum(location)); nulls[Anum_pg_tablespace_spcacl - 1] = 'n'; @@ -426,9 +423,8 @@ DropTableSpace(DropTableSpaceStmt *stmt) tablespaceoid = HeapTupleGetOid(tuple); - /* Must be superuser or owner */ - if (GetUserId() != ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner && - !superuser()) + /* Must be tablespace owner */ + if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, tablespacename); @@ -711,8 +707,8 @@ RenameTableSpace(const char *oldname, const char *newname) heap_endscan(scan); - /* Must be owner or superuser */ - if (newform->spcowner != GetUserId() && !superuser()) + /* Must be owner */ + if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId())) aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_TABLESPACE, oldname); /* Validate new name */ @@ -750,7 +746,7 @@ RenameTableSpace(const char *oldname, const char *newname) * Change tablespace owner */ void -AlterTableSpaceOwner(const char *name, AclId newOwnerSysId) +AlterTableSpaceOwner(const char *name, Oid newOwnerId) { Relation rel; ScanKeyData entry[1]; @@ -778,7 +774,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (spcForm->spcowner != newOwnerSysId) + if (spcForm->spcowner != newOwnerId) { Datum repl_val[Natts_pg_tablespace]; char repl_null[Natts_pg_tablespace]; @@ -798,7 +794,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId) memset(repl_repl, ' ', sizeof(repl_repl)); repl_repl[Anum_pg_tablespace_spcowner - 1] = 'r'; - repl_val[Anum_pg_tablespace_spcowner - 1] = Int32GetDatum(newOwnerSysId); + repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwnerId); /* * Determine the modified ACL for the new owner. This is only @@ -811,7 +807,7 @@ AlterTableSpaceOwner(const char *name, AclId newOwnerSysId) if (!isNull) { newAcl = aclnewowner(DatumGetAclP(aclDatum), - spcForm->spcowner, newOwnerSysId); + spcForm->spcowner, newOwnerId); repl_repl[Anum_pg_tablespace_spcacl - 1] = 'r'; repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl); } diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 280022feaa1e45e6902f61123ca5e029e1770187..53570c77409bc13498d80b6e1de73678dc266a92 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.72 2005/05/06 17:24:53 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.73 2005/06/28 05:08:54 tgl Exp $ * * DESCRIPTION * The "DefineFoo" routines take the parse tree and pick out the @@ -2016,7 +2016,7 @@ GetDomainConstraints(Oid typeOid) * Change the owner of a type. */ void -AlterTypeOwner(List *names, AclId newOwnerSysId) +AlterTypeOwner(List *names, Oid newOwnerId) { TypeName *typename; Oid typeOid; @@ -2063,7 +2063,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId) * If the new owner is the same as the existing owner, consider the * command to have succeeded. This is for dump restoration purposes. */ - if (typTup->typowner != newOwnerSysId) + if (typTup->typowner != newOwnerId) { /* Otherwise, must be superuser to change object ownership */ if (!superuser()) @@ -2075,7 +2075,7 @@ AlterTypeOwner(List *names, AclId newOwnerSysId) * Modify the owner --- okay to scribble on typTup because it's a * copy */ - typTup->typowner = newOwnerSysId; + typTup->typowner = newOwnerId; simple_heap_update(rel, &tup->t_self, tup); diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 3c70c579785e6fb27b905313e6cfe4dd3da2fa77..131f1896f928c563d39e4ddae58693eff2803799 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -1,12 +1,12 @@ /*------------------------------------------------------------------------- * * user.c - * Commands for manipulating users and groups. + * Commands for manipulating roles (formerly called users). * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.151 2005/04/14 20:03:24 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.152 2005/06/28 05:08:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -14,15 +14,14 @@ #include "access/heapam.h" #include "catalog/indexing.h" +#include "catalog/pg_auth_members.h" +#include "catalog/pg_authid.h" #include "catalog/pg_database.h" -#include "catalog/pg_group.h" -#include "catalog/pg_shadow.h" -#include "catalog/pg_type.h" #include "commands/user.h" #include "libpq/crypt.h" #include "miscadmin.h" -#include "utils/acl.h" #include "utils/builtins.h" +#include "utils/catcache.h" #include "utils/flatfiles.h" #include "utils/fmgroids.h" #include "utils/guc.h" @@ -32,46 +31,46 @@ extern bool Password_encryption; - -static void CheckPgUserAclNotNull(void); -static void UpdateGroupMembership(Relation group_rel, HeapTuple group_tuple, - List *members); -static IdList *IdListToArray(List *members); -static List *IdArrayToList(IdList *oldarray); +static List *roleNamesToIds(List *memberNames); +static void AddRoleMems(const char *rolename, Oid roleid, + List *memberNames, List *memberIds, + Oid grantorId, bool admin_opt); +static void DelRoleMems(const char *rolename, Oid roleid, + List *memberNames, List *memberIds, + bool admin_opt); /* - * CREATE USER + * CREATE ROLE */ void -CreateUser(CreateUserStmt *stmt) +CreateRole(CreateRoleStmt *stmt) { - Relation pg_shadow_rel; - TupleDesc pg_shadow_dsc; - HeapScanDesc scan; + Relation pg_authid_rel; + TupleDesc pg_authid_dsc; HeapTuple tuple; - Datum new_record[Natts_pg_shadow]; - char new_record_nulls[Natts_pg_shadow]; - bool user_exists = false, - sysid_exists = false, - havesysid = false; - int max_id; + Datum new_record[Natts_pg_authid]; + char new_record_nulls[Natts_pg_authid]; + Oid roleid; ListCell *item; ListCell *option; - char *password = NULL; /* PostgreSQL user password */ + char *password = NULL; /* user password */ bool encrypt_password = Password_encryption; /* encrypt password? */ char encrypted_password[MD5_PASSWD_LEN + 1]; - int sysid = 0; /* PgSQL system id (valid if havesysid) */ + bool issuper = false; /* Make the user a superuser? */ + bool createrole = false; /* Can this user create roles? */ bool createdb = false; /* Can the user create databases? */ - bool createuser = false; /* Can this user create users? */ - List *groupElts = NIL; /* The groups the user is a member of */ + bool canlogin = false; /* Can this user login? */ + List *roleElts = NIL; /* roles the user is a member of */ + List *rolememElts = NIL; /* roles which will be members of this role */ char *validUntil = NULL; /* The time the login is valid * until */ DefElem *dpassword = NULL; - DefElem *dsysid = NULL; DefElem *dcreatedb = NULL; - DefElem *dcreateuser = NULL; - DefElem *dgroupElts = NULL; + DefElem *dcreaterole = NULL; + DefElem *dcanlogin = NULL; + DefElem *droleElts = NULL; + DefElem *drolememElts = NULL; DefElem *dvalidUntil = NULL; /* Extract options from the statement node tree */ @@ -95,11 +94,16 @@ CreateUser(CreateUserStmt *stmt) } else if (strcmp(defel->defname, "sysid") == 0) { - if (dsysid) + ereport(WARNING, + (errmsg("SYSID can no longer be specified"))); + } + else if (strcmp(defel->defname, "createrole") == 0) + { + if (dcreaterole) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); - dsysid = defel; + dcreaterole = defel; } else if (strcmp(defel->defname, "createdb") == 0) { @@ -109,21 +113,29 @@ CreateUser(CreateUserStmt *stmt) errmsg("conflicting or redundant options"))); dcreatedb = defel; } - else if (strcmp(defel->defname, "createuser") == 0) + else if (strcmp(defel->defname, "canlogin") == 0) { - if (dcreateuser) + if (dcanlogin) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); - dcreateuser = defel; + dcanlogin = defel; } - else if (strcmp(defel->defname, "groupElts") == 0) + else if (strcmp(defel->defname, "roleElts") == 0) { - if (dgroupElts) + if (droleElts) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); - dgroupElts = defel; + droleElts = defel; + } + else if (strcmp(defel->defname, "rolememElts") == 0) + { + if (drolememElts) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + drolememElts = defel; } else if (strcmp(defel->defname, "validUntil") == 0) { @@ -140,83 +152,51 @@ CreateUser(CreateUserStmt *stmt) if (dcreatedb) createdb = intVal(dcreatedb->arg) != 0; - if (dcreateuser) - createuser = intVal(dcreateuser->arg) != 0; - if (dsysid) + if (dcreaterole) { - sysid = intVal(dsysid->arg); - if (sysid <= 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("user ID must be positive"))); - havesysid = true; + createrole = intVal(dcreaterole->arg) != 0; + /* XXX issuper is implied by createrole for now */ + issuper = createrole; } + if (dcanlogin) + canlogin = intVal(dcanlogin->arg) != 0; if (dvalidUntil) validUntil = strVal(dvalidUntil->arg); if (dpassword) password = strVal(dpassword->arg); - if (dgroupElts) - groupElts = (List *) dgroupElts->arg; + if (droleElts) + roleElts = (List *) droleElts->arg; + if (drolememElts) + rolememElts = (List *) drolememElts->arg; /* Check some permissions first */ - if (password) - CheckPgUserAclNotNull(); - if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to create users"))); + errmsg("must be superuser to create roles"))); - if (strcmp(stmt->user, "public") == 0) + if (strcmp(stmt->role, "public") == 0) ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), - errmsg("user name \"%s\" is reserved", - stmt->user))); + errmsg("role name \"%s\" is reserved", + stmt->role))); /* - * Scan the pg_shadow relation to be certain the user or id doesn't - * already exist. Note we secure exclusive lock, because we also need - * to be sure of what the next usesysid should be, and we need to - * protect our eventual update of the flat password file. + * Check the pg_authid relation to be certain the role doesn't + * already exist. Note we secure exclusive lock because + * we need to protect our eventual update of the flat auth file. */ - pg_shadow_rel = heap_open(ShadowRelationId, ExclusiveLock); - pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); - - scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL); - max_id = 99; /* start auto-assigned ids at 100 */ - while (!user_exists && !sysid_exists && - (tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - Form_pg_shadow shadow_form = (Form_pg_shadow) GETSTRUCT(tuple); - int32 this_sysid; - - user_exists = (strcmp(NameStr(shadow_form->usename), stmt->user) == 0); - - this_sysid = shadow_form->usesysid; - if (havesysid) /* customized id wanted */ - sysid_exists = (this_sysid == sysid); - else - { - /* pick 1 + max */ - if (this_sysid > max_id) - max_id = this_sysid; - } - } - heap_endscan(scan); + pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock); + pg_authid_dsc = RelationGetDescr(pg_authid_rel); - if (user_exists) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("user \"%s\" already exists", - stmt->user))); - if (sysid_exists) + tuple = SearchSysCache(AUTHNAME, + PointerGetDatum(stmt->role), + 0, 0, 0); + if (HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("user ID %d is already assigned", sysid))); - - /* If no sysid given, use max existing id + 1 */ - if (!havesysid) - sysid = max_id + 1; + errmsg("role \"%s\" already exists", + stmt->role))); /* * Build a tuple to insert @@ -224,105 +204,123 @@ CreateUser(CreateUserStmt *stmt) MemSet(new_record, 0, sizeof(new_record)); MemSet(new_record_nulls, ' ', sizeof(new_record_nulls)); - new_record[Anum_pg_shadow_usename - 1] = - DirectFunctionCall1(namein, CStringGetDatum(stmt->user)); - new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(sysid); - AssertState(BoolIsValid(createdb)); - new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb); - AssertState(BoolIsValid(createuser)); - new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser); - /* superuser gets catupd right by default */ - new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser); + new_record[Anum_pg_authid_rolname - 1] = + DirectFunctionCall1(namein, CStringGetDatum(stmt->role)); + + new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper); + new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole); + new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb); + /* superuser gets catupdate right by default */ + new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper); + new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin); if (password) { if (!encrypt_password || isMD5(password)) - new_record[Anum_pg_shadow_passwd - 1] = + new_record[Anum_pg_authid_rolpassword - 1] = DirectFunctionCall1(textin, CStringGetDatum(password)); else { - if (!EncryptMD5(password, stmt->user, strlen(stmt->user), + if (!EncryptMD5(password, stmt->role, strlen(stmt->role), encrypted_password)) elog(ERROR, "password encryption failed"); - new_record[Anum_pg_shadow_passwd - 1] = + new_record[Anum_pg_authid_rolpassword - 1] = DirectFunctionCall1(textin, CStringGetDatum(encrypted_password)); } } else - new_record_nulls[Anum_pg_shadow_passwd - 1] = 'n'; + new_record_nulls[Anum_pg_authid_rolpassword - 1] = 'n'; if (validUntil) - new_record[Anum_pg_shadow_valuntil - 1] = - DirectFunctionCall1(abstimein, CStringGetDatum(validUntil)); + new_record[Anum_pg_authid_rolvaliduntil - 1] = + DirectFunctionCall3(timestamptz_in, + CStringGetDatum(validUntil), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + else - new_record_nulls[Anum_pg_shadow_valuntil - 1] = 'n'; + new_record_nulls[Anum_pg_authid_rolvaliduntil - 1] = 'n'; - new_record_nulls[Anum_pg_shadow_useconfig - 1] = 'n'; + new_record_nulls[Anum_pg_authid_rolconfig - 1] = 'n'; - tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls); + tuple = heap_formtuple(pg_authid_dsc, new_record, new_record_nulls); /* - * Insert new record in the pg_shadow table + * Insert new record in the pg_authid table */ - simple_heap_insert(pg_shadow_rel, tuple); + roleid = simple_heap_insert(pg_authid_rel, tuple); + Assert(OidIsValid(roleid)); /* Update indexes */ - CatalogUpdateIndexes(pg_shadow_rel, tuple); + CatalogUpdateIndexes(pg_authid_rel, tuple); /* - * Add the user to the groups specified. We'll just call the below - * AlterGroup for this. + * Add the new role to the specified existing roles. */ - foreach(item, groupElts) + foreach(item, roleElts) { - AlterGroupStmt ags; + char *oldrolename = strVal(lfirst(item)); + Oid oldroleid = get_roleid_checked(oldrolename); - ags.name = strVal(lfirst(item)); /* the group name to add - * this in */ - ags.action = +1; - ags.listUsers = list_make1(makeInteger(sysid)); - AlterGroup(&ags, "CREATE USER"); + AddRoleMems(oldrolename, oldroleid, + list_make1(makeString(stmt->role)), + list_make1_oid(roleid), + GetUserId(), false); } + /* + * Add the specified members to this new role. + */ + AddRoleMems(stmt->role, roleid, + rolememElts, roleNamesToIds(rolememElts), + GetUserId(), false); + /* * Now we can clean up; but keep lock until commit (to avoid possible * deadlock when commit code tries to acquire lock). */ - heap_close(pg_shadow_rel, NoLock); + heap_close(pg_authid_rel, NoLock); /* - * Set flag to update flat password file at commit. + * Set flag to update flat auth file at commit. */ - user_file_update_needed(); + auth_file_update_needed(); } - /* - * ALTER USER + * ALTER ROLE */ void -AlterUser(AlterUserStmt *stmt) +AlterRole(AlterRoleStmt *stmt) { - Datum new_record[Natts_pg_shadow]; - char new_record_nulls[Natts_pg_shadow]; - char new_record_repl[Natts_pg_shadow]; - Relation pg_shadow_rel; - TupleDesc pg_shadow_dsc; + Datum new_record[Natts_pg_authid]; + char new_record_nulls[Natts_pg_authid]; + char new_record_repl[Natts_pg_authid]; + Relation pg_authid_rel; + TupleDesc pg_authid_dsc; HeapTuple tuple, new_tuple; ListCell *option; - char *password = NULL; /* PostgreSQL user password */ + char *password = NULL; /* user password */ bool encrypt_password = Password_encryption; /* encrypt password? */ char encrypted_password[MD5_PASSWD_LEN + 1]; - int createdb = -1; /* Can the user create databases? */ - int createuser = -1; /* Can this user create users? */ + int issuper = -1; /* Make the user a superuser? */ + int createrole = -1; /* Can this user create roles? */ + int createdb = -1; /* Can the user create databases? */ + int canlogin = -1; /* Can this user login? */ + int adminopt = 0; /* Can this user grant this role to others? */ + List *rolememElts = NIL; /* The roles which will be added/removed to this role */ char *validUntil = NULL; /* The time the login is valid * until */ DefElem *dpassword = NULL; DefElem *dcreatedb = NULL; - DefElem *dcreateuser = NULL; + DefElem *dcreaterole = NULL; + DefElem *dcanlogin = NULL; + DefElem *dadminopt = NULL; DefElem *dvalidUntil = NULL; + DefElem *drolememElts = NULL; + Oid roleid; /* Extract options from the statement node tree */ foreach(option, stmt->options) @@ -351,13 +349,29 @@ AlterUser(AlterUserStmt *stmt) errmsg("conflicting or redundant options"))); dcreatedb = defel; } - else if (strcmp(defel->defname, "createuser") == 0) + else if (strcmp(defel->defname, "createrole") == 0) { - if (dcreateuser) + if (dcreaterole) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); - dcreateuser = defel; + dcreaterole = defel; + } + else if (strcmp(defel->defname, "canlogin") == 0) + { + if (dcanlogin) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + dcanlogin = defel; + } + else if (strcmp(defel->defname, "adminopt") == 0) + { + if (dadminopt) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + dadminopt = defel; } else if (strcmp(defel->defname, "validUntil") == 0) { @@ -367,6 +381,14 @@ AlterUser(AlterUserStmt *stmt) errmsg("conflicting or redundant options"))); dvalidUntil = defel; } + else if (strcmp(defel->defname, "rolememElts") == 0 && stmt->action != 0) + { + if (drolememElts) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + drolememElts = defel; + } else elog(ERROR, "option \"%s\" not recognized", defel->defname); @@ -374,42 +396,54 @@ AlterUser(AlterUserStmt *stmt) if (dcreatedb) createdb = intVal(dcreatedb->arg); - if (dcreateuser) - createuser = intVal(dcreateuser->arg); + if (dcreaterole) + { + createrole = intVal(dcreaterole->arg); + /* XXX createrole implies issuper for now */ + issuper = createrole; + } + if (dcanlogin) + canlogin = intVal(dcanlogin->arg); + if (dadminopt) + adminopt = intVal(dadminopt->arg); if (dvalidUntil) validUntil = strVal(dvalidUntil->arg); if (dpassword) password = strVal(dpassword->arg); - - if (password) - CheckPgUserAclNotNull(); + if (drolememElts) + rolememElts = (List *) drolememElts->arg; /* must be superuser or just want to change your own password */ if (!superuser() && - !(createdb < 0 && - createuser < 0 && + !(issuper < 0 && + createrole < 0 && + createdb < 0 && + canlogin < 0 && !validUntil && + !rolememElts && + !adminopt && password && - strcmp(GetUserNameFromId(GetUserId()), stmt->user) == 0)) + strcmp(GetUserNameFromId(GetUserId()), stmt->role) == 0)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied"))); /* - * Scan the pg_shadow relation to be certain the user exists. Note we - * secure exclusive lock to protect our update of the flat password - * file. + * Scan the pg_authid relation to be certain the user exists. Note we + * secure exclusive lock to protect our update of the flat auth file. */ - pg_shadow_rel = heap_open(ShadowRelationId, ExclusiveLock); - pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); + pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock); + pg_authid_dsc = RelationGetDescr(pg_authid_rel); - tuple = SearchSysCache(SHADOWNAME, - PointerGetDatum(stmt->user), + tuple = SearchSysCache(AUTHNAME, + PointerGetDatum(stmt->role), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", stmt->user))); + errmsg("role \"%s\" does not exist", stmt->role))); + + roleid = HeapTupleGetOid(tuple); /* * Build an updated tuple, perusing the information just obtained @@ -418,65 +452,79 @@ AlterUser(AlterUserStmt *stmt) MemSet(new_record_nulls, ' ', sizeof(new_record_nulls)); MemSet(new_record_repl, ' ', sizeof(new_record_repl)); - new_record[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein, - CStringGetDatum(stmt->user)); - new_record_repl[Anum_pg_shadow_usename - 1] = 'r'; - - /* createdb */ - if (createdb >= 0) - { - new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(createdb > 0); - new_record_repl[Anum_pg_shadow_usecreatedb - 1] = 'r'; - } + new_record[Anum_pg_authid_rolname - 1] = DirectFunctionCall1(namein, + CStringGetDatum(stmt->role)); + new_record_repl[Anum_pg_authid_rolname - 1] = 'r'; /* - * createuser (superuser) and catupd + * issuper/createrole/catupdate/etc * - * XXX It's rather unclear how to handle catupd. It's probably best to + * XXX It's rather unclear how to handle catupdate. It's probably best to * keep it equal to the superuser status, otherwise you could end up * with a situation where no existing superuser can alter the - * catalogs, including pg_shadow! + * catalogs, including pg_authid! */ - if (createuser >= 0) + if (issuper >= 0) { - new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(createuser > 0); - new_record_repl[Anum_pg_shadow_usesuper - 1] = 'r'; + new_record[Anum_pg_authid_rolsuper - 1] = BoolGetDatum(issuper > 0); + new_record_repl[Anum_pg_authid_rolsuper - 1] = 'r'; - new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(createuser > 0); - new_record_repl[Anum_pg_shadow_usecatupd - 1] = 'r'; + new_record[Anum_pg_authid_rolcatupdate - 1] = BoolGetDatum(issuper > 0); + new_record_repl[Anum_pg_authid_rolcatupdate - 1] = 'r'; + } + + if (createrole >= 0) + { + new_record[Anum_pg_authid_rolcreaterole - 1] = BoolGetDatum(createrole > 0); + new_record_repl[Anum_pg_authid_rolcreaterole - 1] = 'r'; + } + + if (createdb >= 0) + { + new_record[Anum_pg_authid_rolcreatedb - 1] = BoolGetDatum(createdb > 0); + new_record_repl[Anum_pg_authid_rolcreatedb - 1] = 'r'; + } + + if (canlogin >= 0) + { + new_record[Anum_pg_authid_rolcanlogin - 1] = BoolGetDatum(canlogin > 0); + new_record_repl[Anum_pg_authid_rolcanlogin - 1] = 'r'; } /* password */ if (password) { if (!encrypt_password || isMD5(password)) - new_record[Anum_pg_shadow_passwd - 1] = + new_record[Anum_pg_authid_rolpassword - 1] = DirectFunctionCall1(textin, CStringGetDatum(password)); else { - if (!EncryptMD5(password, stmt->user, strlen(stmt->user), + if (!EncryptMD5(password, stmt->role, strlen(stmt->role), encrypted_password)) elog(ERROR, "password encryption failed"); - new_record[Anum_pg_shadow_passwd - 1] = + new_record[Anum_pg_authid_rolpassword - 1] = DirectFunctionCall1(textin, CStringGetDatum(encrypted_password)); } - new_record_repl[Anum_pg_shadow_passwd - 1] = 'r'; + new_record_repl[Anum_pg_authid_rolpassword - 1] = 'r'; } /* valid until */ if (validUntil) { - new_record[Anum_pg_shadow_valuntil - 1] = - DirectFunctionCall1(abstimein, CStringGetDatum(validUntil)); - new_record_repl[Anum_pg_shadow_valuntil - 1] = 'r'; + new_record[Anum_pg_authid_rolvaliduntil - 1] = + DirectFunctionCall3(timestamptz_in, + CStringGetDatum(validUntil), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + new_record_repl[Anum_pg_authid_rolvaliduntil - 1] = 'r'; } - new_tuple = heap_modifytuple(tuple, pg_shadow_dsc, new_record, + new_tuple = heap_modifytuple(tuple, pg_authid_dsc, new_record, new_record_nulls, new_record_repl); - simple_heap_update(pg_shadow_rel, &tuple->t_self, new_tuple); + simple_heap_update(pg_authid_rel, &tuple->t_self, new_tuple); /* Update indexes */ - CatalogUpdateIndexes(pg_shadow_rel, new_tuple); + CatalogUpdateIndexes(pg_authid_rel, new_tuple); ReleaseSysCache(tuple); heap_freetuple(new_tuple); @@ -485,59 +533,68 @@ AlterUser(AlterUserStmt *stmt) * Now we can clean up; but keep lock until commit (to avoid possible * deadlock when commit code tries to acquire lock). */ - heap_close(pg_shadow_rel, NoLock); + heap_close(pg_authid_rel, NoLock); + + if (stmt->action == +1) /* add members to role */ + AddRoleMems(stmt->role, roleid, + rolememElts, roleNamesToIds(rolememElts), + GetUserId(), adminopt); + else if (stmt->action == -1) /* drop members from role */ + DelRoleMems(stmt->role, roleid, + rolememElts, roleNamesToIds(rolememElts), + adminopt); /* - * Set flag to update flat password file at commit. + * Set flag to update flat auth file at commit. */ - user_file_update_needed(); + auth_file_update_needed(); } /* - * ALTER USER ... SET + * ALTER ROLE ... SET */ void -AlterUserSet(AlterUserSetStmt *stmt) +AlterRoleSet(AlterRoleSetStmt *stmt) { char *valuestr; HeapTuple oldtuple, newtuple; Relation rel; - Datum repl_val[Natts_pg_shadow]; - char repl_null[Natts_pg_shadow]; - char repl_repl[Natts_pg_shadow]; + Datum repl_val[Natts_pg_authid]; + char repl_null[Natts_pg_authid]; + char repl_repl[Natts_pg_authid]; int i; valuestr = flatten_set_variable_args(stmt->variable, stmt->value); /* * RowExclusiveLock is sufficient, because we don't need to update the - * flat password file. + * flat auth file. */ - rel = heap_open(ShadowRelationId, RowExclusiveLock); - oldtuple = SearchSysCache(SHADOWNAME, - PointerGetDatum(stmt->user), + rel = heap_open(AuthIdRelationId, RowExclusiveLock); + oldtuple = SearchSysCache(AUTHNAME, + PointerGetDatum(stmt->role), 0, 0, 0); if (!HeapTupleIsValid(oldtuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", stmt->user))); + errmsg("role \"%s\" does not exist", stmt->role))); if (!(superuser() || - ((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetUserId())) + (HeapTupleGetOid(oldtuple) == GetUserId()))) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied"))); - for (i = 0; i < Natts_pg_shadow; i++) + for (i = 0; i < Natts_pg_authid; i++) repl_repl[i] = ' '; - repl_repl[Anum_pg_shadow_useconfig - 1] = 'r'; + repl_repl[Anum_pg_authid_rolconfig - 1] = 'r'; if (strcmp(stmt->variable, "all") == 0 && valuestr == NULL) { /* RESET ALL */ - repl_null[Anum_pg_shadow_useconfig - 1] = 'n'; + repl_null[Anum_pg_authid_rolconfig - 1] = 'n'; } else { @@ -545,10 +602,10 @@ AlterUserSet(AlterUserSetStmt *stmt) bool isnull; ArrayType *array; - repl_null[Anum_pg_shadow_useconfig - 1] = ' '; + repl_null[Anum_pg_authid_rolconfig - 1] = ' '; - datum = SysCacheGetAttr(SHADOWNAME, oldtuple, - Anum_pg_shadow_useconfig, &isnull); + datum = SysCacheGetAttr(AUTHNAME, oldtuple, + Anum_pg_authid_rolconfig, &isnull); array = isnull ? NULL : DatumGetArrayTypeP(datum); @@ -558,9 +615,9 @@ AlterUserSet(AlterUserSetStmt *stmt) array = GUCArrayDelete(array, stmt->variable); if (array) - repl_val[Anum_pg_shadow_useconfig - 1] = PointerGetDatum(array); + repl_val[Anum_pg_authid_rolconfig - 1] = PointerGetDatum(array); else - repl_null[Anum_pg_shadow_useconfig - 1] = 'n'; + repl_null[Anum_pg_authid_rolconfig - 1] = 'n'; } newtuple = heap_modifytuple(oldtuple, RelationGetDescr(rel), repl_val, repl_null, repl_repl); @@ -574,60 +631,61 @@ AlterUserSet(AlterUserSetStmt *stmt) /* - * DROP USER + * DROP ROLE */ void -DropUser(DropUserStmt *stmt) +DropRole(DropRoleStmt *stmt) { - Relation pg_shadow_rel; - TupleDesc pg_shadow_dsc; + Relation pg_authid_rel, pg_auth_members_rel; ListCell *item; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to drop users"))); + errmsg("must be superuser to drop roles"))); /* - * Scan the pg_shadow relation to find the usesysid of the user to be + * Scan the pg_authid relation to find the Oid of the role to be * deleted. Note we secure exclusive lock, because we need to protect - * our update of the flat password file. + * our update of the flat auth file. */ - pg_shadow_rel = heap_open(ShadowRelationId, ExclusiveLock); - pg_shadow_dsc = RelationGetDescr(pg_shadow_rel); + pg_authid_rel = heap_open(AuthIdRelationId, ExclusiveLock); + pg_auth_members_rel = heap_open(AuthMemRelationId, ExclusiveLock); - foreach(item, stmt->users) + foreach(item, stmt->roles) { - const char *user = strVal(lfirst(item)); + const char *role = strVal(lfirst(item)); HeapTuple tuple, tmp_tuple; Relation pg_rel; TupleDesc pg_dsc; ScanKeyData scankey; HeapScanDesc scan; - AclId usesysid; + CatCList *auth_mem_list; + Oid roleid; + int i; - tuple = SearchSysCache(SHADOWNAME, - PointerGetDatum(user), + tuple = SearchSysCache(AUTHNAME, + PointerGetDatum(role), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", user))); + errmsg("role \"%s\" does not exist", role))); - usesysid = ((Form_pg_shadow) GETSTRUCT(tuple))->usesysid; + roleid = HeapTupleGetOid(tuple); - if (usesysid == GetUserId()) + if (roleid == GetUserId()) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("current user cannot be dropped"))); - if (usesysid == GetSessionUserId()) + errmsg("current role cannot be dropped"))); + if (roleid == GetSessionUserId()) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("session user cannot be dropped"))); + errmsg("session role cannot be dropped"))); /* - * Check if user still owns a database. If so, error out. + * Check if role still owns a database. If so, error out. * * (It used to be that this function would drop the database * automatically. This is not only very dangerous for people that @@ -639,8 +697,8 @@ DropUser(DropUserStmt *stmt) ScanKeyInit(&scankey, Anum_pg_database_datdba, - BTEqualStrategyNumber, F_INT4EQ, - Int32GetDatum(usesysid)); + BTEqualStrategyNumber, F_OIDEQ, + roleid); scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey); @@ -651,8 +709,8 @@ DropUser(DropUserStmt *stmt) dbname = NameStr(((Form_pg_database) GETSTRUCT(tmp_tuple))->datname); ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("user \"%s\" cannot be dropped", user), - errdetail("The user owns database \"%s\".", dbname))); + errmsg("role \"%s\" cannot be dropped", role), + errdetail("The role owns database \"%s\".", dbname))); } heap_endscan(scan); @@ -660,66 +718,64 @@ DropUser(DropUserStmt *stmt) /* * Somehow we'd have to check for tables, views, etc. owned by the - * user as well, but those could be spread out over all sorts of + * role as well, but those could be spread out over all sorts of * databases which we don't have access to (easily). */ /* - * Remove the user from the pg_shadow table + * Remove the role from the pg_authid table */ - simple_heap_delete(pg_shadow_rel, &tuple->t_self); + simple_heap_delete(pg_authid_rel, &tuple->t_self); ReleaseSysCache(tuple); /* - * Remove user from groups + * Remove role from roles * - * try calling alter group drop user for every group + * scan pg_auth_members and remove tuples which have + * roleid == member or roleid == role */ - pg_rel = heap_open(GroupRelationId, ExclusiveLock); - pg_dsc = RelationGetDescr(pg_rel); - scan = heap_beginscan(pg_rel, SnapshotNow, 0, NULL); - while ((tmp_tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - AlterGroupStmt ags; + auth_mem_list = SearchSysCacheList(AUTHMEMROLEMEM, 1, + ObjectIdGetDatum(roleid), + 0, 0, 0); - /* the group name from which to try to drop the user: */ - ags.name = pstrdup(NameStr(((Form_pg_group) GETSTRUCT(tmp_tuple))->groname)); - ags.action = -1; - ags.listUsers = list_make1(makeInteger(usesysid)); - AlterGroup(&ags, "DROP USER"); + for (i = 0; i < auth_mem_list->n_members; i++) + { + HeapTuple authmemtup = &auth_mem_list->members[i]->tuple; + simple_heap_delete(pg_auth_members_rel, &authmemtup->t_self); } - heap_endscan(scan); - heap_close(pg_rel, ExclusiveLock); + ReleaseSysCacheList(auth_mem_list); - /* - * Advance command counter so that later iterations of this loop - * will see the changes already made. This is essential if, for - * example, we are trying to drop two users who are members of the - * same group --- the AlterGroup for the second user had better - * see the tuple updated from the first one. - */ - CommandCounterIncrement(); + auth_mem_list = SearchSysCacheList(AUTHMEMMEMROLE, 1, + ObjectIdGetDatum(roleid), + 0, 0, 0); + + for (i = 0; i < auth_mem_list->n_members; i++) + { + HeapTuple authmemtup = &auth_mem_list->members[i]->tuple; + simple_heap_delete(pg_auth_members_rel, &authmemtup->t_self); + } + ReleaseSysCacheList(auth_mem_list); } /* * Now we can clean up; but keep lock until commit (to avoid possible * deadlock when commit code tries to acquire lock). */ - heap_close(pg_shadow_rel, NoLock); + heap_close(pg_auth_members_rel, NoLock); + heap_close(pg_authid_rel, NoLock); /* - * Set flag to update flat password file at commit. + * Set flag to update flat auth file at commit. */ - user_file_update_needed(); + auth_file_update_needed(); } - /* - * Rename user + * Rename role */ void -RenameUser(const char *oldname, const char *newname) +RenameRole(const char *oldname, const char *newname) { HeapTuple oldtuple, newtuple; @@ -727,22 +783,23 @@ RenameUser(const char *oldname, const char *newname) Relation rel; Datum datum; bool isnull; - Datum repl_val[Natts_pg_shadow]; - char repl_null[Natts_pg_shadow]; - char repl_repl[Natts_pg_shadow]; + Datum repl_val[Natts_pg_authid]; + char repl_null[Natts_pg_authid]; + char repl_repl[Natts_pg_authid]; int i; + Oid roleid; /* ExclusiveLock because we need to update the password file */ - rel = heap_open(ShadowRelationId, ExclusiveLock); + rel = heap_open(AuthIdRelationId, ExclusiveLock); dsc = RelationGetDescr(rel); - oldtuple = SearchSysCache(SHADOWNAME, + oldtuple = SearchSysCache(AUTHNAME, CStringGetDatum(oldname), 0, 0, 0); if (!HeapTupleIsValid(oldtuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", oldname))); + errmsg("role \"%s\" does not exist", oldname))); /* * XXX Client applications probably store the session user somewhere, @@ -750,43 +807,46 @@ RenameUser(const char *oldname, const char *newname) * not be an actual problem besides a little confusion, so think about * this and decide. */ - if (((Form_pg_shadow) GETSTRUCT(oldtuple))->usesysid == GetSessionUserId()) + + roleid = HeapTupleGetOid(oldtuple); + + if (roleid == GetSessionUserId()) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("session user may not be renamed"))); + errmsg("session role may not be renamed"))); /* make sure the new name doesn't exist */ - if (SearchSysCacheExists(SHADOWNAME, + if (SearchSysCacheExists(AUTHNAME, CStringGetDatum(newname), 0, 0, 0)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("user \"%s\" already exists", newname))); + errmsg("role \"%s\" already exists", newname))); /* must be superuser */ if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to rename users"))); + errmsg("must be superuser to rename roles"))); - for (i = 0; i < Natts_pg_shadow; i++) + for (i = 0; i < Natts_pg_authid; i++) repl_repl[i] = ' '; - repl_repl[Anum_pg_shadow_usename - 1] = 'r'; - repl_val[Anum_pg_shadow_usename - 1] = DirectFunctionCall1(namein, + repl_repl[Anum_pg_authid_rolname - 1] = 'r'; + repl_val[Anum_pg_authid_rolname - 1] = DirectFunctionCall1(namein, CStringGetDatum(newname)); - repl_null[Anum_pg_shadow_usename - 1] = ' '; + repl_null[Anum_pg_authid_rolname - 1] = ' '; - datum = heap_getattr(oldtuple, Anum_pg_shadow_passwd, dsc, &isnull); + datum = heap_getattr(oldtuple, Anum_pg_authid_rolpassword, dsc, &isnull); if (!isnull && isMD5(DatumGetCString(DirectFunctionCall1(textout, datum)))) { /* MD5 uses the username as salt, so just clear it on a rename */ - repl_repl[Anum_pg_shadow_passwd - 1] = 'r'; - repl_null[Anum_pg_shadow_passwd - 1] = 'n'; + repl_repl[Anum_pg_authid_rolpassword - 1] = 'r'; + repl_null[Anum_pg_authid_rolpassword - 1] = 'n'; ereport(NOTICE, - (errmsg("MD5 password cleared because of user rename"))); + (errmsg("MD5 password cleared because of role rename"))); } newtuple = heap_modifytuple(oldtuple, dsc, repl_val, repl_null, repl_repl); @@ -797,551 +857,322 @@ RenameUser(const char *oldname, const char *newname) ReleaseSysCache(oldtuple); heap_close(rel, NoLock); - user_file_update_needed(); + auth_file_update_needed(); } - /* - * CheckPgUserAclNotNull + * GrantRoleStmt * - * check to see if there is an ACL on pg_shadow - */ -static void -CheckPgUserAclNotNull(void) -{ - HeapTuple htup; - - htup = SearchSysCache(RELOID, - ObjectIdGetDatum(ShadowRelationId), - 0, 0, 0); - if (!HeapTupleIsValid(htup)) /* should not happen, we hope */ - elog(ERROR, "cache lookup failed for relation %u", ShadowRelationId); - - if (heap_attisnull(htup, Anum_pg_class_relacl)) - { - Form_pg_class classForm = (Form_pg_class) GETSTRUCT(htup); - - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("before using passwords you must revoke privileges on %s", - NameStr(classForm->relname)), - errdetail("This restriction is to prevent unprivileged users from reading the passwords."), - errhint("Try REVOKE ALL ON \"%s\" FROM PUBLIC.", - NameStr(classForm->relname)))); - } - - ReleaseSysCache(htup); -} - - -/* - * CREATE GROUP + * Grant/Revoke roles to/from roles */ void -CreateGroup(CreateGroupStmt *stmt) +GrantRole(GrantRoleStmt *stmt) { - Relation pg_group_rel; - HeapScanDesc scan; - HeapTuple tuple; - TupleDesc pg_group_dsc; - bool group_exists = false, - sysid_exists = false, - havesysid = false; - int max_id; - Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group]; + Oid grantor; + List *grantee_ids; ListCell *item; - ListCell *option; - List *newlist = NIL; - IdList *grolist; - int sysid = 0; - List *userElts = NIL; - DefElem *dsysid = NULL; - DefElem *duserElts = NULL; - - foreach(option, stmt->options) - { - DefElem *defel = (DefElem *) lfirst(option); - if (strcmp(defel->defname, "sysid") == 0) - { - if (dsysid) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); - dsysid = defel; - } - else if (strcmp(defel->defname, "userElts") == 0) - { - if (duserElts) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"))); - duserElts = defel; - } - else - elog(ERROR, "option \"%s\" not recognized", - defel->defname); - } - - if (dsysid) - { - sysid = intVal(dsysid->arg); - if (sysid <= 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("group ID must be positive"))); - havesysid = true; - } + if (stmt->grantor) + grantor = get_roleid_checked(stmt->grantor); + else + grantor = GetUserId(); - if (duserElts) - userElts = (List *) duserElts->arg; + grantee_ids = roleNamesToIds(stmt->grantee_roles); /* - * Make sure the user can do this. - */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to create groups"))); - - if (strcmp(stmt->name, "public") == 0) - ereport(ERROR, - (errcode(ERRCODE_RESERVED_NAME), - errmsg("group name \"%s\" is reserved", - stmt->name))); - - /* - * Scan the pg_group relation to be certain the group or id doesn't - * already exist. Note we secure exclusive lock, because we also need - * to be sure of what the next grosysid should be, and we need to - * protect our eventual update of the flat group file. + * Step through all of the granted roles and add/remove + * entries for the grantees, or, if admin_opt is set, then + * just add/remove the admin option. + * + * Note: Permissions checking is done by AddRoleMems/DelRoleMems */ - pg_group_rel = heap_open(GroupRelationId, ExclusiveLock); - pg_group_dsc = RelationGetDescr(pg_group_rel); - - scan = heap_beginscan(pg_group_rel, SnapshotNow, 0, NULL); - max_id = 99; /* start auto-assigned ids at 100 */ - while (!group_exists && !sysid_exists && - (tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + foreach(item, stmt->granted_roles) { - Form_pg_group group_form = (Form_pg_group) GETSTRUCT(tuple); - int32 this_sysid; + char *rolename = strVal(lfirst(item)); + Oid roleid = get_roleid_checked(rolename); - group_exists = (strcmp(NameStr(group_form->groname), stmt->name) == 0); - - this_sysid = group_form->grosysid; - if (havesysid) /* customized id wanted */ - sysid_exists = (this_sysid == sysid); + if (stmt->is_grant) + AddRoleMems(rolename, roleid, + stmt->grantee_roles, grantee_ids, + grantor, stmt->admin_opt); else - { - /* pick 1 + max */ - if (this_sysid > max_id) - max_id = this_sysid; - } + DelRoleMems(rolename, roleid, + stmt->grantee_roles, grantee_ids, + stmt->admin_opt); } - heap_endscan(scan); - - if (group_exists) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("group \"%s\" already exists", - stmt->name))); - if (sysid_exists) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("group ID %d is already assigned", sysid))); +} - /* If no sysid given, use max existing id + 1 */ - if (!havesysid) - sysid = max_id + 1; +/* + * roleNamesToIds + * + * Given a list of role names (as String nodes), generate a list of role OIDs + * in the same order. + */ +static List * +roleNamesToIds(List *memberNames) +{ + List *result = NIL; + ListCell *l; - /* - * Translate the given user names to ids - */ - foreach(item, userElts) + foreach(l, memberNames) { - const char *groupuser = strVal(lfirst(item)); - int32 userid = get_usesysid(groupuser); + char *rolename = strVal(lfirst(l)); + Oid roleid = get_roleid_checked(rolename); - if (!list_member_int(newlist, userid)) - newlist = lappend_int(newlist, userid); + result = lappend_oid(result, roleid); } - - /* build an array to insert */ - if (newlist) - grolist = IdListToArray(newlist); - else - grolist = NULL; - - /* - * Form a tuple to insert - */ - new_record[Anum_pg_group_groname - 1] = - DirectFunctionCall1(namein, CStringGetDatum(stmt->name)); - new_record[Anum_pg_group_grosysid - 1] = Int32GetDatum(sysid); - new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(grolist); - - new_record_nulls[Anum_pg_group_groname - 1] = ' '; - new_record_nulls[Anum_pg_group_grosysid - 1] = ' '; - new_record_nulls[Anum_pg_group_grolist - 1] = grolist ? ' ' : 'n'; - - tuple = heap_formtuple(pg_group_dsc, new_record, new_record_nulls); - - /* - * Insert a new record in the pg_group table - */ - simple_heap_insert(pg_group_rel, tuple); - - /* Update indexes */ - CatalogUpdateIndexes(pg_group_rel, tuple); - - /* - * Now we can clean up; but keep lock until commit (to avoid possible - * deadlock when commit code tries to acquire lock). - */ - heap_close(pg_group_rel, NoLock); - - /* - * Set flag to update flat group file at commit. - */ - group_file_update_needed(); + return result; } - /* - * ALTER GROUP + * AddRoleMems -- Add given members to the specified role + * + * rolename: name of role to add to (used only for error messages) + * roleid: OID of role to add to + * memberNames: list of names of roles to add (used only for error messages) + * memberIds: OIDs of roles to add + * grantorId: who is granting the membership + * admin_opt: granting admin option? */ -void -AlterGroup(AlterGroupStmt *stmt, const char *tag) +static void +AddRoleMems(const char *rolename, Oid roleid, + List *memberNames, List *memberIds, + Oid grantorId, bool admin_opt) { - Relation pg_group_rel; - TupleDesc pg_group_dsc; - HeapTuple group_tuple; - IdList *oldarray; - Datum datum; - bool null; - List *newlist; - ListCell *item; + Relation pg_authmem_rel; + TupleDesc pg_authmem_dsc; + ListCell *nameitem; + ListCell *iditem; - /* - * Make sure the user can do this. - */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to alter groups"))); + Assert(list_length(memberNames) == list_length(memberIds)); - /* - * Secure exclusive lock to protect our update of the flat group file. - */ - pg_group_rel = heap_open(GroupRelationId, ExclusiveLock); - pg_group_dsc = RelationGetDescr(pg_group_rel); + /* Skip permission check if nothing to do */ + if (!memberIds) + return; /* - * Fetch existing tuple for group. + * Check permissions: must be superuser or have admin option on the + * role to be changed. + * + * XXX: The admin option is not considered to be inherited through + * multiple roles, unlike normal 'is_member_of_role' privilege checks. */ - group_tuple = SearchSysCache(GRONAME, - PointerGetDatum(stmt->name), - 0, 0, 0); - if (!HeapTupleIsValid(group_tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("group \"%s\" does not exist", stmt->name))); + if (!superuser()) + { + HeapTuple authmem_chk_tuple; + Form_pg_auth_members authmem_chk; - /* Fetch old group membership. */ - datum = heap_getattr(group_tuple, Anum_pg_group_grolist, - pg_group_dsc, &null); - oldarray = null ? NULL : DatumGetIdListP(datum); + if (grantorId != GetUserId()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to set grantor ID"))); + + authmem_chk_tuple = SearchSysCache(AUTHMEMROLEMEM, + ObjectIdGetDatum(roleid), + ObjectIdGetDatum(grantorId), + 0, 0); + if (!HeapTupleIsValid(authmem_chk_tuple)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser or have admin option on role \"%s\"", + rolename))); - /* initialize list with old array contents */ - newlist = IdArrayToList(oldarray); + authmem_chk = (Form_pg_auth_members) GETSTRUCT(authmem_chk_tuple); + if (!authmem_chk->admin_option) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser or have admin option on role \"%s\"", + rolename))); + ReleaseSysCache(authmem_chk_tuple); + } /* - * Now decide what to do. + * Secure exclusive lock to protect our update of the flat auth file. */ - AssertState(stmt->action == +1 || stmt->action == -1); + pg_authmem_rel = heap_open(AuthMemRelationId, ExclusiveLock); + pg_authmem_dsc = RelationGetDescr(pg_authmem_rel); - if (stmt->action == +1) /* add users, might also be invoked by - * create user */ + forboth(nameitem, memberNames, iditem, memberIds) { + const char *membername = strVal(lfirst(nameitem)); + Oid memberid = lfirst_oid(iditem); + HeapTuple authmem_tuple; + HeapTuple tuple; + Datum new_record[Natts_pg_auth_members]; + char new_record_nulls[Natts_pg_auth_members]; + char new_record_repl[Natts_pg_auth_members]; + /* - * convert the to be added usernames to sysids and add them to the - * list + * Check if entry for this role/member already exists; + * if so, give warning unless we are adding admin option. */ - foreach(item, stmt->listUsers) + authmem_tuple = SearchSysCache(AUTHMEMROLEMEM, + ObjectIdGetDatum(roleid), + ObjectIdGetDatum(memberid), + 0, 0); + if (HeapTupleIsValid(authmem_tuple) && !admin_opt) { - int32 sysid; - - if (strcmp(tag, "ALTER GROUP") == 0) - { - /* Get the uid of the proposed user to add. */ - sysid = get_usesysid(strVal(lfirst(item))); - } - else if (strcmp(tag, "CREATE USER") == 0) - { - /* - * in this case we already know the uid and it wouldn't be - * in the cache anyway yet - */ - sysid = intVal(lfirst(item)); - } - else - { - elog(ERROR, "unexpected tag: \"%s\"", tag); - sysid = 0; /* keep compiler quiet */ - } - - if (!list_member_int(newlist, sysid)) - newlist = lappend_int(newlist, sysid); + ereport(NOTICE, + (errmsg("role \"%s\" is already a member of role \"%s\"", + membername, rolename))); + ReleaseSysCache(authmem_tuple); + continue; } - /* Do the update */ - UpdateGroupMembership(pg_group_rel, group_tuple, newlist); - } /* endif alter group add user */ + /* Build a tuple to insert or update */ + MemSet(new_record, 0, sizeof(new_record)); + MemSet(new_record_nulls, ' ', sizeof(new_record_nulls)); + MemSet(new_record_repl, ' ', sizeof(new_record_repl)); - else if (stmt->action == -1) /* drop users from group */ - { - bool is_dropuser = strcmp(tag, "DROP USER") == 0; + new_record[Anum_pg_auth_members_roleid - 1] = ObjectIdGetDatum(roleid); + new_record[Anum_pg_auth_members_member - 1] = ObjectIdGetDatum(memberid); + new_record[Anum_pg_auth_members_grantor - 1] = ObjectIdGetDatum(grantorId); + new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(admin_opt); - if (newlist == NIL) + if (HeapTupleIsValid(authmem_tuple)) { - if (!is_dropuser) - ereport(WARNING, - (errcode(ERRCODE_WARNING), - errmsg("group \"%s\" does not have any members", - stmt->name))); + new_record_repl[Anum_pg_auth_members_grantor - 1] = 'r'; + new_record_repl[Anum_pg_auth_members_admin_option - 1] = 'r'; + tuple = heap_modifytuple(authmem_tuple, pg_authmem_dsc, + new_record, + new_record_nulls, new_record_repl); + simple_heap_update(pg_authmem_rel, &tuple->t_self, tuple); + CatalogUpdateIndexes(pg_authmem_rel, tuple); + ReleaseSysCache(authmem_tuple); } else { - /* - * convert the to be dropped usernames to sysids and remove - * them from the list - */ - foreach(item, stmt->listUsers) - { - int32 sysid; - - if (!is_dropuser) - { - /* Get the uid of the proposed user to drop. */ - sysid = get_usesysid(strVal(lfirst(item))); - } - else - { - /* for dropuser we already know the uid */ - sysid = intVal(lfirst(item)); - } - if (list_member_int(newlist, sysid)) - newlist = list_delete_int(newlist, sysid); - else if (!is_dropuser) - ereport(WARNING, - (errcode(ERRCODE_WARNING), - errmsg("user \"%s\" is not in group \"%s\"", - strVal(lfirst(item)), stmt->name))); - } - - /* Do the update */ - UpdateGroupMembership(pg_group_rel, group_tuple, newlist); - } /* endif group not null */ - } /* endif alter group drop user */ - - ReleaseSysCache(group_tuple); + tuple = heap_formtuple(pg_authmem_dsc, + new_record, new_record_nulls); + simple_heap_insert(pg_authmem_rel, tuple); + CatalogUpdateIndexes(pg_authmem_rel, tuple); + } + } /* * Now we can clean up; but keep lock until commit (to avoid possible * deadlock when commit code tries to acquire lock). */ - heap_close(pg_group_rel, NoLock); - - /* - * Set flag to update flat group file at commit. - */ - group_file_update_needed(); + heap_close(pg_authmem_rel, NoLock); } /* - * Subroutine for AlterGroup: given a pg_group tuple and a desired new - * membership (expressed as an integer list), form and write an updated tuple. - * The pg_group relation must be open and locked already. + * DelRoleMems -- Remove given members from the specified role + * + * rolename: name of role to del from (used only for error messages) + * roleid: OID of role to del from + * memberNames: list of names of roles to del (used only for error messages) + * memberIds: OIDs of roles to del + * admin_opt: remove admin option only? */ static void -UpdateGroupMembership(Relation group_rel, HeapTuple group_tuple, - List *members) +DelRoleMems(const char *rolename, Oid roleid, + List *memberNames, List *memberIds, + bool admin_opt) { - IdList *newarray; - Datum new_record[Natts_pg_group]; - char new_record_nulls[Natts_pg_group]; - char new_record_repl[Natts_pg_group]; - HeapTuple tuple; + Relation pg_authmem_rel; + TupleDesc pg_authmem_dsc; + ListCell *nameitem; + ListCell *iditem; - newarray = IdListToArray(members); + Assert(list_length(memberNames) == list_length(memberIds)); + + /* Skip permission check if nothing to do */ + if (!memberIds) + return; /* - * Form an updated tuple with the new array and write it back. + * Check permissions: must be superuser or have admin option on the + * role to be changed. + * + * XXX: The admin option is not considered to be inherited through + * multiple roles, unlike normal 'is_member_of_role' privilege checks. */ - MemSet(new_record, 0, sizeof(new_record)); - MemSet(new_record_nulls, ' ', sizeof(new_record_nulls)); - MemSet(new_record_repl, ' ', sizeof(new_record_repl)); - - new_record[Anum_pg_group_grolist - 1] = PointerGetDatum(newarray); - new_record_repl[Anum_pg_group_grolist - 1] = 'r'; - - tuple = heap_modifytuple(group_tuple, RelationGetDescr(group_rel), - new_record, new_record_nulls, new_record_repl); - - simple_heap_update(group_rel, &group_tuple->t_self, tuple); - - /* Update indexes */ - CatalogUpdateIndexes(group_rel, tuple); -} - - -/* - * Convert an integer list of sysids to an array. - */ -static IdList * -IdListToArray(List *members) -{ - int nmembers = list_length(members); - IdList *newarray; - ListCell *item; - int i; - - newarray = palloc(ARR_OVERHEAD(1) + nmembers * sizeof(int32)); - newarray->size = ARR_OVERHEAD(1) + nmembers * sizeof(int32); - newarray->flags = 0; - newarray->elemtype = INT4OID; - ARR_NDIM(newarray) = 1; /* one dimensional array */ - ARR_LBOUND(newarray)[0] = 1; /* axis starts at one */ - ARR_DIMS(newarray)[0] = nmembers; /* axis is this long */ - i = 0; - foreach(item, members) - ((int *) ARR_DATA_PTR(newarray))[i++] = lfirst_int(item); - - return newarray; -} - -/* - * Convert an array of sysids to an integer list. - */ -static List * -IdArrayToList(IdList *oldarray) -{ - List *newlist = NIL; - int hibound, - i; - - if (oldarray == NULL) - return NIL; - - Assert(ARR_NDIM(oldarray) == 1); - Assert(ARR_ELEMTYPE(oldarray) == INT4OID); - - hibound = ARR_DIMS(oldarray)[0]; - - for (i = 0; i < hibound; i++) + if (!superuser()) { - int32 sysid; + HeapTuple authmem_chk_tuple; + Form_pg_auth_members authmem_chk; + + authmem_chk_tuple = SearchSysCache(AUTHMEMROLEMEM, + ObjectIdGetDatum(roleid), + ObjectIdGetDatum(GetUserId()), + 0, 0); + if (!HeapTupleIsValid(authmem_chk_tuple)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser or have admin option on role \"%s\"", + rolename))); - sysid = ((int32 *) ARR_DATA_PTR(oldarray))[i]; - /* filter out any duplicates --- probably a waste of time */ - if (!list_member_int(newlist, sysid)) - newlist = lappend_int(newlist, sysid); + authmem_chk = (Form_pg_auth_members) GETSTRUCT(authmem_chk_tuple); + if (!authmem_chk->admin_option) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser or have admin option on role \"%s\"", + rolename))); + ReleaseSysCache(authmem_chk_tuple); } - return newlist; -} - - -/* - * DROP GROUP - */ -void -DropGroup(DropGroupStmt *stmt) -{ - Relation pg_group_rel; - HeapTuple tuple; - /* - * Make sure the user can do this. + * Secure exclusive lock to protect our update of the flat auth file. */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to drop groups"))); + pg_authmem_rel = heap_open(AuthMemRelationId, ExclusiveLock); + pg_authmem_dsc = RelationGetDescr(pg_authmem_rel); - /* - * Secure exclusive lock to protect our update of the flat group file. - */ - pg_group_rel = heap_open(GroupRelationId, ExclusiveLock); + forboth(nameitem, memberNames, iditem, memberIds) + { + const char *membername = strVal(lfirst(nameitem)); + Oid memberid = lfirst_oid(iditem); + HeapTuple authmem_tuple; - /* Find and delete the group. */ + /* + * Find entry for this role/member + */ + authmem_tuple = SearchSysCache(AUTHMEMROLEMEM, + ObjectIdGetDatum(roleid), + ObjectIdGetDatum(memberid), + 0, 0); + if (!HeapTupleIsValid(authmem_tuple)) + { + ereport(WARNING, + (errmsg("role \"%s\" is not a member of role \"%s\"", + membername, rolename))); + continue; + } - tuple = SearchSysCacheCopy(GRONAME, - PointerGetDatum(stmt->name), - 0, 0, 0); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("group \"%s\" does not exist", stmt->name))); + if (!admin_opt) + { + /* Remove the entry altogether */ + simple_heap_delete(pg_authmem_rel, &authmem_tuple->t_self); + } + else + { + /* Just turn off the admin option */ + HeapTuple tuple; + Datum new_record[Natts_pg_auth_members]; + char new_record_nulls[Natts_pg_auth_members]; + char new_record_repl[Natts_pg_auth_members]; + + /* Build a tuple to update with */ + MemSet(new_record, 0, sizeof(new_record)); + MemSet(new_record_nulls, ' ', sizeof(new_record_nulls)); + MemSet(new_record_repl, ' ', sizeof(new_record_repl)); + + new_record[Anum_pg_auth_members_admin_option - 1] = BoolGetDatum(false); + new_record_repl[Anum_pg_auth_members_admin_option - 1] = 'r'; + + tuple = heap_modifytuple(authmem_tuple, pg_authmem_dsc, + new_record, + new_record_nulls, new_record_repl); + simple_heap_update(pg_authmem_rel, &tuple->t_self, tuple); + CatalogUpdateIndexes(pg_authmem_rel, tuple); + } - simple_heap_delete(pg_group_rel, &tuple->t_self); + ReleaseSysCache(authmem_tuple); + } /* * Now we can clean up; but keep lock until commit (to avoid possible * deadlock when commit code tries to acquire lock). */ - heap_close(pg_group_rel, NoLock); - - /* - * Set flag to update flat group file at commit. - */ - group_file_update_needed(); -} - - -/* - * Rename group - */ -void -RenameGroup(const char *oldname, const char *newname) -{ - HeapTuple tup; - Relation rel; - - /* ExclusiveLock because we need to update the flat group file */ - rel = heap_open(GroupRelationId, ExclusiveLock); - - tup = SearchSysCacheCopy(GRONAME, - CStringGetDatum(oldname), - 0, 0, 0); - if (!HeapTupleIsValid(tup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("group \"%s\" does not exist", oldname))); - - /* make sure the new name doesn't exist */ - if (SearchSysCacheExists(GRONAME, - CStringGetDatum(newname), - 0, 0, 0)) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("group \"%s\" already exists", newname))); - - /* must be superuser */ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to rename groups"))); - - /* rename */ - namestrcpy(&(((Form_pg_group) GETSTRUCT(tup))->groname), newname); - simple_heap_update(rel, &tup->t_self, tup); - CatalogUpdateIndexes(rel, tup); - - heap_close(rel, NoLock); - heap_freetuple(tup); - - group_file_update_needed(); + heap_close(pg_authmem_rel, NoLock); } diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 048a3e41562f70b001388389b74fb75ef454c7fb..7df2a92a6c6c32f575c6b3cb877104dc427c072e 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.108 2005/06/09 21:52:07 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/variable.c,v 1.109 2005/06/28 05:08:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,7 +19,7 @@ #include <ctype.h> #include "access/xact.h" -#include "catalog/pg_shadow.h" +#include "catalog/pg_authid.h" #include "commands/variable.h" #include "miscadmin.h" #include "parser/scansup.h" @@ -567,46 +567,46 @@ assign_client_encoding(const char *value, bool doit, GucSource source) * SET SESSION AUTHORIZATION * * When resetting session auth after an error, we can't expect to do catalog - * lookups. Hence, the stored form of the value must provide a numeric userid + * lookups. Hence, the stored form of the value must provide a numeric oid * that can be re-used directly. We store the string in the form of * NAMEDATALEN 'x's, followed by T or F to indicate superuserness, followed - * by the numeric userid, followed by a comma, followed by the user name. - * This cannot be confused with a plain user name because of the NAMEDATALEN + * by the numeric oid, followed by a comma, followed by the role name. + * This cannot be confused with a plain role name because of the NAMEDATALEN * limit on names, so we can tell whether we're being passed an initial - * username or a saved/restored value. + * role name or a saved/restored value. */ extern char *session_authorization_string; /* in guc.c */ const char * assign_session_authorization(const char *value, bool doit, GucSource source) { - AclId usesysid = 0; + Oid roleid = InvalidOid; bool is_superuser = false; - const char *actual_username = NULL; + const char *actual_rolename = NULL; char *result; if (strspn(value, "x") == NAMEDATALEN && (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F')) { /* might be a saved userid string */ - AclId savedsysid; + Oid savedoid; char *endptr; - savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10); + savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10); if (endptr != value + NAMEDATALEN + 1 && *endptr == ',') { /* syntactically valid, so break out the data */ - usesysid = savedsysid; + roleid = savedoid; is_superuser = (value[NAMEDATALEN] == 'T'); - actual_username = endptr + 1; + actual_rolename = endptr + 1; } } - if (usesysid == 0) + if (roleid == InvalidOid) { /* not a saved ID, so look it up */ - HeapTuple userTup; + HeapTuple roleTup; if (!IsTransactionState()) { @@ -618,38 +618,38 @@ assign_session_authorization(const char *value, bool doit, GucSource source) return NULL; } - userTup = SearchSysCache(SHADOWNAME, + roleTup = SearchSysCache(AUTHNAME, PointerGetDatum(value), 0, 0, 0); - if (!HeapTupleIsValid(userTup)) + if (!HeapTupleIsValid(roleTup)) { if (source >= PGC_S_INTERACTIVE) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", value))); + errmsg("role \"%s\" does not exist", value))); return NULL; } - usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; - is_superuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; - actual_username = value; + roleid = HeapTupleGetOid(roleTup); + is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper; + actual_rolename = value; - ReleaseSysCache(userTup); + ReleaseSysCache(roleTup); } if (doit) - SetSessionAuthorization(usesysid, is_superuser); + SetSessionAuthorization(roleid, is_superuser); - result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_username)); + result = (char *) malloc(NAMEDATALEN + 32 + strlen(actual_rolename)); if (!result) return NULL; memset(result, 'x', NAMEDATALEN); - sprintf(result + NAMEDATALEN, "%c%lu,%s", + sprintf(result + NAMEDATALEN, "%c%u,%s", is_superuser ? 'T' : 'F', - (unsigned long) usesysid, - actual_username); + roleid, + actual_rolename); return result; } @@ -662,13 +662,13 @@ show_session_authorization(void) * assign_session_authorization */ const char *value = session_authorization_string; - AclId savedsysid; + Oid savedoid; char *endptr; Assert(strspn(value, "x") == NAMEDATALEN && (value[NAMEDATALEN] == 'T' || value[NAMEDATALEN] == 'F')); - savedsysid = (AclId) strtoul(value + NAMEDATALEN + 1, &endptr, 10); + savedoid = (Oid) strtoul(value + NAMEDATALEN + 1, &endptr, 10); Assert(endptr != value + NAMEDATALEN + 1 && *endptr == ','); diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 938474610ae80df3fcb45d2ac22118d6a2248481..3ef33cfd39fc8278fcf20d0512a601014352e1d4 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.250 2005/06/20 18:37:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.251 2005/06/28 05:08:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -352,7 +352,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte) { AclMode requiredPerms; Oid relOid; - AclId userid; + Oid userid; /* * Only plain-relation RTEs need to be checked here. Subquery RTEs diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 5b5499454b81627774e00b7822adaeeacee94f76..b7a0bc344ffe932208452767be1fe203cabb78b4 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -61,7 +61,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.133 2005/05/06 17:24:53 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeAgg.c,v 1.134 2005/06/28 05:08:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1270,7 +1270,7 @@ ExecInitAgg(Agg *node, EState *estate) /* Check that aggregate owner has permission to call component fns */ { HeapTuple procTuple; - AclId aggOwner; + Oid aggOwner; procTuple = SearchSysCache(PROCOID, ObjectIdGetDatum(aggref->aggfnoid), diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 58e80334f6100afa7bec00a891f799ea8c4f460a..d9c95d1b9ac8567b1da3768e3851464af56a1951 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.62 2005/02/20 04:45:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/crypt.c,v 1.63 2005/06/28 05:08:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -29,7 +29,7 @@ int -md5_crypt_verify(const Port *port, const char *user, char *client_pass) +md5_crypt_verify(const Port *port, const char *role, char *client_pass) { char *shadow_pass = NULL, *valuntil = NULL, @@ -39,13 +39,11 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass) ListCell *token; char *crypt_client_pass = client_pass; - if ((line = get_user_line(user)) == NULL) + if ((line = get_role_line(role)) == NULL) return STATUS_ERROR; - /* Skip over username and usesysid */ + /* Skip over rolename */ token = list_head(*line); - if (token) - token = lnext(token); if (token) token = lnext(token); if (token) @@ -146,17 +144,28 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass) /* * Password OK, now check to be sure we are not past valuntil */ - AbsoluteTime vuntil; - if (valuntil == NULL || *valuntil == '\0') - vuntil = INVALID_ABSTIME; - else - vuntil = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein, - CStringGetDatum(valuntil))); - if (vuntil != INVALID_ABSTIME && vuntil < GetCurrentAbsoluteTime()) - retval = STATUS_ERROR; - else retval = STATUS_OK; + else + { + TimestampTz vuntil; + AbsoluteTime sec; + int usec; + TimestampTz curtime; + + vuntil = DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in, + CStringGetDatum(valuntil), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1))); + + sec = GetCurrentAbsoluteTimeUsec(&usec); + curtime = AbsoluteTimeUsecToTimestampTz(sec, usec); + + if (vuntil < curtime) + retval = STATUS_ERROR; + else + retval = STATUS_OK; + } } if (port->auth_method == uaMD5) diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index ab5d7e41674f9d9370b554966dca53a0dd65a0f3..52608eb45371af4c37b9b46a12b712573500604e 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.142 2005/06/27 02:04:25 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.143 2005/06/28 05:08:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,7 +53,8 @@ /* * These variables hold the pre-parsed contents of the hba and ident - * configuration files. Each is a list of sublists, one sublist for + * configuration files, as well as the flat auth file. + * Each is a list of sublists, one sublist for * each (non-empty, non-comment) line of the file. Each sublist's * first item is an integer line number (so we can give somewhat-useful * location info in error messages). Remaining items are palloc'd strings, @@ -69,20 +70,13 @@ static List *hba_line_nums = NIL; static List *ident_lines = NIL; static List *ident_line_nums = NIL; -/* pre-parsed content of group file and corresponding line #s */ -static List *group_lines = NIL; -static List *group_line_nums = NIL; - -/* pre-parsed content of user passwd file and corresponding line #s */ -static List *user_lines = NIL; -static List *user_line_nums = NIL; +/* pre-parsed content of flat auth file and corresponding line #s */ +static List *role_lines = NIL; +static List *role_line_nums = NIL; /* sorted entries so we can do binary search lookups */ -static List **user_sorted = NULL; /* sorted user list, for bsearch() */ -static List **group_sorted = NULL; /* sorted group list, for - * bsearch() */ -static int user_length; -static int group_length; +static List **role_sorted = NULL; /* sorted role list, for bsearch() */ +static int role_length; static void tokenize_file(const char *filename, FILE *file, List **lines, List **line_nums); @@ -109,7 +103,7 @@ pg_isblank(const char c) * return empty string as *buf and position the file to the beginning * of the next line or EOF, whichever comes first. Allow spaces in * quoted strings. Terminate on unquoted commas. Handle - * comments. Treat unquoted keywords that might be user names or + * comments. Treat unquoted keywords that might be role names or * database names specially, by appending a newline to them. */ static void @@ -199,7 +193,8 @@ next_token(FILE *fp, char *buf, int bufsz) if (!saw_quote && (strcmp(start_buf, "all") == 0 || strcmp(start_buf, "sameuser") == 0 || - strcmp(start_buf, "samegroup") == 0)) + strcmp(start_buf, "samegroup") == 0 || + strcmp(start_buf, "samerole") == 0)) { /* append newline to a magical keyword */ *buf++ = '\n'; @@ -434,94 +429,58 @@ tokenize_file(const char *filename, FILE *file, } } - /* - * Compare two lines based on their user/group names. - * - * Used for qsort() sorting. - */ -static int -user_group_qsort_cmp(const void *list1, const void *list2) -{ - char *user1 = linitial(*(List **) list1); - char *user2 = linitial(*(List **) list2); - - return strcmp(user1, user2); -} - - -/* - * Compare two lines based on their user/group names. + * Compare two lines based on their role/member names. * * Used for bsearch() lookup. */ static int -user_group_bsearch_cmp(const void *user, const void *list) +role_bsearch_cmp(const void *role, const void *list) { - char *user2 = linitial(*(List **) list); + char *role2 = linitial(*(List **) list); - return strcmp(user, user2); + return strcmp(role, role2); } /* - * Lookup a group name in the pg_group file + * Lookup a role name in the pg_auth file */ -static List ** -get_group_line(const char *group) +List ** +get_role_line(const char *role) { /* On some versions of Solaris, bsearch of zero items dumps core */ - if (group_length == 0) + if (role_length == 0) return NULL; - return (List **) bsearch((void *) group, - (void *) group_sorted, - group_length, + return (List **) bsearch((void *) role, + (void *) role_sorted, + role_length, sizeof(List *), - user_group_bsearch_cmp); + role_bsearch_cmp); } /* - * Lookup a user name in the pg_shadow file - */ -List ** -get_user_line(const char *user) -{ - /* On some versions of Solaris, bsearch of zero items dumps core */ - if (user_length == 0) - return NULL; - - return (List **) bsearch((void *) user, - (void *) user_sorted, - user_length, - sizeof(List *), - user_group_bsearch_cmp); -} - - -/* - * Does user belong to group? + * Does member belong to role? */ static bool -check_group(char *group, char *user) +check_member(const char *role, const char *member) { List **line; + List **line2; ListCell *line_item; - char *usesysid; - if ((line = get_user_line(user)) == NULL) - return false; /* if user not exist, say "no" */ - /* Skip over username to get usesysid */ - usesysid = (char *) lsecond(*line); + if ((line = get_role_line(member)) == NULL) + return false; /* if member not exist, say "no" */ - if ((line = get_group_line(group)) == NULL) - return false; /* if group not exist, say "no" */ + if ((line2 = get_role_line(role)) == NULL) + return false; /* if role not exist, say "no" */ - /* skip over the group name, examine all the member usesysid's */ - for_each_cell(line_item, lnext(list_head(*line))) + /* skip over the role name, password, valuntil, examine all the members */ + for_each_cell(line_item, lfourth(*line2)) { - if (strcmp((char *) lfirst(line_item), usesysid) == 0) + if (strcmp((char *) lfirst(line_item), member) == 0) return true; } @@ -529,10 +488,10 @@ check_group(char *group, char *user) } /* - * Check comma user list for a specific user, handle group names. + * Check comma member list for a specific role, handle role names. */ static bool -check_user(char *user, char *param_str) +check_role(char *role, char *param_str) { char *tok; @@ -540,10 +499,10 @@ check_user(char *user, char *param_str) { if (tok[0] == '+') { - if (check_group(tok + 1, user)) + if (check_member(tok + 1, role)) return true; } - else if (strcmp(tok, user) == 0 || + else if (strcmp(tok, role) == 0 || strcmp(tok, "all\n") == 0) return true; } @@ -552,10 +511,10 @@ check_user(char *user, char *param_str) } /* - * Check to see if db/user combination matches param string. + * Check to see if db/role combination matches param string. */ static bool -check_db(char *dbname, char *user, char *param_str) +check_db(char *dbname, char *role, char *param_str) { char *tok; @@ -565,12 +524,13 @@ check_db(char *dbname, char *user, char *param_str) return true; else if (strcmp(tok, "sameuser\n") == 0) { - if (strcmp(dbname, user) == 0) + if (strcmp(dbname, role) == 0) return true; } - else if (strcmp(tok, "samegroup\n") == 0) + else if (strcmp(tok, "samegroup\n") == 0 || + strcmp(tok, "samerole\n") == 0) { - if (check_group(dbname, user)) + if (check_member(dbname, role)) return true; } else if (strcmp(tok, dbname) == 0) @@ -655,7 +615,7 @@ parse_hba(List *line, int line_num, hbaPort *port, { char *token; char *db; - char *user; + char *role; struct addrinfo *gai_result; struct addrinfo hints; int ret; @@ -675,11 +635,11 @@ parse_hba(List *line, int line_num, hbaPort *port, goto hba_syntax; db = lfirst(line_item); - /* Get the user. */ + /* Get the role. */ line_item = lnext(line_item); if (!line_item) goto hba_syntax; - user = lfirst(line_item); + role = lfirst(line_item); line_item = lnext(line_item); if (!line_item) @@ -735,11 +695,11 @@ parse_hba(List *line, int line_num, hbaPort *port, goto hba_syntax; db = lfirst(line_item); - /* Get the user. */ + /* Get the role. */ line_item = lnext(line_item); if (!line_item) goto hba_syntax; - user = lfirst(line_item); + role = lfirst(line_item); /* Read the IP address field. (with or without CIDR netmask) */ line_item = lnext(line_item); @@ -861,10 +821,10 @@ parse_hba(List *line, int line_num, hbaPort *port, else goto hba_syntax; - /* Does the entry match database and user? */ + /* Does the entry match database and role? */ if (!check_db(port->database_name, port->user_name, db)) return; - if (!check_user(port->user_name, user)) + if (!check_role(port->user_name, role)) return; /* Success */ @@ -923,27 +883,27 @@ check_hba(hbaPort *port) /* - * Load group/user name mapping file + * Load role/password mapping file */ void -load_group(void) +load_role(void) { char *filename; - FILE *group_file; + FILE *role_file; /* Discard any old data */ - if (group_lines || group_line_nums) - free_lines(&group_lines, &group_line_nums); - if (group_sorted) - pfree(group_sorted); - group_sorted = NULL; - group_length = 0; + if (role_lines || role_line_nums) + free_lines(&role_lines, &role_line_nums); + if (role_sorted) + pfree(role_sorted); + role_sorted = NULL; + role_length = 0; /* Read in the file contents */ - filename = group_getflatfilename(); - group_file = AllocateFile(filename, "r"); + filename = auth_getflatfilename(); + role_file = AllocateFile(filename, "r"); - if (group_file == NULL) + if (role_file == NULL) { /* no complaint if not there */ if (errno != ENOENT) @@ -954,84 +914,25 @@ load_group(void) return; } - tokenize_file(filename, group_file, &group_lines, &group_line_nums); + tokenize_file(filename, role_file, &role_lines, &role_line_nums); - FreeFile(group_file); + FreeFile(role_file); pfree(filename); - /* create sorted lines for binary searching */ - group_length = list_length(group_lines); - if (group_length) + /* create array for binary searching */ + role_length = list_length(role_lines); + if (role_length) { - int i = 0; - ListCell *line; + int i = 0; + ListCell *line; - group_sorted = palloc(group_length * sizeof(List *)); - - foreach(line, group_lines) - group_sorted[i++] = lfirst(line); - - qsort((void *) group_sorted, - group_length, - sizeof(List *), - user_group_qsort_cmp); - } -} - - -/* - * Load user/password mapping file - */ -void -load_user(void) -{ - char *filename; - FILE *user_file; - - /* Discard any old data */ - if (user_lines || user_line_nums) - free_lines(&user_lines, &user_line_nums); - if (user_sorted) - pfree(user_sorted); - user_sorted = NULL; - user_length = 0; - - /* Read in the file contents */ - filename = user_getflatfilename(); - user_file = AllocateFile(filename, "r"); - - if (user_file == NULL) - { - /* no complaint if not there */ - if (errno != ENOENT) - ereport(LOG, - (errcode_for_file_access(), - errmsg("could not open file \"%s\": %m", filename))); - pfree(filename); - return; - } - - tokenize_file(filename, user_file, &user_lines, &user_line_nums); - - FreeFile(user_file); - pfree(filename); - - /* create sorted lines for binary searching */ - user_length = list_length(user_lines); - if (user_length) - { - int i = 0; - ListCell *line; - - user_sorted = palloc(user_length * sizeof(List *)); - - foreach(line, user_lines) - user_sorted[i++] = lfirst(line); + role_sorted = palloc(role_length * sizeof(List *)); + foreach(line, role_lines) + { + role_sorted[i++] = lfirst(line); + } - qsort((void *) user_sorted, - user_length, - sizeof(List *), - user_group_qsort_cmp); + /* We assume the flat file was written already-sorted */ } } @@ -1108,18 +1009,18 @@ read_pg_database_line(FILE *fp, char *dbname, /* * Process one line from the ident config file. * - * Take the line and compare it to the needed map, pg_user and ident_user. + * Take the line and compare it to the needed map, pg_role and ident_user. * *found_p and *error_p are set according to our results. */ static void parse_ident_usermap(List *line, int line_number, const char *usermap_name, - const char *pg_user, const char *ident_user, + const char *pg_role, const char *ident_user, bool *found_p, bool *error_p) { ListCell *line_item; char *token; char *file_map; - char *file_pguser; + char *file_pgrole; char *file_ident_user; *found_p = false; @@ -1139,16 +1040,16 @@ parse_ident_usermap(List *line, int line_number, const char *usermap_name, token = lfirst(line_item); file_ident_user = token; - /* Get the PG username token */ + /* Get the PG rolename token */ line_item = lnext(line_item); if (!line_item) goto ident_syntax; token = lfirst(line_item); - file_pguser = token; + file_pgrole = token; /* Match? */ if (strcmp(file_map, usermap_name) == 0 && - strcmp(file_pguser, pg_user) == 0 && + strcmp(file_pgrole, pg_role) == 0 && strcmp(file_ident_user, ident_user) == 0) *found_p = true; @@ -1167,17 +1068,17 @@ ident_syntax: * Scan the (pre-parsed) ident usermap file line by line, looking for a match * * See if the user with ident username "ident_user" is allowed to act - * as Postgres user "pguser" according to usermap "usermap_name". + * as Postgres user "pgrole" according to usermap "usermap_name". * - * Special case: For usermap "sameuser", don't look in the usermap - * file. That's an implied map where "pguser" must be identical to + * Special case: For usermap "samerole", don't look in the usermap + * file. That's an implied map where "pgrole" must be identical to * "ident_user" in order to be authorized. * * Iff authorized, return true. */ static bool check_ident_usermap(const char *usermap_name, - const char *pg_user, + const char *pg_role, const char *ident_user) { bool found_entry = false, @@ -1190,9 +1091,10 @@ check_ident_usermap(const char *usermap_name, errmsg("cannot use Ident authentication without usermap field"))); found_entry = false; } - else if (strcmp(usermap_name, "sameuser\n") == 0) + else if (strcmp(usermap_name, "sameuser\n") == 0 || + strcmp(usermap_name, "samerole\n") == 0) { - if (strcmp(pg_user, ident_user) == 0) + if (strcmp(pg_role, ident_user) == 0) found_entry = true; else found_entry = false; @@ -1205,7 +1107,7 @@ check_ident_usermap(const char *usermap_name, forboth(line_cell, ident_lines, num_cell, ident_line_nums) { parse_ident_usermap(lfirst(line_cell), lfirst_int(num_cell), - usermap_name, pg_user, ident_user, + usermap_name, pg_role, ident_user, &found_entry, &error); if (found_entry || error) break; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index b6885f0d14932b0e74e2aa3a824b44aaf078ed18..ce16d2eba182fec697bfa0b626114839132495cf 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.309 2005/06/26 22:05:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.310 2005/06/28 05:08:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1761,8 +1761,7 @@ _copyPrivGrantee(PrivGrantee *from) { PrivGrantee *newnode = makeNode(PrivGrantee); - COPY_STRING_FIELD(username); - COPY_STRING_FIELD(groupname); + COPY_STRING_FIELD(rolname); return newnode; } @@ -1778,6 +1777,21 @@ _copyFuncWithArgs(FuncWithArgs *from) return newnode; } +static GrantRoleStmt * +_copyGrantRoleStmt(GrantRoleStmt *from) +{ + GrantRoleStmt *newnode = makeNode(GrantRoleStmt); + + COPY_NODE_FIELD(granted_roles); + COPY_NODE_FIELD(grantee_roles); + COPY_SCALAR_FIELD(is_grant); + COPY_SCALAR_FIELD(admin_opt); + COPY_STRING_FIELD(grantor); + COPY_SCALAR_FIELD(behavior); + + return newnode; +} + static DeclareCursorStmt * _copyDeclareCursorStmt(DeclareCursorStmt *from) { @@ -2374,46 +2388,47 @@ _copyDropPLangStmt(DropPLangStmt *from) return newnode; } -static CreateUserStmt * -_copyCreateUserStmt(CreateUserStmt *from) +static CreateRoleStmt * +_copyCreateRoleStmt(CreateRoleStmt *from) { - CreateUserStmt *newnode = makeNode(CreateUserStmt); + CreateRoleStmt *newnode = makeNode(CreateRoleStmt); - COPY_STRING_FIELD(user); + COPY_STRING_FIELD(role); COPY_NODE_FIELD(options); return newnode; } -static AlterUserStmt * -_copyAlterUserStmt(AlterUserStmt *from) +static AlterRoleStmt * +_copyAlterRoleStmt(AlterRoleStmt *from) { - AlterUserStmt *newnode = makeNode(AlterUserStmt); + AlterRoleStmt *newnode = makeNode(AlterRoleStmt); - COPY_STRING_FIELD(user); + COPY_STRING_FIELD(role); COPY_NODE_FIELD(options); + COPY_SCALAR_FIELD(action); return newnode; } -static AlterUserSetStmt * -_copyAlterUserSetStmt(AlterUserSetStmt *from) +static AlterRoleSetStmt * +_copyAlterRoleSetStmt(AlterRoleSetStmt *from) { - AlterUserSetStmt *newnode = makeNode(AlterUserSetStmt); + AlterRoleSetStmt *newnode = makeNode(AlterRoleSetStmt); - COPY_STRING_FIELD(user); + COPY_STRING_FIELD(role); COPY_STRING_FIELD(variable); COPY_NODE_FIELD(value); return newnode; } -static DropUserStmt * -_copyDropUserStmt(DropUserStmt *from) +static DropRoleStmt * +_copyDropRoleStmt(DropRoleStmt *from) { - DropUserStmt *newnode = makeNode(DropUserStmt); + DropRoleStmt *newnode = makeNode(DropRoleStmt); - COPY_NODE_FIELD(users); + COPY_NODE_FIELD(roles); return newnode; } @@ -2441,39 +2456,6 @@ _copyConstraintsSetStmt(ConstraintsSetStmt *from) return newnode; } -static CreateGroupStmt * -_copyCreateGroupStmt(CreateGroupStmt *from) -{ - CreateGroupStmt *newnode = makeNode(CreateGroupStmt); - - COPY_STRING_FIELD(name); - COPY_NODE_FIELD(options); - - return newnode; -} - -static AlterGroupStmt * -_copyAlterGroupStmt(AlterGroupStmt *from) -{ - AlterGroupStmt *newnode = makeNode(AlterGroupStmt); - - COPY_STRING_FIELD(name); - COPY_SCALAR_FIELD(action); - COPY_NODE_FIELD(listUsers); - - return newnode; -} - -static DropGroupStmt * -_copyDropGroupStmt(DropGroupStmt *from) -{ - DropGroupStmt *newnode = makeNode(DropGroupStmt); - - COPY_STRING_FIELD(name); - - return newnode; -} - static ReindexStmt * _copyReindexStmt(ReindexStmt *from) { @@ -2927,6 +2909,9 @@ copyObject(void *from) case T_GrantStmt: retval = _copyGrantStmt(from); break; + case T_GrantRoleStmt: + retval = _copyGrantRoleStmt(from); + break; case T_DeclareCursorStmt: retval = _copyDeclareCursorStmt(from); break; @@ -3071,17 +3056,17 @@ copyObject(void *from) case T_DropPLangStmt: retval = _copyDropPLangStmt(from); break; - case T_CreateUserStmt: - retval = _copyCreateUserStmt(from); + case T_CreateRoleStmt: + retval = _copyCreateRoleStmt(from); break; - case T_AlterUserStmt: - retval = _copyAlterUserStmt(from); + case T_AlterRoleStmt: + retval = _copyAlterRoleStmt(from); break; - case T_AlterUserSetStmt: - retval = _copyAlterUserSetStmt(from); + case T_AlterRoleSetStmt: + retval = _copyAlterRoleSetStmt(from); break; - case T_DropUserStmt: - retval = _copyDropUserStmt(from); + case T_DropRoleStmt: + retval = _copyDropRoleStmt(from); break; case T_LockStmt: retval = _copyLockStmt(from); @@ -3089,15 +3074,6 @@ copyObject(void *from) case T_ConstraintsSetStmt: retval = _copyConstraintsSetStmt(from); break; - case T_CreateGroupStmt: - retval = _copyCreateGroupStmt(from); - break; - case T_AlterGroupStmt: - retval = _copyAlterGroupStmt(from); - break; - case T_DropGroupStmt: - retval = _copyDropGroupStmt(from); - break; case T_ReindexStmt: retval = _copyReindexStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 31a2c302244a20d8394b6e65a4865bdb31b71c9a..ade4f16a090885c880ed1e4ab42479aad84a5701 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.246 2005/06/26 22:05:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.247 2005/06/28 05:08:57 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -778,8 +778,7 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b) static bool _equalPrivGrantee(PrivGrantee *a, PrivGrantee *b) { - COMPARE_STRING_FIELD(username); - COMPARE_STRING_FIELD(groupname); + COMPARE_STRING_FIELD(rolname); return true; } @@ -793,6 +792,19 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b) return true; } +static bool +_equalGrantRoleStmt(GrantRoleStmt *a, GrantRoleStmt *b) +{ + COMPARE_NODE_FIELD(granted_roles); + COMPARE_NODE_FIELD(grantee_roles); + COMPARE_SCALAR_FIELD(is_grant); + COMPARE_SCALAR_FIELD(admin_opt); + COMPARE_STRING_FIELD(grantor); + COMPARE_SCALAR_FIELD(behavior); + + return true; +} + static bool _equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b) { @@ -1295,27 +1307,28 @@ _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b) } static bool -_equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b) +_equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b) { - COMPARE_STRING_FIELD(user); + COMPARE_STRING_FIELD(role); COMPARE_NODE_FIELD(options); return true; } static bool -_equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b) +_equalAlterRoleStmt(AlterRoleStmt *a, AlterRoleStmt *b) { - COMPARE_STRING_FIELD(user); + COMPARE_STRING_FIELD(role); COMPARE_NODE_FIELD(options); + COMPARE_SCALAR_FIELD(action); return true; } static bool -_equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b) +_equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b) { - COMPARE_STRING_FIELD(user); + COMPARE_STRING_FIELD(role); COMPARE_STRING_FIELD(variable); COMPARE_NODE_FIELD(value); @@ -1323,9 +1336,9 @@ _equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b) } static bool -_equalDropUserStmt(DropUserStmt *a, DropUserStmt *b) +_equalDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b) { - COMPARE_NODE_FIELD(users); + COMPARE_NODE_FIELD(roles); return true; } @@ -1349,33 +1362,6 @@ _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b) return true; } -static bool -_equalCreateGroupStmt(CreateGroupStmt *a, CreateGroupStmt *b) -{ - COMPARE_STRING_FIELD(name); - COMPARE_NODE_FIELD(options); - - return true; -} - -static bool -_equalAlterGroupStmt(AlterGroupStmt *a, AlterGroupStmt *b) -{ - COMPARE_STRING_FIELD(name); - COMPARE_SCALAR_FIELD(action); - COMPARE_NODE_FIELD(listUsers); - - return true; -} - -static bool -_equalDropGroupStmt(DropGroupStmt *a, DropGroupStmt *b) -{ - COMPARE_STRING_FIELD(name); - - return true; -} - static bool _equalReindexStmt(ReindexStmt *a, ReindexStmt *b) { @@ -1971,6 +1957,9 @@ equal(void *a, void *b) case T_GrantStmt: retval = _equalGrantStmt(a, b); break; + case T_GrantRoleStmt: + retval = _equalGrantRoleStmt(a, b); + break; case T_DeclareCursorStmt: retval = _equalDeclareCursorStmt(a, b); break; @@ -2115,17 +2104,17 @@ equal(void *a, void *b) case T_DropPLangStmt: retval = _equalDropPLangStmt(a, b); break; - case T_CreateUserStmt: - retval = _equalCreateUserStmt(a, b); + case T_CreateRoleStmt: + retval = _equalCreateRoleStmt(a, b); break; - case T_AlterUserStmt: - retval = _equalAlterUserStmt(a, b); + case T_AlterRoleStmt: + retval = _equalAlterRoleStmt(a, b); break; - case T_AlterUserSetStmt: - retval = _equalAlterUserSetStmt(a, b); + case T_AlterRoleSetStmt: + retval = _equalAlterRoleSetStmt(a, b); break; - case T_DropUserStmt: - retval = _equalDropUserStmt(a, b); + case T_DropRoleStmt: + retval = _equalDropRoleStmt(a, b); break; case T_LockStmt: retval = _equalLockStmt(a, b); @@ -2133,15 +2122,6 @@ equal(void *a, void *b) case T_ConstraintsSetStmt: retval = _equalConstraintsSetStmt(a, b); break; - case T_CreateGroupStmt: - retval = _equalCreateGroupStmt(a, b); - break; - case T_AlterGroupStmt: - retval = _equalAlterGroupStmt(a, b); - break; - case T_DropGroupStmt: - retval = _equalDropGroupStmt(a, b); - break; case T_ReindexStmt: retval = _equalReindexStmt(a, b); break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 91705123bd7959c8db8f0e8a4950a674c3716972..81fb9c88fa6d2bff3402fff4bc4917e90c7373ce 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.256 2005/06/26 22:05:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.257 2005/06/28 05:08:57 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -1535,7 +1535,7 @@ _outRangeTblEntry(StringInfo str, RangeTblEntry *node) WRITE_BOOL_FIELD(inh); WRITE_BOOL_FIELD(inFromCl); WRITE_UINT_FIELD(requiredPerms); - WRITE_UINT_FIELD(checkAsUser); + WRITE_OID_FIELD(checkAsUser); } static void diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 9b27dc478ef8c42268104ccc177ad0300c23d7f1..2e9c842051a39e4c92ca38295abeef86d1f19b62 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.179 2005/06/26 22:05:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.180 2005/06/28 05:08:57 tgl Exp $ * * NOTES * Path and Plan nodes do not have any readfuncs support, because we @@ -917,7 +917,7 @@ _readRangeTblEntry(void) READ_BOOL_FIELD(inh); READ_BOOL_FIELD(inFromCl); READ_UINT_FIELD(requiredPerms); - READ_UINT_FIELD(checkAsUser); + READ_OID_FIELD(checkAsUser); READ_DONE(); } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 28e1ac0264d1642344004743960a6e8f68b09836..d822a7176a72cc9a32af4d9ac1e2cab5564a35b0 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.498 2005/06/26 22:05:38 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.499 2005/06/28 05:08:57 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -133,19 +133,20 @@ static void doNegateFloat(Value *v); %type <node> stmt schema_stmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt AlterUserStmt AlterUserSetStmt + AlterRoleStmt AlterRoleSetStmt AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt - CreateAssertStmt CreateTrigStmt CreateUserStmt + CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt - DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt + DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt - GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt + GrantRoleStmt GrantStmt IndexStmt InsertStmt ListenStmt LoadStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt - RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt + RemoveFuncStmt RemoveOperStmt RenameStmt RevokeRoleStmt RevokeStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt SelectStmt TransactionStmt TruncateStmt UnlistenStmt UpdateStmt VacuumStmt @@ -170,17 +171,16 @@ static void doNegateFloat(Value *v); %type <ival> opt_lock lock_type cast_context %type <boolean> opt_force opt_or_replace opt_grant_grant_option opt_revoke_grant_option + opt_alter_admin_option + opt_grant_admin_option opt_revoke_admin_option opt_nowait %type <boolean> like_including_defaults -%type <list> user_list +%type <list> role_list -%type <list> OptGroupList -%type <defelt> OptGroupElem - -%type <list> OptUserList -%type <defelt> OptUserElem +%type <list> OptRoleList +%type <defelt> OptRoleElem %type <str> OptSchemaName %type <list> OptSchemaEltList @@ -308,7 +308,7 @@ static void doNegateFloat(Value *v); %type <ival> Iconst %type <str> Sconst comment_text -%type <str> UserId opt_boolean ColId_or_Sconst +%type <str> RoleId opt_granted_by opt_boolean ColId_or_Sconst %type <list> var_list var_list_or_default %type <str> ColId ColLabel var_name type_name param_name %type <node> var_value zone_value @@ -336,7 +336,7 @@ static void doNegateFloat(Value *v); */ /* ordinary key words in alphabetical order */ -%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER +%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD ADMIN AFTER AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION @@ -347,8 +347,8 @@ static void doNegateFloat(Value *v); CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB - CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME - CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE + CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_TIME + CURRENT_TIMESTAMP CURRENT_ROLE CURRENT_USER CURSOR CYCLE DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS @@ -360,7 +360,7 @@ static void doNegateFloat(Value *v); FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM FULL FUNCTION - GLOBAL GRANT GREATEST GROUP_P + GLOBAL GRANT GRANTED GREATEST GROUP_P HANDLER HAVING HEADER HOLD HOUR_P @@ -375,13 +375,13 @@ static void doNegateFloat(Value *v); LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION - LOCK_P + LOCK_P LOGIN MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB - NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P - NULLIF NUMERIC + NOCREATEROLE NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P + NULLIF NUMERIC NOLOGIN OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNER @@ -394,10 +394,10 @@ static void doNegateFloat(Value *v); READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT - ROLLBACK ROW ROWS RULE + ROLE ROLLBACK ROW ROWS RULE SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE - SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE + SERIALIZABLE SESSION SESSION_ROLE SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYMMETRIC SYSID SYSTEM_P @@ -497,6 +497,8 @@ stmt : | AlterOwnerStmt | AlterSeqStmt | AlterTableStmt + | AlterRoleSetStmt + | AlterRoleStmt | AlterUserSetStmt | AlterUserStmt | AnalyzeStmt @@ -520,6 +522,7 @@ stmt : | CreateStmt | CreateTableSpaceStmt | CreateTrigStmt + | CreateRoleStmt | CreateUserStmt | CreatedbStmt | DeallocateStmt @@ -535,11 +538,13 @@ stmt : | DropStmt | DropTableSpaceStmt | DropTrigStmt + | DropRoleStmt | DropUserStmt | DropdbStmt | ExecuteStmt | ExplainStmt | FetchStmt + | GrantRoleStmt | GrantStmt | IndexStmt | InsertStmt @@ -553,6 +558,7 @@ stmt : | RemoveFuncStmt | RemoveOperStmt | RenameStmt + | RevokeRoleStmt | RevokeStmt | RuleStmt | SelectStmt @@ -571,16 +577,16 @@ stmt : /***************************************************************************** * - * Create a new Postgres DBMS user + * Create a new Postgres DBMS role * * *****************************************************************************/ -CreateUserStmt: - CREATE USER UserId opt_with OptUserList +CreateRoleStmt: + CREATE ROLE RoleId opt_with OptRoleList { - CreateUserStmt *n = makeNode(CreateUserStmt); - n->user = $3; + CreateRoleStmt *n = makeNode(CreateRoleStmt); + n->role = $3; n->options = $5; $$ = (Node *)n; } @@ -591,6 +597,80 @@ opt_with: WITH {} | /*EMPTY*/ {} ; +/***************************************************************************** + * + * Create a new Postgres DBMS user (role with implied login ability) + * + * + *****************************************************************************/ + +CreateUserStmt: + CREATE USER RoleId opt_with OptRoleList + { + CreateRoleStmt *n = makeNode(CreateRoleStmt); + n->role = $3; + n->options = $5; + n->options = lappend(n->options,makeDefElem("canlogin", (Node *)makeInteger(TRUE))); + $$ = (Node *)n; + } + ; + + +/***************************************************************************** + * + * Alter a postgresql DBMS role + * + * + *****************************************************************************/ + +AlterRoleStmt: + ALTER ROLE RoleId opt_with OptRoleList + { + AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; + n->options = $5; + $$ = (Node *)n; + } + | ALTER ROLE RoleId add_drop ROLE role_list opt_alter_admin_option + { + AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; + n->action = $4; + n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6)); + n->options = lappend(n->options,makeDefElem("adminopt", (Node *)makeInteger($7))); + $$ = (Node *)n; + } + ; + +add_drop: ADD { $$ = +1; } + | DROP { $$ = -1; } + ; + +opt_alter_admin_option: + ADMIN OPTION { $$ = TRUE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + +AlterRoleSetStmt: + ALTER ROLE RoleId SET set_rest + { + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = $3; + n->variable = $5->name; + n->value = $5->args; + $$ = (Node *)n; + } + | ALTER ROLE RoleId VariableResetStmt + { + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = $3; + n->variable = ((VariableResetStmt *)$4)->name; + n->value = NIL; + $$ = (Node *)n; + } + ; + + /***************************************************************************** * * Alter a postgresql DBMS user @@ -599,10 +679,10 @@ opt_with: WITH {} *****************************************************************************/ AlterUserStmt: - ALTER USER UserId opt_with OptUserList + ALTER USER RoleId opt_with OptRoleList { - AlterUserStmt *n = makeNode(AlterUserStmt); - n->user = $3; + AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; n->options = $5; $$ = (Node *)n; } @@ -610,18 +690,18 @@ AlterUserStmt: AlterUserSetStmt: - ALTER USER UserId SET set_rest + ALTER USER RoleId SET set_rest { - AlterUserSetStmt *n = makeNode(AlterUserSetStmt); - n->user = $3; + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = $3; n->variable = $5->name; n->value = $5->args; $$ = (Node *)n; } - | ALTER USER UserId VariableResetStmt + | ALTER USER RoleId VariableResetStmt { - AlterUserSetStmt *n = makeNode(AlterUserSetStmt); - n->user = $3; + AlterRoleSetStmt *n = makeNode(AlterRoleSetStmt); + n->role = $3; n->variable = ((VariableResetStmt *)$4)->name; n->value = NIL; $$ = (Node *)n; @@ -629,6 +709,24 @@ AlterUserSetStmt: ; +/***************************************************************************** + * + * Drop a postgresql DBMS role + * + * XXX Ideally this would have CASCADE/RESTRICT options, but since a role + * might own objects in multiple databases, there is presently no way to + * implement either cascading or restricting. Caveat DBA. + *****************************************************************************/ + +DropRoleStmt: + DROP ROLE role_list + { + DropRoleStmt *n = makeNode(DropRoleStmt); + n->roles = $3; + $$ = (Node *)n; + } + ; + /***************************************************************************** * * Drop a postgresql DBMS user @@ -639,23 +737,23 @@ AlterUserSetStmt: *****************************************************************************/ DropUserStmt: - DROP USER user_list + DROP USER role_list { - DropUserStmt *n = makeNode(DropUserStmt); - n->users = $3; + DropRoleStmt *n = makeNode(DropRoleStmt); + n->roles = $3; $$ = (Node *)n; } ; /* - * Options for CREATE USER and ALTER USER + * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER for backwards compat) */ -OptUserList: - OptUserList OptUserElem { $$ = lappend($1, $2); } +OptRoleList: + OptRoleList OptRoleElem { $$ = lappend($1, $2); } | /* EMPTY */ { $$ = NIL; } ; -OptUserElem: +OptRoleElem: PASSWORD Sconst { $$ = makeDefElem("password", (Node *)makeString($2)); @@ -680,66 +778,75 @@ OptUserElem: { $$ = makeDefElem("createdb", (Node *)makeInteger(FALSE)); } + | CREATEROLE + { + $$ = makeDefElem("createrole", (Node *)makeInteger(TRUE)); + } | CREATEUSER { - $$ = makeDefElem("createuser", (Node *)makeInteger(TRUE)); + $$ = makeDefElem("createrole", (Node *)makeInteger(TRUE)); + } + | LOGIN + { + $$ = makeDefElem("canlogin", (Node *)makeInteger(TRUE)); + } + | NOCREATEROLE + { + $$ = makeDefElem("createrole", (Node *)makeInteger(FALSE)); } | NOCREATEUSER { - $$ = makeDefElem("createuser", (Node *)makeInteger(FALSE)); + $$ = makeDefElem("createrole", (Node *)makeInteger(FALSE)); } - | IN_P GROUP_P user_list + | NOLOGIN { - $$ = makeDefElem("groupElts", (Node *)$3); + $$ = makeDefElem("canlogin", (Node *)makeInteger(FALSE)); + } + | IN_P ROLE role_list + { + $$ = makeDefElem("roleElts", (Node *)$3); + } + | IN_P GROUP_P role_list + { + $$ = makeDefElem("roleElts", (Node *)$3); } | VALID UNTIL Sconst { $$ = makeDefElem("validUntil", (Node *)makeString($3)); } + | ROLE role_list + { + $$ = makeDefElem("rolememElts", (Node *)$2); + } + | USER role_list + { + $$ = makeDefElem("rolememElts", (Node *)$2); + } ; -user_list: user_list ',' UserId { $$ = lappend($1, makeString($3)); } - | UserId { $$ = list_make1(makeString($1)); } +role_list: role_list ',' RoleId { $$ = lappend($1, makeString($3)); } + | RoleId { $$ = list_make1(makeString($1)); } ; /***************************************************************************** * - * Create a postgresql group + * Create a postgresql group (role without login ability) * * *****************************************************************************/ CreateGroupStmt: - CREATE GROUP_P UserId opt_with OptGroupList + CREATE GROUP_P RoleId opt_with OptRoleList { - CreateGroupStmt *n = makeNode(CreateGroupStmt); - n->name = $3; + CreateRoleStmt *n = makeNode(CreateRoleStmt); + n->role = $3; n->options = $5; $$ = (Node *)n; } ; -/* - * Options for CREATE GROUP - */ -OptGroupList: - OptGroupList OptGroupElem { $$ = lappend($1, $2); } - | /* EMPTY */ { $$ = NIL; } - ; - -OptGroupElem: - USER user_list - { - $$ = makeDefElem("userElts", (Node *)$2); - } - | SYSID Iconst - { - $$ = makeDefElem("sysid", (Node *)makeInteger($2)); - } - ; - /***************************************************************************** * @@ -749,20 +856,16 @@ OptGroupElem: *****************************************************************************/ AlterGroupStmt: - ALTER GROUP_P UserId add_drop USER user_list + ALTER GROUP_P RoleId add_drop USER role_list { - AlterGroupStmt *n = makeNode(AlterGroupStmt); - n->name = $3; + AlterRoleStmt *n = makeNode(AlterRoleStmt); + n->role = $3; n->action = $4; - n->listUsers = $6; + n->options = lappend(n->options,makeDefElem("rolememElts", (Node *)$6)); $$ = (Node *)n; } ; -add_drop: ADD { $$ = +1; } - | DROP { $$ = -1; } - ; - /***************************************************************************** * @@ -772,10 +875,10 @@ add_drop: ADD { $$ = +1; } *****************************************************************************/ DropGroupStmt: - DROP GROUP_P UserId + DROP GROUP_P role_list { - DropGroupStmt *n = makeNode(DropGroupStmt); - n->name = $3; + DropRoleStmt *n = makeNode(DropRoleStmt); + n->roles = $3; $$ = (Node *)n; } ; @@ -788,7 +891,7 @@ DropGroupStmt: *****************************************************************************/ CreateSchemaStmt: - CREATE SCHEMA OptSchemaName AUTHORIZATION UserId OptSchemaEltList + CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); /* One can omit the schema name or the authorization id. */ @@ -1307,8 +1410,8 @@ alter_rel_cmds: /* Subcommands that are for ALTER TABLE or ALTER INDEX */ alter_rel_cmd: - /* ALTER [TABLE|INDEX] <name> OWNER TO UserId */ - OWNER TO UserId + /* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */ + OWNER TO RoleId { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_ChangeOwner; @@ -3013,6 +3116,36 @@ from_in: FROM {} ; +/***************************************************************************** + * + * GRANT and REVOKE ROLE statements + * + *****************************************************************************/ + +GrantRoleStmt: GRANT ROLE role_list TO role_list opt_grant_admin_option + opt_granted_by + { + GrantRoleStmt *n = makeNode(GrantRoleStmt); + n->granted_roles = $3; + n->grantee_roles = $5; + n->is_grant = true; + n->admin_opt = $6; + n->grantor = $7; + $$ = (Node*)n; + } + +RevokeRoleStmt: REVOKE ROLE opt_revoke_admin_option role_list FROM role_list + opt_drop_behavior + { + GrantRoleStmt *n = makeNode(GrantRoleStmt); + n->granted_roles = $4; + n->grantee_roles = $6; + n->is_grant = false; + n->admin_opt = $3; + n->behavior = $7; + $$ = (Node*)n; + } + /***************************************************************************** * * GRANT and REVOKE statements @@ -3139,26 +3272,24 @@ grantee_list: | grantee_list ',' grantee { $$ = lappend($1, $3); } ; -grantee: ColId +grantee: RoleId { PrivGrantee *n = makeNode(PrivGrantee); /* This hack lets us avoid reserving PUBLIC as a keyword*/ if (strcmp($1, "public") == 0) - n->username = NULL; + n->rolname = NULL; else - n->username = $1; - n->groupname = NULL; + n->rolname = $1; $$ = (Node *)n; } - | GROUP_P ColId + | GROUP_P RoleId { PrivGrantee *n = makeNode(PrivGrantee); /* Treat GROUP PUBLIC as a synonym for PUBLIC */ if (strcmp($2, "public") == 0) - n->groupname = NULL; + n->rolname = NULL; else - n->groupname = $2; - n->username = NULL; + n->rolname = $2; $$ = (Node *)n; } ; @@ -3169,11 +3300,26 @@ opt_grant_grant_option: | /*EMPTY*/ { $$ = FALSE; } ; +opt_grant_admin_option: + WITH ADMIN OPTION { $$ = TRUE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + +opt_granted_by: + GRANTED BY RoleId { $$ = $3; } + | /*EMPTY*/ { $$ = NULL; } + ; + opt_revoke_grant_option: GRANT OPTION FOR { $$ = TRUE; } | /*EMPTY*/ { $$ = FALSE; } ; +opt_revoke_admin_option: + ADMIN OPTION FOR { $$ = TRUE; } + | /*EMPTY*/ { $$ = FALSE; } + ; + function_with_argtypes_list: function_with_argtypes { $$ = list_make1($1); } @@ -3727,10 +3873,10 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name n->newname = $7; $$ = (Node *)n; } - | ALTER GROUP_P UserId RENAME TO UserId + | ALTER GROUP_P RoleId RENAME TO RoleId { RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_GROUP; + n->renameType = OBJECT_ROLE; n->subname = $3; n->newname = $6; $$ = (Node *)n; @@ -3796,10 +3942,18 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name n->renameType = OBJECT_TRIGGER; $$ = (Node *)n; } - | ALTER USER UserId RENAME TO UserId + | ALTER ROLE RoleId RENAME TO RoleId { RenameStmt *n = makeNode(RenameStmt); - n->renameType = OBJECT_USER; + n->renameType = OBJECT_ROLE; + n->subname = $3; + n->newname = $6; + $$ = (Node *)n; + } + | ALTER USER RoleId RENAME TO RoleId + { + RenameStmt *n = makeNode(RenameStmt); + n->renameType = OBJECT_ROLE; n->subname = $3; n->newname = $6; $$ = (Node *)n; @@ -3825,7 +3979,7 @@ opt_column: COLUMN { $$ = COLUMN; } * *****************************************************************************/ -AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId +AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_AGGREGATE; @@ -3834,7 +3988,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $9; $$ = (Node *)n; } - | ALTER CONVERSION_P any_name OWNER TO UserId + | ALTER CONVERSION_P any_name OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_CONVERSION; @@ -3842,7 +3996,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $6; $$ = (Node *)n; } - | ALTER DATABASE database_name OWNER TO UserId + | ALTER DATABASE database_name OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_DATABASE; @@ -3850,7 +4004,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $6; $$ = (Node *)n; } - | ALTER DOMAIN_P any_name OWNER TO UserId + | ALTER DOMAIN_P any_name OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_DOMAIN; @@ -3858,7 +4012,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $6; $$ = (Node *)n; } - | ALTER FUNCTION func_name func_args OWNER TO UserId + | ALTER FUNCTION func_name func_args OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_FUNCTION; @@ -3867,7 +4021,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $7; $$ = (Node *)n; } - | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO UserId + | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPERATOR; @@ -3876,7 +4030,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $9; $$ = (Node *)n; } - | ALTER OPERATOR CLASS any_name USING access_method OWNER TO UserId + | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPCLASS; @@ -3885,7 +4039,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $9; $$ = (Node *)n; } - | ALTER SCHEMA name OWNER TO UserId + | ALTER SCHEMA name OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_SCHEMA; @@ -3893,7 +4047,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $6; $$ = (Node *)n; } - | ALTER TYPE_P any_name OWNER TO UserId + | ALTER TYPE_P any_name OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_TYPE; @@ -3901,7 +4055,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO UserId n->newowner = $6; $$ = (Node *)n; } - | ALTER TABLESPACE name OWNER TO UserId + | ALTER TABLESPACE name OWNER TO RoleId { AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_TABLESPACE; @@ -6903,6 +7057,33 @@ func_expr: func_name '(' ')' $$ = (Node *)makeTypeCast((Node *)s, d); } + | CURRENT_ROLE + { + FuncCall *n = makeNode(FuncCall); + n->funcname = SystemFuncName("current_user"); + n->args = NIL; + n->agg_star = FALSE; + n->agg_distinct = FALSE; + $$ = (Node *)n; + } + | SESSION_ROLE + { + FuncCall *n = makeNode(FuncCall); + n->funcname = SystemFuncName("session_user"); + n->args = NIL; + n->agg_star = FALSE; + n->agg_distinct = FALSE; + $$ = (Node *)n; + } + | ROLE + { + FuncCall *n = makeNode(FuncCall); + n->funcname = SystemFuncName("current_user"); + n->args = NIL; + n->agg_star = FALSE; + n->agg_distinct = FALSE; + $$ = (Node *)n; + } | CURRENT_USER { FuncCall *n = makeNode(FuncCall); @@ -7685,7 +7866,7 @@ AexprConst: Iconst Iconst: ICONST { $$ = $1; }; Sconst: SCONST { $$ = $1; }; -UserId: ColId { $$ = $1; }; +RoleId: ColId { $$ = $1; }; /* * Name classification hierarchy. @@ -7774,6 +7955,7 @@ unreserved_keyword: | CONVERSION_P | COPY | CREATEDB + | CREATEROLE | CREATEUSER | CSV | CURSOR @@ -7834,6 +8016,7 @@ unreserved_keyword: | LOCAL | LOCATION | LOCK_P + | LOGIN | MATCH | MAXVALUE | MINUTE_P @@ -7845,7 +8028,9 @@ unreserved_keyword: | NEXT | NO | NOCREATEDB + | NOCREATEROLE | NOCREATEUSER + | NOLOGIN | NOTHING | NOTIFY | NOWAIT @@ -8045,6 +8230,7 @@ reserved_keyword: | CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP + | CURRENT_ROLE | CURRENT_USER | DEFAULT | DEFERRABLE @@ -8083,6 +8269,7 @@ reserved_keyword: | PRIMARY | REFERENCES | SELECT + | SESSION_ROLE | SESSION_USER | SOME | SYMMETRIC @@ -8093,6 +8280,7 @@ reserved_keyword: | TRUE_P | UNION | UNIQUE + | ROLE | USER | USING | WHEN diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 41e45bc7475d71489acf085c871581ec743c05eb..a11d4affc1df3ea385f0e476d6d8b06353589d6a 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.159 2005/06/26 22:05:39 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.160 2005/06/28 05:08:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -269,6 +269,7 @@ static const ScanKeyword ScanKeywords[] = { {"returns", RETURNS}, {"revoke", REVOKE}, {"right", RIGHT}, + {"role", ROLE}, {"rollback", ROLLBACK}, {"row", ROW}, {"rows", ROWS}, diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 5786ac44d0709fb6c54559e3537be849d9e3b67f..51d200736b08ef46a909804e8daacb35b836ab37 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.111 2005/06/05 00:38:09 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_relation.c,v 1.112 2005/06/28 05:08:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -567,7 +567,7 @@ addRangeTableEntry(ParseState *pstate, rte->inFromCl = inFromCl; rte->requiredPerms = ACL_SELECT; - rte->checkAsUser = 0; /* not set-uid by default, either */ + rte->checkAsUser = InvalidOid; /* not set-uid by default, either */ /* * Add completed RTE to pstate's range table list, but not to join @@ -620,7 +620,7 @@ addRangeTableEntryForRelation(ParseState *pstate, rte->inFromCl = inFromCl; rte->requiredPerms = ACL_SELECT; - rte->checkAsUser = 0; /* not set-uid by default, either */ + rte->checkAsUser = InvalidOid; /* not set-uid by default, either */ /* * Add completed RTE to pstate's range table list, but not to join @@ -698,7 +698,7 @@ addRangeTableEntryForSubquery(ParseState *pstate, rte->inFromCl = inFromCl; rte->requiredPerms = 0; - rte->checkAsUser = 0; + rte->checkAsUser = InvalidOid; /* * Add completed RTE to pstate's range table list, but not to join @@ -823,7 +823,7 @@ addRangeTableEntryForFunction(ParseState *pstate, rte->inFromCl = inFromCl; rte->requiredPerms = 0; - rte->checkAsUser = 0; + rte->checkAsUser = InvalidOid; /* * Add completed RTE to pstate's range table list, but not to join @@ -882,7 +882,7 @@ addRangeTableEntryForJoin(ParseState *pstate, rte->inFromCl = inFromCl; rte->requiredPerms = 0; - rte->checkAsUser = 0; + rte->checkAsUser = InvalidOid; /* * Add completed RTE to pstate's range table list, but not to join diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 8366bdb8b4cec4aa9bbdcaa5a8e526d2b7dd14b6..b429275d9f65041ece7982b49c0e4769019771e4 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -13,7 +13,7 @@ * * Copyright (c) 2001-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.96 2005/06/25 23:58:57 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.97 2005/06/28 05:08:59 tgl Exp $ * ---------- */ #include "postgres.h" @@ -34,7 +34,6 @@ #include "access/heapam.h" #include "access/xact.h" #include "catalog/pg_database.h" -#include "catalog/pg_shadow.h" #include "libpq/libpq.h" #include "libpq/pqsignal.h" #include "mb/pg_wchar.h" diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 6ca13944f8aca04833869659a80a9a437cdf0710..27b28b89f544e6e9259d21df47619220694d6535 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.454 2005/06/17 22:32:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.455 2005/06/28 05:08:59 tgl Exp $ * * NOTES * @@ -2032,12 +2032,11 @@ reaper(SIGNAL_ARGS) FatalError = false; /* - * Load the flat user/group files into postmaster's caches. - * The startup process has recomputed these from the database - * contents, so we wait till it finishes before loading them. + * Load the flat authorization file into postmaster's cache. + * The startup process has recomputed this from the database + * contents, so we wait till it finishes before loading it. */ - load_user(); - load_group(); + load_role(); /* * Crank up the background writer. It doesn't matter if this @@ -2664,8 +2663,7 @@ BackendRun(Port *port) load_hba(); load_ident(); - load_user(); - load_group(); + load_role(); #endif /* @@ -3290,10 +3288,9 @@ sigusr1_handler(SIGNAL_ARGS) if (CheckPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE)) { /* - * Password or group file has changed. + * Authorization file has changed. */ - load_user(); - load_group(); + load_role(); } if (CheckPostmasterSignal(PMSIGNAL_WAKEN_CHILDREN)) diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index c793cabd2a9afc107c6045e6a2bec39c88c4d6a6..c28ea627e507d5822e7861fb463bc927b2a0f2dd 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.104 2005/04/14 20:03:25 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/rewrite/rewriteDefine.c,v 1.105 2005/06/28 05:08:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -33,9 +33,9 @@ #include "utils/syscache.h" -static void setRuleCheckAsUser_Query(Query *qry, AclId userid); -static void setRuleCheckAsUser_Expr(Node *node, AclId userid); -static bool setRuleCheckAsUser_walker(Node *node, AclId *context); +static void setRuleCheckAsUser_Query(Query *qry, Oid userid); +static void setRuleCheckAsUser_Expr(Node *node, Oid userid); +static bool setRuleCheckAsUser_walker(Node *node, Oid *context); /* @@ -505,7 +505,7 @@ DefineQueryRewrite(RuleStmt *stmt) * them always. */ static void -setRuleCheckAsUser_Query(Query *qry, AclId userid) +setRuleCheckAsUser_Query(Query *qry, Oid userid) { ListCell *l; @@ -534,13 +534,13 @@ setRuleCheckAsUser_Query(Query *qry, AclId userid) * Expression-tree walker to find sublink queries */ static void -setRuleCheckAsUser_Expr(Node *node, AclId userid) +setRuleCheckAsUser_Expr(Node *node, Oid userid) { (void) setRuleCheckAsUser_walker(node, &userid); } static bool -setRuleCheckAsUser_walker(Node *node, AclId *context) +setRuleCheckAsUser_walker(Node *node, Oid *context) { if (node == NULL) return false; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index b7a96922e9481a1589508464277f8ba467c8dba0..3677fd2ebac17312c101e6822ed7cd6a100e3941 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.154 2005/06/04 19:19:42 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.155 2005/06/28 05:08:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -945,7 +945,7 @@ ApplyRetrieveRule(Query *parsetree, subrte->checkAsUser = rte->checkAsUser; rte->requiredPerms = 0; /* no permission check on subquery itself */ - rte->checkAsUser = 0; + rte->checkAsUser = InvalidOid; /* * FOR UPDATE/SHARE of view? diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 82bd8eafc1185ba8b91f0b58483379bdb0bc341f..40d5e7d7ce6cf9b20b2ca889203c0dc544b25924 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.238 2005/06/22 21:14:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.239 2005/06/28 05:09:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,7 +20,6 @@ #include "access/twophase.h" #include "catalog/catalog.h" #include "catalog/namespace.h" -#include "catalog/pg_shadow.h" #include "commands/alter.h" #include "commands/async.h" #include "commands/cluster.h" @@ -279,12 +278,11 @@ check_xact_readonly(Node *parsetree) case T_AlterDatabaseSetStmt: case T_AlterDomainStmt: case T_AlterFunctionStmt: - case T_AlterGroupStmt: + case T_AlterRoleStmt: + case T_AlterRoleSetStmt: case T_AlterOwnerStmt: case T_AlterSeqStmt: case T_AlterTableStmt: - case T_AlterUserStmt: - case T_AlterUserSetStmt: case T_RenameStmt: case T_CommentStmt: case T_DefineStmt: @@ -293,7 +291,7 @@ check_xact_readonly(Node *parsetree) case T_CreatedbStmt: case T_CreateDomainStmt: case T_CreateFunctionStmt: - case T_CreateGroupStmt: + case T_CreateRoleStmt: case T_IndexStmt: case T_CreatePLangStmt: case T_CreateOpClassStmt: @@ -304,7 +302,6 @@ check_xact_readonly(Node *parsetree) case T_CreateTableSpaceStmt: case T_CreateTrigStmt: case T_CompositeTypeStmt: - case T_CreateUserStmt: case T_ViewStmt: case T_RemoveAggrStmt: case T_DropCastStmt: @@ -312,13 +309,13 @@ check_xact_readonly(Node *parsetree) case T_DropdbStmt: case T_DropTableSpaceStmt: case T_RemoveFuncStmt: - case T_DropGroupStmt: + case T_DropRoleStmt: case T_DropPLangStmt: case T_RemoveOperStmt: case T_RemoveOpClassStmt: case T_DropPropertyStmt: - case T_DropUserStmt: case T_GrantStmt: + case T_GrantRoleStmt: case T_TruncateStmt: ereport(ERROR, (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), @@ -679,11 +676,14 @@ ProcessUtility(Node *parsetree, } break; - case T_GrantStmt: ExecuteGrantStmt((GrantStmt *) parsetree); break; + case T_GrantRoleStmt: + GrantRole((GrantRoleStmt *) parsetree); + break; + /* * ******************************** object creation / * destruction ******************************** @@ -958,22 +958,22 @@ ProcessUtility(Node *parsetree, break; /* - * ******************************** USER statements **** + * ******************************** ROLE statements **** */ - case T_CreateUserStmt: - CreateUser((CreateUserStmt *) parsetree); + case T_CreateRoleStmt: + CreateRole((CreateRoleStmt *) parsetree); break; - case T_AlterUserStmt: - AlterUser((AlterUserStmt *) parsetree); + case T_AlterRoleStmt: + AlterRole((AlterRoleStmt *) parsetree); break; - case T_AlterUserSetStmt: - AlterUserSet((AlterUserSetStmt *) parsetree); + case T_AlterRoleSetStmt: + AlterRoleSet((AlterRoleSetStmt *) parsetree); break; - case T_DropUserStmt: - DropUser((DropUserStmt *) parsetree); + case T_DropRoleStmt: + DropRole((DropRoleStmt *) parsetree); break; case T_LockStmt: @@ -984,18 +984,6 @@ ProcessUtility(Node *parsetree, AfterTriggerSetState((ConstraintsSetStmt *) parsetree); break; - case T_CreateGroupStmt: - CreateGroup((CreateGroupStmt *) parsetree); - break; - - case T_AlterGroupStmt: - AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP"); - break; - - case T_DropGroupStmt: - DropGroup((DropGroupStmt *) parsetree); - break; - case T_CheckPointStmt: if (!superuser()) ereport(ERROR, @@ -1350,9 +1338,6 @@ CreateCommandTag(Node *parsetree) case OBJECT_FUNCTION: tag = "ALTER FUNCTION"; break; - case OBJECT_GROUP: - tag = "ALTER GROUP"; - break; case OBJECT_INDEX: tag = "ALTER INDEX"; break; @@ -1362,6 +1347,9 @@ CreateCommandTag(Node *parsetree) case OBJECT_OPCLASS: tag = "ALTER OPERATOR CLASS"; break; + case OBJECT_ROLE: + tag = "ALTER ROLE"; + break; case OBJECT_SCHEMA: tag = "ALTER SCHEMA"; break; @@ -1371,9 +1359,6 @@ CreateCommandTag(Node *parsetree) case OBJECT_TRIGGER: tag = "ALTER TRIGGER"; break; - case OBJECT_USER: - tag = "ALTER USER"; - break; default: tag = "ALTER TABLE"; } @@ -1450,6 +1435,14 @@ CreateCommandTag(Node *parsetree) } break; + case T_GrantRoleStmt: + { + GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree; + + tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE"; + } + break; + case T_DefineStmt: switch (((DefineStmt *) parsetree)->kind) { @@ -1588,20 +1581,20 @@ CreateCommandTag(Node *parsetree) tag = "DROP LANGUAGE"; break; - case T_CreateUserStmt: - tag = "CREATE USER"; + case T_CreateRoleStmt: + tag = "CREATE ROLE"; break; - case T_AlterUserStmt: - tag = "ALTER USER"; + case T_AlterRoleStmt: + tag = "ALTER ROLE"; break; - case T_AlterUserSetStmt: - tag = "ALTER USER"; + case T_AlterRoleSetStmt: + tag = "ALTER ROLE"; break; - case T_DropUserStmt: - tag = "DROP USER"; + case T_DropRoleStmt: + tag = "DROP ROLE"; break; case T_LockStmt: @@ -1612,18 +1605,6 @@ CreateCommandTag(Node *parsetree) tag = "SET CONSTRAINTS"; break; - case T_CreateGroupStmt: - tag = "CREATE GROUP"; - break; - - case T_AlterGroupStmt: - tag = "ALTER GROUP"; - break; - - case T_DropGroupStmt: - tag = "DROP GROUP"; - break; - case T_CheckPointStmt: tag = "CHECKPOINT"; break; diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 68b34f3dce58bc747fe014678057ad317fc74a16..4d5904b76901dc4526a9d88feff36291ad1a7f63 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.114 2005/05/27 00:57:49 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.115 2005/06/28 05:09:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,20 +17,33 @@ #include <ctype.h> #include "catalog/namespace.h" -#include "catalog/pg_group.h" -#include "catalog/pg_shadow.h" +#include "catalog/pg_authid.h" +#include "catalog/pg_auth_members.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" #include "commands/tablespace.h" #include "miscadmin.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/catcache.h" +#include "utils/inval.h" #include "utils/lsyscache.h" +#include "utils/memutils.h" #include "utils/syscache.h" -#define ACL_IDTYPE_GID_KEYWORD "group" -#define ACL_IDTYPE_UID_KEYWORD "user" +#define ACL_IDTYPE_ROLE_KEYWORD "role" + +/* The rolmemcache is a possibly-empty list of role OIDs. + * rolmemRole is the Role for which the cache was generated. + * In the event of a Role change the cache will be regenerated. + */ +static List *rolmemcache = NIL; +static Oid rolmemRole = InvalidOid; + +/* rolmemcache and rolmemRole only valid when + * rolmemcacheValid is true */ +static bool rolmemcacheValid = false; static const char *getid(const char *s, char *n); static void putid(char *p, const char *s); @@ -38,10 +51,9 @@ static Acl *allocacl(int n); static const char *aclparse(const char *s, AclItem *aip); static bool aclitem_match(const AclItem *a1, const AclItem *a2); static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, - AclId ownerid); -static Acl *recursive_revoke(Acl *acl, AclId grantee, AclMode revoke_privs, - AclId ownerid, DropBehavior behavior); -static bool in_group(AclId uid, AclId gid); + Oid ownerId); +static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, + Oid ownerId, DropBehavior behavior); static AclMode convert_priv_string(text *priv_type_text); @@ -58,6 +70,9 @@ static AclMode convert_schema_priv_string(text *priv_type_text); static Oid convert_tablespace_name(text *tablespacename); static AclMode convert_tablespace_priv_string(text *priv_type_text); +static void RolMemCacheCallback(Datum arg, Oid relid); +static void recomputeRolMemCache(Oid roleid); + /* * getid @@ -175,7 +190,6 @@ aclparse(const char *s, AclItem *aip) AclMode privs, goption, read; - uint32 idtype; char name[NAMEDATALEN]; char name2[NAMEDATALEN]; @@ -184,27 +198,22 @@ aclparse(const char *s, AclItem *aip) #ifdef ACLDEBUG elog(LOG, "aclparse: input = \"%s\"", s); #endif - idtype = ACL_IDTYPE_UID; s = getid(s, name); if (*s != '=') { /* we just read a keyword, not a name */ - if (strcmp(name, ACL_IDTYPE_GID_KEYWORD) == 0) - idtype = ACL_IDTYPE_GID; - else if (strcmp(name, ACL_IDTYPE_UID_KEYWORD) != 0) + if (strcmp(name, ACL_IDTYPE_ROLE_KEYWORD) != 0) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("unrecognized key word: \"%s\"", name), - errhint("ACL key word must be \"group\" or \"user\"."))); + errhint("ACL key word must be \"role\"."))); s = getid(s, name); /* move s to the name beyond the keyword */ if (name[0] == '\0') ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("missing name"), - errhint("A name must follow the \"group\" or \"user\" key word."))); + errhint("A name must follow the \"role\" key word."))); } - if (name[0] == '\0') - idtype = ACL_IDTYPE_WORLD; if (*s != '=') ereport(ERROR, @@ -263,18 +272,10 @@ aclparse(const char *s, AclItem *aip) privs |= read; } - switch (idtype) - { - case ACL_IDTYPE_UID: - aip->ai_grantee = get_usesysid(name); - break; - case ACL_IDTYPE_GID: - aip->ai_grantee = get_grosysid(name); - break; - case ACL_IDTYPE_WORLD: - aip->ai_grantee = ACL_ID_WORLD; - break; - } + if (name[0] == '\0') + aip->ai_grantee = ACL_ID_PUBLIC; + else + aip->ai_grantee = get_roleid_checked(name); /* * XXX Allow a degree of backward compatibility by defaulting the @@ -287,23 +288,24 @@ aclparse(const char *s, AclItem *aip) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("a name must follow the \"/\" sign"))); - - aip->ai_grantor = get_usesysid(name2); + aip->ai_grantor = get_roleid_checked(name2); } else { - aip->ai_grantor = BOOTSTRAP_USESYSID; + aip->ai_grantor = BOOTSTRAP_SUPERUSERID; ereport(WARNING, (errcode(ERRCODE_INVALID_GRANTOR), - errmsg("defaulting grantor to user ID %u", BOOTSTRAP_USESYSID))); + errmsg("defaulting grantor to user ID %u", + BOOTSTRAP_SUPERUSERID))); } - ACLITEM_SET_PRIVS_IDTYPE(*aip, privs, goption, idtype); + ACLITEM_SET_PRIVS_GOPTIONS(*aip, privs, goption); #ifdef ACLDEBUG - elog(LOG, "aclparse: correctly read [%x %d %x]", - idtype, aip->ai_grantee, privs); + elog(LOG, "aclparse: correctly read [%u %x %x]", + aip->ai_grantee, privs, goption); #endif + return s; } @@ -375,7 +377,6 @@ aclitemout(PG_FUNCTION_ARGS) char *out; HeapTuple htup; unsigned i; - char *tmpname; out = palloc(strlen("group =/") + 2 * N_ACL_RIGHTS + @@ -385,41 +386,21 @@ aclitemout(PG_FUNCTION_ARGS) p = out; *p = '\0'; - switch (ACLITEM_GET_IDTYPE(*aip)) + if (aip->ai_grantee != ACL_ID_PUBLIC) { - case ACL_IDTYPE_UID: - htup = SearchSysCache(SHADOWSYSID, - ObjectIdGetDatum(aip->ai_grantee), - 0, 0, 0); - if (HeapTupleIsValid(htup)) - { - putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename)); - ReleaseSysCache(htup); - } - else - { - /* Generate numeric UID if we don't find an entry */ - sprintf(p, "%d", aip->ai_grantee); - } - break; - case ACL_IDTYPE_GID: - strcpy(p, "group "); - p += strlen(p); - tmpname = get_groname(aip->ai_grantee); - if (tmpname != NULL) - putid(p, tmpname); - else - { - /* Generate numeric GID if we don't find an entry */ - sprintf(p, "%d", aip->ai_grantee); - } - break; - case ACL_IDTYPE_WORLD: - break; - default: - elog(ERROR, "unrecognized idtype: %d", - (int) ACLITEM_GET_IDTYPE(*aip)); - break; + htup = SearchSysCache(AUTHOID, + ObjectIdGetDatum(aip->ai_grantee), + 0, 0, 0); + if (HeapTupleIsValid(htup)) + { + putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname)); + ReleaseSysCache(htup); + } + else + { + /* Generate numeric OID if we don't find an entry */ + sprintf(p, "%u", aip->ai_grantee); + } } while (*p) ++p; @@ -437,18 +418,18 @@ aclitemout(PG_FUNCTION_ARGS) *p++ = '/'; *p = '\0'; - htup = SearchSysCache(SHADOWSYSID, + htup = SearchSysCache(AUTHOID, ObjectIdGetDatum(aip->ai_grantor), 0, 0, 0); if (HeapTupleIsValid(htup)) { - putid(p, NameStr(((Form_pg_shadow) GETSTRUCT(htup))->usename)); + putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname)); ReleaseSysCache(htup); } else { - /* Generate numeric UID if we don't find an entry */ - sprintf(p, "%d", aip->ai_grantor); + /* Generate numeric OID if we don't find an entry */ + sprintf(p, "%u", aip->ai_grantor); } while (*p) @@ -466,8 +447,7 @@ aclitemout(PG_FUNCTION_ARGS) static bool aclitem_match(const AclItem *a1, const AclItem *a2) { - return ACLITEM_GET_IDTYPE(*a1) == ACLITEM_GET_IDTYPE(*a2) && - a1->ai_grantee == a2->ai_grantee && + return a1->ai_grantee == a2->ai_grantee && a1->ai_grantor == a2->ai_grantor; } @@ -511,7 +491,7 @@ hash_aclitem(PG_FUNCTION_ARGS) * newly-created objects (or any object with a NULL acl entry). */ Acl * -acldefault(GrantObjectType objtype, AclId ownerid) +acldefault(GrantObjectType objtype, Oid ownerId) { AclMode world_default; AclMode owner_default; @@ -558,10 +538,9 @@ acldefault(GrantObjectType objtype, AclId ownerid) if (world_default != ACL_NO_RIGHTS) { - aip->ai_grantee = ACL_ID_WORLD; - aip->ai_grantor = ownerid; - ACLITEM_SET_PRIVS_IDTYPE(*aip, world_default, ACL_NO_RIGHTS, - ACL_IDTYPE_WORLD); + aip->ai_grantee = ACL_ID_PUBLIC; + aip->ai_grantor = ownerId; + ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS); aip++; } @@ -575,10 +554,9 @@ acldefault(GrantObjectType objtype, AclId ownerid) * without any explicit "_SYSTEM"-like ACL entry, by internally * special-casing the owner whereever we are testing grant options. */ - aip->ai_grantee = ownerid; - aip->ai_grantor = ownerid; - ACLITEM_SET_PRIVS_IDTYPE(*aip, owner_default, ACL_NO_RIGHTS, - ACL_IDTYPE_UID); + aip->ai_grantee = ownerId; + aip->ai_grantor = ownerId; + ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS); return acl; } @@ -590,7 +568,7 @@ acldefault(GrantObjectType objtype, AclId ownerid) * old_acl: the input ACL array * mod_aip: defines the privileges to be added, removed, or substituted * modechg: ACL_MODECHG_ADD, ACL_MODECHG_DEL, or ACL_MODECHG_EQL - * ownerid: AclId of object owner + * ownerId: Oid of object owner * behavior: RESTRICT or CASCADE behavior for recursive removal * * ownerid and behavior are only relevant when the update operation specifies @@ -602,7 +580,7 @@ acldefault(GrantObjectType objtype, AclId ownerid) */ Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, - int modechg, AclId ownerid, DropBehavior behavior) + int modechg, Oid ownerId, DropBehavior behavior) { Acl *new_acl = NULL; AclItem *old_aip, @@ -627,7 +605,7 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip, /* If granting grant options, check for circularity */ if (modechg != ACL_MODECHG_DEL && ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS) - check_circularity(old_acl, mod_aip, ownerid); + check_circularity(old_acl, mod_aip, ownerId); num = ACL_NUM(old_acl); old_aip = ACL_DAT(old_acl); @@ -661,9 +639,8 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip, /* initialize the new entry with no permissions */ new_aip[dst].ai_grantee = mod_aip->ai_grantee; new_aip[dst].ai_grantor = mod_aip->ai_grantor; - ACLITEM_SET_PRIVS_IDTYPE(new_aip[dst], - ACL_NO_RIGHTS, ACL_NO_RIGHTS, - ACLITEM_GET_IDTYPE(*mod_aip)); + ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst], + ACL_NO_RIGHTS, ACL_NO_RIGHTS); num++; /* set num to the size of new_acl */ } @@ -704,14 +681,14 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip, /* * Remove abandoned privileges (cascading revoke). Currently we can - * only handle this when the grantee is a user. + * only handle this when the grantee is not PUBLIC. */ if ((old_goptions & ~new_goptions) != 0) { - Assert(ACLITEM_GET_IDTYPE(*mod_aip) == ACL_IDTYPE_UID); + Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC); new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee, (old_goptions & ~new_goptions), - ownerid, behavior); + ownerId, behavior); } return new_acl; @@ -721,15 +698,15 @@ aclupdate(const Acl *old_acl, const AclItem *mod_aip, * Update an ACL array to reflect a change of owner to the parent object * * old_acl: the input ACL array (must not be NULL) - * oldownerid: AclId of the old object owner - * newownerid: AclId of the new object owner + * oldOwnerId: Oid of the old object owner + * newOwnerId: Oid of the new object owner * * The result is a modified copy; the input object is not changed. * * NB: caller is responsible for having detoasted the input ACL, if needed. */ Acl * -aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid) +aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId) { Acl *new_acl; AclItem *new_aip; @@ -755,18 +732,14 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid) memcpy(new_aip, old_aip, num * sizeof(AclItem)); for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++) { - /* grantor is always a UID, but grantee might not be */ - if (dst_aip->ai_grantor == oldownerid) - dst_aip->ai_grantor = newownerid; - else if (dst_aip->ai_grantor == newownerid) + if (dst_aip->ai_grantor == oldOwnerId) + dst_aip->ai_grantor = newOwnerId; + else if (dst_aip->ai_grantor == newOwnerId) + newpresent = true; + if (dst_aip->ai_grantee == oldOwnerId) + dst_aip->ai_grantee = newOwnerId; + else if (dst_aip->ai_grantee == newOwnerId) newpresent = true; - if (ACLITEM_GET_IDTYPE(*dst_aip) == ACL_IDTYPE_UID) - { - if (dst_aip->ai_grantee == oldownerid) - dst_aip->ai_grantee = newownerid; - else if (dst_aip->ai_grantee == newownerid) - newpresent = true; - } } /* @@ -836,7 +809,7 @@ aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid) */ static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, - AclId ownerid) + Oid ownerId) { Acl *acl; AclItem *aip; @@ -845,13 +818,13 @@ check_circularity(const Acl *old_acl, const AclItem *mod_aip, AclMode own_privs; /* - * For now, grant options can only be granted to users, not groups or - * PUBLIC. Otherwise we'd have to work a bit harder here. + * For now, grant options can only be granted to roles, not PUBLIC. + * Otherwise we'd have to work a bit harder here. */ - Assert(ACLITEM_GET_IDTYPE(*mod_aip) == ACL_IDTYPE_UID); + Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC); /* The owner always has grant options, no need to check */ - if (mod_aip->ai_grantor == ownerid) + if (mod_aip->ai_grantor == ownerId) return; /* Make a working copy */ @@ -864,15 +837,14 @@ cc_restart: aip = ACL_DAT(acl); for (i = 0; i < num; i++) { - if (ACLITEM_GET_IDTYPE(aip[i]) == ACL_IDTYPE_UID && - aip[i].ai_grantee == mod_aip->ai_grantee && + if (aip[i].ai_grantee == mod_aip->ai_grantee && ACLITEM_GET_GOPTIONS(aip[i]) != ACL_NO_RIGHTS) { Acl *new_acl; /* We'll actually zap ordinary privs too, but no matter */ new_acl = aclupdate(acl, &aip[i], ACL_MODECHG_DEL, - ownerid, DROP_CASCADE); + ownerId, DROP_CASCADE); pfree(acl); acl = new_acl; @@ -884,7 +856,7 @@ cc_restart: /* Now we can compute grantor's independently-derived privileges */ own_privs = aclmask(acl, mod_aip->ai_grantor, - ownerid, + ownerId, ACL_GRANT_OPTION_FOR(ACLITEM_GET_GOPTIONS(*mod_aip)), ACLMASK_ALL); own_privs = ACL_OPTION_TO_PRIVS(own_privs); @@ -908,16 +880,16 @@ cc_restart: * acl: the input ACL list * grantee: the user from whom some grant options have been revoked * revoke_privs: the grant options being revoked - * ownerid: AclId of object owner + * ownerId: Oid of object owner * behavior: RESTRICT or CASCADE behavior for recursive removal * * The input Acl object is pfree'd if replaced. */ static Acl * recursive_revoke(Acl *acl, - AclId grantee, + Oid grantee, AclMode revoke_privs, - AclId ownerid, + Oid ownerId, DropBehavior behavior) { AclMode still_has; @@ -926,11 +898,11 @@ recursive_revoke(Acl *acl, num; /* The owner can never truly lose grant options, so short-circuit */ - if (grantee == ownerid) + if (grantee == ownerId) return acl; /* The grantee might still have the privileges via another grantor */ - still_has = aclmask(acl, grantee, ownerid, + still_has = aclmask(acl, grantee, ownerId, ACL_GRANT_OPTION_FOR(revoke_privs), ACLMASK_ALL); revoke_privs &= ~still_has; @@ -956,13 +928,12 @@ restart: mod_acl.ai_grantor = grantee; mod_acl.ai_grantee = aip[i].ai_grantee; - ACLITEM_SET_PRIVS_IDTYPE(mod_acl, - revoke_privs, - revoke_privs, - ACLITEM_GET_IDTYPE(aip[i])); + ACLITEM_SET_PRIVS_GOPTIONS(mod_acl, + revoke_privs, + revoke_privs); new_acl = aclupdate(acl, &mod_acl, ACL_MODECHG_DEL, - ownerid, behavior); + ownerId, behavior); pfree(acl); acl = new_acl; @@ -976,10 +947,10 @@ restart: /* - * aclmask --- compute bitmask of all privileges held by userid. + * aclmask --- compute bitmask of all privileges held by roleid. * * When 'how' = ACLMASK_ALL, this simply returns the privilege bits - * held by the given userid according to the given ACL list, ANDed + * held by the given roleid according to the given ACL list, ANDed * with 'mask'. (The point of passing 'mask' is to let the routine * exit early if all privileges of interest have been found.) * @@ -990,20 +961,20 @@ restart: * Usage patterns: * * To see if any of a set of privileges are held: - * if (aclmask(acl, userid, ownerid, privs, ACLMASK_ANY) != 0) + * if (aclmask(acl, roleid, ownerId, privs, ACLMASK_ANY) != 0) * * To see if all of a set of privileges are held: - * if (aclmask(acl, userid, ownerid, privs, ACLMASK_ALL) == privs) + * if (aclmask(acl, roleid, ownerId, privs, ACLMASK_ALL) == privs) * * To determine exactly which of a set of privileges are held: - * heldprivs = aclmask(acl, userid, ownerid, privs, ACLMASK_ALL); + * heldprivs = aclmask(acl, roleid, ownerId, privs, ACLMASK_ALL); + * */ AclMode -aclmask(const Acl *acl, AclId userid, AclId ownerid, +aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how) { AclMode result; - AclMode remaining; AclItem *aidat; int i, num; @@ -1022,7 +993,7 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid, result = 0; /* Owner always implicitly has all grant options */ - if (userid == ownerid) + if (is_member_of_role(roleid,ownerId)) { result = mask & ACLITEM_ALL_GOPTION_BITS; if (result == mask) @@ -1033,39 +1004,19 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid, aidat = ACL_DAT(acl); /* - * Check privileges granted directly to user or to public - */ - for (i = 0; i < num; i++) - { - AclItem *aidata = &aidat[i]; - - if (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_WORLD - || (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_UID - && aidata->ai_grantee == userid)) - { - result |= (aidata->ai_privs & mask); - if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) - return result; - } - } - - /* - * Check privileges granted via groups. We do this in a separate pass - * to minimize expensive lookups in pg_group. + * Check privileges granted directly to role, indirectly + * via role membership or to public */ - remaining = (mask & ~result); for (i = 0; i < num; i++) { AclItem *aidata = &aidat[i]; - if (ACLITEM_GET_IDTYPE(*aidata) == ACL_IDTYPE_GID - && (aidata->ai_privs & remaining) - && in_group(userid, aidata->ai_grantee)) + if (aidata->ai_grantee == ACL_ID_PUBLIC || + is_member_of_role(roleid, aidata->ai_grantee)) { result |= (aidata->ai_privs & mask); if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; - remaining = (mask & ~result); } } @@ -1074,55 +1025,19 @@ aclmask(const Acl *acl, AclId userid, AclId ownerid, /* - * Is user a member of group? + * Is member a member of role? + * relmemcache includes the role itself too */ -static bool -in_group(AclId uid, AclId gid) -{ - bool result = false; - HeapTuple tuple; - Datum att; - bool isNull; - IdList *glist; - AclId *aidp; - int i, - num; +bool +is_member_of_role(Oid member, Oid role) +{ + /* Fast path for simple case */ + if (member == role) + return true; - tuple = SearchSysCache(GROSYSID, - ObjectIdGetDatum(gid), - 0, 0, 0); - if (HeapTupleIsValid(tuple)) - { - att = SysCacheGetAttr(GROSYSID, - tuple, - Anum_pg_group_grolist, - &isNull); - if (!isNull) - { - /* be sure the IdList is not toasted */ - glist = DatumGetIdListP(att); - /* scan it */ - num = IDLIST_NUM(glist); - aidp = IDLIST_DAT(glist); - for (i = 0; i < num; ++i) - { - if (aidp[i] == uid) - { - result = true; - break; - } - } - /* if IdList was toasted, free detoasted copy */ - if ((Pointer) glist != DatumGetPointer(att)) - pfree(glist); - } - ReleaseSysCache(tuple); - } - else - ereport(WARNING, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("group with ID %u does not exist", gid))); - return result; + recomputeRolMemCache(member); + + return list_member_oid(rolmemcache, role); } @@ -1162,10 +1077,9 @@ aclcontains(PG_FUNCTION_ARGS) aidat = ACL_DAT(acl); for (i = 0; i < num; ++i) { - if (aip->ai_grantee == aidat[i].ai_grantee - && ACLITEM_GET_IDTYPE(*aip) == ACLITEM_GET_IDTYPE(aidat[i]) - && aip->ai_grantor == aidat[i].ai_grantor - && (ACLITEM_GET_RIGHTS(*aip) & ACLITEM_GET_RIGHTS(aidat[i])) == ACLITEM_GET_RIGHTS(*aip)) + if (aip->ai_grantee == aidat[i].ai_grantee && + aip->ai_grantor == aidat[i].ai_grantor && + (ACLITEM_GET_RIGHTS(*aip) & ACLITEM_GET_RIGHTS(aidat[i])) == ACLITEM_GET_RIGHTS(*aip)) PG_RETURN_BOOL(true); } PG_RETURN_BOOL(false); @@ -1174,51 +1088,22 @@ aclcontains(PG_FUNCTION_ARGS) Datum makeaclitem(PG_FUNCTION_ARGS) { - int32 u_grantee = PG_GETARG_INT32(0); - int32 g_grantee = PG_GETARG_INT32(1); - int32 grantor = PG_GETARG_INT32(2); - text *privtext = PG_GETARG_TEXT_P(3); - bool goption = PG_GETARG_BOOL(4); + Oid grantee = PG_GETARG_OID(0); + Oid grantor = PG_GETARG_OID(1); + text *privtext = PG_GETARG_TEXT_P(2); + bool goption = PG_GETARG_BOOL(3); AclItem *aclitem; AclMode priv; priv = convert_priv_string(privtext); - aclitem = (AclItem *) palloc(sizeof(*aclitem)); + aclitem = (AclItem *) palloc(sizeof(AclItem)); - if (u_grantee == 0 && g_grantee == 0) - { - aclitem ->ai_grantee = ACL_ID_WORLD; + aclitem->ai_grantee = grantee; + aclitem->ai_grantor = grantor; - ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_WORLD); - } - else if (u_grantee != 0 && g_grantee != 0) - { - ereport(ERROR, - (errcode(ERRCODE_DATA_EXCEPTION), - errmsg("cannot specify both user and group"))); - } - else if (u_grantee != 0) - { - aclitem ->ai_grantee = u_grantee; - - ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_UID); - } - else - /* (g_grantee != 0) */ - { - aclitem ->ai_grantee = g_grantee; - - ACLITEM_SET_IDTYPE(*aclitem, ACL_IDTYPE_GID); - } - - aclitem ->ai_grantor = grantor; - - ACLITEM_SET_PRIVS(*aclitem, priv); - if (goption) - ACLITEM_SET_GOPTIONS(*aclitem, priv); - else - ACLITEM_SET_GOPTIONS(*aclitem, ACL_NO_RIGHTS); + ACLITEM_SET_PRIVS_GOPTIONS(*aclitem, priv, + (goption ? priv : ACL_NO_RIGHTS)); PG_RETURN_ACLITEM_P(aclitem); } @@ -1267,7 +1152,7 @@ convert_priv_string(text *priv_type_text) * has_table_privilege variants * These are all named "has_table_privilege" at the SQL level. * They take various combinations of relation name, relation OID, - * user name, user sysid, or implicit user = current_user. + * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. @@ -1281,19 +1166,20 @@ convert_priv_string(text *priv_type_text) Datum has_table_privilege_name_name(PG_FUNCTION_ARGS) { - Name username = PG_GETARG_NAME(0); + Name rolename = PG_GETARG_NAME(0); text *tablename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; Oid tableoid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*rolename)); + tableoid = convert_table_name(tablename); mode = convert_table_priv_string(priv_type_text); - aclresult = pg_class_aclcheck(tableoid, usesysid, mode); + aclresult = pg_class_aclcheck(tableoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1309,16 +1195,16 @@ has_table_privilege_name(PG_FUNCTION_ARGS) { text *tablename = PG_GETARG_TEXT_P(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; Oid tableoid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); tableoid = convert_table_name(tablename); mode = convert_table_priv_string(priv_type_text); - aclresult = pg_class_aclcheck(tableoid, usesysid, mode); + aclresult = pg_class_aclcheck(tableoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1334,14 +1220,15 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); Oid tableoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_table_priv_string(priv_type_text); - aclresult = pg_class_aclcheck(tableoid, usesysid, mode); + aclresult = pg_class_aclcheck(tableoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1357,14 +1244,14 @@ has_table_privilege_id(PG_FUNCTION_ARGS) { Oid tableoid = PG_GETARG_OID(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); mode = convert_table_priv_string(priv_type_text); - aclresult = pg_class_aclcheck(tableoid, usesysid, mode); + aclresult = pg_class_aclcheck(tableoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1372,12 +1259,12 @@ has_table_privilege_id(PG_FUNCTION_ARGS) /* * has_table_privilege_id_name * Check user privileges on a table given - * usesysid, text tablename, and text priv name. + * roleid, text tablename, and text priv name. */ Datum has_table_privilege_id_name(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); text *tablename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); Oid tableoid; @@ -1387,7 +1274,7 @@ has_table_privilege_id_name(PG_FUNCTION_ARGS) tableoid = convert_table_name(tablename); mode = convert_table_priv_string(priv_type_text); - aclresult = pg_class_aclcheck(tableoid, usesysid, mode); + aclresult = pg_class_aclcheck(tableoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1395,12 +1282,12 @@ has_table_privilege_id_name(PG_FUNCTION_ARGS) /* * has_table_privilege_id_id * Check user privileges on a table given - * usesysid, table oid, and text priv name. + * roleid, table oid, and text priv name. */ Datum has_table_privilege_id_id(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Oid tableoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); AclMode mode; @@ -1408,7 +1295,7 @@ has_table_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_table_priv_string(priv_type_text); - aclresult = pg_class_aclcheck(tableoid, usesysid, mode); + aclresult = pg_class_aclcheck(tableoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1491,7 +1378,7 @@ convert_table_priv_string(text *priv_type_text) * has_database_privilege variants * These are all named "has_database_privilege" at the SQL level. * They take various combinations of database name, database OID, - * user name, user sysid, or implicit user = current_user. + * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. @@ -1508,16 +1395,17 @@ has_database_privilege_name_name(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); text *databasename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; Oid databaseoid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + databaseoid = convert_database_name(databasename); mode = convert_database_priv_string(priv_type_text); - aclresult = pg_database_aclcheck(databaseoid, usesysid, mode); + aclresult = pg_database_aclcheck(databaseoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1533,16 +1421,16 @@ has_database_privilege_name(PG_FUNCTION_ARGS) { text *databasename = PG_GETARG_TEXT_P(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; Oid databaseoid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); databaseoid = convert_database_name(databasename); mode = convert_database_priv_string(priv_type_text); - aclresult = pg_database_aclcheck(databaseoid, usesysid, mode); + aclresult = pg_database_aclcheck(databaseoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1558,14 +1446,15 @@ has_database_privilege_name_id(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); Oid databaseoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_database_priv_string(priv_type_text); - aclresult = pg_database_aclcheck(databaseoid, usesysid, mode); + aclresult = pg_database_aclcheck(databaseoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1581,14 +1470,14 @@ has_database_privilege_id(PG_FUNCTION_ARGS) { Oid databaseoid = PG_GETARG_OID(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); mode = convert_database_priv_string(priv_type_text); - aclresult = pg_database_aclcheck(databaseoid, usesysid, mode); + aclresult = pg_database_aclcheck(databaseoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1596,12 +1485,12 @@ has_database_privilege_id(PG_FUNCTION_ARGS) /* * has_database_privilege_id_name * Check user privileges on a database given - * usesysid, text databasename, and text priv name. + * roleid, text databasename, and text priv name. */ Datum has_database_privilege_id_name(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); text *databasename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); Oid databaseoid; @@ -1611,7 +1500,7 @@ has_database_privilege_id_name(PG_FUNCTION_ARGS) databaseoid = convert_database_name(databasename); mode = convert_database_priv_string(priv_type_text); - aclresult = pg_database_aclcheck(databaseoid, usesysid, mode); + aclresult = pg_database_aclcheck(databaseoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1619,12 +1508,12 @@ has_database_privilege_id_name(PG_FUNCTION_ARGS) /* * has_database_privilege_id_id * Check user privileges on a database given - * usesysid, database oid, and text priv name. + * roleid, database oid, and text priv name. */ Datum has_database_privilege_id_id(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Oid databaseoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); AclMode mode; @@ -1632,7 +1521,7 @@ has_database_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_database_priv_string(priv_type_text); - aclresult = pg_database_aclcheck(databaseoid, usesysid, mode); + aclresult = pg_database_aclcheck(databaseoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1703,7 +1592,7 @@ convert_database_priv_string(text *priv_type_text) * has_function_privilege variants * These are all named "has_function_privilege" at the SQL level. * They take various combinations of function name, function OID, - * user name, user sysid, or implicit user = current_user. + * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. @@ -1720,16 +1609,17 @@ has_function_privilege_name_name(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); text *functionname = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; Oid functionoid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + functionoid = convert_function_name(functionname); mode = convert_function_priv_string(priv_type_text); - aclresult = pg_proc_aclcheck(functionoid, usesysid, mode); + aclresult = pg_proc_aclcheck(functionoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1745,16 +1635,16 @@ has_function_privilege_name(PG_FUNCTION_ARGS) { text *functionname = PG_GETARG_TEXT_P(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; Oid functionoid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); functionoid = convert_function_name(functionname); mode = convert_function_priv_string(priv_type_text); - aclresult = pg_proc_aclcheck(functionoid, usesysid, mode); + aclresult = pg_proc_aclcheck(functionoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1770,14 +1660,15 @@ has_function_privilege_name_id(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); Oid functionoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_function_priv_string(priv_type_text); - aclresult = pg_proc_aclcheck(functionoid, usesysid, mode); + aclresult = pg_proc_aclcheck(functionoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1793,14 +1684,14 @@ has_function_privilege_id(PG_FUNCTION_ARGS) { Oid functionoid = PG_GETARG_OID(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); mode = convert_function_priv_string(priv_type_text); - aclresult = pg_proc_aclcheck(functionoid, usesysid, mode); + aclresult = pg_proc_aclcheck(functionoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1808,12 +1699,12 @@ has_function_privilege_id(PG_FUNCTION_ARGS) /* * has_function_privilege_id_name * Check user privileges on a function given - * usesysid, text functionname, and text priv name. + * roleid, text functionname, and text priv name. */ Datum has_function_privilege_id_name(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); text *functionname = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); Oid functionoid; @@ -1823,7 +1714,7 @@ has_function_privilege_id_name(PG_FUNCTION_ARGS) functionoid = convert_function_name(functionname); mode = convert_function_priv_string(priv_type_text); - aclresult = pg_proc_aclcheck(functionoid, usesysid, mode); + aclresult = pg_proc_aclcheck(functionoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1831,12 +1722,12 @@ has_function_privilege_id_name(PG_FUNCTION_ARGS) /* * has_function_privilege_id_id * Check user privileges on a function given - * usesysid, function oid, and text priv name. + * roleid, function oid, and text priv name. */ Datum has_function_privilege_id_id(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Oid functionoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); AclMode mode; @@ -1844,7 +1735,7 @@ has_function_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_function_priv_string(priv_type_text); - aclresult = pg_proc_aclcheck(functionoid, usesysid, mode); + aclresult = pg_proc_aclcheck(functionoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1907,7 +1798,7 @@ convert_function_priv_string(text *priv_type_text) * has_language_privilege variants * These are all named "has_language_privilege" at the SQL level. * They take various combinations of language name, language OID, - * user name, user sysid, or implicit user = current_user. + * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. @@ -1924,16 +1815,17 @@ has_language_privilege_name_name(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); text *languagename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; Oid languageoid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + languageoid = convert_language_name(languagename); mode = convert_language_priv_string(priv_type_text); - aclresult = pg_language_aclcheck(languageoid, usesysid, mode); + aclresult = pg_language_aclcheck(languageoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1949,16 +1841,16 @@ has_language_privilege_name(PG_FUNCTION_ARGS) { text *languagename = PG_GETARG_TEXT_P(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; Oid languageoid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); languageoid = convert_language_name(languagename); mode = convert_language_priv_string(priv_type_text); - aclresult = pg_language_aclcheck(languageoid, usesysid, mode); + aclresult = pg_language_aclcheck(languageoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1974,14 +1866,15 @@ has_language_privilege_name_id(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); Oid languageoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_language_priv_string(priv_type_text); - aclresult = pg_language_aclcheck(languageoid, usesysid, mode); + aclresult = pg_language_aclcheck(languageoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -1997,14 +1890,14 @@ has_language_privilege_id(PG_FUNCTION_ARGS) { Oid languageoid = PG_GETARG_OID(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); mode = convert_language_priv_string(priv_type_text); - aclresult = pg_language_aclcheck(languageoid, usesysid, mode); + aclresult = pg_language_aclcheck(languageoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2012,12 +1905,12 @@ has_language_privilege_id(PG_FUNCTION_ARGS) /* * has_language_privilege_id_name * Check user privileges on a language given - * usesysid, text languagename, and text priv name. + * roleid, text languagename, and text priv name. */ Datum has_language_privilege_id_name(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); text *languagename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); Oid languageoid; @@ -2027,7 +1920,7 @@ has_language_privilege_id_name(PG_FUNCTION_ARGS) languageoid = convert_language_name(languagename); mode = convert_language_priv_string(priv_type_text); - aclresult = pg_language_aclcheck(languageoid, usesysid, mode); + aclresult = pg_language_aclcheck(languageoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2035,12 +1928,12 @@ has_language_privilege_id_name(PG_FUNCTION_ARGS) /* * has_language_privilege_id_id * Check user privileges on a language given - * usesysid, language oid, and text priv name. + * roleid, language oid, and text priv name. */ Datum has_language_privilege_id_id(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Oid languageoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); AclMode mode; @@ -2048,7 +1941,7 @@ has_language_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_language_priv_string(priv_type_text); - aclresult = pg_language_aclcheck(languageoid, usesysid, mode); + aclresult = pg_language_aclcheck(languageoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2111,7 +2004,7 @@ convert_language_priv_string(text *priv_type_text) * has_schema_privilege variants * These are all named "has_schema_privilege" at the SQL level. * They take various combinations of schema name, schema OID, - * user name, user sysid, or implicit user = current_user. + * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. @@ -2128,16 +2021,17 @@ has_schema_privilege_name_name(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); text *schemaname = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; Oid schemaoid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + schemaoid = convert_schema_name(schemaname); mode = convert_schema_priv_string(priv_type_text); - aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode); + aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2153,16 +2047,16 @@ has_schema_privilege_name(PG_FUNCTION_ARGS) { text *schemaname = PG_GETARG_TEXT_P(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; Oid schemaoid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); schemaoid = convert_schema_name(schemaname); mode = convert_schema_priv_string(priv_type_text); - aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode); + aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2178,14 +2072,15 @@ has_schema_privilege_name_id(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); Oid schemaoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_schema_priv_string(priv_type_text); - aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode); + aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2201,14 +2096,14 @@ has_schema_privilege_id(PG_FUNCTION_ARGS) { Oid schemaoid = PG_GETARG_OID(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); mode = convert_schema_priv_string(priv_type_text); - aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode); + aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2216,12 +2111,12 @@ has_schema_privilege_id(PG_FUNCTION_ARGS) /* * has_schema_privilege_id_name * Check user privileges on a schema given - * usesysid, text schemaname, and text priv name. + * roleid, text schemaname, and text priv name. */ Datum has_schema_privilege_id_name(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); text *schemaname = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); Oid schemaoid; @@ -2231,7 +2126,7 @@ has_schema_privilege_id_name(PG_FUNCTION_ARGS) schemaoid = convert_schema_name(schemaname); mode = convert_schema_priv_string(priv_type_text); - aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode); + aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2239,12 +2134,12 @@ has_schema_privilege_id_name(PG_FUNCTION_ARGS) /* * has_schema_privilege_id_id * Check user privileges on a schema given - * usesysid, schema oid, and text priv name. + * roleid, schema oid, and text priv name. */ Datum has_schema_privilege_id_id(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Oid schemaoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); AclMode mode; @@ -2252,7 +2147,7 @@ has_schema_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_schema_priv_string(priv_type_text); - aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode); + aclresult = pg_namespace_aclcheck(schemaoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2319,7 +2214,7 @@ convert_schema_priv_string(text *priv_type_text) * has_tablespace_privilege variants * These are all named "has_tablespace_privilege" at the SQL level. * They take various combinations of tablespace name, tablespace OID, - * user name, user sysid, or implicit user = current_user. + * user name, user OID, or implicit user = current_user. * * The result is a boolean value: true if user has the indicated * privilege, false if not. @@ -2336,16 +2231,17 @@ has_tablespace_privilege_name_name(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); text *tablespacename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; Oid tablespaceoid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + tablespaceoid = convert_tablespace_name(tablespacename); mode = convert_tablespace_priv_string(priv_type_text); - aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2361,16 +2257,16 @@ has_tablespace_privilege_name(PG_FUNCTION_ARGS) { text *tablespacename = PG_GETARG_TEXT_P(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; Oid tablespaceoid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); tablespaceoid = convert_tablespace_name(tablespacename); mode = convert_tablespace_priv_string(priv_type_text); - aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2386,14 +2282,15 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS) Name username = PG_GETARG_NAME(0); Oid tablespaceoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); - int32 usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = get_usesysid(NameStr(*username)); + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_tablespace_priv_string(priv_type_text); - aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2409,14 +2306,14 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS) { Oid tablespaceoid = PG_GETARG_OID(0); text *priv_type_text = PG_GETARG_TEXT_P(1); - AclId usesysid; + Oid roleid; AclMode mode; AclResult aclresult; - usesysid = GetUserId(); + roleid = GetUserId(); mode = convert_tablespace_priv_string(priv_type_text); - aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2424,12 +2321,12 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS) /* * has_tablespace_privilege_id_name * Check user privileges on a tablespace given - * usesysid, text tablespacename, and text priv name. + * roleid, text tablespacename, and text priv name. */ Datum has_tablespace_privilege_id_name(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); text *tablespacename = PG_GETARG_TEXT_P(1); text *priv_type_text = PG_GETARG_TEXT_P(2); Oid tablespaceoid; @@ -2439,7 +2336,7 @@ has_tablespace_privilege_id_name(PG_FUNCTION_ARGS) tablespaceoid = convert_tablespace_name(tablespacename); mode = convert_tablespace_priv_string(priv_type_text); - aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2447,12 +2344,12 @@ has_tablespace_privilege_id_name(PG_FUNCTION_ARGS) /* * has_tablespace_privilege_id_id * Check user privileges on a tablespace given - * usesysid, tablespace oid, and text priv name. + * roleid, tablespace oid, and text priv name. */ Datum has_tablespace_privilege_id_id(PG_FUNCTION_ARGS) { - int32 usesysid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Oid tablespaceoid = PG_GETARG_OID(1); text *priv_type_text = PG_GETARG_TEXT_P(2); AclMode mode; @@ -2460,7 +2357,7 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_tablespace_priv_string(priv_type_text); - aclresult = pg_tablespace_aclcheck(tablespaceoid, usesysid, mode); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); } @@ -2515,3 +2412,110 @@ convert_tablespace_priv_string(text *priv_type_text) errmsg("unrecognized privilege type: \"%s\"", priv_type))); return ACL_NO_RIGHTS; /* keep compiler quiet */ } + +void +InitializeAcl(void) +{ + if (!IsBootstrapProcessingMode()) + { + /* + * In normal mode, set a callback on any syscache + * invalidation of pg_auth_members rows + */ + CacheRegisterSyscacheCallback(AUTHMEMROLEMEM, + RolMemCacheCallback, + (Datum) 0); + + /* Force role/member cache to be recomputed on next use */ + rolmemcacheValid = false; + } +} + +/* + * RolMemCacheCallback + * Syscache inval callback function + */ +static void +RolMemCacheCallback(Datum arg, Oid relid) +{ + /* Force role/member cache to be recomputed on next use */ + rolmemcacheValid = false; +} + + +/* + * recomputeRolMemCache - recompute the role/member cache if needed + */ +static void +recomputeRolMemCache(Oid roleid) +{ + int i; + Oid memberOid; + List *roles_list_hunt = NIL; + List *roles_list = NIL; + List *newrolmemcache; + CatCList *memlist; + MemoryContext oldctx; + + /* Do nothing if rolmemcache is already valid */ + if (rolmemcacheValid && rolmemRole == roleid) + return; + + if (rolmemRole != roleid) + rolmemcacheValid = false; + + /* + * Find all the roles which this role is a member of, + * including multi-level recursion + */ + + /* + * Include the current role itself to simplify checks + * later on, also should be at the head so lookup should + * be fast. + */ + roles_list = lappend_oid(roles_list, roleid); + roles_list_hunt = lappend_oid(roles_list_hunt, roleid); + + while (roles_list_hunt) + { + memberOid = linitial_oid(roles_list_hunt); + memlist = SearchSysCacheList(AUTHMEMMEMROLE, 1, + ObjectIdGetDatum(memberOid), + 0, 0, 0); + for (i = 0; i < memlist->n_members; i++) { + HeapTuple roletup = &memlist->members[i]->tuple; + Form_pg_auth_members rolemem = (Form_pg_auth_members) GETSTRUCT(roletup); + + if (!list_member_oid(roles_list,rolemem->roleid)) { + roles_list = lappend_oid(roles_list,rolemem->roleid); + roles_list_hunt = lappend_oid(roles_list_hunt,rolemem->roleid); + } + } + roles_list_hunt = list_delete_oid(roles_list_hunt, memberOid); + ReleaseSysCacheList(memlist); + } + + /* + * Now that we've built the list of role Oids this + * role is a member of, save it in permanent storage + */ + oldctx = MemoryContextSwitchTo(TopMemoryContext); + newrolmemcache = list_copy(roles_list); + MemoryContextSwitchTo(oldctx); + + /* + * Now safe to assign to state variable + */ + list_free(rolmemcache); + rolmemcache = newrolmemcache; + + /* + * Mark as valid + */ + rolmemRole = roleid; + rolmemcacheValid = true; + + /* Clean up */ + list_free(roles_list); +} diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 90c8ea695bb532ddf78ae52692c55a22a5b17a64..870513fb9d512a98f413406f2a64e0b05614ce2b 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -8,14 +8,13 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.22 2005/05/11 01:41:41 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.23 2005/06/28 05:09:00 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/xact.h" -#include "catalog/pg_shadow.h" #include "fmgr.h" #include "funcapi.h" #include "miscadmin.h" @@ -306,7 +305,7 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS) if (!OidIsValid(beentry->userid)) PG_RETURN_NULL(); - PG_RETURN_INT32(beentry->userid); + PG_RETURN_OID(beentry->userid); } diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index a0d561f1f0f53ecd9a0a67b5944185f9ef537cd5..8de31643a68a93916c91a79aa4af3d957b8913fa 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -17,7 +17,7 @@ * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.79 2005/05/30 07:20:58 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.80 2005/06/28 05:09:00 tgl Exp $ * * ---------- */ @@ -3036,7 +3036,7 @@ ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes, { void *qplan; Relation query_rel; - AclId save_uid; + Oid save_uid; /* * The query is always run against the FK table except when this is an @@ -3089,7 +3089,7 @@ ri_PerformCheck(RI_QueryKey *qkey, void *qplan, Snapshot crosscheck_snapshot; int limit; int spi_result; - AclId save_uid; + Oid save_uid; Datum vals[RI_MAX_NUMKEYS * 2]; char nulls[RI_MAX_NUMKEYS * 2]; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 0bd1d73eae10512edb9a13c78a1ac41debfe81ef..cbebd5495c0b16a88a796c722b146c172fae0b21 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.201 2005/06/26 22:05:40 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.202 2005/06/28 05:09:01 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -46,13 +46,13 @@ #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/pg_authid.h" #include "catalog/pg_cast.h" #include "catalog/pg_constraint.h" #include "catalog/pg_depend.h" #include "catalog/pg_index.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_trigger.h" #include "executor/spi.h" #include "funcapi.h" @@ -1194,17 +1194,17 @@ pg_get_expr_worker(text *expr, Oid relid, char *relname, int prettyFlags) /* ---------- - * get_userbyid - Get a user name by usesysid and - * fallback to 'unknown (UID=n)' + * get_userbyid - Get a user name by roleid and + * fallback to 'unknown (OID=n)' * ---------- */ Datum pg_get_userbyid(PG_FUNCTION_ARGS) { - int32 uid = PG_GETARG_INT32(0); + Oid roleid = PG_GETARG_OID(0); Name result; - HeapTuple usertup; - Form_pg_shadow user_rec; + HeapTuple roletup; + Form_pg_authid role_rec; /* * Allocate space for the result @@ -1213,19 +1213,19 @@ pg_get_userbyid(PG_FUNCTION_ARGS) memset(NameStr(*result), 0, NAMEDATALEN); /* - * Get the pg_shadow entry and print the result + * Get the pg_authid entry and print the result */ - usertup = SearchSysCache(SHADOWSYSID, - ObjectIdGetDatum(uid), + roletup = SearchSysCache(AUTHOID, + ObjectIdGetDatum(roleid), 0, 0, 0); - if (HeapTupleIsValid(usertup)) + if (HeapTupleIsValid(roletup)) { - user_rec = (Form_pg_shadow) GETSTRUCT(usertup); - StrNCpy(NameStr(*result), NameStr(user_rec->usename), NAMEDATALEN); - ReleaseSysCache(usertup); + role_rec = (Form_pg_authid) GETSTRUCT(roletup); + StrNCpy(NameStr(*result), NameStr(role_rec->rolname), NAMEDATALEN); + ReleaseSysCache(roletup); } else - sprintf(NameStr(*result), "unknown (UID=%d)", uid); + sprintf(NameStr(*result), "unknown (OID=%u)", roleid); PG_RETURN_NAME(result); } diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index 5390d94462acdf9ceb6c4fd46c29a14a0641a4ee..ea10f8c8cd3d36a6129623ebd70d02523f328e11 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.125 2005/05/01 18:56:19 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/lsyscache.c,v 1.126 2005/06/28 05:09:01 tgl Exp $ * * NOTES * Eventually, the index information should go through here, too. @@ -24,8 +24,6 @@ #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" -#include "catalog/pg_shadow.h" -#include "catalog/pg_group.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" @@ -2010,66 +2008,35 @@ get_namespace_name(Oid nspid) return NULL; } -/* ---------- PG_SHADOW CACHE ---------- */ +/* ---------- PG_AUTHID CACHE ---------- */ /* - * get_usesysid - * - * Given a user name, look up the user's sysid. - * Raises an error if no such user (rather than returning zero, - * which might possibly be a valid usesysid). - * - * Note: the type of usesysid is currently int4, but may change to Oid - * someday. It'd be reasonable to return zero on failure if we were - * using Oid ... + * get_roleid + * Given a role name, look up the role's OID. + * Returns InvalidOid if no such role. */ -AclId -get_usesysid(const char *username) +Oid +get_roleid(const char *rolname) { - AclId userId; - HeapTuple userTup; - - userTup = SearchSysCache(SHADOWNAME, - PointerGetDatum(username), - 0, 0, 0); - if (!HeapTupleIsValid(userTup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", username))); - - userId = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; - - ReleaseSysCache(userTup); - - return userId; + return GetSysCacheOid(AUTHNAME, + PointerGetDatum(rolname), + 0, 0, 0); } /* - * get_grosysid - * - * Given a group name, look up the group's sysid. - * Raises an error if no such group (rather than returning zero, - * which might possibly be a valid grosysid). - * + * get_roleid_checked + * Given a role name, look up the role's OID. + * ereports if no such role. */ -AclId -get_grosysid(char *groname) +Oid +get_roleid_checked(const char *rolname) { - AclId groupId; - HeapTuple groupTup; + Oid roleid; - groupTup = SearchSysCache(GRONAME, - PointerGetDatum(groname), - 0, 0, 0); - if (!HeapTupleIsValid(groupTup)) + roleid = get_roleid(rolname); + if (!OidIsValid(roleid)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("group \"%s\" does not exist", groname))); - - groupId = ((Form_pg_group) GETSTRUCT(groupTup))->grosysid; - - ReleaseSysCache(groupTup); - - return groupId; + errmsg("role \"%s\" does not exist", rolname))); + return roleid; } - diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index c6cfbc5be240037a68c04fc60457f0139b2b02cb..cd24460857fb9ff2927c10028a2313c5ecc3dfb2 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.99 2005/05/11 01:26:02 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/cache/syscache.c,v 1.100 2005/06/28 05:09:01 tgl Exp $ * * NOTES * These routines allow the parser/planner/executor to perform @@ -27,9 +27,10 @@ #include "catalog/pg_aggregate.h" #include "catalog/pg_amop.h" #include "catalog/pg_amproc.h" +#include "catalog/pg_authid.h" +#include "catalog/pg_auth_members.h" #include "catalog/pg_cast.h" #include "catalog/pg_conversion.h" -#include "catalog/pg_group.h" #include "catalog/pg_index.h" #include "catalog/pg_inherits.h" #include "catalog/pg_language.h" @@ -38,7 +39,6 @@ #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" #include "catalog/pg_rewrite.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "utils/catcache.h" @@ -172,6 +172,46 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }}, + {AuthMemRelationId, /* AUTHMEMMEMROLE */ + AuthMemMemRoleIndexId, + 0, + 2, + { + Anum_pg_auth_members_member, + Anum_pg_auth_members_roleid, + 0, + 0 + }}, + {AuthMemRelationId, /* AUTHMEMROLEMEM */ + AuthMemRoleMemIndexId, + 0, + 2, + { + Anum_pg_auth_members_roleid, + Anum_pg_auth_members_member, + 0, + 0 + }}, + {AuthIdRelationId, /* AUTHNAME */ + AuthIdRolnameIndexId, + 0, + 1, + { + Anum_pg_authid_rolname, + 0, + 0, + 0 + }}, + {AuthIdRelationId, /* AUTHOID */ + AuthIdOidIndexId, + 0, + 1, + { + ObjectIdAttributeNumber, + 0, + 0, + 0 + }}, { CastRelationId, /* CASTSOURCETARGET */ CastSourceTargetIndexId, @@ -233,26 +273,6 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }}, - {GroupRelationId, /* GRONAME */ - GroupNameIndexId, - 0, - 1, - { - Anum_pg_group_groname, - 0, - 0, - 0 - }}, - {GroupRelationId, /* GROSYSID */ - GroupSysidIndexId, - 0, - 1, - { - Anum_pg_group_grosysid, - 0, - 0, - 0 - }}, {IndexRelationId, /* INDEXRELID */ IndexRelidIndexId, Anum_pg_index_indrelid, @@ -383,26 +403,6 @@ static const struct cachedesc cacheinfo[] = { 0, 0 }}, - {ShadowRelationId, /* SHADOWNAME */ - ShadowNameIndexId, - 0, - 1, - { - Anum_pg_shadow_usename, - 0, - 0, - 0 - }}, - {ShadowRelationId, /* SHADOWSYSID */ - ShadowSysidIndexId, - 0, - 1, - { - Anum_pg_shadow_usesysid, - 0, - 0, - 0 - }}, {StatisticRelationId, /* STATRELATT */ StatisticRelidAttnumIndexId, Anum_pg_statistic_starelid, diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 0733f190c2bff8e32a2540986db1a0e811b70be1..dd6134ccfd00aa57d7c6b753e1272bdc271fa245 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.95 2005/05/29 04:23:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.96 2005/06/28 05:09:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -769,7 +769,7 @@ fmgr_oldstyle(PG_FUNCTION_ARGS) struct fmgr_security_definer_cache { FmgrInfo flinfo; - AclId userid; + Oid userid; }; /* @@ -786,7 +786,7 @@ fmgr_security_definer(PG_FUNCTION_ARGS) Datum result; FmgrInfo *save_flinfo; struct fmgr_security_definer_cache * volatile fcache; - AclId save_userid; + Oid save_userid; HeapTuple tuple; if (!fcinfo->flinfo->fn_extra) diff --git a/src/backend/utils/init/flatfiles.c b/src/backend/utils/init/flatfiles.c index fcbc99189ffd7768b2f7f5341165cc9f8ee76371..8b129692f45e6ee3513dd1504f5b4be8f0d6c8fe 100644 --- a/src/backend/utils/init/flatfiles.c +++ b/src/backend/utils/init/flatfiles.c @@ -4,9 +4,10 @@ * Routines for maintaining "flat file" images of the shared catalogs. * * We use flat files so that the postmaster and not-yet-fully-started - * backends can look at the contents of pg_database, pg_shadow, and pg_group - * for authentication purposes. This module is responsible for keeping the - * flat-file images as nearly in sync with database reality as possible. + * backends can look at the contents of pg_database, pg_authid, and + * pg_auth_members for authentication purposes. This module is + * responsible for keeping the flat-file images as nearly in sync with + * database reality as possible. * * The tricky part of the write_xxx_file() routines in this module is that * they need to be able to operate in the context of the database startup @@ -22,7 +23,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.8 2005/06/17 22:32:47 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.9 2005/06/28 05:09:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -31,12 +32,14 @@ #include <sys/stat.h> #include <unistd.h> +#include "access/genam.h" #include "access/heapam.h" #include "access/twophase_rmgr.h" +#include "catalog/indexing.h" +#include "catalog/pg_auth_members.h" +#include "catalog/pg_authid.h" #include "catalog/pg_database.h" -#include "catalog/pg_group.h" #include "catalog/pg_namespace.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_tablespace.h" #include "commands/trigger.h" #include "miscadmin.h" @@ -45,19 +48,18 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/flatfiles.h" +#include "utils/fmgroids.h" #include "utils/resowner.h" #include "utils/syscache.h" /* Actual names of the flat files (within $PGDATA/global/) */ #define DATABASE_FLAT_FILE "pg_database" -#define GROUP_FLAT_FILE "pg_group" -#define USER_FLAT_FILE "pg_pwd" +#define AUTH_FLAT_FILE "pg_auth" /* Info bits in a flatfiles 2PC record */ #define FF_BIT_DATABASE 1 -#define FF_BIT_GROUP 2 -#define FF_BIT_USER 4 +#define FF_BIT_AUTH 2 /* @@ -73,8 +75,7 @@ * SubTransactionId is seen at top-level commit. */ static SubTransactionId database_file_update_subid = InvalidSubTransactionId; -static SubTransactionId group_file_update_subid = InvalidSubTransactionId; -static SubTransactionId user_file_update_subid = InvalidSubTransactionId; +static SubTransactionId auth_file_update_subid = InvalidSubTransactionId; /* @@ -88,23 +89,13 @@ database_file_update_needed(void) } /* - * Mark flat group file as needing an update (because pg_group changed) + * Mark flat auth file as needing an update (because pg_auth changed) */ void -group_file_update_needed(void) +auth_file_update_needed(void) { - if (group_file_update_subid == InvalidSubTransactionId) - group_file_update_subid = GetCurrentSubTransactionId(); -} - -/* - * Mark flat user file as needing an update (because pg_shadow changed) - */ -void -user_file_update_needed(void) -{ - if (user_file_update_subid == InvalidSubTransactionId) - user_file_update_subid = GetCurrentSubTransactionId(); + if (auth_file_update_subid == InvalidSubTransactionId) + auth_file_update_subid = GetCurrentSubTransactionId(); } @@ -128,39 +119,20 @@ database_getflatfilename(void) } /* - * group_getflatfilename --- get full pathname of group file - * - * Note that result string is palloc'd, and should be freed by the caller. - */ -char * -group_getflatfilename(void) -{ - int bufsize; - char *pfnam; - - bufsize = strlen(DataDir) + strlen("/global/") + - strlen(GROUP_FLAT_FILE) + 1; - pfnam = (char *) palloc(bufsize); - snprintf(pfnam, bufsize, "%s/global/%s", DataDir, GROUP_FLAT_FILE); - - return pfnam; -} - -/* - * Get full pathname of password file. + * Get full pathname of auth file. * * Note that result string is palloc'd, and should be freed by the caller. */ char * -user_getflatfilename(void) +auth_getflatfilename(void) { int bufsize; char *pfnam; bufsize = strlen(DataDir) + strlen("/global/") + - strlen(USER_FLAT_FILE) + 1; + strlen(AUTH_FLAT_FILE) + 1; pfnam = (char *) palloc(bufsize); - snprintf(pfnam, bufsize, "%s/global/%s", DataDir, USER_FLAT_FILE); + snprintf(pfnam, bufsize, "%s/global/%s", DataDir, AUTH_FLAT_FILE); return pfnam; } @@ -189,7 +161,7 @@ fputs_quote(const char *str, FILE *fp) /* * name_okay * - * We must disallow newlines in user and group names because + * We must disallow newlines in role names because * hba.c's parser won't handle fields split across lines, even if quoted. */ static bool @@ -322,165 +294,81 @@ write_database_file(Relation drel) /* - * write_group_file: update the flat group file + * Support for write_auth_file */ -static void -write_group_file(Relation grel) -{ - char *filename, - *tempname; - int bufsize; - FILE *fp; - mode_t oumask; - HeapScanDesc scan; - HeapTuple tuple; - - /* - * Create a temporary filename to be renamed later. This prevents the - * backend from clobbering the flat file while the postmaster - * might be reading from it. - */ - filename = group_getflatfilename(); - bufsize = strlen(filename) + 12; - tempname = (char *) palloc(bufsize); - snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid); - - oumask = umask((mode_t) 077); - fp = AllocateFile(tempname, "w"); - umask(oumask); - if (fp == NULL) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not write to temporary file \"%s\": %m", - tempname))); - - /* - * Read pg_group and write the file. - */ - scan = heap_beginscan(grel, SnapshotNow, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - Form_pg_group grpform = (Form_pg_group) GETSTRUCT(tuple); - HeapTupleHeader tup = tuple->t_data; - char *tp; /* ptr to tuple data */ - long off; /* offset in tuple data */ - bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */ - Datum datum; - char *groname; - IdList *grolist_p; - AclId *aidp; - int i, - num; - - groname = NameStr(grpform->groname); - - /* - * Check for illegal characters in the group name. - */ - if (!name_okay(groname)) - { - ereport(LOG, - (errmsg("invalid group name \"%s\"", groname))); - continue; - } - - /* - * We can't use heap_getattr() here because during startup we will - * not have any tupdesc for pg_group. Fortunately it's not too - * hard to work around this. grolist is the first possibly-null - * field so we can compute its offset directly. - */ - tp = (char *) tup + tup->t_hoff; - off = offsetof(FormData_pg_group, grolist); - - if (HeapTupleHasNulls(tuple) && - att_isnull(Anum_pg_group_grolist - 1, bp)) - { - /* grolist is null, so we can ignore this group */ - continue; - } - - /* assume grolist is pass-by-ref */ - datum = PointerGetDatum(tp + off); - - /* - * We can't currently support out-of-line toasted group lists in - * startup mode (the tuptoaster won't work). This sucks, but it - * should be something of a corner case. Live with it until we - * can redesign pg_group. - * - * Detect startup mode by noting whether we got a tupdesc. - */ - if (VARATT_IS_EXTERNAL(DatumGetPointer(datum)) && - RelationGetDescr(grel) == NULL) - continue; - /* be sure the IdList is not toasted */ - grolist_p = DatumGetIdListP(datum); +typedef struct { + Oid roleid; + char* rolname; + char* rolpassword; + char* rolvaliduntil; + List* roles_names; +} auth_entry; + +typedef struct { + Oid roleid; + Oid memberid; +} authmem_entry; + +static int +oid_compar(const void *a, const void *b) +{ + const auth_entry *a_auth = (const auth_entry*) a; + const auth_entry *b_auth = (const auth_entry*) b; - /* - * The file format is: "groupname" usesysid1 usesysid2 ... - * - * We ignore groups that have no members. - */ - aidp = IDLIST_DAT(grolist_p); - num = IDLIST_NUM(grolist_p); - if (num > 0) - { - fputs_quote(groname, fp); - fprintf(fp, "\t%u", aidp[0]); - for (i = 1; i < num; ++i) - fprintf(fp, " %u", aidp[i]); - fputs("\n", fp); - } + if (a_auth->roleid < b_auth->roleid) return -1; + if (a_auth->roleid > b_auth->roleid) return 1; + return 0; +} - /* if IdList was toasted, free detoasted copy */ - if ((Pointer) grolist_p != DatumGetPointer(datum)) - pfree(grolist_p); - } - heap_endscan(scan); +static int +name_compar(const void *a, const void *b) +{ + const auth_entry *a_auth = (const auth_entry*) a; + const auth_entry *b_auth = (const auth_entry*) b; - if (FreeFile(fp)) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not write to temporary file \"%s\": %m", - tempname))); + return strcmp(a_auth->rolname,b_auth->rolname); +} - /* - * Rename the temp file to its final name, deleting the old flat file. - * We expect that rename(2) is an atomic action. - */ - if (rename(tempname, filename)) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not rename file \"%s\" to \"%s\": %m", - tempname, filename))); +static int +mem_compar(const void *a, const void *b) +{ + const authmem_entry *a_auth = (const authmem_entry*) a; + const authmem_entry *b_auth = (const authmem_entry*) b; - pfree(tempname); - pfree(filename); + if (a_auth->memberid < b_auth->memberid) return -1; + if (a_auth->memberid > b_auth->memberid) return 1; + return 0; } - /* - * write_user_file: update the flat password file + * write_auth_file: update the flat auth file */ static void -write_user_file(Relation urel) +write_auth_file(Relation rel_auth, Relation rel_authmem, bool startup) { char *filename, *tempname; int bufsize; + BlockNumber totalblocks; FILE *fp; mode_t oumask; HeapScanDesc scan; HeapTuple tuple; + int curr_role = 0; + int total_roles = 0; + int curr_mem = 0; + int total_mem = 0; + int est_rows; + auth_entry *auth_info; + authmem_entry *authmem_info = NULL; /* * Create a temporary filename to be renamed later. This prevents the - * backend from clobbering the flat file while the postmaster might + * backend from clobbering the pg_auth file while the postmaster might * be reading from it. */ - filename = user_getflatfilename(); + filename = auth_getflatfilename(); bufsize = strlen(filename) + 12; tempname = (char *) palloc(bufsize); snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid); @@ -495,39 +383,41 @@ write_user_file(Relation urel) tempname))); /* - * Read pg_shadow and write the file. + * Read pg_authid and fill temporary data structures. */ - scan = heap_beginscan(urel, SnapshotNow, 0, NULL); + totalblocks = RelationGetNumberOfBlocks(rel_auth); + totalblocks = totalblocks ? totalblocks : 1; + est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_authid))); + auth_info = (auth_entry*) palloc(est_rows*sizeof(auth_entry)); + + scan = heap_beginscan(rel_auth, SnapshotNow, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Form_pg_shadow pwform = (Form_pg_shadow) GETSTRUCT(tuple); + Form_pg_authid pwform = (Form_pg_authid) GETSTRUCT(tuple); HeapTupleHeader tup = tuple->t_data; char *tp; /* ptr to tuple data */ long off; /* offset in tuple data */ bits8 *bp = tup->t_bits; /* ptr to null bitmask in tuple */ Datum datum; - char *usename, - *passwd, - *valuntil; - AclId usesysid; - usename = NameStr(pwform->usename); - usesysid = pwform->usesysid; + auth_info[curr_role].roleid = HeapTupleGetOid(tuple); + auth_info[curr_role].rolname = pstrdup(NameStr(pwform->rolname)); + auth_info[curr_role].roles_names = NIL; /* * We can't use heap_getattr() here because during startup we will - * not have any tupdesc for pg_shadow. Fortunately it's not too - * hard to work around this. passwd is the first possibly-null + * not have any tupdesc for pg_authid. Fortunately it's not too + * hard to work around this. rolpassword is the first possibly-null * field so we can compute its offset directly. */ tp = (char *) tup + tup->t_hoff; - off = offsetof(FormData_pg_shadow, passwd); + off = offsetof(FormData_pg_authid, rolpassword); if (HeapTupleHasNulls(tuple) && - att_isnull(Anum_pg_shadow_passwd - 1, bp)) + att_isnull(Anum_pg_authid_rolpassword - 1, bp)) { /* passwd is null, emit as an empty string */ - passwd = pstrdup(""); + auth_info[curr_role].rolpassword = pstrdup(""); } else { @@ -539,59 +429,175 @@ write_user_file(Relation urel) * if it is, ignore it, since we can't handle that in startup mode. */ if (VARATT_IS_EXTERNAL(DatumGetPointer(datum))) - passwd = pstrdup(""); + auth_info[curr_role].rolpassword = pstrdup(""); else - passwd = DatumGetCString(DirectFunctionCall1(textout, datum)); + auth_info[curr_role].rolpassword = DatumGetCString(DirectFunctionCall1(textout, datum)); /* assume passwd has attlen -1 */ off = att_addlength(off, -1, tp + off); } if (HeapTupleHasNulls(tuple) && - att_isnull(Anum_pg_shadow_valuntil - 1, bp)) + att_isnull(Anum_pg_authid_rolvaliduntil - 1, bp)) { - /* valuntil is null, emit as an empty string */ - valuntil = pstrdup(""); + /* rolvaliduntil is null, emit as an empty string */ + auth_info[curr_role].rolvaliduntil = pstrdup(""); } else { - /* assume valuntil has attalign 'i' */ - off = att_align(off, 'i'); - /* assume valuntil is pass-by-value, integer size */ - datum = Int32GetDatum(*((int32 *) (tp + off))); - valuntil = DatumGetCString(DirectFunctionCall1(abstimeout, datum)); + /* + * rolvaliduntil is timestamptz, which we assume is double + * alignment and pass-by-reference. + */ + off = att_align(off, 'd'); + datum = PointerGetDatum(tp + off); + auth_info[curr_role].rolvaliduntil = DatumGetCString(DirectFunctionCall1(timestamptz_out, datum)); } /* * Check for illegal characters in the user name and password. */ - if (!name_okay(usename)) + if (!name_okay(auth_info[curr_role].rolname)) { ereport(LOG, - (errmsg("invalid user name \"%s\"", usename))); + (errmsg("invalid role name \"%s\"", + auth_info[curr_role].rolname))); + pfree(auth_info[curr_role].rolname); + pfree(auth_info[curr_role].rolpassword); + pfree(auth_info[curr_role].rolvaliduntil); continue; } - if (!name_okay(passwd)) + if (!name_okay(auth_info[curr_role].rolpassword)) { ereport(LOG, - (errmsg("invalid user password \"%s\"", passwd))); + (errmsg("invalid role password \"%s\"", + auth_info[curr_role].rolpassword))); + pfree(auth_info[curr_role].rolname); + pfree(auth_info[curr_role].rolpassword); + pfree(auth_info[curr_role].rolvaliduntil); continue; } - /* - * The file format is: "usename" usesysid "passwd" "valuntil" + curr_role++; + total_roles++; + } + heap_endscan(scan); + + Assert(total_roles <= est_rows); + + qsort(auth_info, total_roles, sizeof(auth_entry), oid_compar); + + /* + * Read pg_auth_members into temporary data structure, too + */ + totalblocks = RelationGetNumberOfBlocks(rel_authmem); + totalblocks = totalblocks ? totalblocks : 1; + est_rows = totalblocks * (BLCKSZ / (sizeof(HeapTupleHeaderData)+sizeof(FormData_pg_auth_members))); + authmem_info = (authmem_entry*) palloc(est_rows*sizeof(authmem_entry)); + + scan = heap_beginscan(rel_authmem, SnapshotNow, 0, NULL); + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Form_pg_auth_members memform = (Form_pg_auth_members) GETSTRUCT(tuple); + + authmem_info[curr_mem].roleid = memform->roleid; + authmem_info[curr_mem].memberid = memform->member; + curr_mem++; + total_mem++; + } + heap_endscan(scan); + + Assert(total_mem <= est_rows); + + qsort(authmem_info, total_mem, sizeof(authmem_entry), mem_compar); + + for (curr_role = 0; curr_role < total_roles; curr_role++) + { + int first_found, last_found, curr_mem; + List *roles_list_hunt = NIL; + List *roles_list = NIL; + ListCell *mem = NULL; + auth_entry *found_role = NULL, key_auth; + authmem_entry key; + authmem_entry *found_mem = NULL; + + roles_list_hunt = lappend_oid(roles_list_hunt, + auth_info[curr_role].roleid); + + while (roles_list_hunt) + { + key.memberid = linitial_oid(roles_list_hunt); + roles_list_hunt = list_delete_first(roles_list_hunt); + if (total_mem) + found_mem = bsearch(&key, authmem_info, total_mem, + sizeof(authmem_entry), mem_compar); + if (found_mem) + { + /* + * bsearch found a match for us; but if there were multiple + * matches it could have found any one of them. + */ + first_found = last_found = (found_mem - authmem_info); + while (first_found > 0 && + mem_compar(&key, &authmem_info[first_found - 1]) == 0) + first_found--; + while (last_found + 1 < total_mem && + mem_compar(&key, &authmem_info[last_found + 1]) == 0) + last_found++; + + for (curr_mem = first_found; curr_mem <= last_found; curr_mem++) + { + Oid otherrole = authmem_info[curr_mem].roleid; + + if (!list_member_oid(roles_list, otherrole)) + { + roles_list = lappend_oid(roles_list, + otherrole); + roles_list_hunt = lappend_oid(roles_list_hunt, + otherrole); + } + } + } + } + + foreach(mem, roles_list) + { + key_auth.roleid = lfirst_oid(mem); + found_role = bsearch(&key_auth, auth_info, total_roles, sizeof(auth_entry), oid_compar); + auth_info[curr_role].roles_names = lappend(auth_info[curr_role].roles_names,found_role->rolname); + } + } + + qsort(auth_info, total_roles, sizeof(auth_entry), name_compar); + + for (curr_role = 0; curr_role < total_roles; curr_role++) + { + ListCell *mem = NULL; + + /*---------- + * The file format is: + * "rolename" "password" "validuntil" "member" "member" ... + * where lines are expected to be in order by rolename + *---------- */ - fputs_quote(usename, fp); - fprintf(fp, " %u ", usesysid); - fputs_quote(passwd, fp); + fputs_quote(auth_info[curr_role].rolname, fp); + fputs(" ", fp); + fputs_quote(auth_info[curr_role].rolpassword, fp); fputs(" ", fp); - fputs_quote(valuntil, fp); + fputs_quote(auth_info[curr_role].rolvaliduntil, fp); + + foreach(mem, auth_info[curr_role].roles_names) + { + fputs(" ", fp); + fputs_quote(lfirst(mem), fp); + } + fputs("\n", fp); - pfree(passwd); - pfree(valuntil); + pfree(auth_info[curr_role].rolname); + pfree(auth_info[curr_role].rolpassword); + pfree(auth_info[curr_role].rolvaliduntil); } - heap_endscan(scan); if (FreeFile(fp)) ereport(ERROR, @@ -609,6 +615,8 @@ write_user_file(Relation urel) errmsg("could not rename file \"%s\" to \"%s\": %m", tempname, filename))); + pfree(auth_info); + pfree(authmem_info); pfree(tempname); pfree(filename); } @@ -634,7 +642,7 @@ BuildFlatFiles(bool database_only) { ResourceOwner owner; RelFileNode rnode; - Relation rel; + Relation rel, rel_auth, rel_authmem; /* * We don't have any hope of running a real relcache, but we can use @@ -657,21 +665,16 @@ BuildFlatFiles(bool database_only) if (!database_only) { - /* hard-wired path to pg_group */ + /* hard-wired path to pg_auth */ rnode.spcNode = GLOBALTABLESPACE_OID; rnode.dbNode = 0; - rnode.relNode = GroupRelationId; + rnode.relNode = AuthIdRelationId; + rel_auth = XLogOpenRelation(rnode); - rel = XLogOpenRelation(rnode); - write_group_file(rel); - - /* hard-wired path to pg_shadow */ rnode.spcNode = GLOBALTABLESPACE_OID; rnode.dbNode = 0; - rnode.relNode = ShadowRelationId; - - rel = XLogOpenRelation(rnode); - write_user_file(rel); + rnode.relNode = AuthMemRelationId; + rel_authmem = XLogOpenRelation(rnode); } CurrentResourceOwner = NULL; @@ -699,19 +702,17 @@ void AtEOXact_UpdateFlatFiles(bool isCommit) { Relation drel = NULL; - Relation grel = NULL; - Relation urel = NULL; + Relation arel = NULL; + Relation mrel = NULL; if (database_file_update_subid == InvalidSubTransactionId && - group_file_update_subid == InvalidSubTransactionId && - user_file_update_subid == InvalidSubTransactionId) + auth_file_update_subid == InvalidSubTransactionId) return; /* nothing to do */ if (!isCommit) { database_file_update_subid = InvalidSubTransactionId; - group_file_update_subid = InvalidSubTransactionId; - user_file_update_subid = InvalidSubTransactionId; + auth_file_update_subid = InvalidSubTransactionId; return; } @@ -731,10 +732,10 @@ AtEOXact_UpdateFlatFiles(bool isCommit) */ if (database_file_update_subid != InvalidSubTransactionId) drel = heap_open(DatabaseRelationId, ExclusiveLock); - if (group_file_update_subid != InvalidSubTransactionId) - grel = heap_open(GroupRelationId, ExclusiveLock); - if (user_file_update_subid != InvalidSubTransactionId) - urel = heap_open(ShadowRelationId, ExclusiveLock); + if (auth_file_update_subid != InvalidSubTransactionId) { + arel = heap_open(AuthIdRelationId, ExclusiveLock); + mrel = heap_open(AuthMemRelationId, ExclusiveLock); + } /* Okay to write the files */ if (database_file_update_subid != InvalidSubTransactionId) @@ -744,18 +745,12 @@ AtEOXact_UpdateFlatFiles(bool isCommit) heap_close(drel, NoLock); } - if (group_file_update_subid != InvalidSubTransactionId) - { - group_file_update_subid = InvalidSubTransactionId; - write_group_file(grel); - heap_close(grel, NoLock); - } - - if (user_file_update_subid != InvalidSubTransactionId) + if (auth_file_update_subid != InvalidSubTransactionId) { - user_file_update_subid = InvalidSubTransactionId; - write_user_file(urel); - heap_close(urel, NoLock); + auth_file_update_subid = InvalidSubTransactionId; + write_auth_file(arel, mrel, false); + heap_close(arel, NoLock); + heap_close(mrel, NoLock); } /* @@ -785,15 +780,10 @@ AtPrepare_UpdateFlatFiles(void) database_file_update_subid = InvalidSubTransactionId; info |= FF_BIT_DATABASE; } - if (group_file_update_subid != InvalidSubTransactionId) - { - group_file_update_subid = InvalidSubTransactionId; - info |= FF_BIT_GROUP; - } - if (user_file_update_subid != InvalidSubTransactionId) + if (auth_file_update_subid != InvalidSubTransactionId) { - user_file_update_subid = InvalidSubTransactionId; - info |= FF_BIT_USER; + auth_file_update_subid = InvalidSubTransactionId; + info |= FF_BIT_AUTH; } if (info != 0) RegisterTwoPhaseRecord(TWOPHASE_RM_FLATFILES_ID, info, @@ -817,29 +807,23 @@ AtEOSubXact_UpdateFlatFiles(bool isCommit, if (database_file_update_subid == mySubid) database_file_update_subid = parentSubid; - if (group_file_update_subid == mySubid) - group_file_update_subid = parentSubid; - - if (user_file_update_subid == mySubid) - user_file_update_subid = parentSubid; + if (auth_file_update_subid == mySubid) + auth_file_update_subid = parentSubid; } else { if (database_file_update_subid == mySubid) database_file_update_subid = InvalidSubTransactionId; - if (group_file_update_subid == mySubid) - group_file_update_subid = InvalidSubTransactionId; - - if (user_file_update_subid == mySubid) - user_file_update_subid = InvalidSubTransactionId; + if (auth_file_update_subid == mySubid) + auth_file_update_subid = InvalidSubTransactionId; } } /* - * This trigger is fired whenever someone modifies pg_database, pg_shadow - * or pg_group via general-purpose INSERT/UPDATE/DELETE commands. + * This trigger is fired whenever someone modifies pg_database, pg_authid + * or pg_auth_members via general-purpose INSERT/UPDATE/DELETE commands. * * It is sufficient for this to be a STATEMENT trigger since we don't * care which individual rows changed. It doesn't much matter whether @@ -862,11 +846,11 @@ flatfile_update_trigger(PG_FUNCTION_ARGS) case DatabaseRelationId: database_file_update_needed(); break; - case GroupRelationId: - group_file_update_needed(); + case AuthIdRelationId: + auth_file_update_needed(); break; - case ShadowRelationId: - user_file_update_needed(); + case AuthMemRelationId: + auth_file_update_needed(); break; default: elog(ERROR, "flatfile_update_trigger was called for wrong table"); @@ -895,8 +879,6 @@ flatfile_twophase_postcommit(TransactionId xid, uint16 info, */ if (info & FF_BIT_DATABASE) database_file_update_needed(); - if (info & FF_BIT_GROUP) - group_file_update_needed(); - if (info & FF_BIT_USER) - user_file_update_needed(); + if (info & FF_BIT_AUTH) + auth_file_update_needed(); } diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 508c56e1e03c5f066a64898c8c723d495435b49d..1db2992899697a9d9a1e7be841f284d223e0cef0 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.142 2005/06/20 02:17:30 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.143 2005/06/28 05:09:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -29,7 +29,7 @@ #include <utime.h> #endif -#include "catalog/pg_shadow.h" +#include "catalog/pg_authid.h" #include "libpq/libpq-be.h" #include "miscadmin.h" #include "storage/fd.h" @@ -251,7 +251,7 @@ make_absolute_path(const char *path) /* ---------------------------------------------------------------- - * User ID things + * Role ID things * * The authenticated user is determined at connection start and never * changes. The session user can be changed only by SET SESSION @@ -261,60 +261,60 @@ make_absolute_path(const char *path) * restore the current user id if you need to change it. * ---------------------------------------------------------------- */ -static AclId AuthenticatedUserId = 0; -static AclId SessionUserId = 0; -static AclId CurrentUserId = 0; +static Oid AuthenticatedUserId = InvalidOid; +static Oid SessionUserId = InvalidOid; +static Oid CurrentUserId = InvalidOid; static bool AuthenticatedUserIsSuperuser = false; /* * This function is relevant for all privilege checks. */ -AclId +Oid GetUserId(void) { - AssertState(AclIdIsValid(CurrentUserId)); + AssertState(OidIsValid(CurrentUserId)); return CurrentUserId; } void -SetUserId(AclId newid) +SetUserId(Oid roleid) { - AssertArg(AclIdIsValid(newid)); - CurrentUserId = newid; + AssertArg(OidIsValid(roleid)); + CurrentUserId = roleid; } /* * This value is only relevant for informational purposes. */ -AclId +Oid GetSessionUserId(void) { - AssertState(AclIdIsValid(SessionUserId)); + AssertState(OidIsValid(SessionUserId)); return SessionUserId; } void -SetSessionUserId(AclId newid) +SetSessionUserId(Oid roleid) { - AssertArg(AclIdIsValid(newid)); - SessionUserId = newid; + AssertArg(OidIsValid(roleid)); + SessionUserId = roleid; /* Current user defaults to session user. */ - if (!AclIdIsValid(CurrentUserId)) - CurrentUserId = newid; + if (!OidIsValid(CurrentUserId)) + CurrentUserId = roleid; } void -InitializeSessionUserId(const char *username) +InitializeSessionUserId(const char *rolename) { - HeapTuple userTup; + HeapTuple roleTup; Datum datum; bool isnull; - AclId usesysid; + Oid roleid; /* * Don't do scans if we're bootstrapping, none of the system catalogs @@ -325,23 +325,23 @@ InitializeSessionUserId(const char *username) /* call only once */ AssertState(!OidIsValid(AuthenticatedUserId)); - userTup = SearchSysCache(SHADOWNAME, - PointerGetDatum(username), + roleTup = SearchSysCache(AUTHNAME, + PointerGetDatum(rolename), 0, 0, 0); - if (!HeapTupleIsValid(userTup)) + if (!HeapTupleIsValid(roleTup)) ereport(FATAL, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user \"%s\" does not exist", username))); + errmsg("role \"%s\" does not exist", rolename))); - usesysid = ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid; + roleid = HeapTupleGetOid(roleTup); - AuthenticatedUserId = usesysid; - AuthenticatedUserIsSuperuser = ((Form_pg_shadow) GETSTRUCT(userTup))->usesuper; + AuthenticatedUserId = roleid; + AuthenticatedUserIsSuperuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper; - SetSessionUserId(usesysid); /* sets CurrentUserId too */ + SetSessionUserId(roleid); /* sets CurrentUserId too */ /* Record username and superuser status as GUC settings too */ - SetConfigOption("session_authorization", username, + SetConfigOption("session_authorization", rolename, PGC_BACKEND, PGC_S_OVERRIDE); SetConfigOption("is_superuser", AuthenticatedUserIsSuperuser ? "on" : "off", @@ -349,11 +349,11 @@ InitializeSessionUserId(const char *username) /* * Set up user-specific configuration variables. This is a good place - * to do it so we don't have to read pg_shadow twice during session + * to do it so we don't have to read pg_authid twice during session * startup. */ - datum = SysCacheGetAttr(SHADOWNAME, userTup, - Anum_pg_shadow_useconfig, &isnull); + datum = SysCacheGetAttr(AUTHNAME, roleTup, + Anum_pg_authid_rolconfig, &isnull); if (!isnull) { ArrayType *a = DatumGetArrayTypeP(datum); @@ -361,7 +361,7 @@ InitializeSessionUserId(const char *username) ProcessGUCArray(a, PGC_S_USER); } - ReleaseSysCache(userTup); + ReleaseSysCache(roleTup); } @@ -374,10 +374,10 @@ InitializeSessionUserIdStandalone(void) /* call only once */ AssertState(!OidIsValid(AuthenticatedUserId)); - AuthenticatedUserId = BOOTSTRAP_USESYSID; + AuthenticatedUserId = BOOTSTRAP_SUPERUSERID; AuthenticatedUserIsSuperuser = true; - SetSessionUserId(BOOTSTRAP_USESYSID); + SetSessionUserId(BOOTSTRAP_SUPERUSERID); } @@ -390,19 +390,19 @@ InitializeSessionUserIdStandalone(void) * to indicate whether the *current* session userid is a superuser. */ void -SetSessionAuthorization(AclId userid, bool is_superuser) +SetSessionAuthorization(Oid roleid, bool is_superuser) { /* Must have authenticated already, else can't make permission check */ - AssertState(AclIdIsValid(AuthenticatedUserId)); + AssertState(OidIsValid(AuthenticatedUserId)); - if (userid != AuthenticatedUserId && + if (roleid != AuthenticatedUserId && !AuthenticatedUserIsSuperuser) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to set session authorization"))); - SetSessionUserId(userid); - SetUserId(userid); + SetSessionUserId(roleid); + SetUserId(roleid); SetConfigOption("is_superuser", is_superuser ? "on" : "off", @@ -411,30 +411,29 @@ SetSessionAuthorization(AclId userid, bool is_superuser) /* - * Get user name from user id + * Get user name from user oid */ char * -GetUserNameFromId(AclId userid) +GetUserNameFromId(Oid roleid) { HeapTuple tuple; char *result; - tuple = SearchSysCache(SHADOWSYSID, - ObjectIdGetDatum(userid), + tuple = SearchSysCache(AUTHOID, + ObjectIdGetDatum(roleid), 0, 0, 0); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("invalid user ID: %d", userid))); + errmsg("invalid role OID: %u", roleid))); - result = pstrdup(NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename)); + result = pstrdup(NameStr(((Form_pg_authid) GETSTRUCT(tuple))->rolname)); ReleaseSysCache(tuple); return result; } - /*------------------------------------------------------------------------- * Interlock-file support * diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 1836aee81d7f0881df05febf174c62df25ad808e..9baacacfffd9400341ead1dbb5869bcab58f23c5 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.149 2005/06/24 01:06:26 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.150 2005/06/28 05:09:02 tgl Exp $ * * *------------------------------------------------------------------------- @@ -20,11 +20,11 @@ #include <math.h> #include <unistd.h> -#include "catalog/catalog.h" #include "access/heapam.h" +#include "catalog/catalog.h" #include "catalog/namespace.h" +#include "catalog/pg_authid.h" #include "catalog/pg_database.h" -#include "catalog/pg_shadow.h" #include "catalog/pg_tablespace.h" #include "libpq/hba.h" #include "mb/pg_wchar.h" @@ -37,6 +37,7 @@ #include "storage/procarray.h" #include "storage/sinval.h" #include "storage/smgr.h" +#include "utils/acl.h" #include "utils/flatfiles.h" #include "utils/fmgroids.h" #include "utils/guc.h" @@ -49,7 +50,7 @@ static bool FindMyDatabase(const char *name, Oid *db_id, Oid *db_tablespace); static void ReverifyMyDatabase(const char *name); static void InitCommunication(void); static void ShutdownPostgres(int code, Datum arg); -static bool ThereIsAtLeastOneUser(void); +static bool ThereIsAtLeastOneRole(void); /*** InitPostgres support ***/ @@ -415,12 +416,12 @@ InitPostgres(const char *dbname, const char *username) else if (!IsUnderPostmaster) { InitializeSessionUserIdStandalone(); - if (!ThereIsAtLeastOneUser()) + if (!ThereIsAtLeastOneRole()) ereport(WARNING, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("no users are defined in this database system"), - errhint("You should immediately run CREATE USER \"%s\" WITH SYSID %d CREATEUSER;.", - username, BOOTSTRAP_USESYSID))); + errmsg("no roles are defined in this database system"), + errhint("You should immediately run CREATE USER \"%s\" CREATEUSER;.", + username))); } else { @@ -469,6 +470,9 @@ InitPostgres(const char *dbname, const char *username) /* set default namespace search path */ InitializeSearchPath(); + /* set up ACL framework (currently just sets RolMemCache callback) */ + InitializeAcl(); + /* initialize client encoding */ InitializeClientEncoding(); @@ -530,22 +534,22 @@ ShutdownPostgres(int code, Datum arg) /* - * Returns true if at least one user is defined in this database cluster. + * Returns true if at least one role is defined in this database cluster. */ static bool -ThereIsAtLeastOneUser(void) +ThereIsAtLeastOneRole(void) { - Relation pg_shadow_rel; + Relation pg_authid_rel; HeapScanDesc scan; bool result; - pg_shadow_rel = heap_open(ShadowRelationId, AccessExclusiveLock); + pg_authid_rel = heap_open(AuthIdRelationId, AccessExclusiveLock); - scan = heap_beginscan(pg_shadow_rel, SnapshotNow, 0, NULL); + scan = heap_beginscan(pg_authid_rel, SnapshotNow, 0, NULL); result = (heap_getnext(scan, ForwardScanDirection) != NULL); heap_endscan(scan); - heap_close(pg_shadow_rel, AccessExclusiveLock); + heap_close(pg_authid_rel, AccessExclusiveLock); return result; } diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 0ab8e742336ae1eabdf6b16d313ea40a41856e09..84d8085503a7603df2a2588a98fbcbc64ee0259b 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <peter_e@gmx.net>. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.270 2005/06/26 19:16:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.271 2005/06/28 05:09:02 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -5108,7 +5108,7 @@ ParseLongOption(const char *string, char **name, char **value) /* - * Handle options fetched from pg_database.datconfig or pg_shadow.useconfig. + * Handle options fetched from pg_database.datconfig or pg_authid.rolconfig. * The array parameter must be an array of TEXT (it must not be NULL). */ void @@ -5154,7 +5154,7 @@ ProcessGUCArray(ArrayType *array, GucSource source) /* * We process all these options at SUSET level. We assume that - * the right to insert an option into pg_database or pg_shadow was + * the right to insert an option into pg_database or pg_authid was * checked when it was inserted. */ SetConfigOption(name, value, PGC_SUSET, source); diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c index 520dc470cdcef7e6cab563bdc86a3e8425b1466b..9e965b8107f72420c88b87e8478d6655f281b574 100644 --- a/src/backend/utils/misc/superuser.c +++ b/src/backend/utils/misc/superuser.c @@ -14,29 +14,29 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.31 2005/05/29 20:38:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/superuser.c,v 1.32 2005/06/28 05:09:02 tgl Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" -#include "catalog/pg_shadow.h" +#include "catalog/pg_authid.h" #include "utils/inval.h" #include "utils/syscache.h" #include "miscadmin.h" /* - * In common cases the same userid (ie, the session or current ID) will + * In common cases the same roleid (ie, the session or current ID) will * be queried repeatedly. So we maintain a simple one-entry cache for - * the status of the last requested userid. The cache can be flushed - * at need by watching for cache update events on pg_shadow. + * the status of the last requested roleid. The cache can be flushed + * at need by watching for cache update events on pg_authid. */ -static AclId last_userid = 0; /* 0 == cache not valid */ -static bool last_userid_is_super = false; -static bool userid_callback_registered = false; +static Oid last_roleid = InvalidOid; /* InvalidOid == cache not valid */ +static bool last_roleid_is_super = false; +static bool roleid_callback_registered = false; -static void UseridCallback(Datum arg, Oid relid); +static void RoleidCallback(Datum arg, Oid relid); /* @@ -50,49 +50,49 @@ superuser(void) /* - * The specified userid has Postgres superuser privileges + * The specified role has Postgres superuser privileges */ bool -superuser_arg(AclId userid) +superuser_arg(Oid roleid) { bool result; - HeapTuple utup; + HeapTuple rtup; /* Quick out for cache hit */ - if (AclIdIsValid(last_userid) && last_userid == userid) - return last_userid_is_super; + if (OidIsValid(last_roleid) && last_roleid == roleid) + return last_roleid_is_super; /* Special escape path in case you deleted all your users. */ - if (!IsUnderPostmaster && userid == BOOTSTRAP_USESYSID) + if (!IsUnderPostmaster && roleid == BOOTSTRAP_SUPERUSERID) return true; - /* OK, look up the information in pg_shadow */ - utup = SearchSysCache(SHADOWSYSID, - Int32GetDatum(userid), + /* OK, look up the information in pg_authid */ + rtup = SearchSysCache(AUTHOID, + ObjectIdGetDatum(roleid), 0, 0, 0); - if (HeapTupleIsValid(utup)) + if (HeapTupleIsValid(rtup)) { - result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper; - ReleaseSysCache(utup); + result = ((Form_pg_authid) GETSTRUCT(rtup))->rolsuper; + ReleaseSysCache(rtup); } else { - /* Report "not superuser" for invalid userids */ + /* Report "not superuser" for invalid roleids */ result = false; } /* If first time through, set up callback for cache flushes */ - if (!userid_callback_registered) + if (!roleid_callback_registered) { - CacheRegisterSyscacheCallback(SHADOWSYSID, - UseridCallback, + CacheRegisterSyscacheCallback(AUTHOID, + RoleidCallback, (Datum) 0); - userid_callback_registered = true; + roleid_callback_registered = true; } /* Cache the result for next time */ - last_userid = userid; - last_userid_is_super = result; + last_roleid = roleid; + last_roleid_is_super = result; return result; } @@ -102,8 +102,8 @@ superuser_arg(AclId userid) * Syscache inval callback function */ static void -UseridCallback(Datum arg, Oid relid) +RoleidCallback(Datum arg, Oid relid) { - /* Invalidate our local cache in case user's superuserness changed */ - last_userid = 0; + /* Invalidate our local cache in case role's superuserness changed */ + last_roleid = InvalidOid; } diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 2442f43ddcf583e1a34b048b8014b56f462913c0..58fb04860aead46de8fd63fda2bcd8af06ac8349 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -42,7 +42,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * Portions taken from FreeBSD. * - * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.86 2005/06/26 03:03:45 momjian Exp $ + * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.87 2005/06/28 05:09:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -169,7 +169,7 @@ static void test_connections(void); static void test_buffers(void); static void setup_config(void); static void bootstrap_template1(char *short_version); -static void setup_shadow(void); +static void setup_auth(void); static void get_set_pwd(void); static void unlimit_systables(void); static void setup_depend(void); @@ -1316,11 +1316,11 @@ bootstrap_template1(char *short_version) * set up the shadow password table */ static void -setup_shadow(void) +setup_auth(void) { PG_CMD_DECL; char **line; - static char *pg_shadow_setup[] = { + static char *pg_authid_setup[] = { /* * Create triggers to ensure manual updates to shared catalogs * will be reflected into their "flat file" copies. @@ -1328,22 +1328,22 @@ setup_shadow(void) "CREATE TRIGGER pg_sync_pg_database " " AFTER INSERT OR UPDATE OR DELETE ON pg_database " " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", - "CREATE TRIGGER pg_sync_pg_group " - " AFTER INSERT OR UPDATE OR DELETE ON pg_group " + "CREATE TRIGGER pg_sync_pg_authid " + " AFTER INSERT OR UPDATE OR DELETE ON pg_authid " " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", - "CREATE TRIGGER pg_sync_pg_pwd " - " AFTER INSERT OR UPDATE OR DELETE ON pg_shadow " + "CREATE TRIGGER pg_sync_pg_auth_members " + " AFTER INSERT OR UPDATE OR DELETE ON pg_auth_members " " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", /* - * needs to be done before alter user, because alter user checks - * that pg_shadow is secure ... + * The authid table shouldn't be readable except through views, + * to ensure passwords are not publicly visible. */ - "REVOKE ALL on pg_shadow FROM public;\n", + "REVOKE ALL on pg_authid FROM public;\n", NULL }; - fputs(_("initializing pg_shadow ... "), stdout); + fputs(_("initializing pg_authid ... "), stdout); fflush(stdout); snprintf(cmd, sizeof(cmd), @@ -1353,7 +1353,7 @@ setup_shadow(void) PG_CMD_OPEN; - for (line = pg_shadow_setup; *line != NULL; line++) + for (line = pg_authid_setup; *line != NULL; line++) PG_CMD_PUTS(*line); PG_CMD_CLOSE; @@ -1461,13 +1461,12 @@ unlimit_systables(void) char **line; static char *systables_setup[] = { "ALTER TABLE pg_attrdef CREATE TOAST TABLE;\n", + "ALTER TABLE pg_authid CREATE TOAST TABLE;\n", "ALTER TABLE pg_constraint CREATE TOAST TABLE;\n", "ALTER TABLE pg_database CREATE TOAST TABLE;\n", "ALTER TABLE pg_description CREATE TOAST TABLE;\n", - "ALTER TABLE pg_group CREATE TOAST TABLE;\n", "ALTER TABLE pg_proc CREATE TOAST TABLE;\n", "ALTER TABLE pg_rewrite CREATE TOAST TABLE;\n", - "ALTER TABLE pg_shadow CREATE TOAST TABLE;\n", "ALTER TABLE pg_statistic CREATE TOAST TABLE;\n", NULL }; @@ -2624,7 +2623,7 @@ main(int argc, char *argv[]) /* Create the stuff we don't need to use bootstrap mode for */ - setup_shadow(); + setup_auth(); if (pwprompt || pwfilename) get_set_pwd(); diff --git a/src/include/access/twophase.h b/src/include/access/twophase.h index 08f1f9bd9fef10ae941ee3a8a2f2ff7ad4377856..e90b9e304db18be4528381d57ba87a2792bb7304 100644 --- a/src/include/access/twophase.h +++ b/src/include/access/twophase.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/twophase.h,v 1.3 2005/06/19 20:00:39 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/twophase.h,v 1.4 2005/06/28 05:09:03 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,7 +34,7 @@ extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid); extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, TimestampTz prepared_at, - AclId owner, Oid databaseid); + Oid owner, Oid databaseid); extern void StartPrepare(GlobalTransaction gxact); extern void EndPrepare(GlobalTransaction gxact); diff --git a/src/include/c.h b/src/include/c.h index 1a92038774748a9f2a95b441073136f1b96ca80f..202e45271e5bb32622c308e3ede81891b3d07fb9 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/c.h,v 1.185 2005/06/08 15:50:28 tgl Exp $ + * $PostgreSQL: pgsql/src/include/c.h,v 1.186 2005/06/28 05:09:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -366,7 +366,7 @@ typedef double float8; /* * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, - * CommandId, AclId + * CommandId */ /* typedef Oid is in postgres_ext.h */ @@ -394,8 +394,6 @@ typedef uint32 CommandId; #define FirstCommandId ((CommandId) 0) -typedef int32 AclId; /* user and group identifiers */ - /* * Array indexing support */ @@ -507,8 +505,6 @@ typedef NameData *Name; #define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) -#define AclIdIsValid(aclId) ((bool) ((aclId) != 0)) - #define RegProcedureIsValid(p) OidIsValid(p) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 1e5c7ce0fa0f6c2ab460e17a223a9cea8428e1df..5a1943723dc9561b8cb9c12865761aaf98af4bac 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.282 2005/06/27 12:45:22 teodor Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.283 2005/06/28 05:09:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200506271 +#define CATALOG_VERSION_NO 200506272 #endif diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 8be3527be2c53752aca535fde627218eb81d69b9..757a2095792f6bbde753916e4977a851927d0892 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.87 2005/04/14 20:03:27 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/indexing.h,v 1.88 2005/06/28 05:09:04 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -83,6 +83,16 @@ DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index,2658, on pg_attribute using DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index,2659, on pg_attribute using btree(attrelid oid_ops, attnum int2_ops)); #define AttributeRelidNumIndexId 2659 +DECLARE_UNIQUE_INDEX(pg_authid_rolname_index,2676, on pg_authid using btree(rolname name_ops)); +#define AuthIdRolnameIndexId 2676 +DECLARE_UNIQUE_INDEX(pg_authid_oid_index,2677, on pg_authid using btree(oid oid_ops)); +#define AuthIdOidIndexId 2677 + +DECLARE_UNIQUE_INDEX(pg_auth_members_role_member_index,2694, on pg_auth_members using btree(roleid oid_ops, member oid_ops)); +#define AuthMemRoleMemIndexId 2694 +DECLARE_UNIQUE_INDEX(pg_auth_members_member_role_index,2695, on pg_auth_members using btree(member oid_ops, roleid oid_ops)); +#define AuthMemMemRoleIndexId 2695 + DECLARE_UNIQUE_INDEX(pg_cast_oid_index,2660, on pg_cast using btree(oid oid_ops)); #define CastOidIndexId 2660 DECLARE_UNIQUE_INDEX(pg_cast_source_target_index,2661, on pg_cast using btree(castsource oid_ops, casttarget oid_ops)); @@ -127,11 +137,6 @@ DECLARE_INDEX(pg_depend_reference_index,2674, on pg_depend using btree(refclassi DECLARE_UNIQUE_INDEX(pg_description_o_c_o_index,2675, on pg_description using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops)); #define DescriptionObjIndexId 2675 -DECLARE_UNIQUE_INDEX(pg_group_name_index,2676, on pg_group using btree(groname name_ops)); -#define GroupNameIndexId 2676 -DECLARE_UNIQUE_INDEX(pg_group_sysid_index,2677, on pg_group using btree(grosysid int4_ops)); -#define GroupSysidIndexId 2677 - /* This following index is not used for a cache and is not unique */ DECLARE_INDEX(pg_index_indrelid_index,2678, on pg_index using btree(indrelid oid_ops)); #define IndexIndrelidIndexId 2678 @@ -174,11 +179,6 @@ DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index,2692, on pg_rewrite using btree(oid oi DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index,2693, on pg_rewrite using btree(ev_class oid_ops, rulename name_ops)); #define RewriteRelRulenameIndexId 2693 -DECLARE_UNIQUE_INDEX(pg_shadow_usename_index,2694, on pg_shadow using btree(usename name_ops)); -#define ShadowNameIndexId 2694 -DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index,2695, on pg_shadow using btree(usesysid int4_ops)); -#define ShadowSysidIndexId 2695 - DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index,2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops)); #define StatisticRelidAttnumIndexId 2696 diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index ddca993a68a2f68a1c6362c3dd9c39110fc44138..bda89f440541ae4a3873a58ee6f10034ebaaad81 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.117 2005/04/29 22:28:24 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.118 2005/06/28 05:09:04 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -226,7 +226,7 @@ typedef FormData_pg_attribute *Form_pg_attribute; #define Schema_pg_type \ { 1247, {"typname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typnamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ -{ 1247, {"typowner"}, 23, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ +{ 1247, {"typowner"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1247, {"typlen"}, 21, -1, 2, 4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \ { 1247, {"typbyval"}, 16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1247, {"typtype"}, 18, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ @@ -250,7 +250,7 @@ typedef FormData_pg_attribute *Form_pg_attribute; DATA(insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0)); DATA(insert ( 1247 typnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0)); -DATA(insert ( 1247 typowner 23 -1 4 3 0 -1 -1 t p i t f f t 0)); +DATA(insert ( 1247 typowner 26 -1 4 3 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1247 typlen 21 -1 2 4 0 -1 -1 t p s t f f t 0)); DATA(insert ( 1247 typbyval 16 -1 1 5 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1247 typtype 18 -1 1 6 0 -1 -1 t p c t f f t 0)); @@ -286,7 +286,7 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0)); #define Schema_pg_proc \ { 1255, {"proname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \ { 1255, {"pronamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ -{ 1255, {"proowner"}, 23, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ +{ 1255, {"proowner"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1255, {"prolang"}, 26, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1255, {"proisagg"}, 16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ { 1255, {"prosecdef"}, 16, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \ @@ -305,7 +305,7 @@ DATA(insert ( 1247 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0)); DATA(insert ( 1255 pronamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0)); -DATA(insert ( 1255 proowner 23 -1 4 3 0 -1 -1 t p i t f f t 0)); +DATA(insert ( 1255 proowner 26 -1 4 3 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1255 prolang 26 -1 4 4 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1255 proisagg 16 -1 1 5 0 -1 -1 t p c t f f t 0)); DATA(insert ( 1255 prosecdef 16 -1 1 6 0 -1 -1 t p c t f f t 0)); @@ -385,7 +385,7 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0)); { 1259, {"relname"}, 19, -1, NAMEDATALEN, 1, 0, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \ { 1259, {"relnamespace"}, 26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1259, {"reltype"}, 26, -1, 4, 3, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ -{ 1259, {"relowner"}, 23, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ +{ 1259, {"relowner"}, 26, -1, 4, 4, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1259, {"relam"}, 26, -1, 4, 5, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1259, {"relfilenode"}, 26, -1, 4, 6, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ { 1259, {"reltablespace"}, 26, -1, 4, 7, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \ @@ -411,7 +411,7 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0)); DATA(insert ( 1259 relnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1259 reltype 26 -1 4 3 0 -1 -1 t p i t f f t 0)); -DATA(insert ( 1259 relowner 23 -1 4 4 0 -1 -1 t p i t f f t 0)); +DATA(insert ( 1259 relowner 26 -1 4 4 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1259 relam 26 -1 4 5 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1259 relfilenode 26 -1 4 6 0 -1 -1 t p i t f f t 0)); DATA(insert ( 1259 reltablespace 26 -1 4 7 0 -1 -1 t p i t f f t 0)); diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h new file mode 100644 index 0000000000000000000000000000000000000000..e08fd2e6ae1cd352bc164d4a2735d950ec264989 --- /dev/null +++ b/src/include/catalog/pg_auth_members.h @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- + * + * pg_auth_members.h + * definition of the system "authorization identifier members" relation + * (pg_auth_members) along with the relation's initial contents. + * + * + * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/catalog/pg_auth_members.h,v 1.1 2005/06/28 05:09:04 tgl Exp $ + * + * NOTES + * the genbki.sh script reads this file and generates .bki + * information from the DATA() statements. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AUTH_MEMBERS_H +#define PG_AUTH_MEMBERS_H + +/* ---------------- + * pg_auth_members definition. cpp turns this into + * typedef struct FormData_pg_auth_members + * ---------------- + */ +#define AuthMemRelationId 1261 + +CATALOG(pg_auth_members,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +{ + Oid roleid; /* ID of a role */ + Oid member; /* ID of a member of that role */ + Oid grantor; /* who granted the membership */ + bool admin_option; /* granted with admin option? */ +} FormData_pg_auth_members; + +/* ---------------- + * Form_pg_auth_members corresponds to a pointer to a tuple with + * the format of pg_auth_members relation. + * ---------------- + */ +typedef FormData_pg_auth_members *Form_pg_auth_members; + +/* ---------------- + * compiler constants for pg_auth_members + * ---------------- + */ +#define Natts_pg_auth_members 4 +#define Anum_pg_auth_members_roleid 1 +#define Anum_pg_auth_members_member 2 +#define Anum_pg_auth_members_grantor 3 +#define Anum_pg_auth_members_admin_option 4 + +#endif /* PG_AUTH_MEMBERS_H */ diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h new file mode 100644 index 0000000000000000000000000000000000000000..2ea15fea8a1a7cb8702a00585bc8aabf731a90aa --- /dev/null +++ b/src/include/catalog/pg_authid.h @@ -0,0 +1,94 @@ +/*------------------------------------------------------------------------- + * + * pg_authid.h + * definition of the system "authorization identifier" relation (pg_authid) + * along with the relation's initial contents. + * + * pg_shadow and pg_group are now publicly accessible views on pg_authid. + * + * + * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/catalog/pg_authid.h,v 1.1 2005/06/28 05:09:05 tgl Exp $ + * + * NOTES + * the genbki.sh script reads this file and generates .bki + * information from the DATA() statements. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_AUTHID_H +#define PG_AUTHID_H + +/* + * The CATALOG definition has to refer to the type of rolvaliduntil as + * "timestamptz" (lower case) so that bootstrap mode recognizes it. But + * the C header files define this type as TimestampTz. Since the field is + * potentially-null and therefore can't be accessed directly from C code, + * there is no particular need for the C struct definition to show the + * field type as TimestampTz --- instead we just make it Datum. + */ + +#define timestamptz Datum + + +/* ---------------- + * pg_authid definition. cpp turns this into + * typedef struct FormData_pg_authid + * ---------------- + */ +#define AuthIdRelationId 1260 + +CATALOG(pg_authid,1260) BKI_SHARED_RELATION +{ + NameData rolname; /* name of role */ + bool rolsuper; /* read this field via superuser() only! */ + bool rolcreaterole; /* allowed to create more roles? */ + bool rolcreatedb; /* allowed to create databases? */ + bool rolcatupdate; /* allowed to alter catalogs manually? */ + bool rolcanlogin; /* allowed to log in as session user? */ + + /* remaining fields may be null; use heap_getattr to read them! */ + text rolpassword; /* password, if any */ + timestamptz rolvaliduntil; /* password expiration time, if any */ + text rolconfig[1]; /* GUC settings to apply at login */ +} FormData_pg_authid; + +#undef timestamptz + + +/* ---------------- + * Form_pg_authid corresponds to a pointer to a tuple with + * the format of pg_authid relation. + * ---------------- + */ +typedef FormData_pg_authid *Form_pg_authid; + +/* ---------------- + * compiler constants for pg_authid + * ---------------- + */ +#define Natts_pg_authid 9 +#define Anum_pg_authid_rolname 1 +#define Anum_pg_authid_rolsuper 2 +#define Anum_pg_authid_rolcreaterole 3 +#define Anum_pg_authid_rolcreatedb 4 +#define Anum_pg_authid_rolcatupdate 5 +#define Anum_pg_authid_rolcanlogin 6 +#define Anum_pg_authid_rolpassword 7 +#define Anum_pg_authid_rolvaliduntil 8 +#define Anum_pg_authid_rolconfig 9 + +/* ---------------- + * initial contents of pg_authid + * + * The uppercase quantities will be replaced at initdb time with + * user choices. + * ---------------- + */ +DATA(insert OID = 10 ( "POSTGRES" t t t t t _null_ _null_ _null_ )); + +#define BOOTSTRAP_SUPERUSERID 10 + +#endif /* PG_AUTHID_H */ diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index e08d6d60d338df3e53f54c43cc21e60a373f9c82..b6d8f556b4899c280da3fce1a41a24e96c5356e6 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.88 2005/04/29 22:28:24 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.89 2005/06/28 05:09:05 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -47,7 +47,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP NameData relname; /* class name */ Oid relnamespace; /* OID of namespace containing this class */ Oid reltype; /* OID of associated entry in pg_type */ - int4 relowner; /* class owner */ + Oid relowner; /* class owner */ Oid relam; /* index access method; 0 if not an index */ Oid relfilenode; /* identifier of physical storage file */ Oid reltablespace; /* identifier of table space for relation */ diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h index e9cd3ccca24fff1857af1a34adeb288a60123b41..eb874446455d276b7cc07bb0153c5c48e4142d0c 100644 --- a/src/include/catalog/pg_conversion.h +++ b/src/include/catalog/pg_conversion.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_conversion.h,v 1.15 2005/04/14 01:38:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_conversion.h,v 1.16 2005/06/28 05:09:05 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -46,7 +46,7 @@ CATALOG(pg_conversion,2607) { NameData conname; Oid connamespace; - int4 conowner; + Oid conowner; int4 conforencoding; int4 contoencoding; regproc conproc; @@ -86,7 +86,7 @@ typedef FormData_pg_conversion *Form_pg_conversion; #include "nodes/parsenodes.h" extern Oid ConversionCreate(const char *conname, Oid connamespace, - AclId conowner, + Oid conowner, int32 conforencoding, int32 contoencoding, Oid conproc, bool def); extern void ConversionDrop(Oid conversionOid, DropBehavior behavior); diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h index 69b41e317206b13e5339703b98d52f2ff09fb580..37c57f8508c8b154eb436d91c18dca002acb6723 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.35 2005/04/14 01:38:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_database.h,v 1.36 2005/06/28 05:09:06 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -36,7 +36,7 @@ CATALOG(pg_database,1262) BKI_SHARED_RELATION { NameData datname; /* database name */ - int4 datdba; /* sysid of owner */ + Oid datdba; /* owner of database */ int4 encoding; /* character encoding */ bool datistemplate; /* allowed as CREATE DATABASE template? */ bool datallowconn; /* new connections allowed? */ diff --git a/src/include/catalog/pg_group.h b/src/include/catalog/pg_group.h deleted file mode 100644 index 216d51a6660eeedfbb573ebf4686bf547332943a..0000000000000000000000000000000000000000 --- a/src/include/catalog/pg_group.h +++ /dev/null @@ -1,45 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_group.h - * - * - * - * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * $PostgreSQL: pgsql/src/include/catalog/pg_group.h,v 1.21 2005/04/14 01:38:20 tgl Exp $ - * - * NOTES - * the genbki.sh script reads this file and generates .bki - * information from the DATA() statements. - * - *------------------------------------------------------------------------- - */ -#ifndef PG_GROUP_H -#define PG_GROUP_H - -/* ---------------- - * postgres.h contains the system type definitions and the - * CATALOG(), BKI_BOOTSTRAP and DATA() sugar words so this file - * can be read by both genbki.sh and the C compiler. - * ---------------- - */ -#define GroupRelationId 1261 - -CATALOG(pg_group,1261) BKI_SHARED_RELATION BKI_WITHOUT_OIDS -{ - NameData groname; - int4 grosysid; - int4 grolist[1]; -} FormData_pg_group; - -/* VARIABLE LENGTH STRUCTURE */ - -typedef FormData_pg_group *Form_pg_group; - -#define Natts_pg_group 3 -#define Anum_pg_group_groname 1 -#define Anum_pg_group_grosysid 2 -#define Anum_pg_group_grolist 3 - -#endif /* PG_GROUP_H */ diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h index f6cb4cf8e5bd9a423bb8ba9b46ee9468363f5b1f..c460500578c94318c9db6d9fa2850dfa73054acf 100644 --- a/src/include/catalog/pg_namespace.h +++ b/src/include/catalog/pg_namespace.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_namespace.h,v 1.17 2005/04/14 01:38:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_namespace.h,v 1.18 2005/06/28 05:09:06 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -41,7 +41,7 @@ CATALOG(pg_namespace,2615) { NameData nspname; - int4 nspowner; + Oid nspowner; aclitem nspacl[1]; /* VARIABLE LENGTH FIELD */ } FormData_pg_namespace; @@ -82,6 +82,6 @@ DESCR("Standard public schema"); /* * prototypes for functions in pg_namespace.c */ -extern Oid NamespaceCreate(const char *nspName, int32 ownerSysId); +extern Oid NamespaceCreate(const char *nspName, Oid ownerId); #endif /* PG_NAMESPACE_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 6043fec22d0baa6ce41e0aa3bbd787fb93ceab9d..23485ff0ebbd4a56c7d3aa6749e701ac0e95997f 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -27,7 +27,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.64 2005/04/14 01:38:20 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.65 2005/06/28 05:09:07 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -57,7 +57,7 @@ CATALOG(pg_opclass,2616) Oid opcamid; /* index access method opclass is for */ NameData opcname; /* name of this opclass */ Oid opcnamespace; /* namespace of this opclass */ - int4 opcowner; /* opclass owner */ + Oid opcowner; /* opclass owner */ Oid opcintype; /* type of data indexed by opclass */ bool opcdefault; /* T if opclass is default for opcintype */ Oid opckeytype; /* type of data in index, or InvalidOid */ diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index f87b6a07383ef40d747a8548600301aa6e988b23..9de43736eae27e953f1d78b56361f9e39a99a10f 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.134 2005/06/24 20:53:31 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.135 2005/06/28 05:09:07 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -42,7 +42,7 @@ CATALOG(pg_operator,2617) { NameData oprname; /* name of operator */ Oid oprnamespace; /* OID of namespace containing this oper */ - int4 oprowner; /* oper owner */ + Oid oprowner; /* operator owner */ char oprkind; /* 'l', 'r', or 'b' */ bool oprcanhash; /* can be used in hash join? */ Oid oprleft; /* left arg type, or 0 if 'l' oprkind */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 049024ae40c0ccc9d20bc0d919dec4b3d9f1f0c3..5326a770592d7b0b6c8a9fb08bdc41bf09dc62da 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.371 2005/06/26 03:04:01 momjian Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.372 2005/06/28 05:09:09 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -41,7 +41,7 @@ CATALOG(pg_proc,1255) BKI_BOOTSTRAP { NameData proname; /* procedure name */ Oid pronamespace; /* OID of namespace containing this proc */ - int4 proowner; /* proc owner */ + Oid proowner; /* procedure owner */ Oid prolang; /* OID of pg_language entry */ bool proisagg; /* is it an aggregate? */ bool prosecdef; /* security definer */ @@ -1355,7 +1355,7 @@ DATA(insert OID = 1037 ( aclcontains PGNSP PGUID 12 f f t f i 2 16 "1034 103 DESCR("does ACL contain item?"); DATA(insert OID = 1062 ( aclitemeq PGNSP PGUID 12 f f t f i 2 16 "1033 1033" _null_ _null_ _null_ aclitem_eq - _null_ )); DESCR("equality operator for ACL items"); -DATA(insert OID = 1365 ( makeaclitem PGNSP PGUID 12 f f t f i 5 1033 "23 23 23 25 16" _null_ _null_ _null_ makeaclitem - _null_ )); +DATA(insert OID = 1365 ( makeaclitem PGNSP PGUID 12 f f t f i 4 1033 "26 26 25 16" _null_ _null_ _null_ makeaclitem - _null_ )); DESCR("make ACL item"); DATA(insert OID = 1044 ( bpcharin PGNSP PGUID 12 f f t f i 3 1042 "2275 26 23" _null_ _null_ _null_ bpcharin - _null_ )); DESCR("I/O"); @@ -2251,8 +2251,8 @@ DATA(insert OID = 1640 ( pg_get_viewdef PGNSP PGUID 12 f f t f s 1 25 "25" _ DESCR("select statement of a view"); DATA(insert OID = 1641 ( pg_get_viewdef PGNSP PGUID 12 f f t f s 1 25 "26" _null_ _null_ _null_ pg_get_viewdef - _null_ )); DESCR("select statement of a view"); -DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 f f t f s 1 19 "23" _null_ _null_ _null_ pg_get_userbyid - _null_ )); -DESCR("user name by UID (with fallback)"); +DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 f f t f s 1 19 "26" _null_ _null_ _null_ pg_get_userbyid - _null_ )); +DESCR("role name by OID (with fallback)"); DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 f f t f s 1 25 "26" _null_ _null_ _null_ pg_get_indexdef - _null_ )); DESCR("index description"); DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 f f t f s 1 25 "26" _null_ _null_ _null_ pg_get_triggerdef - _null_ )); @@ -2785,10 +2785,10 @@ DATA(insert OID = 1922 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 DESCR("user privilege on relation by username, rel name"); DATA(insert OID = 1923 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_table_privilege_name_id - _null_ )); DESCR("user privilege on relation by username, rel oid"); -DATA(insert OID = 1924 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_table_privilege_id_name - _null_ )); -DESCR("user privilege on relation by usesysid, rel name"); -DATA(insert OID = 1925 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_table_privilege_id_id - _null_ )); -DESCR("user privilege on relation by usesysid, rel oid"); +DATA(insert OID = 1924 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_table_privilege_id_name - _null_ )); +DESCR("user privilege on relation by user oid, rel name"); +DATA(insert OID = 1925 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_table_privilege_id_id - _null_ )); +DESCR("user privilege on relation by user oid, rel oid"); DATA(insert OID = 1926 ( has_table_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_table_privilege_name - _null_ )); DESCR("current user privilege on relation by rel name"); DATA(insert OID = 1927 ( has_table_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_table_privilege_id - _null_ )); @@ -2821,7 +2821,7 @@ DATA(insert OID = 1937 ( pg_stat_get_backend_pid PGNSP PGUID 12 f f t f s 1 23 DESCR("Statistics: PID of backend"); DATA(insert OID = 1938 ( pg_stat_get_backend_dbid PGNSP PGUID 12 f f t f s 1 26 "23" _null_ _null_ _null_ pg_stat_get_backend_dbid - _null_ )); DESCR("Statistics: Database ID of backend"); -DATA(insert OID = 1939 ( pg_stat_get_backend_userid PGNSP PGUID 12 f f t f s 1 23 "23" _null_ _null_ _null_ pg_stat_get_backend_userid - _null_ )); +DATA(insert OID = 1939 ( pg_stat_get_backend_userid PGNSP PGUID 12 f f t f s 1 26 "23" _null_ _null_ _null_ pg_stat_get_backend_userid - _null_ )); DESCR("Statistics: User ID of backend"); DATA(insert OID = 1940 ( pg_stat_get_backend_activity PGNSP PGUID 12 f f t f s 1 25 "23" _null_ _null_ _null_ pg_stat_get_backend_activity - _null_ )); DESCR("Statistics: Current query of backend"); @@ -3171,10 +3171,10 @@ DATA(insert OID = 2250 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 DESCR("user privilege on database by username, database name"); DATA(insert OID = 2251 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_database_privilege_name_id - _null_ )); DESCR("user privilege on database by username, database oid"); -DATA(insert OID = 2252 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_database_privilege_id_name - _null_ )); -DESCR("user privilege on database by usesysid, database name"); -DATA(insert OID = 2253 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_database_privilege_id_id - _null_ )); -DESCR("user privilege on database by usesysid, database oid"); +DATA(insert OID = 2252 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_database_privilege_id_name - _null_ )); +DESCR("user privilege on database by user oid, database name"); +DATA(insert OID = 2253 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_database_privilege_id_id - _null_ )); +DESCR("user privilege on database by user oid, database oid"); DATA(insert OID = 2254 ( has_database_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_database_privilege_name - _null_ )); DESCR("current user privilege on database by database name"); DATA(insert OID = 2255 ( has_database_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_database_privilege_id - _null_ )); @@ -3184,10 +3184,10 @@ DATA(insert OID = 2256 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 DESCR("user privilege on function by username, function name"); DATA(insert OID = 2257 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_function_privilege_name_id - _null_ )); DESCR("user privilege on function by username, function oid"); -DATA(insert OID = 2258 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_function_privilege_id_name - _null_ )); -DESCR("user privilege on function by usesysid, function name"); -DATA(insert OID = 2259 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_function_privilege_id_id - _null_ )); -DESCR("user privilege on function by usesysid, function oid"); +DATA(insert OID = 2258 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_function_privilege_id_name - _null_ )); +DESCR("user privilege on function by user oid, function name"); +DATA(insert OID = 2259 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_function_privilege_id_id - _null_ )); +DESCR("user privilege on function by user oid, function oid"); DATA(insert OID = 2260 ( has_function_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_function_privilege_name - _null_ )); DESCR("current user privilege on function by function name"); DATA(insert OID = 2261 ( has_function_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_function_privilege_id - _null_ )); @@ -3197,10 +3197,10 @@ DATA(insert OID = 2262 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 DESCR("user privilege on language by username, language name"); DATA(insert OID = 2263 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_language_privilege_name_id - _null_ )); DESCR("user privilege on language by username, language oid"); -DATA(insert OID = 2264 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_language_privilege_id_name - _null_ )); -DESCR("user privilege on language by usesysid, language name"); -DATA(insert OID = 2265 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_language_privilege_id_id - _null_ )); -DESCR("user privilege on language by usesysid, language oid"); +DATA(insert OID = 2264 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_language_privilege_id_name - _null_ )); +DESCR("user privilege on language by user oid, language name"); +DATA(insert OID = 2265 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_language_privilege_id_id - _null_ )); +DESCR("user privilege on language by user oid, language oid"); DATA(insert OID = 2266 ( has_language_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_language_privilege_name - _null_ )); DESCR("current user privilege on language by language name"); DATA(insert OID = 2267 ( has_language_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_language_privilege_id - _null_ )); @@ -3210,10 +3210,10 @@ DATA(insert OID = 2268 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 DESCR("user privilege on schema by username, schema name"); DATA(insert OID = 2269 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_schema_privilege_name_id - _null_ )); DESCR("user privilege on schema by username, schema oid"); -DATA(insert OID = 2270 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_schema_privilege_id_name - _null_ )); -DESCR("user privilege on schema by usesysid, schema name"); -DATA(insert OID = 2271 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_schema_privilege_id_id - _null_ )); -DESCR("user privilege on schema by usesysid, schema oid"); +DATA(insert OID = 2270 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_schema_privilege_id_name - _null_ )); +DESCR("user privilege on schema by user oid, schema name"); +DATA(insert OID = 2271 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_schema_privilege_id_id - _null_ )); +DESCR("user privilege on schema by user oid, schema oid"); DATA(insert OID = 2272 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_schema_privilege_name - _null_ )); DESCR("current user privilege on schema by schema name"); DATA(insert OID = 2273 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_schema_privilege_id - _null_ )); @@ -3223,10 +3223,10 @@ DATA(insert OID = 2390 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s DESCR("user privilege on tablespace by username, tablespace name"); DATA(insert OID = 2391 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" _null_ _null_ _null_ has_tablespace_privilege_name_id - _null_ )); DESCR("user privilege on tablespace by username, tablespace oid"); -DATA(insert OID = 2392 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" _null_ _null_ _null_ has_tablespace_privilege_id_name - _null_ )); -DESCR("user privilege on tablespace by usesysid, tablespace name"); -DATA(insert OID = 2393 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" _null_ _null_ _null_ has_tablespace_privilege_id_id - _null_ )); -DESCR("user privilege on tablespace by usesysid, tablespace oid"); +DATA(insert OID = 2392 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "26 25 25" _null_ _null_ _null_ has_tablespace_privilege_id_name - _null_ )); +DESCR("user privilege on tablespace by user oid, tablespace name"); +DATA(insert OID = 2393 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 3 16 "26 26 25" _null_ _null_ _null_ has_tablespace_privilege_id_id - _null_ )); +DESCR("user privilege on tablespace by user oid, tablespace oid"); DATA(insert OID = 2394 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" _null_ _null_ _null_ has_tablespace_privilege_name - _null_ )); DESCR("current user privilege on tablespace by tablespace name"); DATA(insert OID = 2395 ( has_tablespace_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" _null_ _null_ _null_ has_tablespace_privilege_id - _null_ )); diff --git a/src/include/catalog/pg_shadow.h b/src/include/catalog/pg_shadow.h deleted file mode 100644 index 3c24d82d450f766a02ad4a03045e6b87004b1b05..0000000000000000000000000000000000000000 --- a/src/include/catalog/pg_shadow.h +++ /dev/null @@ -1,78 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_shadow.h - * definition of the system "shadow" relation (pg_shadow) - * along with the relation's initial contents. - * - * pg_user is now a publicly accessible view on pg_shadow. - * - * - * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * $PostgreSQL: pgsql/src/include/catalog/pg_shadow.h,v 1.28 2005/04/14 01:38:21 tgl Exp $ - * - * NOTES - * the genbki.sh script reads this file and generates .bki - * information from the DATA() statements. - * - *------------------------------------------------------------------------- - */ -#ifndef PG_SHADOW_H -#define PG_SHADOW_H - - -/* ---------------- - * pg_shadow definition. cpp turns this into - * typedef struct FormData_pg_shadow - * ---------------- - */ -#define ShadowRelationId 1260 - -CATALOG(pg_shadow,1260) BKI_SHARED_RELATION BKI_WITHOUT_OIDS -{ - NameData usename; - int4 usesysid; - bool usecreatedb; - bool usesuper; /* read this field via superuser() only */ - bool usecatupd; - - /* remaining fields may be null; use heap_getattr to read them! */ - text passwd; - int4 valuntil; /* actually abstime */ - text useconfig[1]; -} FormData_pg_shadow; - -/* ---------------- - * Form_pg_shadow corresponds to a pointer to a tuple with - * the format of pg_shadow relation. - * ---------------- - */ -typedef FormData_pg_shadow *Form_pg_shadow; - -/* ---------------- - * compiler constants for pg_shadow - * ---------------- - */ -#define Natts_pg_shadow 8 -#define Anum_pg_shadow_usename 1 -#define Anum_pg_shadow_usesysid 2 -#define Anum_pg_shadow_usecreatedb 3 -#define Anum_pg_shadow_usesuper 4 -#define Anum_pg_shadow_usecatupd 5 -#define Anum_pg_shadow_passwd 6 -#define Anum_pg_shadow_valuntil 7 -#define Anum_pg_shadow_useconfig 8 - -/* ---------------- - * initial contents of pg_shadow - * - * The uppercase quantities will be replaced at initdb time with - * user choices. - * ---------------- - */ -DATA(insert ( "POSTGRES" PGUID t t t _null_ _null_ _null_ )); - -#define BOOTSTRAP_USESYSID 1 - -#endif /* PG_SHADOW_H */ diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h index 7c440042746d277c940ebcc11c7f1b53a5f95cc3..831e5753d129f90db9f16b363ef4d76f15868c9a 100644 --- a/src/include/catalog/pg_tablespace.h +++ b/src/include/catalog/pg_tablespace.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.6 2005/04/14 01:38:21 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_tablespace.h,v 1.7 2005/06/28 05:09:12 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -36,7 +36,7 @@ CATALOG(pg_tablespace,1213) BKI_SHARED_RELATION { NameData spcname; /* tablespace name */ - int4 spcowner; /* sysid of owner */ + Oid spcowner; /* owner of tablespace */ text spclocation; /* physical location (VAR LENGTH) */ aclitem spcacl[1]; /* access permissions (VAR LENGTH) */ } FormData_pg_tablespace; diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 8a4207e9ea6bce9cf7db2b1d45dac15559981a49..44b8cf0cedb430ebaff43f9d523640a7a7cfd98a 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.161 2005/05/30 01:20:50 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_type.h,v 1.162 2005/06/28 05:09:12 tgl Exp $ * * NOTES * the genbki.sh script reads this file and generates .bki @@ -44,7 +44,7 @@ CATALOG(pg_type,1247) BKI_BOOTSTRAP { NameData typname; /* type name */ Oid typnamespace; /* OID of namespace containing this type */ - int4 typowner; /* type owner */ + Oid typowner; /* type owner */ /* * For a fixed-size type, typlen is the number of bytes we use to diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 47224831aad905e1028a4bdd9f2c266217db0474..b64b361d27aa4b16a7ab5c16791579de984152cf 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.9 2004/12/31 22:03:28 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/commands/conversioncmds.h,v 1.10 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,6 @@ extern void CreateConversionCommand(CreateConversionStmt *parsetree); extern void DropConversionCommand(List *conversion_name, DropBehavior behavior); extern void RenameConversion(List *name, const char *newname); -extern void AlterConversionOwner(List *name, AclId newOwnerSysId); +extern void AlterConversionOwner(List *name, Oid newOwnerId); #endif /* CONVERSIONCMDS_H */ diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index 7ffd7abeb0305fada248c51b711b90c18d48a533..1a4fd5123c29cc8cd8ba32b390e17f2793160fdb 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.38 2005/06/06 17:01:25 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.39 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -65,7 +65,7 @@ extern void createdb(const CreatedbStmt *stmt); extern void dropdb(const char *dbname); extern void RenameDatabase(const char *oldname, const char *newname); extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt); -extern void AlterDatabaseOwner(const char *dbname, AclId newOwnerSysId); +extern void AlterDatabaseOwner(const char *dbname, Oid newOwnerId); extern Oid get_database_oid(const char *dbname); extern char *get_database_name(Oid dbid); diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 1ae5649c137c5606d4b0735621985a5daf87129b..10c3438065a76282927f09ab0e5c0926a5529eed 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.65 2005/06/22 21:14:31 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.66 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,7 +50,7 @@ extern void RemoveFunctionById(Oid funcOid); extern void SetFunctionReturnType(Oid funcOid, Oid newRetType); extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType); extern void RenameFunction(List *name, List *argtypes, const char *newname); -extern void AlterFunctionOwner(List *name, List *argtypes, AclId newOwnerSysId); +extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId); extern void AlterFunction(AlterFunctionStmt *stmt); extern void CreateCast(CreateCastStmt *stmt); extern void DropCast(DropCastStmt *stmt); @@ -61,20 +61,20 @@ extern void DefineOperator(List *names, List *parameters); extern void RemoveOperator(RemoveOperStmt *stmt); extern void RemoveOperatorById(Oid operOid); extern void AlterOperatorOwner(List *name, TypeName *typeName1, - TypeName *typename2, AclId newOwnerSysId); + TypeName *typename2, Oid newOwnerId); /* commands/aggregatecmds.c */ extern void DefineAggregate(List *names, List *parameters); extern void RemoveAggregate(RemoveAggrStmt *stmt); extern void RenameAggregate(List *name, TypeName *basetype, const char *newname); -extern void AlterAggregateOwner(List *name, TypeName *basetype, AclId newOwnerSysId); +extern void AlterAggregateOwner(List *name, TypeName *basetype, Oid newOwnerId); /* commands/opclasscmds.c */ extern void DefineOpClass(CreateOpClassStmt *stmt); extern void RemoveOpClass(RemoveOpClassStmt *stmt); extern void RemoveOpClassById(Oid opclassOid); extern void RenameOpClass(List *name, const char *access_method, const char *newname); -extern void AlterOpClassOwner(List *name, const char *access_method, AclId newOwnerSysId); +extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId); /* support routines in commands/define.c */ diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h index 54edffa986c206012728835a784e5e20ea93fc17..4528591b3cbd5c0fdb2f0d1a8646ba57f09771a2 100644 --- a/src/include/commands/schemacmds.h +++ b/src/include/commands/schemacmds.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.9 2004/12/31 22:03:28 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/commands/schemacmds.h,v 1.10 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,6 @@ extern void RemoveSchema(List *names, DropBehavior behavior); extern void RemoveSchemaById(Oid schemaOid); extern void RenameSchema(const char *oldname, const char *newname); -extern void AlterSchemaOwner(const char *name, AclId newOwnerSysId); +extern void AlterSchemaOwner(const char *name, Oid newOwnerId); #endif /* SCHEMACMDS_H */ diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index fe99a191a3390c74fc873bbb137e4a7757115c34..f6c83c952b6212b296af12f800eeb93d7db3e150 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.9 2005/06/06 17:01:25 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/tablespace.h,v 1.10 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,7 +36,7 @@ typedef struct xl_tblspc_drop_rec extern void CreateTableSpace(CreateTableSpaceStmt *stmt); extern void DropTableSpace(DropTableSpaceStmt *stmt); extern void RenameTableSpace(const char *oldname, const char *newname); -extern void AlterTableSpaceOwner(const char *name, AclId newOwnerSysId); +extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index ad5e04cc37ae10eaf098adb0b3d69e6f39bce8c3..a940a78f483a7a0ff1c87bb1512af8361eba2803 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.10 2004/12/31 22:03:28 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/commands/typecmds.h,v 1.11 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,6 +34,6 @@ extern void AlterDomainDropConstraint(List *names, const char *constrName, extern List *GetDomainConstraints(Oid typeOid); -extern void AlterTypeOwner(List *names, AclId newOwnerSysId); +extern void AlterTypeOwner(List *names, Oid newOwnerId); #endif /* TYPECMDS_H */ diff --git a/src/include/commands/user.h b/src/include/commands/user.h index a37f94940a9ba846ba5d4b1fe1b28b29fae4209e..ab2829a266bba88730e1ff4892103fd6784ec878 100644 --- a/src/include/commands/user.h +++ b/src/include/commands/user.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * user.h - * Commands for manipulating users and groups. + * Commands for manipulating roles (formerly called users). * * - * $PostgreSQL: pgsql/src/include/commands/user.h,v 1.26 2005/02/20 02:22:05 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/user.h,v 1.27 2005/06/28 05:09:12 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -14,15 +14,11 @@ #include "nodes/parsenodes.h" -extern void CreateUser(CreateUserStmt *stmt); -extern void AlterUser(AlterUserStmt *stmt); -extern void AlterUserSet(AlterUserSetStmt *stmt); -extern void DropUser(DropUserStmt *stmt); -extern void RenameUser(const char *oldname, const char *newname); - -extern void CreateGroup(CreateGroupStmt *stmt); -extern void AlterGroup(AlterGroupStmt *stmt, const char *tag); -extern void DropGroup(DropGroupStmt *stmt); -extern void RenameGroup(const char *oldname, const char *newname); +extern void CreateRole(CreateRoleStmt *stmt); +extern void AlterRole(AlterRoleStmt *stmt); +extern void AlterRoleSet(AlterRoleSetStmt *stmt); +extern void DropRole(DropRoleStmt *stmt); +extern void GrantRole(GrantRoleStmt *stmt); +extern void RenameRole(const char *oldname, const char *newname); #endif /* USER_H */ diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 6798a09ad988a90d1999cebc98c3c263e1941ab6..d170f303a4376bee0287805fc7ab2af24b57e92d 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -4,7 +4,7 @@ * Interface to hba.c * * - * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.37 2005/06/27 02:04:25 neilc Exp $ + * $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.38 2005/06/28 05:09:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -30,11 +30,10 @@ typedef enum UserAuth typedef struct Port hbaPort; -extern List **get_user_line(const char *user); +extern List **get_role_line(const char *role); extern void load_hba(void); extern void load_ident(void); -extern void load_user(void); -extern void load_group(void); +extern void load_role(void); extern int hba_getauthmethod(hbaPort *port); extern int authident(hbaPort *port); extern bool read_pg_database_line(FILE *fp, char *dbname, diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 3e9b7d912a4b89ac9ed7526c5a8aff6b4aa949b1..8f6930cd1319ac1ccf24ed83dde8e4bd0d525be3 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -13,7 +13,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.175 2005/02/26 18:43:34 tgl Exp $ + * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.176 2005/06/28 05:09:04 tgl Exp $ * * NOTES * some of the information in this file should be moved to other files. @@ -228,21 +228,21 @@ extern char *DatabasePath; /* now in utils/init/miscinit.c */ extern void SetDatabasePath(const char *path); -extern char *GetUserNameFromId(AclId userid); -extern AclId GetUserId(void); -extern void SetUserId(AclId userid); -extern AclId GetSessionUserId(void); -extern void SetSessionUserId(AclId userid); -extern void InitializeSessionUserId(const char *username); +extern char *GetUserNameFromId(Oid roleid); +extern Oid GetUserId(void); +extern void SetUserId(Oid roleid); +extern Oid GetSessionUserId(void); +extern void SetSessionUserId(Oid roleid); +extern void InitializeSessionUserId(const char *rolename); extern void InitializeSessionUserIdStandalone(void); -extern void SetSessionAuthorization(AclId userid, bool is_superuser); +extern void SetSessionAuthorization(Oid roleid, bool is_superuser); extern void SetDataDir(const char *dir); extern char *make_absolute_path(const char *path); /* in utils/misc/superuser.c */ extern bool superuser(void); /* current user is superuser */ -extern bool superuser_arg(AclId userid); /* given user is superuser */ +extern bool superuser_arg(Oid roleid); /* given user is superuser */ /***************************************************************************** diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index fd923f72af4d75fa1a31aed2ac2321c8f45b0844..3e623911c7011df68a5143d9d069b689d30dd428 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.171 2005/06/26 22:05:41 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.172 2005/06/28 05:09:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -224,6 +224,7 @@ typedef enum NodeTag T_AlterDomainStmt, T_SetOperationStmt, T_GrantStmt, + T_GrantRoleStmt, T_ClosePortalStmt, T_ClusterStmt, T_CopyStmt, @@ -261,19 +262,16 @@ typedef enum NodeTag T_DropPropertyStmt, T_CreatePLangStmt, T_DropPLangStmt, - T_CreateUserStmt, - T_AlterUserStmt, - T_DropUserStmt, + T_CreateRoleStmt, + T_AlterRoleStmt, + T_DropRoleStmt, T_LockStmt, T_ConstraintsSetStmt, - T_CreateGroupStmt, - T_AlterGroupStmt, - T_DropGroupStmt, T_ReindexStmt, T_CheckPointStmt, T_CreateSchemaStmt, T_AlterDatabaseSetStmt, - T_AlterUserSetStmt, + T_AlterRoleSetStmt, T_CreateConversionStmt, T_CreateCastStmt, T_DropCastStmt, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index e011bb9f97855435cb4ffd1e719571644db70219..64acaa72e57f5e169a7a0bcd395637c2dc649f82 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.283 2005/06/22 21:14:31 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.284 2005/06/28 05:09:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -544,7 +544,7 @@ typedef struct RangeTblEntry bool inh; /* inheritance requested? */ bool inFromCl; /* present in FROM clause? */ AclMode requiredPerms; /* bitmask of required access permissions */ - AclId checkAsUser; /* if not zero, check access as this user */ + Oid checkAsUser; /* if valid, check access as this role */ } RangeTblEntry; /* @@ -749,12 +749,12 @@ typedef enum ObjectType OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FUNCTION, - OBJECT_GROUP, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_OPCLASS, OBJECT_OPERATOR, + OBJECT_ROLE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, @@ -762,7 +762,6 @@ typedef enum ObjectType OBJECT_TABLESPACE, OBJECT_TRIGGER, OBJECT_TYPE, - OBJECT_USER, OBJECT_VIEW } ObjectType; @@ -896,8 +895,7 @@ typedef struct GrantStmt typedef struct PrivGrantee { NodeTag type; - char *username; /* if both are NULL then PUBLIC */ - char *groupname; + char *rolname; /* if NULL then PUBLIC */ } PrivGrantee; /* @@ -920,6 +918,23 @@ typedef struct PrivTarget List *objs; } PrivTarget; +/* ---------------------- + * Grant/Revoke Role Statement + * + * Note: the lists of roles are lists of names, as Value strings + * ---------------------- + */ +typedef struct GrantRoleStmt +{ + NodeTag type; + List *granted_roles; /* list of roles to be granted/revoked */ + List *grantee_roles; /* list of member roles to add/delete */ + bool is_grant; /* true = GRANT, false = REVOKE */ + bool admin_opt; /* with admin option */ + char *grantor; /* set grantor to other than current role */ + DropBehavior behavior; /* drop behavior (for REVOKE) */ +} GrantRoleStmt; + /* ---------------------- * Copy Statement * ---------------------- @@ -1123,61 +1138,37 @@ typedef struct DropPLangStmt } DropPLangStmt; /* ---------------------- - * Create/Alter/Drop User Statements + * Create/Alter/Drop Role Statements * ---------------------- */ -typedef struct CreateUserStmt +typedef struct CreateRoleStmt { NodeTag type; - char *user; /* PostgreSQL user login name */ + char *role; /* role name */ List *options; /* List of DefElem nodes */ -} CreateUserStmt; +} CreateRoleStmt; -typedef struct AlterUserStmt +typedef struct AlterRoleStmt { NodeTag type; - char *user; /* PostgreSQL user login name */ + char *role; /* role name */ List *options; /* List of DefElem nodes */ -} AlterUserStmt; + int action; /* +1 = add members, -1 = drop members */ +} AlterRoleStmt; -typedef struct AlterUserSetStmt +typedef struct AlterRoleSetStmt { NodeTag type; - char *user; - char *variable; - List *value; -} AlterUserSetStmt; + char *role; /* role name */ + char *variable; /* GUC variable name */ + List *value; /* value for variable, or NIL for Reset */ +} AlterRoleSetStmt; -typedef struct DropUserStmt +typedef struct DropRoleStmt { NodeTag type; - List *users; /* List of users to remove */ -} DropUserStmt; - -/* ---------------------- - * Create/Alter/Drop Group Statements - * ---------------------- - */ -typedef struct CreateGroupStmt -{ - NodeTag type; - char *name; /* name of the new group */ - List *options; /* List of DefElem nodes */ -} CreateGroupStmt; - -typedef struct AlterGroupStmt -{ - NodeTag type; - char *name; /* name of group to alter */ - int action; /* +1 = add, -1 = drop user */ - List *listUsers; /* list of users to add/drop */ -} AlterGroupStmt; - -typedef struct DropGroupStmt -{ - NodeTag type; - char *name; -} DropGroupStmt; + List *roles; /* List of roles to remove */ +} DropRoleStmt; /* ---------------------- * {Create|Alter} SEQUENCE Statement diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 2382ceae936047c18d2531fd69d5445f1bb57559..b6015f536c0c5282c8c90c71d32d531e7f3e36a5 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -5,7 +5,7 @@ * * Copyright (c) 2001-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.30 2005/06/25 23:58:58 tgl Exp $ + * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.31 2005/06/28 05:09:04 tgl Exp $ * ---------- */ #ifndef PGSTAT_H @@ -101,7 +101,7 @@ typedef struct PgStat_MsgBestart { PgStat_MsgHdr m_hdr; Oid m_databaseid; - AclId m_userid; + Oid m_userid; SockAddr m_clientaddr; } PgStat_MsgBestart; diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index ac04945bcd086576274ada19c284a82084ed5778..f055ac93aa30c64650232c1777affda4676e1af1 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.77 2005/01/27 23:36:14 neilc Exp $ + * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.78 2005/06/28 05:09:13 tgl Exp $ * * NOTES * An ACL array is simply an array of AclItems, representing the union @@ -29,84 +29,64 @@ /* - * typedef AclId is declared in c.h - * * typedef AclMode is declared in parsenodes.h, also the individual privilege * bit meanings are defined there */ -#define ACL_ID_WORLD 0 /* placeholder for id in a WORLD acl item */ - -/* - * AclIdType tag that describes if the AclId is a user, group, etc. - */ -#define ACL_IDTYPE_WORLD 0x00 /* PUBLIC */ -#define ACL_IDTYPE_UID 0x01 /* user id - from pg_shadow */ -#define ACL_IDTYPE_GID 0x02 /* group id - from pg_group */ +#define ACL_ID_PUBLIC 0 /* placeholder for id in a PUBLIC acl item */ /* * AclItem * - * The IDTYPE included in ai_privs identifies the type of the grantee ID. - * The grantor ID currently must always be a user, never a group. (FIXME) - * * Note: must be same size on all platforms, because the size is hardcoded * in the pg_type.h entry for aclitem. */ typedef struct AclItem { - AclId ai_grantee; /* ID that this item grants privs to */ - AclId ai_grantor; /* grantor of privs (always a user id) */ - AclMode ai_privs; /* AclIdType plus privilege bits */ + Oid ai_grantee; /* ID that this item grants privs to */ + Oid ai_grantor; /* grantor of privs */ + AclMode ai_privs; /* privilege bits */ } AclItem; /* - * The AclIdType is stored in the top two bits of the ai_privs field - * of an AclItem. The middle 15 bits are the grant option markers, - * and the lower 15 bits are the actual privileges. We use "rights" + * The upper 16 bits of the ai_privs field of an AclItem are the grant option + * bits, and the lower 16 bits are the actual privileges. We use "rights" * to mean the combined grant option and privilege bits fields. */ -#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0x7FFF) -#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 15) & 0x7FFF) -#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs & 0x3FFFFFFF) -#define ACLITEM_GET_IDTYPE(item) ((item).ai_privs >> 30) +#define ACLITEM_GET_PRIVS(item) ((item).ai_privs & 0xFFFF) +#define ACLITEM_GET_GOPTIONS(item) (((item).ai_privs >> 16) & 0xFFFF) +#define ACLITEM_GET_RIGHTS(item) ((item).ai_privs) -#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0x7FFF) << 15) -#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 15) & 0x7FFF) +#define ACL_GRANT_OPTION_FOR(privs) (((AclMode) (privs) & 0xFFFF) << 16) +#define ACL_OPTION_TO_PRIVS(privs) (((AclMode) (privs) >> 16) & 0xFFFF) #define ACLITEM_SET_PRIVS(item,privs) \ - ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x7FFF)) | \ - ((AclMode) (privs) & 0x7FFF)) + ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0xFFFF)) | \ + ((AclMode) (privs) & 0xFFFF)) #define ACLITEM_SET_GOPTIONS(item,goptions) \ - ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0x7FFF) << 15)) | \ - (((AclMode) (goptions) & 0x7FFF) << 15)) + ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0xFFFF) << 16)) | \ + (((AclMode) (goptions) & 0xFFFF) << 16)) #define ACLITEM_SET_RIGHTS(item,rights) \ - ((item).ai_privs = ((item).ai_privs & ~((AclMode) 0x3FFFFFFF)) | \ - ((AclMode) (rights) & 0x3FFFFFFF)) -#define ACLITEM_SET_IDTYPE(item,idtype) \ - ((item).ai_privs = ((item).ai_privs & ~(((AclMode) 0x03) << 30)) | \ - (((AclMode) (idtype) & 0x03) << 30)) + ((item).ai_privs = (AclMode) (rights)) + +#define ACLITEM_SET_PRIVS_GOPTIONS(item,privs,goptions) \ + ((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \ + (((AclMode) (goptions) & 0xFFFF) << 16)) -#define ACLITEM_SET_PRIVS_IDTYPE(item,privs,goption,idtype) \ - ((item).ai_privs = ((AclMode) (privs) & 0x7FFF) | \ - (((AclMode) (goption) & 0x7FFF) << 15) | \ - ((AclMode) (idtype) << 30)) -#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0x7FFF) -#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0x7FFF << 15) +#define ACLITEM_ALL_PRIV_BITS ((AclMode) 0xFFFF) +#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16) /* * Definitions for convenient access to Acl (array of AclItem) and IdList - * (array of AclId). These are standard PostgreSQL arrays, but are restricted + * (array of Oid). These are standard PostgreSQL arrays, but are restricted * to have one dimension. We also ignore the lower bound when reading, * and set it to one when writing. * * CAUTION: as of PostgreSQL 7.1, these arrays are toastable (just like all * other array types). Therefore, be careful to detoast them with the * macros provided, unless you know for certain that a particular array - * can't have been toasted. Presently, we do not provide toast tables for - * pg_class or pg_group, so the entries in those tables won't have been - * stored externally --- but they could have been compressed! + * can't have been toasted. */ @@ -121,13 +101,13 @@ typedef ArrayType Acl; #define ACL_SIZE(ACL) ARR_SIZE(ACL) /* - * IdList a one-dimensional array of AclId + * IdList a one-dimensional array of Oid */ typedef ArrayType IdList; #define IDLIST_NUM(IDL) (ARR_DIMS(IDL)[0]) -#define IDLIST_DAT(IDL) ((AclId *) ARR_DATA_PTR(IDL)) -#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(AclId))) +#define IDLIST_DAT(IDL) ((Oid *) ARR_DATA_PTR(IDL)) +#define IDLIST_N_SIZE(N) (ARR_OVERHEAD(1) + ((N) * sizeof(Oid))) #define IDLIST_SIZE(IDL) ARR_SIZE(IDL) /* @@ -221,14 +201,18 @@ typedef enum AclObjectKind /* * routines used internally */ -extern Acl *acldefault(GrantObjectType objtype, AclId ownerid); +extern Acl *acldefault(GrantObjectType objtype, Oid ownerId); extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip, - int modechg, AclId ownerid, DropBehavior behavior); -extern Acl *aclnewowner(const Acl *old_acl, AclId oldownerid, AclId newownerid); + int modechg, Oid ownerId, DropBehavior behavior); +extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId); -extern AclMode aclmask(const Acl *acl, AclId userid, AclId ownerid, +extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how); +extern bool is_member_of_role(Oid member, Oid role); + +extern void InitializeAcl(void); + /* * SQL functions (from acl.c) */ @@ -245,40 +229,39 @@ extern Datum hash_aclitem(PG_FUNCTION_ARGS); * prototypes for functions in aclchk.c */ extern void ExecuteGrantStmt(GrantStmt *stmt); -extern char *get_groname(AclId grosysid); -extern AclMode pg_class_aclmask(Oid table_oid, AclId userid, +extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how); -extern AclMode pg_database_aclmask(Oid db_oid, AclId userid, +extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how); -extern AclMode pg_proc_aclmask(Oid proc_oid, AclId userid, +extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid, AclMode mask, AclMaskHow how); -extern AclMode pg_language_aclmask(Oid lang_oid, AclId userid, +extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, AclMode mask, AclMaskHow how); -extern AclMode pg_namespace_aclmask(Oid nsp_oid, AclId userid, +extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how); -extern AclMode pg_tablespace_aclmask(Oid spc_oid, AclId userid, +extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid, AclMode mask, AclMaskHow how); -extern AclResult pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode); -extern AclResult pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode); -extern AclResult pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode); -extern AclResult pg_language_aclcheck(Oid lang_oid, AclId userid, AclMode mode); -extern AclResult pg_namespace_aclcheck(Oid nsp_oid, AclId userid, AclMode mode); -extern AclResult pg_tablespace_aclcheck(Oid spc_oid, AclId userid, AclMode mode); +extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode); +extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode); +extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode); +extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode); +extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode); +extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode); extern void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname); /* ownercheck routines just return true (owner) or false (not) */ -extern bool pg_class_ownercheck(Oid class_oid, AclId userid); -extern bool pg_type_ownercheck(Oid type_oid, AclId userid); -extern bool pg_oper_ownercheck(Oid oper_oid, AclId userid); -extern bool pg_proc_ownercheck(Oid proc_oid, AclId userid); -extern bool pg_namespace_ownercheck(Oid nsp_oid, AclId userid); -extern bool pg_tablespace_ownercheck(Oid spc_oid, AclId userid); -extern bool pg_opclass_ownercheck(Oid opc_oid, AclId userid); -extern bool pg_database_ownercheck(Oid db_oid, AclId userid); -extern bool pg_conversion_ownercheck(Oid conv_oid, AclId userid); +extern bool pg_class_ownercheck(Oid class_oid, Oid roleid); +extern bool pg_type_ownercheck(Oid type_oid, Oid roleid); +extern bool pg_oper_ownercheck(Oid oper_oid, Oid roleid); +extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid); +extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid); +extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid); +extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid); +extern bool pg_database_ownercheck(Oid db_oid, Oid roleid); +extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid); #endif /* ACL_H */ diff --git a/src/include/utils/flatfiles.h b/src/include/utils/flatfiles.h index 939239aa1b94c45c5912ca9a99abad9d48e43552..5faf35db57bf7f6eab43bd09692f8b389d912720 100644 --- a/src/include/utils/flatfiles.h +++ b/src/include/utils/flatfiles.h @@ -4,7 +4,7 @@ * Routines for maintaining "flat file" images of the shared catalogs. * * - * $PostgreSQL: pgsql/src/include/utils/flatfiles.h,v 1.4 2005/06/17 22:32:50 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/flatfiles.h,v 1.5 2005/06/28 05:09:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -14,12 +14,10 @@ #include "fmgr.h" extern void database_file_update_needed(void); -extern void group_file_update_needed(void); -extern void user_file_update_needed(void); +extern void auth_file_update_needed(void); extern char *database_getflatfilename(void); -extern char *group_getflatfilename(void); -extern char *user_getflatfilename(void); +extern char *auth_getflatfilename(void); extern void BuildFlatFiles(bool database_only); diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index b0967edca57c83bac4cd09b823c4960c67d4d5b0..dfd785d5d10a4d745394b0e0e94b12d53255702f 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.99 2005/05/01 18:56:19 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/lsyscache.h,v 1.100 2005/06/28 05:09:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -104,8 +104,8 @@ extern void free_attstatsslot(Oid atttype, Datum *values, int nvalues, float4 *numbers, int nnumbers); extern char *get_namespace_name(Oid nspid); -extern AclId get_usesysid(const char *username); -extern AclId get_grosysid(char *groname); +extern Oid get_roleid(const char *rolname); +extern Oid get_roleid_checked(const char *rolname); #define is_array_type(typid) (get_element_type(typid) != InvalidOid) diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 976788f40578d37ed420d60dba979b101702d151..8a30e08e184a6d1a278179917d84ea0da5e912d5 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -9,7 +9,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.59 2005/03/29 00:17:18 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/syscache.h,v 1.60 2005/06/28 05:09:13 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -36,29 +36,29 @@ #define AMPROCNUM 5 #define ATTNAME 6 #define ATTNUM 7 -#define CASTSOURCETARGET 8 -#define CLAAMNAMENSP 9 -#define CLAOID 10 -#define CONDEFAULT 11 -#define CONNAMENSP 12 -#define CONOID 13 -#define GRONAME 14 -#define GROSYSID 15 -#define INDEXRELID 16 -#define INHRELID 17 -#define LANGNAME 18 -#define LANGOID 19 -#define NAMESPACENAME 20 -#define NAMESPACEOID 21 -#define OPERNAMENSP 22 -#define OPEROID 23 -#define PROCNAMEARGSNSP 24 -#define PROCOID 25 -#define RELNAMENSP 26 -#define RELOID 27 -#define RULERELNAME 28 -#define SHADOWNAME 29 -#define SHADOWSYSID 30 +#define AUTHMEMMEMROLE 8 +#define AUTHMEMROLEMEM 9 +#define AUTHNAME 10 +#define AUTHOID 11 +#define CASTSOURCETARGET 12 +#define CLAAMNAMENSP 13 +#define CLAOID 14 +#define CONDEFAULT 15 +#define CONNAMENSP 16 +#define CONOID 17 +#define INDEXRELID 18 +#define INHRELID 19 +#define LANGNAME 20 +#define LANGOID 21 +#define NAMESPACENAME 22 +#define NAMESPACEOID 23 +#define OPERNAMENSP 24 +#define OPEROID 25 +#define PROCNAMEARGSNSP 26 +#define PROCOID 27 +#define RELNAMENSP 28 +#define RELOID 29 +#define RULERELNAME 30 #define STATRELATT 31 #define TYPENAMENSP 32 #define TYPEOID 33 diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 8ac111b5e18dc6db8f05444ba9ebd965815870a3..8fa8bb18ce38bbbd4631c91db64f69a1dff12d81 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -6,11 +6,12 @@ CREATE USER regressuser2; CREATE USER regressuser3; CREATE USER regressuser4; CREATE USER regressuser4; -- duplicate -ERROR: user "regressuser4" already exists +ERROR: role "regressuser4" already exists CREATE GROUP regressgroup1; CREATE GROUP regressgroup2 WITH USER regressuser1, regressuser2; ALTER GROUP regressgroup1 ADD USER regressuser4; ALTER GROUP regressgroup2 ADD USER regressuser2; -- duplicate +NOTICE: role "regressuser2" is already a member of role "regressgroup2" ALTER GROUP regressgroup2 DROP USER regressuser2; ALTER GROUP regressgroup2 ADD USER regressuser4; -- test owner privileges @@ -275,7 +276,7 @@ DROP FUNCTION testfunc1(int); -- ok GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; -- has_table_privilege function -- bad-input checks -select has_table_privilege(NULL,'pg_shadow','select'); +select has_table_privilege(NULL,'pg_authid','select'); has_table_privilege --------------------- @@ -283,36 +284,36 @@ select has_table_privilege(NULL,'pg_shadow','select'); select has_table_privilege('pg_shad','select'); ERROR: relation "pg_shad" does not exist -select has_table_privilege('nosuchuser','pg_shadow','select'); -ERROR: user "nosuchuser" does not exist -select has_table_privilege('pg_shadow','sel'); +select has_table_privilege('nosuchuser','pg_authid','select'); +ERROR: role "nosuchuser" does not exist +select has_table_privilege('pg_authid','sel'); ERROR: unrecognized privilege type: "sel" -select has_table_privilege(-999999,'pg_shadow','update'); -ERROR: user with ID 4293967297 does not exist +select has_table_privilege(-999999,'pg_authid','update'); +ERROR: role with OID 4293967297 does not exist select has_table_privilege(1,'rule'); ERROR: relation with OID 1 does not exist -- superuser \c - -select has_table_privilege(current_user,'pg_shadow','select'); +select has_table_privilege(current_user,'pg_authid','select'); has_table_privilege --------------------- t (1 row) -select has_table_privilege(current_user,'pg_shadow','insert'); +select has_table_privilege(current_user,'pg_authid','insert'); has_table_privilege --------------------- t (1 row) -select has_table_privilege(t2.usesysid,'pg_shadow','update') +select has_table_privilege(t2.usesysid,'pg_authid','update') from (select usesysid from pg_user where usename = current_user) as t2; has_table_privilege --------------------- t (1 row) -select has_table_privilege(t2.usesysid,'pg_shadow','delete') +select has_table_privilege(t2.usesysid,'pg_authid','delete') from (select usesysid from pg_user where usename = current_user) as t2; has_table_privilege --------------------- @@ -320,21 +321,21 @@ from (select usesysid from pg_user where usename = current_user) as t2; (1 row) select has_table_privilege(current_user,t1.oid,'rule') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; has_table_privilege --------------------- t (1 row) select has_table_privilege(current_user,t1.oid,'references') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; has_table_privilege --------------------- t (1 row) select has_table_privilege(t2.usesysid,t1.oid,'select') -from (select oid from pg_class where relname = 'pg_shadow') as t1, +from (select oid from pg_class where relname = 'pg_authid') as t1, (select usesysid from pg_user where usename = current_user) as t2; has_table_privilege --------------------- @@ -342,34 +343,34 @@ from (select oid from pg_class where relname = 'pg_shadow') as t1, (1 row) select has_table_privilege(t2.usesysid,t1.oid,'insert') -from (select oid from pg_class where relname = 'pg_shadow') as t1, +from (select oid from pg_class where relname = 'pg_authid') as t1, (select usesysid from pg_user where usename = current_user) as t2; has_table_privilege --------------------- t (1 row) -select has_table_privilege('pg_shadow','update'); +select has_table_privilege('pg_authid','update'); has_table_privilege --------------------- t (1 row) -select has_table_privilege('pg_shadow','delete'); +select has_table_privilege('pg_authid','delete'); has_table_privilege --------------------- t (1 row) select has_table_privilege(t1.oid,'select') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; has_table_privilege --------------------- t (1 row) select has_table_privilege(t1.oid,'trigger') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; has_table_privilege --------------------- t @@ -546,8 +547,7 @@ SET SESSION AUTHORIZATION regressuser1; CREATE TABLE atest4 (a int); GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION; GRANT UPDATE ON atest4 TO regressuser2; -GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; -- fail -ERROR: grant options can only be granted to individual users +GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; SET SESSION AUTHORIZATION regressuser2; GRANT SELECT ON atest4 TO regressuser3; GRANT UPDATE ON atest4 TO regressuser3; -- fail diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 384ce37d9c29046d988155906723cb202daf9eda..47fc262c31569a4bc8898ac3f3e27ea10ba67ce4 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1277,12 +1277,15 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem viewname | definition --------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath); + pg_group | SELECT pg_authid.rolname AS groname, pg_authid.oid AS grosysid, ARRAY(SELECT pg_auth_members.member FROM pg_auth_members WHERE (pg_auth_members.roleid = pg_authid.oid)) AS grolist FROM pg_authid WHERE (NOT pg_authid.rolcanlogin); pg_indexes | SELECT n.nspname AS schemaname, c.relname AS tablename, i.relname AS indexname, t.spcname AS "tablespace", pg_get_indexdef(i.oid) AS indexdef FROM ((((pg_index x JOIN pg_class c ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) WHERE ((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char")); pg_locks | SELECT l.locktype, l."database", l.relation, l.page, l.tuple, l.transactionid, l.classid, l.objid, l.objsubid, l."transaction", l.pid, l."mode", l.granted FROM pg_lock_status() l(locktype text, "database" oid, relation oid, page integer, tuple smallint, transactionid xid, classid oid, objid oid, objsubid smallint, "transaction" xid, pid integer, "mode" text, granted boolean); - pg_prepared_xacts | SELECT p."transaction", p.gid, p."prepared", u.usename AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid integer, dbid oid) LEFT JOIN pg_shadow u ON ((p.ownerid = u.usesysid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid))); + pg_prepared_xacts | SELECT p."transaction", p.gid, p."prepared", u.rolname AS "owner", d.datname AS "database" FROM ((pg_prepared_xact() p("transaction" xid, gid text, "prepared" timestamp with time zone, ownerid oid, dbid oid) LEFT JOIN pg_authid u ON ((p.ownerid = u.oid))) LEFT JOIN pg_database d ON ((p.dbid = d.oid))); + pg_roles | SELECT pg_authid.rolname, pg_authid.rolsuper, pg_authid.rolcreaterole, pg_authid.rolcreatedb, pg_authid.rolcatupdate, pg_authid.rolcanlogin, '********'::text AS rolpassword, pg_authid.rolvaliduntil, pg_authid.rolconfig FROM pg_authid; pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename <> '_RETURN'::name); pg_settings | SELECT a.name, a.setting, a.category, a.short_desc, a.extra_desc, a.context, a.vartype, a.source, a.min_val, a.max_val FROM pg_show_all_settings() a(name text, setting text, category text, short_desc text, extra_desc text, context text, vartype text, source text, min_val text, max_val text); - pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid)); + pg_shadow | SELECT pg_authid.rolname AS usename, pg_authid.oid AS usesysid, pg_authid.rolcreatedb AS usecreatedb, pg_authid.rolsuper AS usesuper, pg_authid.rolcatupdate AS usecatupd, pg_authid.rolpassword AS passwd, (pg_authid.rolvaliduntil)::abstime AS valuntil, pg_authid.rolconfig AS useconfig FROM pg_authid WHERE pg_authid.rolcanlogin; + pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.rolname AS usename, pg_stat_get_backend_activity(s.backendid) AS current_query, pg_stat_get_backend_activity_start(s.backendid) AS query_start, pg_stat_get_backend_start(s.backendid) AS backend_start, pg_stat_get_backend_client_addr(s.backendid) AS client_addr, pg_stat_get_backend_client_port(s.backendid) AS client_port FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_authid u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.oid)); pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM (((pg_class c JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char"); pg_stat_all_tables | SELECT c.oid AS relid, n.nspname AS schemaname, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM ((pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, n.nspname, c.relname; pg_stat_database | SELECT d.oid AS datid, d.datname, pg_stat_get_db_numbackends(d.oid) AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, pg_stat_get_db_blocks_hit(d.oid) AS blks_hit FROM pg_database d; @@ -1317,7 +1320,7 @@ SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schem shoelace_obsolete | SELECT shoelace.sl_name, shoelace.sl_avail, shoelace.sl_color, shoelace.sl_len, shoelace.sl_unit, shoelace.sl_len_cm FROM shoelace WHERE (NOT (EXISTS (SELECT shoe.shoename FROM shoe WHERE (shoe.slcolor = shoelace.sl_color)))); street | SELECT r.name, r.thepath, c.cname FROM ONLY road r, real_city c WHERE (c.outline ## r.thepath); toyemp | SELECT emp.name, emp.age, emp."location", (12 * emp.salary) AS annualsal FROM emp; -(41 rows) +(44 rows) SELECT tablename, rulename, definition FROM pg_rules ORDER BY tablename, rulename; diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index 00abd941ccfdf6119cb2bed9b58c88ffa974ded8..581146bbd70b48a937e9ac6e13656c45a87351fb 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -37,6 +37,8 @@ SELECT relname, relhasindex pg_amproc | t pg_attrdef | t pg_attribute | t + pg_auth_members | t + pg_authid | t pg_cast | t pg_class | t pg_constraint | t @@ -44,7 +46,6 @@ SELECT relname, relhasindex pg_database | t pg_depend | t pg_description | t - pg_group | t pg_index | t pg_inherits | t pg_language | t @@ -54,7 +55,6 @@ SELECT relname, relhasindex pg_operator | t pg_proc | t pg_rewrite | t - pg_shadow | t pg_statistic | t pg_tablespace | t pg_trigger | t diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 3e224c556a205f8a1acb5171b200743f7b10fb78..aa65bf599d24700fc17511747a3551e79f3673b0 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -192,43 +192,43 @@ GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; -- has_table_privilege function -- bad-input checks -select has_table_privilege(NULL,'pg_shadow','select'); +select has_table_privilege(NULL,'pg_authid','select'); select has_table_privilege('pg_shad','select'); -select has_table_privilege('nosuchuser','pg_shadow','select'); -select has_table_privilege('pg_shadow','sel'); -select has_table_privilege(-999999,'pg_shadow','update'); +select has_table_privilege('nosuchuser','pg_authid','select'); +select has_table_privilege('pg_authid','sel'); +select has_table_privilege(-999999,'pg_authid','update'); select has_table_privilege(1,'rule'); -- superuser \c - -select has_table_privilege(current_user,'pg_shadow','select'); -select has_table_privilege(current_user,'pg_shadow','insert'); +select has_table_privilege(current_user,'pg_authid','select'); +select has_table_privilege(current_user,'pg_authid','insert'); -select has_table_privilege(t2.usesysid,'pg_shadow','update') +select has_table_privilege(t2.usesysid,'pg_authid','update') from (select usesysid from pg_user where usename = current_user) as t2; -select has_table_privilege(t2.usesysid,'pg_shadow','delete') +select has_table_privilege(t2.usesysid,'pg_authid','delete') from (select usesysid from pg_user where usename = current_user) as t2; select has_table_privilege(current_user,t1.oid,'rule') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; select has_table_privilege(current_user,t1.oid,'references') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; select has_table_privilege(t2.usesysid,t1.oid,'select') -from (select oid from pg_class where relname = 'pg_shadow') as t1, +from (select oid from pg_class where relname = 'pg_authid') as t1, (select usesysid from pg_user where usename = current_user) as t2; select has_table_privilege(t2.usesysid,t1.oid,'insert') -from (select oid from pg_class where relname = 'pg_shadow') as t1, +from (select oid from pg_class where relname = 'pg_authid') as t1, (select usesysid from pg_user where usename = current_user) as t2; -select has_table_privilege('pg_shadow','update'); -select has_table_privilege('pg_shadow','delete'); +select has_table_privilege('pg_authid','update'); +select has_table_privilege('pg_authid','delete'); select has_table_privilege(t1.oid,'select') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; select has_table_privilege(t1.oid,'trigger') -from (select oid from pg_class where relname = 'pg_shadow') as t1; +from (select oid from pg_class where relname = 'pg_authid') as t1; -- non-superuser SET SESSION AUTHORIZATION regressuser3; @@ -298,7 +298,7 @@ CREATE TABLE atest4 (a int); GRANT SELECT ON atest4 TO regressuser2 WITH GRANT OPTION; GRANT UPDATE ON atest4 TO regressuser2; -GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; -- fail +GRANT SELECT ON atest4 TO GROUP regressgroup1 WITH GRANT OPTION; SET SESSION AUTHORIZATION regressuser2;