What is a postgres superuser - sql

I couldn't find the answer in the docs, what exactly is a superuser in postgres?
Does the superuser have all privileges? Is it per database? Per instance?

https://www.postgresql.org/docs/current/static/sql-createrole.html
These clauses determine whether the new role is a "superuser", who can
override all access restrictions within the database.
yes - all privileges in all databases on the specified cluster

A superuser in PostgreSQL is a user who bypasses all permission checks.
Superusers can run commands that can destabilize or crash the database server (e.g., create C functions) and access the operating system.

Superuser is per database. From manual:
SUPERUSER
NOSUPERUSER
These clauses determine whether the new role is a "superuser", who can override all access restrictions within the database. Superuser status is dangerous and should be used only when really needed. You must yourself be a superuser to create a new superuser. If not specified, NOSUPERUSER is the default.
The superuser role bypasses all permission checks.
The term "cluster" in PostgreSQL is a historical and it is un-related to the PostgreSQL command CLUSTER, which is about organizing tables - you set user per-database, not per-cluster. A cluster is created when PostgreSQL is installed. The installation will usually do initdb - it will create a new cluster with one database in for you. Cluster is just data dir with databases inside. For location of that data dir look into manual.

Related

Granting a user access to all databases in Postgres cluster

I have only seen examples of SQL statements granting users access to one database in a Postgres cluster at a time. Is there a way to grant a non-superuser access to all databases and their tables including future databases that get created in the cluster?
Since PostgreSQL v14, this is fairly easy, and you can use the following SQL script:
-- exempt the user from row level security
ALTER ROLE seeall BYPASSRLS;
-- allow the user to read all data
GRANT read_all_data TO seeall;
If you want write access as well, there is also a predefined role pg_write_all_data.
This relies on the fact that by default, everybody has the CONNECT privilege on databases. Of course you also have to configure pg_hba.conf to allow access.
And in case you wonder: no, before v14 you have to grant access to all objects individually. Group roles help with that.

What is the difference between roles and privlages

Would every user who uses my database have a role? Is it more administrators who will have roles, people who need access to all the tables?
Also, I am unable to offer table-level privileges to a role and offer that to a user.. it just won't work. I have to offer the privileges directly onto the user for them to work. Is that normal? Should I be able to offer table-level privileges to a role or do I have to manually offer each of my users the table level privileges?
Would every user who uses my database have a role?
That depends on how you (or, should I rather say, DBA) set it up.
Quite a long time ago, say until Oracle 8i, there were 2 very popular roles: connect and resource so when DBA created a new user, they simply ran
grant connect, resource to new_user;
and the new_user was ready to go as those roles provided most needed privileges such as create session, create table or create view (check documentation for more info about those predefined roles).
However, it turned out that not everyone should be granted e.g. create cluster (which is one of connect's privileges) so nowadays you should create your own roles, if you want - then grant certain privileges to those roles and, finally, grant roles to your users.
Another option is to keep .sql scripts for each of your users. That script should contain list of privileges granted to those users, separately, which means that you shouldn't granted anyone privilege they don't really need.
I am unable to offer table-level privileges to a role and offer that to a user. it just won't work. I have to offer the privileges directly onto the user for them to work. Is that normal?
It works, but not everywhere. Those privileges (the ones granted via roles) won't work in named PL/SQL procedures (i.e. stored procedures, functions, packages). If you have to use those tables in them, yes - you have to grant privileges directly to each of those users.
As opposed to named PL/SQL procedures, privileges granted via roles will work in anonymous PL/SQL blocks or at SQL level.
If you're wondering why would you use roles at all, then, the answer is my first sentence: it depends.

Create user that has permission only to given database

I'm trying to create users in MarkLogic that have permissions to given databases. I read Security Guide from MarkLogic docs page and found that you can set permissions on given URIs, Collections or functions.
Permissions on collections can help me with marking given collections from database as readable only for given set of users, but still other users can create and modify documents in different collections (or create documents without collections).
For e.g.
I have two databases:
Test
Test2
And two users:
UserTest
UserTest2
How can I set permissions that UserTest will have permissions read/update/insert/execute on database Test and can't modify or read anything database Test2?
Each database can be associated with a dedicated security database. The way you describe your use case ("UserTest will have permissions read/update/insert/execute on database Test and can't modify or read anything database Test2"), you might want to consider dedicated security databases for the Test and Test2 databases.
The other way would be to use different document permissions for roles for the two databases. You can set read/update/insert/execute permissions at document level for a given role at insert time, or change them with xdmp:document-add-permissions() (retains previous permissions) or xdmp:document-set-permissions() (overrides previous permissions) after insert. For instance, you could have a role Test-Reader for database Test and a role Test2-Reader for database Test2, and ensure that (1) your UserTest user has the Test-Reader role (but not the Test2-Reader role), and (2) that all documents inserted into the Test database pair the read capability with the Test-Reader role (but not the Test2-Reader role) etc. (Same for the other capabilities.)
If controlling this explicitly sounds like a lot of work, note that default document permissions can be declared to apply implicitly both at the user and at the role level.
Finally, if you set no permissions at all during document insert (and if no implicit/default permissions are defined at user or role level), only users with the admin role can read/update/insert/execute.
Here's the relevant section for document permissions from the Understanding and Using Security Guide: https://docs.marklogic.com/guide/security/permissions#id_85471
There is no user-level specifications for a database. But keep in mind, a database is not accessible on its own - it is accessible by way of an application(s) which is linked to particular database. Unless you allow people to run eval and allow them to eval against another database, then you application will keep people within the specified database. (Note: ML8 Advanced HTTP server changes this a bit because you can switch database on-the-fly per request- but the rules about being stuck to a single database still stands).
The only other item I think is useful to you is the ability to define which URI prefixes a user can write to, but that does not negate the fact that the application level decided which DB is being accessed.

Basic PostgreSQL Questions - Do I need another user?

I installed postgreSQL by default with apt-get and I believe it has automatically added a user for me called "postgres".
I only have one database that I want to sort on postgres, so is
there any point creating another user account for this database or
should I just keep with the one which is installed with postgreSQL
"postgres"?
The user account postgres which is made for me, is it given some
kind of default password? Is it recommended that I put in my own
password?
EDIT: I misinterpreted the question, the OP is asking about internal users, not system users
Original Answer: System users for running servers
Most services running on a linux box are given their own independent user, as a standard security practice. In the off-chance that the postgreSQL server was compromised -- either you made a mistake, or there was a vulnerability in postgresql, or whatever -- the attacker can only gain access to the resources allowed to the user running the postgresql server. If that user is root, you lose the machine. If that user is your user, you lose not quite as much. If that user is postgres, which only has minimal access to anything.. you lose the database, and that's all.
So:
You merely need a single user for the postgreSQL server, regardless of what, exactly, that server process is hosting. If (it sounds like one was) a user was created for you automatically, you're all set with this step. If you need to make one manually (sounds like you don't), you would also have to change the permissions so that the new user can access only what it needs to.
That account very possibly cannot be directly logged into; if it has a password at all it's a lot of random data. In order to use the account, you need to start out as root, and then voluntarily "downgrade" yourself to postgres. In the case of the server, root starts the server "under the name of" postgres. I would advise leaving it alone.
Second Answer: Database users
Once you have a server running, the server will keep its own set of users, for the purposes of accessing the database. The simplest architecture you could use there is just having a base user with full permissions do everything. While this works, it is not advised if you are hosting this externally. A more preferable solution is to have a set of users, similar to how the OS is set up: a bunch of users to do specific tasks, and one admin user to rule them all. That said:
You don't have to, but if you are going to host this anywhere (if you're not just using it for personal things, and it's world-accessible), I would advise extra users with limited permissions.
http://archives.postgresql.org/pgsql-admin/2001-10/msg00192.php
There is no password by default; create one with ALTER USER.
Passwords do not take effect unless pg_hba.conf is set up to use them. If
it is, and you have not assigned a password to postgres, you will not be
able to connect as postgres.
re 1)
the default database user that is created during installation is a "superuser" and for the same reason you should not do your daily work as "root", you shouldn't work with a superuser in a DBMS. So the answer is a clear: yes, do create a second user. You can grant that role all privileges on the default database (also called postgres), so that you don't need a second database.
More details on how to create a user and how to grant privileges can be found in the manual:
http://www.postgresql.org/docs/current/static/sql-createuser.html
http://www.postgresql.org/docs/current/static/sql-grant.html
re 2)
I don't know Linux that well, but usually you should have been asked for a password during installation. At some point in the installation a new data directory is initialized using the command initdb which requires a password to run.
If you don't know the password, you log into the postgres linux account, then you can probably run psql without specifying a password. That enables you to reset the database password and create a new user.
More details about users and authentication are in the manual:
http://www.postgresql.org/docs/current/static/client-authentication.html
http://www.postgresql.org/docs/current/static/user-manag.html

Problems with createdb in postgres

I have to run a simulation with several postgresql databases spread on different machines which all of them are running linux.
I successfully compiled and built postgresql from the source code and I can also run the server, but when I try to create a new db with this command:
./postgresql/bin/createdb db1
I get this error:
createdb: could not connect to database postgres: FATAL: role "giulio" does not exist
where giulio is my username to access all the machines.
On some machine it works while on other it does not. I really cannot figure out the root of the problem. I suppose it is something related with the access control of postgres.
I did several research on google but I was not able to found and to solve the problem.
Does anyone know how to get this work?
Thanks,
-Giulio
PostgreSQL has its own users and roles that are separate from that of your OS. Generally there is a dedicated super user, postgres. For user management info, look here:
http://www.postgresql.org/docs/9.1/interactive/user-manag.html
When executing postgres commands, you need to specify the user with the -U flag (unless you are already logged in as an existing db user). When you called the createdb script, because you didn't use the -U flag, the server assumed that the uid of the caller (giulo) should be used, but you didn't add a user "giulio" to the db, and hence the error message.
So execute the command as
./postgresql/bin/createdb -U postgres db1
and it should work. Then, later on, you may want to create other users and roles in your db rather than doing everything as the superuser.
I would assume that on the machines where the user "giulio" is already known, you executed initdb with exactly this user making him the DB superuser. A quote from inidb(1) (emphasis mine):
--username=username
Selects the user name of the database superuser. This defaults
to the name of the effective user running initdb. It is really
not important what the superuser's name is, but one might choose
to keep the customary name postgres, even if the operating sys‐
tem user's name is different.
On the other machines I assume you did execute initdb with another user, hopefully using postgres.
In order to get back on the standard track I propose, that you delete the database cluster on the machines where "giulio" is the superuser and setup a new database cluster using the standard postgres user. Then add another user "giulio". This will avoid more confusion down the road as some scripts/programs expect a superuser account named postgres.
My answer was more simple...I realized I needed to just run the following:
brew install postgresql
then to check if it worked I ran:
which createdb
to check the file path and if it worked, and it had ! Hope this helps.