From 840b7f5205ff48f260e5be09921a26c9f83a786f Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Sun, 14 Aug 2005 23:35:38 +0000 Subject: [PATCH] Update administrator's guide chapters for ROLEs patch. --- doc/src/sgml/client-auth.sgml | 143 +++++++------ doc/src/sgml/manage-ag.sgml | 16 +- doc/src/sgml/ref/create_role.sgml | 22 +- doc/src/sgml/user-manag.sgml | 330 +++++++++++++++++++++--------- 4 files changed, 339 insertions(+), 172 deletions(-) diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index d2585e3a94f..527676fd626 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.82 2005/06/27 02:04:23 neilc Exp $ +$PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.83 2005/08/14 23:35:37 tgl Exp $ --> <chapter id="client-authentication"> @@ -11,7 +11,7 @@ $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.82 2005/06/27 02:04:23 neil <para> When a client application connects to the database server, it - specifies which <productname>PostgreSQL</productname> user name it + specifies which <productname>PostgreSQL</productname> database user name it wants to connect as, much the same way one logs into a Unix computer as a particular user. Within the SQL environment the active database user name determines access privileges to database objects — see @@ -19,12 +19,22 @@ $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.82 2005/06/27 02:04:23 neil essential to restrict which database users can connect. </para> + <note> + <para> + As explained in <xref linkend="user-manag">, + <productname>PostgreSQL</productname> actually does privilege + management in terms of <quote>roles</>. In this chapter, we + consistently use <firstterm>database user</> to mean <quote>role with the + <literal>LOGIN</> privilege</quote>. + </para> + </note> + <para> <firstterm>Authentication</firstterm> is the process by which the database server establishes the identity of the client, and by extension determines whether the client application (or the user who runs the client application) is permitted to connect with the - user name that was requested. + database user name that was requested. </para> <para> @@ -35,7 +45,7 @@ $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.82 2005/06/27 02:04:23 neil </para> <para> - <productname>PostgreSQL</productname> user names are logically + <productname>PostgreSQL</productname> database user names are logically separate from user names of the operating system in which the server runs. If all the users of a particular server also have accounts on the server's machine, it makes sense to assign database user names @@ -88,13 +98,13 @@ $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.82 2005/06/27 02:04:23 neil <para> A record may have one of the seven formats <synopsis> -local <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> -host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>CIDR-address</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> -hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>CIDR-address</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> -hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>CIDR-address</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> -host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> -hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> -hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>authentication-method</replaceable> <optional><replaceable>authentication-option</replaceable></optional> +local <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> +host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>CIDR-address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> +hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>CIDR-address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> +hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>CIDR-address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> +host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> +hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> +hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-option</replaceable></optional> </synopsis> The meaning of the fields is as follows: @@ -165,16 +175,18 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <term><replaceable>database</replaceable></term> <listitem> <para> - Specifies which databases this record matches. The value + Specifies which database names this record matches. The value <literal>all</literal> specifies that it matches all databases. The value <literal>sameuser</> specifies that the record matches if the requested database has the same name as the - requested user. The value <literal>samegroup</> specifies that - the requested user must be a member of the group with the same - name as the requested database. Otherwise, this is the name of + requested user. The value <literal>samerole</> specifies that + the requested user must be a member of the role with the same + name as the requested database. (<literal>samegroup</> is an + obsolete but still accepted spelling of <literal>samerole</>.) + Otherwise, this is the name of a specific <productname>PostgreSQL</productname> database. Multiple database names can be supplied by separating them with - commas. A file containing database names can be specified by + commas. A separate file containing database names can be specified by preceding the file name with <literal>@</>. </para> </listitem> @@ -184,13 +196,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <term><replaceable>user</replaceable></term> <listitem> <para> - Specifies which <productname>PostgreSQL</> users this record + Specifies which database user names this record matches. The value <literal>all</literal> specifies that it - matches all users. Otherwise, this is the name of a specific - <productname>PostgreSQL</productname> user. Multiple user names - can be supplied by separating them with commas. Group names can - be specified by preceding the group name with <literal>+</>. A - file containing user names can be specified by preceding the + matches all users. Otherwise, this is either the name of a specific + database user, or a group name preceded by <literal>+</>. + (Recall that there is no real distinction between users and groups + in <productname>PostgreSQL</>; a <literal>+</> mark really means + <quote>match any of the roles that are directly or indirectly members + of this role</>, while a name without a <literal>+</> mark matches + only that specific role.) + Multiple user names can be supplied by separating them with commas. + A separate file containing user names can be specified by preceding the file name with <literal>@</>. </para> </listitem> @@ -257,7 +273,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> </varlistentry> <varlistentry> - <term><replaceable>authentication-method</replaceable></term> + <term><replaceable>auth-method</replaceable></term> <listitem> <para> Specifies the authentication method to use when connecting via @@ -369,7 +385,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> </varlistentry> <varlistentry> - <term><replaceable>authentication-option</replaceable></term> + <term><replaceable>auth-option</replaceable></term> <listitem> <para> The meaning of this optional field depends on the chosen @@ -424,7 +440,7 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <title>Example <filename>pg_hba.conf</filename> entries</title> <programlisting> # Allow any user on the local system to connect to any database under -# any user name using Unix-domain sockets (the default for local +# any database user name using Unix-domain sockets (the default for local # connections). # # TYPE DATABASE USER CIDR-ADDRESS METHOD @@ -445,7 +461,7 @@ host all all 127.0.0.1 255.255.255.255 trust # the connection (typically the Unix user name). # # TYPE DATABASE USER CIDR-ADDRESS METHOD -host postgres all 192.168.93.0/24 ident sameuser +host postgres all 192.168.93.0/24 ident sameuser # Allow a user from host 192.168.12.10 to connect to database # "postgres" if the user's password is correctly supplied. @@ -474,10 +490,10 @@ host all all 192.168.0.0/16 ident omicron # If these are the only three lines for local connections, they will # allow local users to connect only to their own databases (databases -# with the same name as their user name) except for administrators and -# members of group "support" who may connect to all databases. The file -# $PGDATA/admins contains a list of user names. Passwords are required in -# all cases. +# with the same name as their database user name) except for administrators +# and members of role "support", who may connect to all databases. The file +# $PGDATA/admins contains a list of names of administrators. Passwords +# are required in all cases. # # TYPE DATABASE USER CIDR-ADDRESS METHOD local sameuser all md5 @@ -487,7 +503,7 @@ local all +support md5 # The last two lines above can be combined into a single line: local all @admins,+support md5 -# The database column can also use lists and file names, but not groups: +# The database column can also use lists and file names: local db1,db2,@demodbs all md5 </programlisting> </example> @@ -506,7 +522,7 @@ local db1,db2,@demodbs all md5 When <literal>trust</> authentication is specified, <productname>PostgreSQL</productname> assumes that anyone who can connect to the server is authorized to access the database with - whatever database user they specify (including the database superuser). + whatever database user name they specify (including superusers). Of course, restrictions made in the <literal>database</> and <literal>user</> columns still apply. This method should only be used when there is adequate @@ -564,8 +580,9 @@ local db1,db2,@demodbs all md5 The password-based authentication methods are <literal>md5</>, <literal>crypt</>, and <literal>password</>. These methods operate similarly except for the way that the password is sent across the - connection. However, <literal>crypt</> does not allow encrypted - passwords to be stored in <structname>pg_shadow</structname>. + connection: respectively, MD5-hashed, crypt-encrypted, and clear-text. + A limitation is that the <literal>crypt</> method does not work with + passwords that have been encrypted in <structname>pg_authid</structname>. </para> <para> @@ -573,15 +590,16 @@ local db1,db2,@demodbs all md5 <quote>sniffing</> attacks then <literal>md5</> is preferred, with <literal>crypt</> a second choice if you must support pre-7.2 clients. Plain <literal>password</> should especially be avoided for - connections over the open Internet (unless you use <acronym>SSL</acronym>, SSH, or - other communications security wrappers around the connection). + connections over the open Internet (unless you use <acronym>SSL</acronym>, + <acronym>SSH</>, or another + communications security wrapper around the connection). </para> <para> <productname>PostgreSQL</productname> database passwords are separate from operating system user passwords. The password for - each database user is stored in the <literal>pg_shadow</> system - catalog table. Passwords can be managed with the SQL commands + each database user is stored in the <literal>pg_authid</> system + catalog. Passwords can be managed with the SQL commands <xref linkend="sql-createuser" endterm="sql-createuser-title"> and <xref linkend="sql-alteruser" endterm="sql-alteruser-title">, e.g., <userinput>CREATE USER foo WITH PASSWORD 'secret';</userinput>. @@ -607,41 +625,44 @@ local db1,db2,@demodbs all md5 <ulink url="http://www.nrl.navy.mil/CCS/people/kenh/kerberos-faq.html"> Kerberos <acronym>FAQ</></ulink> or <ulink url="http://web.mit.edu/kerberos/www/">MIT Kerberos page</ulink> - can be a good starting point for exploration. + can be good starting points for exploration. Several sources for <productname>Kerberos</> distributions exist. </para> <para> - <productname>PostgreSQL</> supports Kerberos version 5, and it has - to be enabled at build time. See - <xref linkend="installation"> for more information. + <productname>PostgreSQL</> supports Kerberos version 5. Kerberos + support has to be enabled when <productname>PostgreSQL</> is built; + see <xref linkend="installation"> for more information. </para> <para> <productname>PostgreSQL</> operates like a normal Kerberos service. The name of the service principal is <literal><replaceable>servicename</>/<replaceable>hostname</>@<replaceable>realm</></literal>. - </para> - <para> + </para> + + <para> <replaceable>servicename</> can be set on the server side using the <xref linkend="guc-krb-srvname"> configuration parameter, and on the - client side using the krbsrvname connection parameter. (See also <xref linkend="libpq-connect">.). The installation default can be changed from the default - <literal>postgres</literal> at build time using - <literal>./configure --with-krb-srvnam=whatever</>). In most environments, - this parameter never needs to be changed. However, to support multiple - <productname>PostgreSQL</> installations on the same host it is necessary. - Some Kerberos implementations may also require a different service name, - such as Microsoft Active Directory which requires the service name - to be in uppercase (<literal>POSTGRES</literal>). - </para> - <para> + client side using the <literal>krbsrvname</> connection parameter. (See + also <xref linkend="libpq-connect">.) The installation default can be + changed from the default <literal>postgres</literal> at build time using + <literal>./configure --with-krb-srvnam=whatever</>. In most environments, + this parameter never needs to be changed. However, to support multiple + <productname>PostgreSQL</> installations on the same host it is necessary. + Some Kerberos implementations may also require a different service name, + such as Microsoft Active Directory which requires the service name + to be in uppercase (<literal>POSTGRES</literal>). + </para> + + <para> <replaceable>hostname</> is the fully qualified host name of the server machine. The service principal's realm is the preferred realm of the server machine. </para> <para> - Client principals must have their <productname>PostgreSQL</> user + Client principals must have their <productname>PostgreSQL</> database user name as their first component, for example <literal>pgusername/otherstuff@realm</>. At present the realm of the client is not checked by <productname>PostgreSQL</>; so if you @@ -661,9 +682,9 @@ local db1,db2,@demodbs all md5 </para> <para> - The keytab file is generated in the Kerberos system, see the - Kerberos documentation for details. The following example is - for MIT-compatible Kerberos 5 implementations: + The keytab file is generated by the Kerberos software; see the + Kerberos documentation for details. The following example is + for MIT-compatible Kerberos 5 implementations: <screen> <prompt>kadmin% </><userinput>ank -randkey postgres/server.my.domain.org</> <prompt>kadmin% </><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</> @@ -672,10 +693,10 @@ local db1,db2,@demodbs all md5 <para> When connecting to the database make sure you have a ticket for a - principal matching the requested database user name. An example: For + principal matching the requested database user name. For example, for database user name <literal>fred</>, both principal <literal>fred@EXAMPLE.COM</> and - <literal>fred/users.example.com@EXAMPLE.COM</> can be used to + <literal>fred/users.example.com@EXAMPLE.COM</> could be used to authenticate to the database server. </para> @@ -900,7 +921,7 @@ FATAL: no pg_hba.conf entry for host "123.123.123.123", user "andym", database This is what you are most likely to get if you succeed in contacting the server, but it does not want to talk to you. As the message suggests, the server refused the connection request because it found - no authorizing entry in its <filename>pg_hba.conf</filename> + no matching entry in its <filename>pg_hba.conf</filename> configuration file. </para> diff --git a/doc/src/sgml/manage-ag.sgml b/doc/src/sgml/manage-ag.sgml index 0ac156cb443..03746b3fda9 100644 --- a/doc/src/sgml/manage-ag.sgml +++ b/doc/src/sgml/manage-ag.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/manage-ag.sgml,v 2.42 2005/06/21 04:02:30 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/manage-ag.sgml,v 2.43 2005/08/14 23:35:37 tgl Exp $ --> <chapter id="managing-databases"> @@ -94,7 +94,7 @@ SELECT datname FROM pg_database; CREATE DATABASE <replaceable>name</>; </synopsis> where <replaceable>name</> follows the usual rules for - <acronym>SQL</acronym> identifiers. The current user automatically + <acronym>SQL</acronym> identifiers. The current role automatically becomes the owner of the new database. It is the privilege of the owner of a database to remove it later on (which also removes all the objects in it, even if they have a different owner). @@ -102,7 +102,7 @@ CREATE DATABASE <replaceable>name</>; <para> The creation of databases is a restricted operation. See <xref - linkend="user-attributes"> for how to grant permission. + linkend="role-attributes"> for how to grant permission. </para> <para> @@ -158,18 +158,18 @@ createdb <replaceable class="parameter">dbname</replaceable> <para> Sometimes you want to create a database for someone else. That - user should become the owner of the new database, so he can + role should become the owner of the new database, so he can configure and manage it himself. To achieve that, use one of the following commands: <programlisting> -CREATE DATABASE <replaceable>dbname</> OWNER <replaceable>username</>; +CREATE DATABASE <replaceable>dbname</> OWNER <replaceable>rolename</>; </programlisting> from the SQL environment, or <programlisting> -createdb -O <replaceable>username</> <replaceable>dbname</> +createdb -O <replaceable>rolename</> <replaceable>dbname</> </programlisting> You must be a superuser to be allowed to create a database for - someone else. + someone else (that is, for a role you are not a member of). </para> </sect1> @@ -327,7 +327,7 @@ ALTER DATABASE mydb SET geqo TO off; <synopsis> DROP DATABASE <replaceable>name</>; </synopsis> - Only the owner of the database (i.e., the user that created it), or + Only the owner of the database, or a superuser, can drop a database. Dropping a database removes all objects that were contained within the database. The destruction of a database cannot diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml index 4cff62a6ec6..599ac1898aa 100644 --- a/doc/src/sgml/ref/create_role.sgml +++ b/doc/src/sgml/ref/create_role.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/create_role.sgml,v 1.2 2005/07/31 17:19:17 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/create_role.sgml,v 1.3 2005/08/14 23:35:38 tgl Exp $ PostgreSQL documentation --> @@ -141,7 +141,7 @@ where <replaceable class="PARAMETER">option</replaceable> can be: <para> These clauses determine whether a role <quote>inherits</> the privileges of roles it is a member of. - A role with <literal>INHERIT</literal> privilege can automatically + A role with the <literal>INHERIT</literal> attribute can automatically use whatever database privileges have been granted to all roles it is directly or indirectly a member of. Without <literal>INHERIT</literal>, membership in another role @@ -162,7 +162,7 @@ where <replaceable class="PARAMETER">option</replaceable> can be: These clauses determine whether a role is allowed to log in; that is, whether the role can be given as the initial session authorization name during client connection. A role having - <literal>LOGIN</literal> privilege can be thought of as a user. + the <literal>LOGIN</literal> attribute can be thought of as a user. Roles without this attribute are useful for managing database privileges, but are not users in the usual sense of the word. If not specified, @@ -188,7 +188,7 @@ where <replaceable class="PARAMETER">option</replaceable> can be: <listitem> <para> Sets the role's password. (A password is only of use for - roles having <literal>LOGIN</literal> privilege, but you can + roles having the <literal>LOGIN</literal> attribute, but you can nonetheless define one for roles without it.) If you do not plan to use password authentication you can omit this option. @@ -325,7 +325,19 @@ where <replaceable class="PARAMETER">option</replaceable> can be: </para> <para> - <literal>INHERIT</> privilege is the default for reasons of backwards + The <literal>INHERIT</> attribute governs inheritance of grantable + privileges (that is, access privileges for database objects and role + memberships). It does not apply to the special role attributes set by + <command>CREATE ROLE</> and <command>ALTER ROLE</>. For example, being + a member of a role with <literal>CREATEDB</> privilege does not immediately + grant the ability to create databases, even if <literal>INHERIT</> is set; + it would be necessary to become that role via + <xref linkend="SQL-SET-ROLE" endterm="SQL-SET-ROLE-title"> before + creating a database. + </para> + + <para> + The <literal>INHERIT</> attribute is the default for reasons of backwards compatibility: in prior releases of <productname>PostgreSQL</productname>, users always had access to all privileges of groups they were members of. However, <literal>NOINHERIT</> provides a closer match to the semantics diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 5ffd878efdc..f42666b8198 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -1,55 +1,73 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.29 2005/03/25 16:38:58 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/user-manag.sgml,v 1.30 2005/08/14 23:35:37 tgl Exp $ --> <chapter id="user-manag"> - <title>Database Users and Privileges</title> + <title>Database Roles and Privileges</title> <para> - Every database cluster contains a set of database users. Those - users are separate from the users managed by the operating system on - which the server runs. Users own database objects (for example, - tables) and can assign privileges on those objects to other users to - control who has access to which object. + <productname>PostgreSQL</productname> manages database access permissions + using the concept of <firstterm>roles</>. A role can be thought of as + either a database user, or a group of database users, depending on how + the role is set up. Roles can own database objects (for example, + tables) and can assign privileges on those objects to other roles to + control who has access to which objects. Furthermore, it is possible + to grant <firstterm>membership</> in a role to another role, thus + allowing the member role use of privileges assigned to the role it is + a member of. </para> <para> - This chapter describes how to create and manage users and introduces + The concept of roles subsumes the concepts of <quote>users</> and + <quote>groups</>. In <productname>PostgreSQL</productname> versions + before 8.1, users and groups were distinct kinds of entities, but now + there are only roles. Any role can act as a user, a group, or both. + </para> + + <para> + This chapter describes how to create and manage roles and introduces the privilege system. More information about the various types of - database objects and the effects of privileges can be found in <xref linkend="ddl">. + database objects and the effects of privileges can be found in + <xref linkend="ddl">. </para> - <sect1 id="database-users"> - <title>Database Users</title> + <sect1 id="database-roles"> + <title>Database Roles</title> - <indexterm zone="database-users"> + <indexterm zone="database-roles"> + <primary>role</primary> + </indexterm> + + <indexterm zone="database-roles"> <primary>user</primary> </indexterm> <indexterm> - <primary>CREATE USER</primary> + <primary>CREATE ROLE</primary> </indexterm> <indexterm> - <primary>DROP USER</primary> + <primary>DROP ROLE</primary> </indexterm> <para> - Database users are conceptually completely separate from + Database roles are conceptually completely separate from operating system users. In practice it might be convenient to - maintain a correspondence, but this is not required. Database user - names are global across a database cluster installation (and not - per individual database). To create a user use the <xref - linkend="sql-createuser" endterm="sql-createuser-title"> SQL command: + maintain a correspondence, but this is not required. Database roles + are global across a database cluster installation (and not + per individual database). To create a role use the <xref + linkend="sql-createrole" endterm="sql-createrole-title"> SQL command: <synopsis> -CREATE USER <replaceable>name</replaceable>; +CREATE ROLE <replaceable>name</replaceable>; </synopsis> <replaceable>name</replaceable> follows the rules for SQL identifiers: either unadorned without special characters, or - double-quoted. To remove an existing user, use the analogous - <xref linkend="sql-dropuser" endterm="sql-dropuser-title"> command: + double-quoted. (In practice, you will usually want to add additional + options, such as <literal>LOGIN</>, to the command. More details appear + below.) To remove an existing role, use the analogous + <xref linkend="sql-droprole" endterm="sql-droprole-title"> command: <synopsis> -DROP USER <replaceable>name</replaceable>; +DROP ROLE <replaceable>name</replaceable>; </synopsis> </para> @@ -73,69 +91,93 @@ dropuser <replaceable>name</replaceable> </para> <para> - To determine the set of existing users, examine the <structname>pg_user</> + To determine the set of existing roles, examine the <structname>pg_roles</> system catalog, for example <synopsis> -SELECT usename FROM pg_user; +SELECT rolname FROM pg_roles; </synopsis> The <xref linkend="app-psql"> program's <literal>\du</> meta-command - is also useful for listing the existing users. + is also useful for listing the existing roles. </para> <para> In order to bootstrap the database system, a freshly initialized - system always contains one predefined user. This user will have the - fixed ID 1, and by default (unless altered when running + system always contains one predefined role. This role is always + a <quote>superuser</>, and by default (unless altered when running <command>initdb</command>) it will have the same name as the operating system user that initialized the database - cluster. Customarily, this user will be named - <literal>postgres</literal>. In order to create more users you - first have to connect as this initial user. + cluster. Customarily, this role will be named + <literal>postgres</literal>. In order to create more roles you + first have to connect as this initial role. </para> <para> - Exactly one user identity is active for a connection to the - database server. The user name to use for a particular database + Every connection to the database server is made in the name of some + particular role, and this role determines the initial access privileges for + commands issued on that connection. + The role name to use for a particular database connection is indicated by the client that is initiating the connection request in an application-specific fashion. For example, the <command>psql</command> program uses the - <option>-U</option> command line option to indicate the user to + <option>-U</option> command line option to indicate the role to connect as. Many applications assume the name of the current operating system user by default (including <command>createuser</> and <command>psql</>). Therefore it - is convenient to maintain a naming correspondence between the two - user sets. + is often convenient to maintain a naming correspondence between + roles and operating system users. </para> <para> - The set of database users a given client connection may connect as + The set of database roles a given client connection may connect as is determined by the client authentication setup, as explained in <xref linkend="client-authentication">. (Thus, a client is not - necessarily limited to connect as the user with the same name as + necessarily limited to connect as the role with the same name as its operating system user, just as a person's login name - need not match her real name.) Since the user + need not match her real name.) Since the role identity determines the set of privileges available to a connected client, it is important to carefully configure this when setting up a multiuser environment. </para> </sect1> - <sect1 id="user-attributes"> - <title>User Attributes</title> + <sect1 id="role-attributes"> + <title>Role Attributes</title> <para> - A database user may have a number of attributes that define its + A database role may have a number of attributes that define its privileges and interact with the client authentication system. <variablelist> <varlistentry> - <term>superuser<indexterm><primary>superuser</></></term> + <term>login privilege<indexterm><primary>login privilege</></></term> + <listitem> + <para> + Only roles that have the <literal>LOGIN</> attribute can be used + as the initial role name for a database connection. A role with + the <literal>LOGIN</> attribute can be considered the same thing + as a <quote>database user</>. To create a role with login privilege, + use either +<programlisting> +CREATE ROLE <replaceable>name</replaceable> LOGIN; +CREATE USER <replaceable>name</replaceable>; +</programlisting> + (<command>CREATE USER</> is equivalent to <command>CREATE ROLE</> + except that <command>CREATE USER</> assumes <literal>LOGIN</> by + default, while <command>CREATE ROLE</> does not.) + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term>superuser status<indexterm><primary>superuser</></></term> <listitem> <para> - A database superuser bypasses all permission checks. Also, - only a superuser can create new users. To create a database - superuser, use <literal>CREATE USER <replaceable>name</replaceable> - CREATEUSER</literal>. + A database superuser bypasses all permission checks. This is a + dangerous privilege and should not be used carelessly; it is best + to do most of your work as a role that is not a superuser. + To create a new database superuser, use <literal>CREATE ROLE + <replaceable>name</replaceable> SUPERUSER</literal>. You must do + this as a role that is already a superuser. </para> </listitem> </varlistentry> @@ -144,14 +186,30 @@ SELECT usename FROM pg_user; <term>database creation<indexterm><primary>database</><secondary>privilege to create</></></term> <listitem> <para> - A user must be explicitly given permission to create databases + A role must be explicitly given permission to create databases (except for superusers, since those bypass all permission - checks). To create such a user, use <literal>CREATE USER + checks). To create such a role, use <literal>CREATE ROLE <replaceable>name</replaceable> CREATEDB</literal>. </para> </listitem> </varlistentry> + <varlistentry> + <term>role creation<indexterm><primary>role</><secondary>privilege to create</></></term> + <listitem> + <para> + A role must be explicitly given permission to create more roles + (except for superusers, since those bypass all permission + checks). To create such a role, use <literal>CREATE ROLE + <replaceable>name</replaceable> CREATEROLE</literal>. + A role with <literal>CREATEROLE</> privilege can alter and drop + other roles, too. However, to alter or drop a superuser role, + superuser status is required; <literal>CREATEROLE</> is not sufficient + for that. + </para> + </listitem> + </varlistentry> + <varlistentry> <term>password<indexterm><primary>password</></></term> <listitem> @@ -161,79 +219,159 @@ SELECT usename FROM pg_user; to the database. The <option>password</>, <option>md5</>, and <option>crypt</> authentication methods make use of passwords. Database passwords are separate from - operating system passwords. Specify a password upon user - creation with <literal>CREATE USER + operating system passwords. Specify a password upon role + creation with <literal>CREATE ROLE <replaceable>name</replaceable> PASSWORD '<replaceable>string</>'</literal>. </para> </listitem> </varlistentry> </variablelist> - A user's attributes can be modified after creation with - <command>ALTER USER</command>.<indexterm><primary>ALTER USER</></> - See the reference pages for the <xref linkend="sql-createuser" - endterm="sql-createuser-title"> and <xref linkend="sql-alteruser" - endterm="sql-alteruser-title"> commands for details. + A role's attributes can be modified after creation with + <command>ALTER ROLE</command>.<indexterm><primary>ALTER ROLE</></> + See the reference pages for the <xref linkend="sql-createrole" + endterm="sql-createrole-title"> and <xref linkend="sql-alterrole" + endterm="sql-alterrole-title"> commands for details. </para> <para> - A user can also set personal defaults for many of the run-time + A role can also have role-specific defaults for many of the run-time configuration settings described in <xref linkend="runtime-config">. For example, if for some reason you want to disable index scans (hint: not a good idea) anytime you connect, you can use <programlisting> -ALTER USER myname SET enable_indexscan TO off; +ALTER ROLE myname SET enable_indexscan TO off; </programlisting> This will save the setting (but not set it immediately). In - subsequent connections by this user it will appear as though + subsequent connections by this role it will appear as though <literal>SET enable_indexscan TO off;</literal> had been executed just before the session started. You can still alter this setting during the session; it will only - be the default. To undo any such setting, use <literal>ALTER USER - <replaceable>username</> RESET <replaceable>varname</>;</literal>. + be the default. To remove a role-specific default setting, use + <literal>ALTER ROLE <replaceable>rolename</> RESET <replaceable>varname</>;</literal>. + Note that role-specific defaults attached to roles without + <literal>LOGIN</> privilege are fairly useless, since they will never + be invoked. </para> </sect1> - <sect1 id="groups"> - <title>Groups</title> + <sect1 id="role-membership"> + <title>Role Membership</title> - <indexterm zone="groups"> - <primary>group</primary> + <indexterm zone="role-membership"> + <primary>role</><secondary>membership in</> </indexterm> <para> - As in Unix, groups are a way of logically grouping users to ease - management of privileges: privileges can be granted to, or revoked - from, a group as a whole. To create a group, use the <xref - linkend="sql-creategroup" endterm="sql-creategroup-title"> SQL command: -<synopsis> -CREATE GROUP <replaceable>name</replaceable>; -</synopsis> + It is frequently convenient to group users together to ease + management of privileges: that way, privileges can be granted to, or + revoked from, a group as a whole. In <productname>PostgreSQL</productname> + this is done by creating a role that represents the group, and then + granting <firstterm>membership</> in the group role to individual user + roles. + </para> - To add users to or remove users from an existing group, use <xref - linkend="sql-altergroup" endterm="sql-altergroup-title">: + <para> + To set up a group role, first create the role: <synopsis> -ALTER GROUP <replaceable>name</replaceable> ADD USER <replaceable>uname1</replaceable>, ... ; -ALTER GROUP <replaceable>name</replaceable> DROP USER <replaceable>uname1</replaceable>, ... ; +CREATE ROLE <replaceable>name</replaceable>; </synopsis> + Typically a role being used as a group would not have the <literal>LOGIN</> + attribute, though you can set it if you wish. + </para> - To destroy a group, use <xref - linkend="sql-dropgroup" endterm="sql-dropgroup-title">: + <para> + Once the group role exists, you can add and remove members using the + <xref linkend="sql-grant" endterm="sql-grant-title"> and + <xref linkend="sql-revoke" endterm="sql-revoke-title"> commands: <synopsis> -DROP GROUP <replaceable>name</replaceable>; +GRANT <replaceable>group_role</replaceable> TO <replaceable>role1</replaceable>, ... ; +REVOKE <replaceable>group_role</replaceable> FROM <replaceable>role1</replaceable>, ... ; </synopsis> - This only drops the group, not its member users. + You can grant membership to other group roles, too (since there isn't + really any distinction between group roles and non-group roles). The + only restriction is that you can't set up circular membership loops. </para> <para> - To determine the set of existing groups, examine the <structname>pg_group</> - system catalog, for example + The members of a role can use the privileges of the group role in two + ways. First, every member of a group can explicitly do + <xref linkend="sql-set-role" endterm="sql-set-role-title"> to + temporarily <quote>become</> the group role. In this state, the + database session has access to the privileges of the group role rather + than the original login role, and any database objects created are + considered owned by the group role not the login role. Second, member + roles that have the <literal>INHERIT</> attribute automatically have use of + privileges of roles they are members of. As an example, suppose we have + done +<programlisting> +CREATE ROLE joe LOGIN INHERIT; +CREATE ROLE admin NOINHERIT; +CREATE ROLE wheel NOINHERIT; +GRANT admin TO joe; +GRANT wheel TO admin; +</programlisting> + Immediately after connecting as role <literal>joe</>, a database + session will have use of privileges granted directly to <literal>joe</> + plus any privileges granted to <literal>admin</>, because <literal>joe</> + <quote>inherits</> <literal>admin</>'s privileges. However, privileges + granted to <literal>wheel</> are not available, because even though + <literal>joe</> is indirectly a member of <literal>wheel</>, the + membership is via <literal>admin</> which has the <literal>NOINHERIT</> + attribute. After +<programlisting> +SET ROLE admin; +</programlisting> + the session would have use of only those privileges granted to + <literal>admin</>, and not those granted to <literal>joe</>. After +<programlisting> +SET ROLE wheel; +</programlisting> + the session would have use of only those privileges granted to + <literal>wheel</>, and not those granted to either <literal>joe</> + or <literal>admin</>. The original privilege state can be restored + with any of +<programlisting> +SET ROLE joe; +SET ROLE NONE; +RESET ROLE; +</programlisting> + </para> + + <note> + <para> + The <command>SET ROLE</> command always allows selecting any role + that the original login role is directly or indirectly a member of. + Thus, in the above example, it is not necessary to become + <literal>admin</> before becoming <literal>wheel</>. + </para> + </note> + + <note> + <para> + In the SQL standard, there is a clear distinction between users and roles, + and users do not automatically inherit privileges while roles do. This + behavior can be obtained in <productname>PostgreSQL</productname> by giving + roles being used as SQL roles the <literal>INHERIT</> attribute, while + giving roles being used as SQL users the <literal>NOINHERIT</> attribute. + However, <productname>PostgreSQL</productname> defaults to giving all roles + the <literal>INHERIT</> attribute, for backwards compatibility with pre-8.1 + releases in which users always had use of permissions granted to groups + they were members of. + </para> + </note> + + <para> + To destroy a group role, use <xref + linkend="sql-droprole" endterm="sql-droprole-title">: <synopsis> -SELECT groname FROM pg_group; +DROP ROLE <replaceable>name</replaceable>; </synopsis> - The <xref linkend="app-psql"> program's <literal>\dg</> meta-command - is also useful for listing the existing groups. + Any memberships in the group role are automatically revoked (but the + member roles are not otherwise affected). Note however that any objects + owned by the group role must first be dropped or reassigned to other + owners; and any permissions granted to the group role must be revoked. </para> </sect1> @@ -256,14 +394,12 @@ SELECT groname FROM pg_group; <primary>REVOKE</primary> </indexterm> - <remark>Being moved to the DDL chapter. Will eventually disappear here.</remark> - <para> When an object is created, it is assigned an owner. The - owner is normally the user that executed the creation statement. + owner is normally the role that executed the creation statement. For most kinds of objects, the initial state is that only the owner (or a superuser) can do anything with the object. To allow - other users to use it, <firstterm>privileges</firstterm> must be + other roles to use it, <firstterm>privileges</firstterm> must be granted. There are several different kinds of privilege: <literal>SELECT</>, <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, @@ -277,25 +413,21 @@ SELECT groname FROM pg_group; <para> To assign privileges, the <command>GRANT</command> command is - used. So, if <literal>joe</literal> is an existing user, and + used. So, if <literal>joe</literal> is an existing role, and <literal>accounts</literal> is an existing table, the privilege to update the table can be granted with <programlisting> GRANT UPDATE ON accounts TO joe; -</programlisting> - To grant a privilege to a group, use -<programlisting> -GRANT SELECT ON accounts TO GROUP staff; </programlisting> The special name <literal>PUBLIC</literal> can - be used to grant a privilege to every user on the system. Writing + be used to grant a privilege to every role on the system. Writing <literal>ALL</literal> in place of a specific privilege specifies that all privileges that apply to the object will be granted. </para> <para> To revoke a privilege, use the fittingly named - <command>REVOKE</command> command: + <xref linkend="sql-revoke" endterm="sql-revoke-title"> command: <programlisting> REVOKE ALL ON accounts FROM PUBLIC; </programlisting> @@ -311,8 +443,10 @@ REVOKE ALL ON accounts FROM PUBLIC; <para> An object can be assigned to a new owner with an <command>ALTER</command> - command of the appropriate kind for the object. Only superusers can do - this. + command of the appropriate kind for the object. Superusers can always do + this; ordinary roles can only do it if they are both the current owner + of the object (or a member of the owning role) and a member of the new + owning role. </para> </sect1> -- GitLab