mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	In commit 1ea0c73c2 I added a section to user-manag.sgml about how to drop
roles that own objects; but as pointed out by Stephen Frost, I neglected
that shared objects (databases or tablespaces) may need special treatment.
Fix that.  Back-patch to supported versions, like the previous patch.
		
	
		
			
				
	
	
		
			512 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			512 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
<!-- doc/src/sgml/user-manag.sgml -->
 | 
						|
 | 
						|
<chapter id="user-manag">
 | 
						|
 <title>Database Roles</title>
 | 
						|
 | 
						|
 <para>
 | 
						|
  <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 functions) 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 to use privileges assigned to another role.
 | 
						|
 </para>
 | 
						|
 | 
						|
 <para>
 | 
						|
  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.
 | 
						|
  More information about the effects of role privileges on various
 | 
						|
  database objects can be found in <xref linkend="ddl-priv">.
 | 
						|
 </para>
 | 
						|
 | 
						|
 <sect1 id="database-roles">
 | 
						|
  <title>Database Roles</title>
 | 
						|
 | 
						|
  <indexterm zone="database-roles">
 | 
						|
   <primary>role</primary>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <indexterm zone="database-roles">
 | 
						|
   <primary>user</primary>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <indexterm>
 | 
						|
   <primary>CREATE ROLE</primary>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <indexterm>
 | 
						|
   <primary>DROP ROLE</primary>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <para>
 | 
						|
   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 roles
 | 
						|
   are global across a database cluster installation (and not
 | 
						|
   per individual database). To create a role use the <xref
 | 
						|
   linkend="sql-createrole"> SQL command:
 | 
						|
<synopsis>
 | 
						|
CREATE ROLE <replaceable>name</replaceable>;
 | 
						|
</synopsis>
 | 
						|
   <replaceable>name</replaceable> follows the rules for SQL
 | 
						|
   identifiers: either unadorned without special characters, or
 | 
						|
   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"> command:
 | 
						|
<synopsis>
 | 
						|
DROP ROLE <replaceable>name</replaceable>;
 | 
						|
</synopsis>
 | 
						|
  </para>
 | 
						|
 | 
						|
  <indexterm>
 | 
						|
   <primary>createuser</primary>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <indexterm>
 | 
						|
   <primary>dropuser</primary>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <para>
 | 
						|
   For convenience, the programs <xref linkend="app-createuser">
 | 
						|
   and <xref linkend="app-dropuser"> are provided as wrappers
 | 
						|
   around these SQL commands that can be called from the shell command
 | 
						|
   line:
 | 
						|
<synopsis>
 | 
						|
createuser <replaceable>name</replaceable>
 | 
						|
dropuser <replaceable>name</replaceable>
 | 
						|
</synopsis>
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   To determine the set of existing roles, examine the <structname>pg_roles</>
 | 
						|
   system catalog, for example
 | 
						|
<synopsis>
 | 
						|
SELECT rolname FROM pg_roles;
 | 
						|
</synopsis>
 | 
						|
   The <xref linkend="app-psql"> program's <literal>\du</> meta-command
 | 
						|
   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 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 role will be named
 | 
						|
   <literal>postgres</literal>. In order to create more roles you
 | 
						|
   first have to connect as this initial role.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Every connection to the database server is made using the name of some
 | 
						|
   particular role, and this role determines the initial access privileges for
 | 
						|
   commands issued in 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 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 often convenient to maintain a naming correspondence between
 | 
						|
   roles and operating system users.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   The set of database roles a given client connection can connect as
 | 
						|
   is determined by the client authentication setup, as explained in
 | 
						|
   <xref linkend="client-authentication">. (Thus, a client is not
 | 
						|
   limited to connect as the role matching
 | 
						|
   its operating system user, just as a person's login name
 | 
						|
   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 privileges when setting up
 | 
						|
   a multiuser environment.
 | 
						|
  </para>
 | 
						|
 </sect1>
 | 
						|
 | 
						|
 <sect1 id="role-attributes">
 | 
						|
  <title>Role Attributes</title>
 | 
						|
 | 
						|
   <para>
 | 
						|
    A database role can have a number of attributes that define its
 | 
						|
    privileges and interact with the client authentication system.
 | 
						|
 | 
						|
    <variablelist>
 | 
						|
     <varlistentry>
 | 
						|
      <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
 | 
						|
        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, except the right
 | 
						|
        to log in.  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>
 | 
						|
 | 
						|
     <varlistentry>
 | 
						|
      <term>database creation<indexterm><primary>database</><secondary>privilege to create</></></term>
 | 
						|
      <listitem>
 | 
						|
       <para>
 | 
						|
        A role must be explicitly given permission to create databases
 | 
						|
        (except for superusers, since those bypass all permission
 | 
						|
        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, as well as grant or revoke membership in them.
 | 
						|
        However, to create, alter, drop, or change membership of a
 | 
						|
        superuser role, superuser status is required;
 | 
						|
        <literal>CREATEROLE</> is insufficient for that.
 | 
						|
       </para>
 | 
						|
      </listitem>
 | 
						|
     </varlistentry>
 | 
						|
 | 
						|
     <varlistentry>
 | 
						|
      <term>initiating replication<indexterm><primary>role</><secondary>privilege to initiate replication</></></term>
 | 
						|
      <listitem>
 | 
						|
       <para>
 | 
						|
        A role must explicitly be given permission to initiate streaming
 | 
						|
        replication (except for superusers, since those bypass all permission
 | 
						|
        checks). A role used for streaming replication must
 | 
						|
        have <literal>LOGIN</> permission as well. To create such a role, use
 | 
						|
        <literal>CREATE ROLE <replaceable>name</replaceable> REPLICATION
 | 
						|
        LOGIN</literal>.
 | 
						|
       </para>
 | 
						|
      </listitem>
 | 
						|
     </varlistentry>
 | 
						|
 | 
						|
     <varlistentry>
 | 
						|
      <term>password<indexterm><primary>password</></></term>
 | 
						|
      <listitem>
 | 
						|
       <para>
 | 
						|
        A password is only significant if the client authentication
 | 
						|
        method requires the user to supply a password when connecting
 | 
						|
        to the database. The <option>password</> and
 | 
						|
        <option>md5</> authentication methods
 | 
						|
        make use of passwords. Database passwords are separate from
 | 
						|
        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 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">
 | 
						|
    and <xref linkend="sql-alterrole"> commands for details.
 | 
						|
   </para>
 | 
						|
 | 
						|
  <tip>
 | 
						|
   <para>
 | 
						|
    It is good practice to create a role that has the <literal>CREATEDB</>
 | 
						|
    and <literal>CREATEROLE</> privileges, but is not a superuser, and then
 | 
						|
    use this role for all routine management of databases and roles.  This
 | 
						|
    approach avoids the dangers of operating as a superuser for tasks that
 | 
						|
    do not really require it.
 | 
						|
   </para>
 | 
						|
  </tip>
 | 
						|
 | 
						|
  <para>
 | 
						|
   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 ROLE myname SET enable_indexscan TO off;
 | 
						|
</programlisting>
 | 
						|
   This will save the setting (but not set it immediately).  In
 | 
						|
   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 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="role-membership">
 | 
						|
  <title>Role Membership</title>
 | 
						|
 | 
						|
  <indexterm zone="role-membership">
 | 
						|
   <primary>role</><secondary>membership in</>
 | 
						|
  </indexterm>
 | 
						|
 | 
						|
  <para>
 | 
						|
   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>
 | 
						|
 | 
						|
  <para>
 | 
						|
   To set up a group role, first create the role:
 | 
						|
<synopsis>
 | 
						|
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>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Once the group role exists, you can add and remove members using the
 | 
						|
   <xref linkend="sql-grant"> and
 | 
						|
   <xref linkend="sql-revoke"> commands:
 | 
						|
<synopsis>
 | 
						|
GRANT <replaceable>group_role</replaceable> TO <replaceable>role1</replaceable>, ... ;
 | 
						|
REVOKE <replaceable>group_role</replaceable> FROM <replaceable>role1</replaceable>, ... ;
 | 
						|
</synopsis>
 | 
						|
   You can grant membership to other group roles, too (since there isn't
 | 
						|
   really any distinction between group roles and non-group roles).  The
 | 
						|
   database will not let you set up circular membership loops.  Also,
 | 
						|
   it is not permitted to grant membership in a role to
 | 
						|
   <literal>PUBLIC</literal>.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   The members of a group role can use the privileges of the role in two
 | 
						|
   ways.  First, every member of a group can explicitly do
 | 
						|
   <xref linkend="sql-set-role"> 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 the privileges of roles of which they are members, including any
 | 
						|
   privileges inherited by those roles.
 | 
						|
   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 backward compatibility with pre-8.1
 | 
						|
    releases in which users always had use of permissions granted to groups
 | 
						|
    they were members of.
 | 
						|
   </para>
 | 
						|
  </note>
 | 
						|
 | 
						|
  <para>
 | 
						|
   The role attributes <literal>LOGIN</>, <literal>SUPERUSER</>,
 | 
						|
   <literal>CREATEDB</>, and <literal>CREATEROLE</> can be thought of as
 | 
						|
   special privileges, but they are never inherited as ordinary privileges
 | 
						|
   on database objects are.  You must actually <command>SET ROLE</> to a
 | 
						|
   specific role having one of these attributes in order to make use of
 | 
						|
   the attribute.  Continuing the above example, we might choose to
 | 
						|
   grant <literal>CREATEDB</> and <literal>CREATEROLE</> to the
 | 
						|
   <literal>admin</> role.  Then a session connecting as role <literal>joe</>
 | 
						|
   would not have these privileges immediately, only after doing
 | 
						|
   <command>SET ROLE admin</>.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   To destroy a group role, use <xref
 | 
						|
   linkend="sql-droprole">:
 | 
						|
<synopsis>
 | 
						|
DROP ROLE <replaceable>name</replaceable>;
 | 
						|
</synopsis>
 | 
						|
   Any memberships in the group role are automatically revoked (but the
 | 
						|
   member roles are not otherwise affected).
 | 
						|
  </para>
 | 
						|
 </sect1>
 | 
						|
 | 
						|
 <sect1 id="role-removal">
 | 
						|
  <title>Dropping Roles</title>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Because roles can own database objects and can hold privileges
 | 
						|
   to access other objects, dropping a role is often not just a matter of a
 | 
						|
   quick <xref linkend="sql-droprole">.  Any objects owned by the role must
 | 
						|
   first be dropped or reassigned to other owners; and any permissions
 | 
						|
   granted to the role must be revoked.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Ownership of objects can be transferred one at a time
 | 
						|
   using <command>ALTER</> commands, for example:
 | 
						|
<programlisting>
 | 
						|
ALTER TABLE bobs_table OWNER TO alice;
 | 
						|
</programlisting>
 | 
						|
   Alternatively, the <xref linkend="sql-reassign-owned"> command can be
 | 
						|
   used to reassign ownership of all objects owned by the role-to-be-dropped
 | 
						|
   to a single other role.  Because <command>REASSIGN OWNED</> cannot access
 | 
						|
   objects in other databases, it is necessary to run it in each database
 | 
						|
   that contains objects owned by the role.  (Note that the first
 | 
						|
   such <command>REASSIGN OWNED</> will change the ownership of any
 | 
						|
   shared-across-databases objects, that is databases or tablespaces, that
 | 
						|
   are owned by the role-to-be-dropped.)
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Once any valuable objects have been transferred to new owners, any
 | 
						|
   remaining objects owned by the role-to-be-dropped can be dropped with
 | 
						|
   the <xref linkend="sql-drop-owned"> command.  Again, this command cannot
 | 
						|
   access objects in other databases, so it is necessary to run it in each
 | 
						|
   database that contains objects owned by the role.  Also, <command>DROP
 | 
						|
   OWNED</> will not drop entire databases or tablespaces, so it is
 | 
						|
   necessary to do that manually if the role owns any databases or
 | 
						|
   tablespaces that have not been transferred to new owners.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   <command>DROP OWNED</> also takes care of removing any privileges granted
 | 
						|
   to the target role for objects that do not belong to it.
 | 
						|
   Because <command>REASSIGN OWNED</> does not touch such objects, it's
 | 
						|
   typically necessary to run both <command>REASSIGN OWNED</>
 | 
						|
   and <command>DROP OWNED</> (in that order!) to fully remove the
 | 
						|
   dependencies of a role to be dropped.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   In short then, the most general recipe for removing a role that has been
 | 
						|
   used to own objects is:
 | 
						|
  </para>
 | 
						|
<programlisting>
 | 
						|
REASSIGN OWNED BY doomed_role TO successor_role;
 | 
						|
DROP OWNED BY doomed_role;
 | 
						|
-- repeat the above commands in each database of the cluster
 | 
						|
DROP ROLE doomed_role;
 | 
						|
</programlisting>
 | 
						|
 | 
						|
  <para>
 | 
						|
   When not all owned objects are to be transferred to the same successor
 | 
						|
   owner, it's best to handle the exceptions manually and then perform
 | 
						|
   the above steps to mop up.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   If <command>DROP ROLE</> is attempted while dependent objects still
 | 
						|
   remain, it will issue messages identifying which objects need to be
 | 
						|
   reassigned or dropped.
 | 
						|
  </para>
 | 
						|
 </sect1>
 | 
						|
 | 
						|
 <sect1 id="perm-functions">
 | 
						|
  <title>Function and Trigger Security</title>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Functions and triggers allow users to insert code into the backend
 | 
						|
   server that other users might execute unintentionally. Hence, both
 | 
						|
   mechanisms permit users to <quote>Trojan horse</quote>
 | 
						|
   others with relative ease. The only real protection is tight
 | 
						|
   control over who can define functions.
 | 
						|
  </para>
 | 
						|
 | 
						|
  <para>
 | 
						|
   Functions run inside the backend
 | 
						|
   server process with the operating system permissions of the
 | 
						|
   database server daemon.  If the programming language
 | 
						|
   used for the function allows unchecked memory accesses, it is
 | 
						|
   possible to change the server's internal data structures.
 | 
						|
   Hence, among many other things, such functions can circumvent any
 | 
						|
   system access controls.  Function languages that allow such access
 | 
						|
   are considered <quote>untrusted</>, and
 | 
						|
   <productname>PostgreSQL</productname> allows only superusers to
 | 
						|
   create functions written in those languages.
 | 
						|
  </para>
 | 
						|
 </sect1>
 | 
						|
 | 
						|
</chapter>
 |