Přístupová práva

V této kapitole budu popisovat jak se připojit k databázi a jak nastavovat uživatelům práva. Jsou to dvě rozdílné, ale úzce související témata. Tato kapitola není ani tak o jazyku SQL, jako spíše o administraci.

Připojení se k databázi

První problém, který budete řešit po nainstalování Postgresu určitě bude, jak se připojit k databázi a jak si vytvořit nějakého uživatele a pro něj schéma. Teď budu popisovat tu část o tom, jak se mohou uživatelé připojit k databázi. Co to je vlastně uživatel, o tom bude řeč v části O uživatelích, skupinách a rolích. Teď vám jen prozradím, abychom si rozuměli, že v Postgresu se uživatelům i skupinám (uživatelů) souhrně říká role.

Konfigurační soubor pg_hba.conf

Možnosti připojení k DBMS se řídí nastavením v souboru pg_hba.conf. Jeho umístění najdete v konfiguračním souboru postgresql.conf pod volbou pg_hba.conf.

V Debianu jsem našel oba soubory v adresáři /etc/postgresql/9.6/main/, v OpenSuSE pro změnu v /var/lib/pgsql/data/.

Jestli nenajdete konfiguraci ani tam, tak můžete umístění konfiguračního souboru PostgreSQL zjistit SQL příkazem SHOW config_file;.

K těmto konfiguračním souborům bude mít povolený přístup pravděpodobně jen superuživatel (uživatel postgres).

Obsah souboru pg_hba.conf

Soubor pg_hba.conf vypadá docela jednoduše. Obsahuje řádky, kde každý řádek popisuje nějaký způsob přihlášení k databázi. Popisuje, kdo se takto může přihlásit, odkud (podle IP adresy), jestli je vyžadováno heslo … Nejlépe se to asi vysvětlí na příkladu:

local   all             postgres                                peer

Tento řádek říká, že se může k databázi připojit přes unix socket (local), může se připojit ke všem databázím (all), tento přístup je umožněn jen uživateli postgres a jako autentizace se použije jen ověření, že ten kdo se chce přihlásit pod nějakým uživatelským jménem (v tomto případě to může být jenom postgres) má stejné uživatelské jméno v operačním systému (peer).

Socket je speciální soubor, kterým můžete komunikovat s programem, v našem případě s PostgreSQL. Tímto souborem lze komunikovat samozřejmě jen tehdy, pracujete-li na stejném počítači, jako je tento soubor. To platí pro klienta i DBMS, takže to umožňuje jen lokální spojení (klient se připojuje ze stejného počítače na kterém běží DBMS). To je i pro autentizaci typu peer nezbytné.
Spojení přes socket je rychlejší než přes internet pomocí TCP/IP.
Spojení přes socket nefunguje ve Windows!

Takovýto řádek buduete mít určitě v pg_hba.conf a to je přesně důvod, proč si po instalaci zakládáte nové uživatele tak, že se přihlásíte příkazem su jako uživatel postgres a pak se můžete k databázi přihlásit bez zadávání hesla (DBMS díky nastavení peer pouze zkontroluje, že se k ní přihlašuje Linuxový uživatel postgres).

Uživatel postgres má superuživatelská práva (může cokoliv). To jen tak na okraj. A teď na další příklad:

host    all             all             127.0.0.1/32            md5
host    all             all               0.0.0.0/0             md5

Tentokrát se jedná o připojení skrz TCP/IP (host) ke všem databázím (all), pro všechny uživatele (all), z IP adresy 127.0.0.1. Číslo 32 za lomítkem je maska adresy. Na vysvěltování jak funguje TCP/IP tu není dost místa, takže vám jen povím, že 32 vyžaduje, aby připojení přišlo z úplně stejné IP adresy, 24 znamená, že musí odpovídat první 3 části IP adresy a 0 znamená, že nemusí odpovídat žádná část. To je případ té druhé řádky – proto je IP adresa samá nula. Kdybyste tam napsali jakékoliv čísla, je to fuk, protože kvůli masce 0 se prostě ignorují (ale něco tam být naspáno musí).
Autentiakace md5 vyžaduje, aby klient poslal heslo zašifrované algoritmem MD5.

Toto nastavení není jediné, které je potřeba pro připojení z interentu. V souboru postgresql.conf je volba listen_addresses, která určuje z jakých IP adres bude Postgres přijímat připojení. Defaultně je nastavena na localhost, tedy pouze z lokálního počítače. Můžete jí nastavit na *, což znamená, že bude akceptovat připojení odkudkoliv. Dále se už přístup řídí řádky v pg_hba.conf.

Řádka v pg_hba.conf

1) Nejdříve se na řádku určuje způsob připojení:

Typ připojení
typvýznam
localSpojení přes socket
hostSpojení přes internet (TCP/IP). Může být SSL, ale nemusí
hostsslSpojení přes internet (TCP/IP), musí být SSL.
hostnosslSpojení přes internet (TCP/IP), nesmí být SSL.

2) Databáze může být buď konkrétní jméno schématu (nebo schémat oddělených čárkou (ale bez mezery)), nebo all, což znamená libovolnou databázi, nebo samerole, což znamená, že jméno databáze je stejné jako jméno přihlašovaného uživatele, nebo že je uživatel členem role tohoto jména.

3) Uživatel může být buď konkrétní jméno role (nebo rolí oddělených čárkou), nebo all, což znamená, že to platí pro všechny role.
Pokud k jménu role připojíte +, pak se nemusí přihlašovat přímo uživatel tohoto jména, ale každý kdo je přímo nebo nepřímo člen této role (o tom co to znamená bude řeč v části o rolích).

4) Adresa je IP adresa, odkud se může uživatel připojit. Jak může vypadat jsem už popisoval výše. Adresa se samozřejmě nezadává pro spojení local.

5) Způsobů autentizace je mnoho, ty nejdůležitější viz tabulka:

Způzoby autentizace
Název metodyPopis
trust Žádná autentizace není potřeba. To si můžete dovolit například na svém osobním notebooku, ke kterému nemá nikdo jiný přístup.
reject Spojení je odmítnuto. K tomu je dobré vědět, že první „řádek‘, který vyhovuje požadovanému spojení (podle jména databáze, uživatele a případně IP adresy), rozhoduje o tom, jestli se uživatel připojí nebo ne. Pokud je odmítnut, žádný další řádek už se nekontroluje.
md5 Klientský program musí poslat heslo ve formátu md5.
peer Ověří, že připojovaný uživatel má stejné uživatelské jméno v operačním systému. Funguje jen pro připojení local.
ident Podobné jako peer. Funguje ale i pro vzdálené připojení. Uživatelské jméno z operačního systému vzdáleného počítače zjistí kontaktováním „ident serveru“ (co je to za server je nad rámec této kapitoly :-). Pokud použijete ident pro spojení local, použije se ve skutečnosti peer autentizace.

O uživatelích, skupinách a rolích

V PostgreSQL před verzí 8.1 jste si mohli založit uživatele (user) a skupiny (group). Uživatel reprezentoval jednoho člověka, který se mohl připojit k databázi. Uživatel mohl být součástí několika skupin. K jedné skupině mohlo být přiřazeno více uživatelů. Skupina i uživatel mohli mít přidělené (granted) práva k databázovým objektům (tabulkám, pohledům, sekvením atd.).

Od verze 8.1 je v Postgresu tzv. role. Uživatel se stal rolí s právem LOGIN (právo na připojení k databázi). A skupina je naopak jen role bez práva LOGIN.

Ikdyž máte podle souboru pg_hba.conf právo se připojit, zadáte správně heslo a všechno, tak bez práva LOGIN se stejně nepřipojíte. Připojením k databázi totiž projdete autentizací (ověřením kdo jste), ale právo LOGIN je potřeba pro autorizaci (povolení něco udělat, přihlásit se).

CREATE USER / ROLE

Příkaz CREATE USER slouží k vytvoření nového uživatele, který bude moci k databázím přistupovat. Od Postgresu v. 8.1 je to alias pro příkaz CREATE ROLE jmeno_role LOGIN;

Nového uživatele nemůže vytvořit každý, ale pouze ten, kdo k tomu má právo. Po nainstalování PostgreSQL existuje jedinný uživatel, který může vytvářet jiné uživatele, a to uživatel postgres.

Uživatel v PostgreSQL není to samé jako uživatel Linuxu, ačkoliv se jejich schoda někdy využívá k autentizaci (viz peer výše).

Řekněme, že jste právě po čerstvé instalaci Postgresu a tak chcete vytvořit prvního uživatele tohoto systému, uživatele rimmer.

Protože zatím jediný linuxový uživatel, který k tomu má práva, je postgres, musíte se připojit k databázi pod tímto uživatelským kontem. Protože neznáte heslo k linuxovému účtu postgres, musíte se přihlásit pomocí programu su.

$ su -
Password:
root:~# su - postgres
postgres:~$ psql
psql (9.2.4)
Pro získání nápovědy napište "help".
postgres=#

Pokud jste se dostali úspěšně až sem, můžete vytvořit prvního uživatele pomocí příkazu CREATE USER nebo CREATE ROLE.

Při vytváření role můžete určit, jaká systémová práva role má mít.

Systémová práva
Právo Popis
SUPERUSER Superuživatel, který může všechno. To je případ uživatele postgres.
LOGIN Možnost připojit se k databázi.
CREATEDB Možnost vytvořit nové schéma.
CREATEROLE Možnost vytvořit další role, pravovat je i mazat.
PASSWORD 'heslo' Toto není právo, ale heslo, pod kterým se uživatel bude přihlašovat, pokud je vyžadována autentizace heslem (md5). Heslo se zadává nezašifrované.

Teď vytvořím uživatele rimmer s právem vytváření nových databází a uživatelů. Nastavím mu heslo na rimmer (opravdu špatné heslo, ale to jen příklad). Existují 2 způsoby, jak to udělat:

CREATE USER rimmer WITH CREATEDB CREATEUSER PASSWORD 'rimmer';
CREATE ROLE rimmer WITH LOGIN CREATEDB CREATEUSER PASSWORD 'rimmer';

Každý uživatel s právem vytváření dalších uživatelů může neomezeně pracovat s cizími tabulkami (číst je, upravovat, mazat …).

Pokud dáte uživateli právo vytvářet role, má právo i měnit práva rolí (pomocí ALTER ROLE, takže si může sám sobě dát právo vytvářet databáze :-). Alespoň že nemůže měnit superuživatelské účty, na to je potřeba právo SUPERUSER).

Pokud se přihlásíte na počítači jako uživatel stejného jména, budete se nejspíš přihlašovat pomocí peer autentizace, tedy bez nutnosti zadávat heslo. Pokud se ale budete přihlašovat přes síť, bude po vás heslo vyžadováno.

petr> psql -U rimmer
psql: FATAL: Peer authentication failed for user "rimmer"
petr> psql -U rimmer -h 127.0.0.1
psql: FATAL: Ident authentication failed for user "rimmer"
petr> psql -U rimmer -h 192.168.1.10
Heslo pro uživatele rimmer:
psql: FATAL: database "rimmer" does not exist

Jak vidíte, první dva pokusy o přihlášení nevyšly (linuxový uživatel petr se snažil přihlásit jako databázový uživatel rimmer). Třetí pokus už vyžadoval heslo a proběhl úspěšně. Protože jsem ale nevytvořil databázi rimmer, neměl se uživatel kam připojit.

Protože má uživatel právo CREATEROLE, může skoro všechno, takže se může připojit i k libovolné jiné databázi.

petr> psql -U rimmer -h 192.168.1.10 rimmer1
Heslo pro uživatele rimmer:
psql (9.2.4)
Pro získání nápovědy napište "help".
rimmer1=#

Můžete si taky databázi vytvořit příkazem createdb.

petr> createdb -U rimmer -h 192.168.1.10 rimmer
Heslo:

Po správném zadání hesla je databáze vytvořena.

Všimněte si, že když se přihlásíte jako superuživatel (postgres, nebo teď rimmer), prompt není ukončen špičatou závorkou >, ale znakem # (sharp).
Uživatel rimmer totiž získal jakési superuživatelské právo (právo CREATEUSER), díky kterému může nakládat s právy ostatních uživatelů. Hned toho využiju k vytvoření uživatele group06.

petr> psql -U rimmer -h 192.168.1.10 rimmer
Heslo pro uživatele rimmer:
psql (9.2.4)
Pro získání nápovědy napište "help".
rimmer1=# CREATE USER group06;
CREATE ROLE

Seznam existujících rolí můžete získat ze systémové tabulky pg_roles. Kupodivu k tomu nemusíte být superuživatel.

rimmer=# SELECT rolname, rolcanlogin, rolsuper, rolcreaterole, rolcreatedb,
rolinherit FROM pg_roles;
 rolname  | rolcanlogin | rolsuper | rolcreaterole | rolcreatedb | rolinherit
----------+-------------+----------+---------------+-------------+------------
 postgres | t           | t        | t             | t           | t
 petr     | t           | f        | f             | t           | t
 rimmer   | t           | t        | f             | f           | t
 group06  | t           | f        | f             | f           | t
(4 řádky)

Taky můžete použít metapříkaz \du.

ALTER ROLE a DROP ROLE

Příkaz ALTER ROLE slouží ke změně uživatelského účtu postgresu. Jeho použití je stejné jako příkazu CREATE USER.

Příkaz DROP USER uživatelský účet smaže.

rimmer=# ALTER ROLE group06 WITH CREATEDB PASSWORD 'group06';
ALTER USER
rimmer=# DROP USER group06;
DROP USER

Uživatele group06 ještě nemažte, budu ho používat při dalším výkladu.

Pokud byste chtěli práva z role odebrat, pak použijte:

ALTER ROLE group06 WITH NOCREATEDB NOCREATEUSER;

A nakonec zmíním příkaz pro smazání databáze, který už dobře znáte:

petr> dropdb -U rimmer -h 192.168.1.10 rimmer
Heslo:
DROP DATABASE

Skupiny

Každá role může fungovat jako skupina. Obvykle role fungující jako skupiny nemají právo LOGIN, ale jinak se od ostatních uživatelů nijak neliší.

Skupině můžete nastavit práva jako uživateli (uživatel a skupina je přeci to samé – role).

Co je ale důležité, skupina může být přidělena (GRANT) uživateli (nebo jiné skupině) jako by to bylo nějaké právo. Všechny práva přidělené „skupině“ pak může využívat i uživatel.

Pokud má uživatel nastavené právo INHERIT, práva ze skupin jsou ihned aktivní. Pokud toto právno nemá, musí použít příkaz SET ROLE, kterým se přepne do dané role (a má k dispozici pouze práva z této role a žádné jiné).

ALTER ROLE group06 WITH INHERIT;
CREATE ROLE dbadmin WITH CREATEDB;
GRANT dbadmin TO group06;

V příkladu jsem nejdříve nastavil roli group06 právo INHERIT. Pak jsem vytvořil roli dbadmin s právem vytváření databází. Nakonec jsem tuto roli přidělil roli group06, která od této chvíle může vytvářet databáze bez nutnosti použití příkazu SET ROLE dbadmin; (díky INHERIT).

Skupiny se používají k snadnému přidělování/odebírání skupiny práv mnoha uživatelům. Nejde jen o práva, která jsem zmíňil doposud, ale i o další práva, která popíšu hned dále.

O přístupových právech k databázovým objektům

GRANT (přidání přístupových práv)

Příkaz GRANT slouží k přidělování přístupových práv k databázovým objektům. (Nepleťte si slovo grant se slovem grand - to označuje příslušníka vysoké španělské šlechty :-).

Příkazu GRANT se musí říct jaká přístupová práva se přídělují, kterému uživateli se přidělují a k jaké tabulce (databázovému objektu) se tyto práva přidělují.

V předchozí části jsem si vytvořil dva uživatele: rimmer a group06. V příkladu si uživatel rimmer vytvoří tabulku seznam, ke které bude dávat přístupová práva uživateli group06.

-- prihlasen uzivatel rimmer
rimmer=# CREATE TABLE seznam (id SERIAL, nazev VARCHAR(20), cena NUMERIC(5,2));
NOTICE:  CREATE TABLE will create implicit sequence 'seznam_id_seq' for SERIAL
CREATE

Přístupová práva můžete přidávat buďto jedné roli (za druhou), nebo jej zpřístupnit všem uživatelům, když použijete speciální roli PUBLIC.

Pokud předáváte práva konkrétnímu uživateli/roli, musí tento uživatel existovat.

Možnosti příkazu GRANT zjistíte pomocí metapříkazu \h GRANT. Uvidíte, jaká všechna práva je možné přidělovat. Zajímavá je možnost ALL, která přidělí roli všechna práva. Spojením PUBLIC a ALL povolíte všechno všem :-).

V příkladě teď přidělím práva uživateli group06 na čtení (SELECT) tabulky seznam a na vkládání záznamu (INSERT).

Než tak ale učiním, ještě se musím zmínit o jednom důležitém metapříkazu: \z. Tento metapříkaz dokáže vypsat přístupová práva k objektům v databázi. Přístupová práva jsou za jménem uživatele/role, ke které se vztahují, a rovnítkem. Jsou označeny jednopísmennými zkratkami, viz následující tabulka. Z ní se také dozvíte jaká že to práva lze nastavovat.

Zkratka Práva Uživatel může ...
r SELECT ("read") použít příkaz SELECT, a také COPY FROM.
w UPDATE ("write") použít příkaz UPDATE. Toto právo je třeba k použití sekvencí (nextval, currval, setval)
a INSERT ("append") použít příkaz UPDATE, a také COPY TO
d DELETE mazat data příkazem DELETE
D TRUNCATE mazat data příkazem TRUNCATE
x REFERENCES vytvořit novou tabulku s referencí na tuto tabulku
t TRIGGER použít příkaz CREATE TRIGGER
arwdDxt Všechny práva Může všechno víše zmíněné.

Za přístupovými právy je za lomítkem jméno role, která přístupová práva přidělila.

rimmer=# \z
 public | seznam        | tabulka  | rimmer=arwdDxt/rimmer |
 public | seznam_id_seq | sekvence |                       |

rimmer=# GRANT SELECT, INSERT ON seznam TO group06;
GRANT
rimmer=# \z seznam
 public | seznam        | tabulka  | rimmer=arwdDxt/rimmer+|
        |               |          | group06=ar/rimmer     |

Teď se k databázi rimmer přihlásím jako uživatel group06 a pokusím se s tabulkou pracovat.

Znovu upozorňuji, že pokud bude mít uživatel právo vytvářet další uživatele (viz ALTER USER), všechna zde popisovaná přístupová práva se budou míjet účinkem.

-- prihlasen uzivatel group06
rimmer=> SELECT * FROM seznam;
 id | nazev | cena
----+-------+------
(0 rows)
rimmer=> INSERT INTO seznam (nazev,cena) VALUES ('abcd',25.2);
ERROR:  seznam_id_seq.nextval: you don't have permissions to set sequence
seznam_id_seq

To slovíčko rimmer, které je v příkladu, označuje název databáze, nikoliv uživatele.

Vložení záznamu do tabulky selhalo, neboť group06 nemá přístup k sekvenci seznam_id_seq, která se automaticky mění při každém vložení záznamu v tabulce. Uživtel group06 musí dostat právo úpravy k této sekvenci. Teď už to půjde rychle.

-- prihlasen uzivatel rimmer
rimmer=# GRANT UPDATE ON seznam_id_seq TO group06;
GRANT
-- prihlasen uzivatel group06
rimmer=> INSERT INTO seznam (nazev,cena) VALUES ('abcd',25.2);
rimmer=> UPDATE seznam SET cena = 0;
ERROR:  seznam: Permission denied.

Na INSERT group06 právo má, na UPDATE ne. Zkusím ještě nastavení práva úpravy pro všechny.

-- prihlasen uzivatel rimmer
rimmer=# GRANT UPDATE ON seznam TO PUBLIC;
GRANT
rimmer=# \z
                                 Access privileges
 Schema |     Name      |   Type   |   Access privileges   | Column access privileges
--------+---------------+----------+-----------------------+--------------------------
 public | seznam        | table    | rimmer=arwdDxt/rimmer+|
        |               |          | group06=ar/rimmer    +|
        |               |          | =w/rimmer             |
 public | seznam_id_seq | sequence | rimmer=rwU/rimmer    +|
        |               |          | group06=w/rimmer      |
(2 rows)

Právo pro public je to, co začíná rovnítkem, bez názvu role před ním.

-- prihlasen uzivatel group06
rimmer=> UPDATE seznam SET cena = 0;
UPDATE 1

REVOKE (odebrání přístupových práv)

Tak, jak příkaz GRANT slouží k přidělování práv, tak příkaz REVOKE slouží k jejich odnímání.

Je třeba zase určit jaká práva se odebírají, komu se odebírají (uživatel nebo PUBLIC) a k jakému objektu v databázi se to vztahuje.

Všechna práva, která jsem v předchozím oddíle přidělil k tabulce seznam pro uživatele group06 zase odeberu a pak ještě odeberu právo UPDATE pro všechny (pro PUBLIC).

-- prihlasen uzivatel rimmer
rimmer=# REVOKE ALL ON seznam FROM group06;
REVOKE
rimmer=# \z
                                  Access privileges
 Schema |     Name      |   Type   |   Access privileges   | Column access privileges
--------+---------------+----------+-----------------------+--------------------------
 public | seznam        | table    | rimmer=arwdDxt/rimmer+|
        |               |          | =w/rimmer             |
 public | seznam_id_seq | sequence | rimmer=rwU/rimmer    +|
        |               |          | group06=w/rimmer      |
(2 rows)

rimmer=# REVOKE UPDATE ON seznam FROM PUBLIC;
REVOKE
rimmer=# \z
                                 Access privileges
 Schema |     Name      |   Type   |   Access privileges   | Column access privileges
--------+---------------+----------+-----------------------+--------------------------
 public | seznam        | table    | rimmer=arwdDxt/rimmer |
 public | seznam_id_seq | sequence | rimmer=rwU/rimmer    +|
        |               |          | group06=w/rimmer      |

MySQL

V MySQL jsou věci o dost jednoduší. Neexistují žádné skupiny a nedělá se žádný rozdíl mezi připojením na socket nebo přes internet. Uživatel se vždy autentizuje pomocí jména a hesla.

Po instalaci je k dispozici uživatel root (přesněji teda root@localhost, viz dále o uživatelských jménech) který má superuživatelská práva.
Nemá nastavené žádné heslo, takže se může jako root přihlásit kdokoliv, kdo má na počítači uživatelský účet (MySQL neporvádí peer autentizaci).

Jméno se skládá z „username“ a z IP adresy, ze které se může připojit. Část IP adresy na konci může být nahrazena % (procentem), které znamená, že se zbytek IP adresy nekontroluje, že se může připojit odkudkoliv. Pokud použijete jen %, znamená to „libovolná IP adresa“.

Několik příkladů jak můžete vytvořit uživatele v MySQL:

  1. CREATE USER 'rimmer'@'%';
  2. CREATE USER rimmer@%;    -- nefunguje, % neni v uvozovkach
  3. CREATE USER rimmer;
  4. CREATE USER rimmer@192.168.1.%;
  5. CREATE USER rimmer@192.168.% IDENTIFED BY 'heslo';
  6. CREATE USER rimmer@localhost;
  7. CREATE USER rimmer@127.0.0.1;

MySQL příkazy zadávané z klienta mysql se obvykle ukládají do souboru ~/.mysql_history. Takže je tu vážné nebezpečí, že se do tohoto souboru uloží i heslo. Soubor by tedy neměl mít právo číst nikdo jiný než vy.

Příklady na 1 a 3 řádce založí téhož uživatele, se jménem rimmer, který se může připojit odkudkoliv bez zadání hesla. Pátý příklad navíc nastaví uživateli heslo.

Ale pozor! Poslední dva příklady neznamenají to samé. Šestý příklad uživatele se může připojit jen prvním způsobem z následujícího příkladu. 7 uživatel jen tím druhým. Protože 'localhost' a '127.0.0.1' nejsou pro MySQL to samé:

# mysql -u rimmer -h localhost jmeno_databaze
# mysql -u rimmer -h 127.0.0.1 jmeno_databaze

Heslo lze změnit uživateli příkazem SET PASSWORD:

SET PASSWORD FOR 'rimmer'@'192.168.1.%' PASSWORD('heslo');

Existující uživatele zjistíte následujícím příkazem:

SELECT User, Host FROM mysql.user;

Schéma mysql je systémové schéma, které obsahuje různé tabulky a pohledy na data využívané DBMS MySQL.

Smazání uživatele:

DROP USER 'rimmer'@'192.168.1.%';

Nastavování autorizace k databázovým objektům se dělá pomocí příkazů GRANT a REVOKE.

GRANT SELECT ON rimmer1.trest TO 'group06'@'%';
GRANT ALL ON rimmer1.* TO 'rimmer'@'192.168.1.%';
GRANT ALL ON *.* TO 'rimmer2'@'localhost' IDENTIFIED BY 'heslo';
REVOKE ALL ON rimmer1.* FROM 'rimmer'@'192.168.1.%';

Speciální právo ALL znamená, že povolujete všechno. Hvědička (*) znamená „všechny schémata“ nebo „všechny objekty v databázi“ (před tečkou je jméno schématu, za tečkou obvykle jméno tabulky).

Pokud uživatel nexistuje, tak jej příkaz GRANT vytvoří, takže mu můžete (ale nemusíte) příkazem GRANT rovnou nastavit i heslo (viz IDENTIFIED BY 'heslo').

V MySQL můžete zobrazit práva přidělená uživateli takto:

SHOW GRANTS FOR 'group06'@'%';

Se zjištěním nastavených práv pro tabulku je to trochu horší:

mysql> SELECT * FROM tables_priv WHERE Table_name = 'trest';
+------+---------+---------+------------+----------------+---------------------+------------+-------------+
| Host | Db      | User    | Table_name | Grantor        | Timestamp           | Table_priv | Column_priv |
+------+---------+---------+------------+----------------+---------------------+------------+-------------+
| %    | rimmer1 | group06 | trest      | root@localhost | 2014-02-04 19:14:30 | Select     |             |
+------+---------+---------+------------+----------------+---------------------+------------+-------------+
1 row in set (0.00 sec)

Další způsoby zjišťování nastavených práv najdete v článku How to Get a List of Permissions of MySQL Users.

MySQL defaultně poslouchá spojení na všech portech, takže není potřeba nic nastavovat. Kdyby vás to ale přeci jen zajímalo, podívejte se na volbu bind-address.

Konfigurační soubor pro MySQL najdete obvykle v /etc/mysql/my.cnf.

SQLite

V SQLite se žádná přístupová práva neřeší a řešit nebudou. SQLite je minimalistická databáze a řešení práv či uživetelů je jedna z věcí, které záměrně ignoruje. Jediný způsob, jak nastavit nějaká práva je nastavení práv k databázovému souboru, v Linuxu například pomocí příkazu chmod.

Oracle

V Oracle se dělá všechno tak nějak jinak, složitěji. Ale nebuďme na něj zlý, Oracle byl jeden z prvních SQL DBMS a ostatní se mohli z jeho chyb poučit :-)

V Oracle se při vytvoření uživatele vytvoří automaticky i jeho schéma (se stejným jménem jako je jméno uživatele). V Oracle se rozlišuje mezi rolí a uživatelem (není to to samé).

Po instalaci Oracle máte k dispozici roli SYS a schéma SYS. Toto schéma obsahuje tabulky a pohledy, které jsou nezbytné pro běh vlatního DBMS. Role SYS je systémová role, tu byste měli tak nějak ignorovat a nechat jí DBMS na hraní.

Dále máte po instalaci k dispozici uživatele SYSTEM, jehož heslo jste vytvářeli během instalace. Tento uživatel má právo na roli DBA, která umožňuje téměř všechno. Ten kdo má roli DBA je, nebojím se to říct, administrátor.

Další administrativní role, která stojí za zmínku, je SYSDBA. Ta umožňuje věci jako je změna znakové sady databáze pomocí ALTER DATABASE, CREATE DATABASE, DROP DATABASE, spouštět a vypínat DBMS atp. Tuto roli můžete někomu přidělit (viz SET ROLE dále), pokud mu chcete něco z těchto věcí umožnit.

Uživatel se vytvoří příkazem CREATE USER:

-- prihlasen uzivatel SYSTEM
oracle> CREATE USER group06 IDENTIFIED BY group06;
User created.

Tímto příkazem se vytvořil uživatel group06 s heslem group06 a i schéma group06.
Pokus o přihlášení příkazem connect username/passowrd:

oracle> connect group06/group06
 ERROR:
 ORA-01045: user GROUP06 lacks CREATE SESSION privilege; logon denied

Pokus selhal, protože uživatel nemá právo CREATE SESSION. Tak mu ho přidělím:

-- prihlasen uzivatel SYSTEM
oracle> GRANT CREATE SESSION TO group06;

Tak teď už se jako group06 přihlásím. Zkusím vytvořit tabulku:

oracle> connect group06/group06
Connected
oracle> CREATE TABLE pokus (id int);
 create table pokus (id int)
 *
 ERROR at line 1:
 ORA-01031: insufficient privileges

Jak vidíte, uživatel group06 nemá právo na vytvoření tabulky. Nemá vlastně žádná práva, která se mu explicitně nepřiřadí. Takže mu ho přidám:

-- prihlasen uzivatel SYSTEM
oracle> GRANT CREATE TABLE TO group06;
-- prihlasen uzivatel GROUP06
create table pokus (id int);
create table pokus (id int)
*
ERROR at line 1:
ORA-01950: no privileges on tablespace 'SYSTEM'

Co je to tablespace? To je místo, kam se ukládají databázová data. Protože jsem při vytváření uživatele group06 neřekl, do jakého tablespace se mají jeho data ukládat, defaultně se snaží ukládat do tablespace jména SYSTEM.

Tablespace SYSTEM je určené pro systémové věci, takže tam by s uživatelé asi data ukládat neměli. Oracle při instalaci vytvoří automaticky tablespace USERS, který je určený pro uživatele. K tomu se ještě vrátím, teď ukážu příkaz, jak je možné přidělit uživateli nějaké místo v tablespace:

-- prihlasen uzivatel SYSTEM
oracle> ALTER USER group06 QUOTA 50m ON SYSTEM;

Tímto příkazem jsem přidělil uživateli group06 50 MiB prostoru v tablespace SYSTEM. Neomezené množství prostoru se dá nastavit klíčovým slovem UNLIMITED.

-- prihlasen uzivatel GROUP06
oracle> CREATE TABLE pokus (id int);
Table created.
oracle> INSERT INTO pokus VALUES (1);
oracle> DELETE FROM pokus;
 1 row deleted.
oracle> DROP TABLE pokus;
 Table dropped.
oracle> CREATE TABLE pokus (id int);
oracle> CREATE VIEW wpokus AS select * from pokus;
 CREATE VIEW wpokus AS select * from pokus
             *
             ERROR at line 1:
             ORA-01031: insufficient privileges

No vida, stačilo právo CREATE TABLE a už můžete s databází docela slušně pracovat. Nemáte ale právo na práci s pohledy (VIEW).

Zadávat každému novému uživateli všechna možná práva je docela otrava (a rádo se na něco zapomene), proto bude lepší přidělit všechna práva nějaké nové ROLI a pak stačí uživateli přidělit jen tuto roli:

-- prihlasen uzivatel SYSTEM
oracle> CREATE ROLE UserRole;
oracle> GRANT CREATE TABLE, CREATE VIEW, CREATE SEQUENCE, CREATE SESSION, CREATE procedure, CREATE synonym To UserRole;
oracle> GRANT UserRole To group06;
Grant succeeded.

Pokud jste pořád někde přihlášení jako group06, pak se nově nabytá role hned neprojeví. Buď se odhlašte a přihlašte, nebo použijte příkaz SET ROLE.

-- prihlasen uzivatel  GROUP06
oracle> CREATE VIEW wpokus AS select * from pokus;
CREATE VIEW wpokus AS select * from pokus
*
ERROR at line 1:
ORA-01031: insufficient privileges
oracle> SET ROLE UserRole;
oracle> CREATE VIEW wpokus AS select * from pokus;
View created.

Vytváření uživatele lze zjednodušit, s ohledem na předchozí povídání, takto:

-- prihlasen uzivatel SYSTEM
CREATE USER group07 IDENTIFIED BY group07 DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;
GRANT UserRole To group07;
Vzdálené připojení k Oracle

Vzdálené připojení k Oracle v SQL Developeru

K databázi na jiném počítači se můžete připojit (v konzovovém klientovi) příkazem CONNECT. Nastavení v SQL Developeru můžete vidět na obrázku.

oracle> connect username/password@host:port /service_name

Konkrétně třeba:

connect rimmer/rimmer@192.168.1.10:1521 /XE

Nezapomeňte, že váš firewall nesmí blokovat TCP port 1521. XE je service name pro databázi Oracle XE.

Heslo uživatele lze změnit takto:

ALTER USER group06 IDENTIFIED BY tajneHeslo;

Všechny uživatele můžete zjistit následujícím příkazem:

oracle> SELECT * FROM all_users;

USERNAME                       USER_ID    CREATED
------------------------------ ---------- --------
XS$NULL                        2147483638 28.08.11
GROUP06                        50         04.02.14
GROUP07                        51         04.02.14
RIMMER                         49         20.11.13
PETR                           48         31.10.13
APEX_040000                    47         28.08.11
APEX_PUBLIC_USER               45         28.08.11
FLOWS_FILES                    44         28.08.11
HR                             43         28.08.11
MDSYS                          42         28.08.11
ANONYMOUS                      35         28.08.11
XDB                            34         28.08.11
CTXSYS                         32         28.08.11
OUTLN                          9          28.08.11
SYSTEM                         5          28.08.11
SYS                            0          28.08.11

16 rows selected.

Nebo takto:

-- prihlasen uzivatel SYSTEM
oracle> SELECT username,  default_tablespace
FROM dba_users
WHERE username in ('RIMMER','GROUP06','GROUP07');

USERNAME               DEFAULT_TABLESPACE
---------------------- ------------------
GROUP06                SYSTEM
GROUP07                USERS
RIMMER                 USERS

Přidělené role a práva zjistíte takto:

-- prihlasen uzivatel SYSTEM
oracle> SELECT * from DBA_ROLE_PRIVS where GRANTEE = 'GROUP07';
GRANTEE  GRANTED_ROLE ADMIN_OPTION DEFAULT_ROLE
-------- ------------ ------------ ------------
GROUP07  USERROLE     NO           YES

oracle> SELECT * from DBA_TAB_PRIVS where GRANTEE = 'GROUP07';

no rows selected

Uživatel group07 nemá nastavená žádná práva nad konkrétní tabulkou.

Komentář Hlášení chyby
Created: 11.9.2005
Last updated: 15.9.2015
Tato stánka používá ke svému běhu cookies, díky kterým je možné monitorovat, co tu provádíte (ne že bych to bez cookies nezvládl). Také vás tu bude špehovat google analytics. Jestli si myslíte, že je to problém, vypněte si cookies ve vašem prohlížeči, nebo odejděte a už se nevracejte :-). Prohlížením tohoto webu souhlasíte s používáním cookies. Dozvědět se více..