The backslash commands in psql are shortcuts for a query or queries that look through the system catalogs. The \l
command looks at information in pg_catalog.pg_database
, specifically, this query:
SELECT d.datname as "Name",
pg_catalog.pg_get_userbyid(d.datdba) as "Owner",
pg_catalog.pg_encoding_to_char(d.encoding) as "Encoding",
d.datcollate as "Collate",
d.datctype as "Ctype",
pg_catalog.array_to_string(d.datacl, E'\n') AS "Access privileges"
FROM pg_catalog.pg_database d
ORDER BY 1;
You can make psql
show what it is using for the backslash commands by passing the -E
flag to it when you invoke it on the command line.
If the permissions on a database or other object are the defaults that PostgreSQL creates them with, the *acl
column will be NULL
. If you change the defaults, as you have, the ACL column will be populated with information related to the GRANT
and/or REVOKE
statements you have ran.
You can see the permissions/ACLs specifically via either \z
or \dp
If you read further here:
http://www.postgresql.org/docs/9.4/static/sql-grant.html
If you scroll down, (or search for the word psql
), you can look at the table that shows you how to interpret the ACLs that you see with \l
or in an ACL column.
For example:
=Tc/vagrant
means that PUBLIC (the implicit role that contains all roles) has permissions to create temporary tables T
and connect c
, because the ACL line =xxxxx
denotes permissions applied to PUBLIC, while rolname=xxxx
applies to that specific role.
This presentation from Dalibo should also help clarify this further: Managing Rights in PostgreSQL
Hope that helps. =)
At the SQL level you can't, since all those tasks are governed by table ownership.
The CREATE
on a tablespace is required but not sufficient to create an index on a table and store the index in that tablespace. If you don't have the CREATE
right on the tablespace you want to put the index in then you cannot CREATE INDEX
that index. However, having that right is not enough; otherwise anybody could create indexes on any table if they had the right to create anything in any tablespace, and we don't want that. Indexes have a performance cost, take heavy locks during creation, and perhaps most importantly an expression index can leak data about the table via a malicious function or operator. So you must also own the table the index is to be created on.
Support for a separate INDEX
right on a table could be added to PostgreSQL, but has not been, and might not get accepted if submitted. For now, you're stuck with having to own the table.
You could write a C extension that installs a ProcessUtility_hook
that checks what operations are being performed and the current user identity, then rejects or permits them as appropriate. You can find examples of ProcessUtility_hook
use in contrib/sepgsql
and externally in the bdr_commandfilter.c
file in the BDR project source code. You have to compile the extension, install it into the file system, then add it to shared_preload_libraries
to install it, so you need full filesystem level access to the server, and usually root access.
A more practical approach is to use a SECURITY DEFINER
function as a wrapper. Write a PL/PgSQL function that runs as the table owner and accepts as arguments the table to index, the column(s) to index, etc. Have it create the CREATE INDEX
expression using format(...)
then pass it to EXECUTE
. Do not allow the user to pass arbitrary SQL expressions as arguments, or you're basically giving them full access via SQL injection. Want multiple columns? You'll have to accept colname text[]
as an argument and quote_ident
each one. And so on. Search for "dynamic SQL plpgsql" to learn more about this approach.
Best Answer
Superusers are always exempt from lowly permission checks. The documentation:
To see whether your current user is a superuser:
To list all superuser roles:
And the schema owner can do it, too. The documentation for
DROP TABLE
:To list schema-owners:
About the same as
\dn
in psql.And who are you?