POSIX ACL

A Unix/Linux szerverek üzemeltetése wikiből
(Változatok közti eltérés)
(valóságközelibb példák)
(Az ACL-ek felépítése és működése: a linux viselkedése bug)
 
(egy szerkesztő 19 közbeeső változata nincs mutatva)
1. sor: 1. sor:
Írta: Tevesz Ágnes, 2009. december.
+
Írta: Tevesz Ágnes és Korn András, 2009. december. Utolsó jelentős módosítás: 2012. november.
   
 
A POSIX ACL (hozzáférés-vezérlési listák) a hagyományos unixos fájlrendszer-jogosultságrendszer kiterjesztése. Olyan jogosultság-konstrukciók is leírhatók a segítségével, amelyek a hagyományos jogosultságrendszerrel nem: pl. hogy egy adott fájlt egy csoport tagjai írhassák és olvashassák, egy másik csoport tagjai csak olvashassák, a többiek pedig se ne írhassák, se ne olvashassák.
 
A POSIX ACL (hozzáférés-vezérlési listák) a hagyományos unixos fájlrendszer-jogosultságrendszer kiterjesztése. Olyan jogosultság-konstrukciók is leírhatók a segítségével, amelyek a hagyományos jogosultságrendszerrel nem: pl. hogy egy adott fájlt egy csoport tagjai írhassák és olvashassák, egy másik csoport tagjai csak olvashassák, a többiek pedig se ne írhassák, se ne olvashassák.
5. sor: 5. sor:
 
== Bevezetés ==
 
== Bevezetés ==
   
Azok a rendszerek, amelyek támogatják/megvalósítják a POSIX- szabványokat (Portable Operating System Interface), általában egy egyszerű, de hatékony fájl-jogosultsági modellt használnak. Minden fájlhoz három jogosultsághalmaz tartozik: külön megadható, milyen jogai legyenek a fájl tulajdonosának, a fájlt birtokló csoportnak és rajtuk kívül mindenk másnak. A három jogosultsághalmaz három-három bitből áll: ezek az olvasás (r), az írás (w) és végrehajtás (x) jogát reprezentálják. Az így kapott jogokat, minden fájl illetve könyvtár esetében, kilenc biten tudjuk tárolni. Megadható ezen felül a ''felhasználói azonosító beállítása'' (set user id), a ''csoportazonosító beállítása'' (set group id) és a ''ragadós'' (sticky) bit is.
+
Azok a rendszerek, amelyek támogatják/megvalósítják a POSIX-szabványokat (Portable Operating System Interface), általában egy egyszerű, de hatékony [[Tervezői_döntések_a_Unixban#A_f.C3.A1jlok_jogosults.C3.A1grendszere|fájl-jogosultsági modell]]t használnak. Minden fájlhoz három jogosultsághalmaz tartozik: külön megadható, milyen jogai legyenek a fájl tulajdonosának, a fájlt birtokló csoportnak és rajtuk kívül mindenk másnak. A három jogosultsághalmaz három-három bitből áll: ezek az olvasás (r), az írás (w) és végrehajtás (x) jogát reprezentálják. Az így kapott jogokat, minden fájl illetve könyvtár esetében, kilenc biten tudjuk tárolni. Megadható ezen felül a ''felhasználói azonosító beállítása'' (set user id), a ''csoportazonosító beállítása'' (set group id) és a ''ragadós'' (sticky) bit is.
   
Az összetett feladatok ellátására ez a modell nem biztosított elég lehetőséget, ezért indították a POSIX 1003.1e fejlesztését és így született meg az ACL (Access Control List) szabványtervezet, amely azonban sosem vált szabvánnyá és már valószínűleg nem is fog. A jövő útja valószínűleg az [http://www.suse.de/~agruen/nfs4acl/ NFSv4 ACL]-eké, de ezeket jelen sorok írásakor csak a szabad unix-féleségek közül csak a [http://en.wikipedia.org/wiki/Access_control_list#Filesystem_ACLs FreeBSD és az OpenSolaris támogatja], míg az 1003.1e szerinti ACL-eket a Linux is; ráadásul a megvalósítás kiforrottnak tekinthető, és a felhasználói programok oldaláról is megvan a szükséges támogatás, úgyhogy még érdemes ezzel az ACL-rendszerrel foglalkozni.
+
Az összetett feladatok ellátására ez a modell nem biztosított elég lehetőséget, ezért indították a POSIX 1003.1e fejlesztését és így született meg az ACL (Access Control List) szabványtervezet, amely azonban sosem vált szabvánnyá és már valószínűleg nem is fog. A jövő útja valószínűleg az [http://wiki.linux-nfs.org/wiki/index.php/ACLs NFSv4 ACL]-eké, de ezeket jelen sorok írásakor (2009. végén) a szabad unix-féleségek közül csak a [http://en.wikipedia.org/wiki/Access_control_list#Filesystem_ACLs FreeBSD és az IllumOS támogatja], míg az 1003.1e szerinti ACL-eket a Linux is; ráadásul a megvalósítás kiforrottnak tekinthető, és a felhasználói programok oldaláról is megvan a szükséges támogatás, úgyhogy még érdemes ezzel az ACL-rendszerrel foglalkozni. (Egy némileg [http://www.suse.de/~agruen/nfs4acl/ elavult NFSv4 ACL patch létezik Linuxhoz is]; ennek a fejlesztése "[http://www.bestbits.at/richacl/ Richacl]" néven folytatódik.)
   
 
== Az ACL-ek felépítése és működése ==
 
== Az ACL-ek felépítése és működése ==
   
Egy ACL bejegyzések sokaságából épül fel (ACE). Egy ACL-bejegyzés három információt tartalmaz:
+
Egy ACL bejegyzések sokaságából épül fel (ACE, access control entry). Egy ACL-bejegyzés három információt tartalmaz:
   
 
* A bejegyzés típusa. A következő típusok léteznek (zárójelben a típusok kódja -- a későbbiekben a rövidség érdekében gyakran a kóddal fogok hivatkozni a bejegyzéstípusokra):
 
* A bejegyzés típusa. A következő típusok léteznek (zárójelben a típusok kódja -- a későbbiekben a rövidség érdekében gyakran a kóddal fogok hivatkozni a bejegyzéstípusokra):
65. sor: 65. sor:
 
Minden ACL kötelezően tartalmaz egy USER_OBJ, egy GROUP_OBJ és egy OTHER típusú bejegyzést. Azokat az ACL-eket, amelyek ezen a három bithármason kívül további elemeket is tartalmaznak, kiterjesztett vagy bővített ACL-eknek hívjuk. Ezek tartalmaznak egy ''mask'' bejegyzést illetve megnevezett felhasználókat és csoportokat is. Más szavakkal: ha egy ACL-ben szerepel GROUP vagy USER típusú (tehát konkrét felhasználóra vagy konkrét csoportra vonatkozó) bejegyzés, akkor kötelezően tartalmaz egy MASK típusú bejegyzést is; a MASK bejegyzés minden egyéb esetben opcionális.
 
Minden ACL kötelezően tartalmaz egy USER_OBJ, egy GROUP_OBJ és egy OTHER típusú bejegyzést. Azokat az ACL-eket, amelyek ezen a három bithármason kívül további elemeket is tartalmaznak, kiterjesztett vagy bővített ACL-eknek hívjuk. Ezek tartalmaznak egy ''mask'' bejegyzést illetve megnevezett felhasználókat és csoportokat is. Más szavakkal: ha egy ACL-ben szerepel GROUP vagy USER típusú (tehát konkrét felhasználóra vagy konkrét csoportra vonatkozó) bejegyzés, akkor kötelezően tartalmaz egy MASK típusú bejegyzést is; a MASK bejegyzés minden egyéb esetben opcionális.
   
A maszk a jogosultságok elbírálásakor jut szerephez. Ha egy processz megpróbál megnyitni egy olyan fájlt amelyhez bővített ACL tartozik, egy jogosultságvizsgáló algoritmus fut le, amelynek a működése a következőképpen foglalható össze:
+
A maszk a jogosultságok elbírálásakor jut szerephez. Ha egy processz megpróbál megnyitni egy olyan fájlt, amelyhez bővített ACL tartozik, egy jogosultságvizsgáló algoritmus fut le, amelynek a működése a következőképpen foglalható össze:
   
 
# Ha a processz effektív UID-ja megegyezik a fájl tulajdonosáéval, akkor a USER_OBJ bejegyzésben megadott jogosultságbitek az érvényesek.
 
# Ha a processz effektív UID-ja megegyezik a fájl tulajdonosáéval, akkor a USER_OBJ bejegyzésben megadott jogosultságbitek az érvényesek.
# Ha nem egyezik, és van a processz effektív UID-jára vonatkozó USER típusú ACL-bejegyzés, az ebben szereplő jogosultságbitek az irányadóak.
+
# Ha nem egyezik, és van a processz effektív UID-jára vonatkozó USER típusú ACL-bejegyzés, az ebben szereplő jogosultságbitek és a maszk ÉS kapcsolata az irányadó, kivéve, ha a maszk üres ("---"), mert akkor az OTHER bejegyzés az irányadó.
# Ha nincs ilyen bejegyzés, és a processz effektív GID-ja megegyezik a fájl tulajdonoscsoportjával, akkor a GROUP_OBJ bejegyzésben megadott jogosultságbitek az irányadóak.
+
#* Ez azt jelenti, hogy az OTHER-ben beállított engedélyek felülírhatják a nevesített user ACL-ekben levő tiltásokat!
# Ha nem egyezik meg, akkor a processz effektív GID-jára és kiegészítő csoportjaira vonatkozó ACL-bejegyzésekben megadott jogosultságokat VAGY kapcsolatba hozzuk egymással, az eredményt pedig ÉS kapcsolatba hozzuk a maszkkal. Az így kapott jogosultságbiteket tekintjük irányadónak; ha ezek lehetővé teszik a fájl megnyitását, akkor az sikerül, ha nem, akkor nem.
+
# Ha nincs ilyen bejegyzés, és a processz effektív GID-ja megegyezik a fájl tulajdonoscsoportjával, akkor a GROUP_OBJ bejegyzésben megadott jogosultságbitek az irányadóak. A maszk nem jut szerephez.
  +
# Ha nem egyezik meg, akkor, ha a maszk nem üres, a processz effektív GID-jára és kiegészítő csoportjaira vonatkozó ACL-bejegyzésekben megadott jogosultságokat VAGY kapcsolatba hozzuk egymással, az eredményt ÉS kapcsolatba hozzuk a maszkkal, és így kapott jogosultságbiteket tekintjük irányadónak; ha ezek lehetővé teszik a fájl megnyitását, akkor az sikerül, ha nem, akkor nem.
  +
# Ha a maszk üres volt, akkor az OTHER-ben levő jogosultságbitek az irányadóak.
  +
#* Vagyis: az OTHER-ben megadott engedély megint erősebb, mint bármiféle tiltás!
 
# Ha nincs ilyen ACL-bejegyzés, akkor az OTHER típusú bejegyzésben szereplő jogosultságbitek jutnak érvényre.
 
# Ha nincs ilyen ACL-bejegyzés, akkor az OTHER típusú bejegyzésben szereplő jogosultságbitek jutnak érvényre.
   
Vegyük észre, hogy ez azt jelenti, hogy az azonos típusú ACL-bejegyzések közül az engedélyezők "erősebbek" a tiltóknál.
+
Vegyük észre, hogy ez azt jelenti, hogy az azonos típusú ACL-bejegyzések közül az engedélyezők "erősebbek" a tiltóknál, az OTHER-ben megadott engedélyek pedig üres maszk esetén "mindent visznek", kivéve, ha az effektiv UID ill. GID egyezik a tulajdonossal ill. tulajdonoscsoporttal. Intuitív, ugye? :) (Ez valószínűleg bug a Linuxban; a Solaris 9 üres maszk esetén is "helyesen" viselkedik. Ha lesz időm, jelentem, hátha megjavítják.)
   
 
Megjegyzés: az itt leírt algoritmus az, amelyet a Linux ténylegesen megvalósítani látszik; az <tt>acl(5)</tt> manpage által leírt algoritmus nem pontosan ez. Nem világos, hogy az implementáció vagy a dokumentáció hibás.
 
Megjegyzés: az itt leírt algoritmus az, amelyet a Linux ténylegesen megvalósítani látszik; az <tt>acl(5)</tt> manpage által leírt algoritmus nem pontosan ez. Nem világos, hogy az implementáció vagy a dokumentáció hibás.
84. sor: 84. sor:
 
!Jogok
 
!Jogok
 
|-
 
|-
|konkrét felhasználó
+
|konkrét csoport
|user:név:rw-
+
|group:név:r-x
 
|r-x
 
|r-x
 
|-
 
|-
97. sor: 97. sor:
 
|}
 
|}
   
Ha valamilyen hagyományos, tehát ACL-eket nem támogató eszközzel kérdezzük le egy fájl jogosultságbitjeit, valahogyan meg kell bennük jeleníteni az ACL által reprezentált jogokat is; tehát szükségünk van egy leképezésre, ami az ACL tartalmát hagyományos unixos jogosultságbitekre képezi le. Egy ilyen leképezés természetesen nem lehet bijekció, hiszen az ACL-nek nagyobb a kifejezőereje, mint a jogosultságbiteknek; de egyértelmű azért lehet. A következő megoldást találták ki:
+
=== ACL leképezése hagyományos jogosultságbitekre ===
  +
  +
Ha valamilyen hagyományos, tehát ACL-eket nem támogató eszközzel kérdezzük le egy fájl jogosultságbitjeit, valahogyan meg kell bennük jeleníteni az ACL által reprezentált jogokat is; tehát szükségünk van egy leképezésre, ami az ACL tartalmát hagyományos unixos jogosultságbitekre képezi le. Egy ilyen leképezés természetesen nem lehet bijekció, hiszen az ACL-nek nagyobb a kifejezőereje, mint a jogosultságbiteknek; de egyértelmű azért lehet.
  +
  +
<small>Ha fontos lenne, hogy a programok a lekérdezett jogosultságbitek alapján maguk is eldönthessék, van-e joguk írni vagy olvasni egy fájlt, akkor a leképezésnek "személyre szabottnak" kellene lennie, tehát a futó processz EUID-ja, EGID-ja és csoporttagságai ismeretében olyan jogosultságbiteket kellene prezentálni, amelyek az effektív hozzáférési jogosultságokat tükrözik. Tehát például, ha egy fájl ACL-je <tt>u::rwx,g::r--,g:csop1:rw,o::---,m::rwx</tt> (vagyis csak a tulajdonos és a csop1 csoport számára írható), akkor azon processzeknek, amelyek EGID-ja nem egyezik meg a tulajdonoscsoportéval, de tagjai a <tt>csop1</tt> csoportnak, azt kellene mutatnunk, hogy az "other" bitcsoport értéke rw. Szerencsére azonban erre szinte soha ''nincs'' szükség, mivel a programoknak alapvetően nem feladata a kernelben amúgy is meglevő jogosultságkezelés reimplementálása (ez mindenképpen csak tökéletlenül sikerülhetne, hiszen lehetetlen transzcendentális módon megállapítani, milyen műveleteket engedélyezne a kernel; vagyis, amíg meg nem próbálunk meg egy műveletet végrehajtani, nem tudjuk megbízhatóan eldönteni, van-e hozzá jogunk).</small>
  +
  +
A POSIX ACL jogosultságbitekre való leképezésére a következő megoldást találták ki:
   
# A tulajdonos jogosultságbitjei megegyeznek a USER_OBJ típusú ACL-bejegyzés tartalmával.
+
# A tulajdonos jogosultságbitjei megegyeznek a USER_OBJ típusú ACL-bejegyzés tartalmával (ez elég természetes).
# Az "egyéb" jogosultságbitjei megegyeznek az OTHER típusú ACL-bejegyzés tartalmával.
+
# Az "egyéb" jogosultságbitjei megegyeznek az OTHER típusú ACL-bejegyzés tartalmával (szintén elég természetes).
 
# A tulajdonoscsoport látszólagos jogosultságbitjei a következőképpen állnak elő:
 
# A tulajdonoscsoport látszólagos jogosultságbitjei a következőképpen állnak elő:
## Ha van MASK típusú bejegyzés az ACL-ben, akkor a tulajdonoscsoport látszólagos jogai a maszk értékével egyeznek meg.
+
## Ha van MASK típusú bejegyzés az ACL-ben, akkor a tulajdonoscsoport látszólagos jogai a maszk értékével egyeznek meg. Ez egyáltalán nem intuitív, és pl. a <tt>find(1) -perm</tt>-et is át tudja verni.
 
## Ha nincs MASK típusú bejegyzés az ACL-ben, akkor a tulajdonoscsoport jogai a GROUP_OBJ típusú bejegyzés értékével egyeznek meg.
 
## Ha nincs MASK típusú bejegyzés az ACL-ben, akkor a tulajdonoscsoport jogai a GROUP_OBJ típusú bejegyzés értékével egyeznek meg.
   
109. sor: 109. sor:
 
Alapértelmezés szerint, amikor módosítjuk az ACL-t egy fájlon vagy könyvtáron, a maszk újraszámolódik és a nevesített felhasználókra és csoportokra vonatkozó jogosultságok összességének VAGY-kapcsolatával fog megegyezni; így, ha pl. egy <tt>ls -l</tt> kimenetét nézzük, képet kapunk arról, legfeljebb milyen jogokat osztottunk ki ACL-ek formájában.
 
Alapértelmezés szerint, amikor módosítjuk az ACL-t egy fájlon vagy könyvtáron, a maszk újraszámolódik és a nevesített felhasználókra és csoportokra vonatkozó jogosultságok összességének VAGY-kapcsolatával fog megegyezni; így, ha pl. egy <tt>ls -l</tt> kimenetét nézzük, képet kapunk arról, legfeljebb milyen jogokat osztottunk ki ACL-ek formájában.
   
Azt is jó tudni, hogy a fent leírt leképezés igazából nem a jogok kiolvasásakor, hanem a fájlrendszerben történő rögzítésükkor történik meg (hiszen az inode-ban adottak a jogosultságbitekhez tartozó mezők, ahová valamilyen értéket be kell írni). Ez azért fontos, mert előfordulhatnak (és elő is fordulnak) olyan hibák, amikor a tulajdonoscsoport jogait tartalmazó mezőbe valami miatt nem a maszk értéke kerül (vagy fordítva), és amíg nem nézzük meg közelről a teljes ACL-t, csak tanácstalanul vakarjuk a fejünket és nem értjük, miért nem működnek az ACL-lel beállított jogok. Jelen sorok írásakor pl. az <tt>xfsrestore</tt> állít be nullás maszkot úgy, hogy azt az értéket, amelynek a maszkban szerepelnie kellene, a tulajdonoscsoport jogosultságaihoz azért beírja. Így ránézésre látszólag minden rendben van, a gyakorlatban viszont nem jut érvényre az ACL, mert minden bitet kimaszkolunk belőle.
+
Azt is jó tudni, hogy a fent leírt leképezés igazából nem a jogok kiolvasásakor, hanem a fájlrendszerben történő rögzítésükkor történik meg (hiszen az inode-ban adottak a jogosultságbitekhez tartozó mezők, ahová valamilyen értéket mindenképpen be kell írni). Ez azért fontos, mert előfordulhatnak (és elő is fordulnak) olyan hibák, amikor a tulajdonoscsoport jogait tartalmazó mezőbe valami miatt nem a maszk értéke kerül (vagy fordítva), és amíg nem nézzük meg közelről a teljes ACL-t, csak tanácstalanul vakarjuk a fejünket és nem értjük, miért nem működnek az ACL-lel beállított jogok. Jelen sorok írásakor (2009. végén) pl. az <tt>xfsrestore</tt> állít be nullás maszkot úgy, hogy azt az értéket, amelynek a maszkban szerepelnie kellene, a tulajdonoscsoport jogosultságaihoz azért beírja. Így ránézésre látszólag minden rendben van, a gyakorlatban viszont nem jut érvényre az ACL, mert minden bitet kimaszkolunk belőle.
  +
  +
Példa:
  +
  +
<pre>
  +
% setfacl -m g::rwx,m::--- test
  +
% ls -la test
  +
-rw----r--+ 1 root root 0 Nov 20 18:26 test
  +
% getfacl test
  +
# file: test
  +
# owner: root
  +
# group: root
  +
user::rw-
  +
group::rwx #effective:---
  +
mask::---
  +
other::r--
  +
  +
% chmod 720 test
  +
% ls -la test
  +
-rwx-w----+ 1 root root 0 Nov 20 18:26 test*
  +
%getfacl test
  +
# file: test
  +
# owner: root
  +
# group: root
  +
user::rwx
  +
group::rwx #effective:-w-
  +
mask::-w-
  +
other::---
  +
</pre>
  +
  +
* A tulajdonoscsoportnak minden joga megvan, de ezeket a jogokat a maszk kimaszkolja.
  +
* Az ls kimenetében a maszkot látjuk, nem a tulajdonoscsoport jogait.
  +
* A chmod a maszkot állította át, nem a tulajdonoscsoport jogait.
   
 
== Hozzáférési ACL ==
 
== Hozzáférési ACL ==
115. sor: 115. sor:
 
Az eddigiekben bemutatott ACL-ek segítségével viszonylag finoman szabályozhatjuk, hogy létező fájlrendszer-objektumokhoz való hozzáféréskor mely felhasználóknak és mely csoportoknak milyen jogai legyenek. Az ilyen típusú ACL-eket hozzáférési ACL-nek hívják.
 
Az eddigiekben bemutatott ACL-ek segítségével viszonylag finoman szabályozhatjuk, hogy létező fájlrendszer-objektumokhoz való hozzáféréskor mely felhasználóknak és mely csoportoknak milyen jogai legyenek. Az ilyen típusú ACL-eket hozzáférési ACL-nek hívják.
   
Nézzünk egy példát. Állítsuk az ''umask''unkat 033-ra; ezzel az újonnan létrehozott fájlok és könyvtárak jogosultságbitjeiből kimaszkoltuk a tulajdonoscsoport és az egyéb végrehajtási és írási jogát (1-es ill. 2-es bit; a 4-es az olvasás).
+
Nézzünk egy példát. Állítsuk az ''umask''unkat 003-ra; ezzel az újonnan létrehozott fájlok és könyvtárak jogosultságbitjeiből kimaszkoltuk az "egyéb" végrehajtási és írási jogát (1-es ill. 2-es bit; a 4-es az olvasás).
   
 
<pre>
 
<pre>
umask 033
+
% umask 003
mkdir konyvtar
+
% mkdir konyvtar
ls -dl konyvtar
+
% ls -dl konyvtar
drwxr--r-- [...] júzer csoport [...] konyvtar
+
drwxrwxr-- [...] júzer csoport [...] konyvtar
 
</pre>
 
</pre>
 
A pontok helyén levő információk most nem fontosak.
 
A pontok helyén levő információk most nem fontosak.
 
Most írassuk ki a <tt>getfacl</tt> paranccsal az ACL-t. A <tt>getfacl</tt> paranccsal megjeleníthetjük egy fájl nevét, tulajdonosát, csoportját és a hozzá tartozó ACL-t.
 
Most írassuk ki a <tt>getfacl</tt> paranccsal az ACL-t. A <tt>getfacl</tt> paranccsal megjeleníthetjük egy fájl nevét, tulajdonosát, csoportját és a hozzá tartozó ACL-t.
 
<pre>
 
<pre>
getfacl konyvtar
+
% getfacl konyvtar
 
# file: konyvtar
 
# file: konyvtar
 
# owner: júzer
 
# owner: júzer
 
# group: csoport
 
# group: csoport
 
user::rwx
 
user::rwx
group::r--
+
group::rwx
 
other::r--
 
other::r--
 
</pre>
 
</pre>
137. sor: 137. sor:
 
Nézzük meg, hogy hogyan tudnánk egy megnevezett felhasználónak, mondjuk Bobnak jogokat biztosítani. Mivel Bobot szeretjük, olvasási, írási és végrehajtási jogot is adunk neki. A <tt>-m</tt> paraméter segítségével tudjuk módosítani a jogokat.
 
Nézzük meg, hogy hogyan tudnánk egy megnevezett felhasználónak, mondjuk Bobnak jogokat biztosítani. Mivel Bobot szeretjük, olvasási, írási és végrehajtási jogot is adunk neki. A <tt>-m</tt> paraméter segítségével tudjuk módosítani a jogokat.
 
<pre>
 
<pre>
setfacl -m u:bob:rwx konyvtar
+
% setfacl -m u:bob:rwx konyvtar
getfacl konyvtar
+
% getfacl konyvtar
 
# file: konyvtar
 
# file: konyvtar
 
# owner: júzer
 
# owner: júzer
144. sor: 144. sor:
 
user::rwx
 
user::rwx
 
user:bob:rwx
 
user:bob:rwx
group::r--
+
group::rwx
 
mask::rwx
 
mask::rwx
 
other::r--
 
other::r--
151. sor: 151. sor:
 
(Vegyük észre, hogy azt, hogy <tt>user:bob:rwx</tt> rövidíthettük úgy, hogy <tt>u:bob:rwx</tt>.)
 
(Vegyük észre, hogy azt, hogy <tt>user:bob:rwx</tt> rövidíthettük úgy, hogy <tt>u:bob:rwx</tt>.)
   
Itt megjelenik ugyebár a Bob nevű felhasználó bejegyzése és a ''mask'' típusú bejegyzés. A ''mask'' bejegyzés automatikusan létrejön, ha szükséges, és nem adtuk meg külön. Ahogy már említettem, a maszk alapértelmezés szerint a nevesített felhasználókra és csoportokra vonatkozó jogosultságok összességének VAGY-kapcsolatával fog megegyezni, így biztosan nem maszkol egyetlen jogot sem. Ha megnézzük az <tt>ls -dl konyvtar</tt> parancs kimenetét, a következőt láthatjuk:
+
Itt megjelenik ugyebár a Bob nevű felhasználó bejegyzése és a ''mask'' típusú bejegyzés. A ''mask'' bejegyzés automatikusan létrejön, ha szükséges, és nem adtuk meg külön. Ahogy már említettem, a maszk alapértelmezés szerint a nevesített felhasználókra és csoportokra, valamint a tulajdonoscsoportra vonatkozó jogosultságok összességének VAGY-kapcsolatával fog megegyezni, így biztosan nem maszkol egyetlen jogot sem. Ha megnézzük az <tt>ls -dl konyvtar</tt> parancs kimenetét, a következőt láthatjuk:
 
<pre>
 
<pre>
 
drwxrwx---+ [...] júzer csoport [...] konyvtar
 
drwxrwx---+ [...] júzer csoport [...] konyvtar
 
</pre>
 
</pre>
Itt a + jel azt mutatja, hogy ''konyvtar''hoz tartozik bővített ACL. Látszik az is, hogy a ''mask'' bejegyzés tartalma jelenik meg a tulajdonoscsoport jogai helyén; ez azért hasznos, mert a ''mask'' az ACL-ek által biztosított jogok felső korlátja. ''Csoport'' jogai még mindig csak az olvasásra korlátozódnak.
+
Itt a + jel azt mutatja, hogy ''konyvtar''hoz tartozik bővített ACL. Ugyan nem látszik, de most már a ''mask'' bejegyzés tartalma jelenik meg a tulajdonoscsoport jogai helyén; ez elvileg azért hasznos, mert a ''mask'' az ACL-ek által biztosított jogok felső korlátja.
   
 
Ha megpróbáljuk módosítani a tulajdonoscsoport jogait a <tt>chmod</tt> segítségével <tt>r-x</tt>-re, akkor a következő történik:
 
Ha megpróbáljuk módosítani a tulajdonoscsoport jogait a <tt>chmod</tt> segítségével <tt>r-x</tt>-re, akkor a következő történik:
 
<pre>
 
<pre>
chmod g-w konyvtar
+
% chmod g-w konyvtar
ls -dl konyvtar
+
% ls -dl konyvtar
 
drwxr-x---+ [...] júzer csoport [...] konyvtar
 
drwxr-x---+ [...] júzer csoport [...] konyvtar
getfacl --omit-header konyvtar
+
% getfacl --omit-header konyvtar
 
user::rwx
 
user::rwx
user:bob:rwx #az érvényesülő jogok:r-x
+
user:bob:rwx #effective:r-x
group::r--
+
group::rwx #effective:r-x
 
mask::r-x
 
mask::r-x
 
other::---
 
other::---
 
</pre>
 
</pre>
Ezen a példán látható a ''mask'' hatása: maszkolja a Bob felhasználó egyes jogait. Ha a <tt>chmod</tt>-dal visszaadnánk az írási jogot, akkor csak a Bob felhasználó tudná újra írni a könyvtárat, tehát a tulajdonoscsoport jogait ez nem érintené.
+
Ezen a példán látható a ''mask'' hatása: maszkolja a Bob felhasználó és a tulajdonoscsoport egyes jogait.
  +
  +
Most vegyük el a tulajdonoscsoport írási és végrehajtási jogát a maszk újraszámolása nélkül, majd chmoddal állítsunk be 2770-es jogokat:
  +
<pre>
  +
% setfacl -n -m g::r konyvtar
  +
% chmod 2770 konyvtar
  +
% ls -dl konyvtar
  +
drwxrws---+ [...] júzer csoport [...] konyvtar
  +
% getfacl konyvtar
  +
# file: konyvtar
  +
# owner: júzer
  +
# group: csoport
  +
# flags: -s-
  +
user::rwx
  +
user:bob:rwx
  +
group::r--
  +
mask::rwx
  +
other::---
  +
</pre>
  +
Látszik, hogy
  +
* hiába adna a 2770-es bitkombináció írási és végrehajtási jogot a tulajdonoscsoportnak, csak a maszk módosult;
  +
* a getfacl kimenetében megjelent az, hogy <tt>flags: -s-</tt>, ami azt jelenti, hogy a setgid bit be van állítva.
  +
A setgidnek igazából semmi köze az ACL-hez; csak azért van ott, hogy az ACL-ek könnyen lementhetőek és helyreállíthatóak legyenek anélkül, hogy a setuid/setgid/sticky bitek állapota elveszne. A getfacl segítségével ugyanis rekurzívan is kilistázhatjuk egy egész könyvtárfa összes ACL-jét, a setfacl pedig a getfacl kimenetét olvasva vissza tudja ezeket állítani; ha a getfacl kimenete nem tartalmazná a setuid/setgid/sticky bitet, akkor szinte használhatatlan lenne. [http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=270099 Sajnos évekig ez volt a helyzet.]
   
 
== Alapértelmezett ACL ==
 
== Alapértelmezett ACL ==
236. sor: 236. sor:
   
 
Ha víruskeresőt futtatunk a bejövő leveleken, általában különböző felhasználóként fut a levelezőszerver és a víruskereső. Azt szeretnénk, ha a levelezőszerver által létrehozott fájlok a víruskereső számára is olvashatóak lennének, de senki más számára nem lennének olvashatóak. Megtehetjük, hogy egy olyan könyvtárba tesszük ezeket a fájlokat, amelyen olyan alapértelmezett ACL van, amely a víruskeresős felhasználónak olvasási jogot biztosít. ACL nélkül megoldás: helyezzük közös csoportba ezt a két felhasználót, és az adott könyvtár legyen ennek a csoportnak a tulajdona, valamint setgid-es. Az is szükséges, hogy a levelezőszerver umaskja megfelelő legyen, tehát ne maszkolja ki a csoport olvasási jogát.
 
Ha víruskeresőt futtatunk a bejövő leveleken, általában különböző felhasználóként fut a levelezőszerver és a víruskereső. Azt szeretnénk, ha a levelezőszerver által létrehozott fájlok a víruskereső számára is olvashatóak lennének, de senki más számára nem lennének olvashatóak. Megtehetjük, hogy egy olyan könyvtárba tesszük ezeket a fájlokat, amelyen olyan alapértelmezett ACL van, amely a víruskeresős felhasználónak olvasási jogot biztosít. ACL nélkül megoldás: helyezzük közös csoportba ezt a két felhasználót, és az adott könyvtár legyen ennek a csoportnak a tulajdona, valamint setgid-es. Az is szükséges, hogy a levelezőszerver umaskja megfelelő legyen, tehát ne maszkolja ki a csoport olvasási jogát.
  +
  +
== Potenciális ZH-kérdések ==
  +
  +
* Milyen elemekből áll(hat) egy POSIX ACL? (A szimbolikus azonosítók nem kellenek betű szerint, csak a szerepük/funkciójuk.)
  +
* Mik a 100-as UID-val, 200-as GID-dal futó, 300-as és 400-as kiegészítő csoporttagsággal rendelkező processz effektív jogai azon a fájlon, amelynek a POSIX ACL-je az alábbi bejegyzéseket tartalmazza? (És itt jönne egy getfacl-kimenet.)
  +
* Mondjon példát olyan jogosultság-specifikációra, amely hagyományos unixos jogosultságokkal nem írható le ésszerűen, de POSIX ACL-ekkel igen!
  +
* Hogyan (és milyen esetekben) lehet a POSIX ACL-ek látszólag szükséges alkalmazását mégis elkerülni és hagyományos unixos jogosultságokkal ugyanazt a hatást elérni? Mutassa ezt be egy példán! (Segítség: lehet, hogy csak ésszerűtlen megoldás van.)
  +
* Használható-e POSIX ACL arra, hogy egy csoport összes tagja számára mindenképpen biztosítsunk hozzáférést egy könyvtár tartalmához, akkor is, ha a csoport tagjai nem működnek ebben együtt? Miért?
  +
* Mit látunk az <tt>ls -l</tt> kimenetében a jogosultságbitek helyén olyan könyvtárbejegyzések esetében, amelyekhez bővített POSIX ACL tartozik?

A lap jelenlegi, 2012. november 20., 23:36-kori változata

Írta: Tevesz Ágnes és Korn András, 2009. december. Utolsó jelentős módosítás: 2012. november.

A POSIX ACL (hozzáférés-vezérlési listák) a hagyományos unixos fájlrendszer-jogosultságrendszer kiterjesztése. Olyan jogosultság-konstrukciók is leírhatók a segítségével, amelyek a hagyományos jogosultságrendszerrel nem: pl. hogy egy adott fájlt egy csoport tagjai írhassák és olvashassák, egy másik csoport tagjai csak olvashassák, a többiek pedig se ne írhassák, se ne olvashassák.

Tartalomjegyzék

[szerkesztés] 1 Bevezetés

Azok a rendszerek, amelyek támogatják/megvalósítják a POSIX-szabványokat (Portable Operating System Interface), általában egy egyszerű, de hatékony fájl-jogosultsági modellt használnak. Minden fájlhoz három jogosultsághalmaz tartozik: külön megadható, milyen jogai legyenek a fájl tulajdonosának, a fájlt birtokló csoportnak és rajtuk kívül mindenk másnak. A három jogosultsághalmaz három-három bitből áll: ezek az olvasás (r), az írás (w) és végrehajtás (x) jogát reprezentálják. Az így kapott jogokat, minden fájl illetve könyvtár esetében, kilenc biten tudjuk tárolni. Megadható ezen felül a felhasználói azonosító beállítása (set user id), a csoportazonosító beállítása (set group id) és a ragadós (sticky) bit is.

Az összetett feladatok ellátására ez a modell nem biztosított elég lehetőséget, ezért indították a POSIX 1003.1e fejlesztését és így született meg az ACL (Access Control List) szabványtervezet, amely azonban sosem vált szabvánnyá és már valószínűleg nem is fog. A jövő útja valószínűleg az NFSv4 ACL-eké, de ezeket jelen sorok írásakor (2009. végén) a szabad unix-féleségek közül csak a FreeBSD és az IllumOS támogatja, míg az 1003.1e szerinti ACL-eket a Linux is; ráadásul a megvalósítás kiforrottnak tekinthető, és a felhasználói programok oldaláról is megvan a szükséges támogatás, úgyhogy még érdemes ezzel az ACL-rendszerrel foglalkozni. (Egy némileg elavult NFSv4 ACL patch létezik Linuxhoz is; ennek a fejlesztése "Richacl" néven folytatódik.)

[szerkesztés] 2 Az ACL-ek felépítése és működése

Egy ACL bejegyzések sokaságából épül fel (ACE, access control entry). Egy ACL-bejegyzés három információt tartalmaz:

  • A bejegyzés típusa. A következő típusok léteznek (zárójelben a típusok kódja -- a későbbiekben a rövidség érdekében gyakran a kóddal fogok hivatkozni a bejegyzéstípusokra):
    1. tulajdonos (ACL_USER_OBJ);
    2. egyéb konkrét felhasználó (ACL_USER);
    3. tulajdonoscsoport (ACL_GROUP_OBJ);
    4. egyéb konkrét csoport (ACL_GROUP);
    5. maszk (ACL_MASK) - ezzel a USER, a GROUP_OBJ és a GROUP típusú ACL-ek által megadott jogokból kimaszkolhatunk bizonyos biteket, l. később;
    6. mindenki más (ACL_OTHER).
  • Annak a csoportnak vagy felhasználónak a neve, amelyikre az adott bejegyzés vonatkozik; ez lehet
    • üres, vagy
    • egy konkrét felhasználó vagy csoport.
  • Az adott felhasználóhoz vagy csoporthoz rendelt jogok:
    • a szokásos r/w/x bit formájában.

A szintaxis a következő:

<acl típusa>:<név>:<jogok>

Az alábbi táblázat az egyes bejegyzéstípusok szintaxisát részletesebben is bemutatja:

Típus Kód Szöveges forma
ACL-bejegyzéstípusok
tulajdonos ACL_USER_OBJ user::rwx
konkrét felhasználó ACL_USER user:név:rwx
tulajdonoscsoport ACL_GROUP_OBJ group::rwx
konkrét csoport ACL_GROUP group:név:rwx
maszk ACL_MASK mask::rwx
egyéb ACL_OTHER other::rwx

Minden ACL kötelezően tartalmaz egy USER_OBJ, egy GROUP_OBJ és egy OTHER típusú bejegyzést. Azokat az ACL-eket, amelyek ezen a három bithármason kívül további elemeket is tartalmaznak, kiterjesztett vagy bővített ACL-eknek hívjuk. Ezek tartalmaznak egy mask bejegyzést illetve megnevezett felhasználókat és csoportokat is. Más szavakkal: ha egy ACL-ben szerepel GROUP vagy USER típusú (tehát konkrét felhasználóra vagy konkrét csoportra vonatkozó) bejegyzés, akkor kötelezően tartalmaz egy MASK típusú bejegyzést is; a MASK bejegyzés minden egyéb esetben opcionális.

A maszk a jogosultságok elbírálásakor jut szerephez. Ha egy processz megpróbál megnyitni egy olyan fájlt, amelyhez bővített ACL tartozik, egy jogosultságvizsgáló algoritmus fut le, amelynek a működése a következőképpen foglalható össze:

  1. Ha a processz effektív UID-ja megegyezik a fájl tulajdonosáéval, akkor a USER_OBJ bejegyzésben megadott jogosultságbitek az érvényesek.
  2. Ha nem egyezik, és van a processz effektív UID-jára vonatkozó USER típusú ACL-bejegyzés, az ebben szereplő jogosultságbitek és a maszk ÉS kapcsolata az irányadó, kivéve, ha a maszk üres ("---"), mert akkor az OTHER bejegyzés az irányadó.
    • Ez azt jelenti, hogy az OTHER-ben beállított engedélyek felülírhatják a nevesített user ACL-ekben levő tiltásokat!
  3. Ha nincs ilyen bejegyzés, és a processz effektív GID-ja megegyezik a fájl tulajdonoscsoportjával, akkor a GROUP_OBJ bejegyzésben megadott jogosultságbitek az irányadóak. A maszk nem jut szerephez.
  4. Ha nem egyezik meg, akkor, ha a maszk nem üres, a processz effektív GID-jára és kiegészítő csoportjaira vonatkozó ACL-bejegyzésekben megadott jogosultságokat VAGY kapcsolatba hozzuk egymással, az eredményt ÉS kapcsolatba hozzuk a maszkkal, és így kapott jogosultságbiteket tekintjük irányadónak; ha ezek lehetővé teszik a fájl megnyitását, akkor az sikerül, ha nem, akkor nem.
  5. Ha a maszk üres volt, akkor az OTHER-ben levő jogosultságbitek az irányadóak.
    • Vagyis: az OTHER-ben megadott engedély megint erősebb, mint bármiféle tiltás!
  6. Ha nincs ilyen ACL-bejegyzés, akkor az OTHER típusú bejegyzésben szereplő jogosultságbitek jutnak érvényre.

Vegyük észre, hogy ez azt jelenti, hogy az azonos típusú ACL-bejegyzések közül az engedélyezők "erősebbek" a tiltóknál, az OTHER-ben megadott engedélyek pedig üres maszk esetén "mindent visznek", kivéve, ha az effektiv UID ill. GID egyezik a tulajdonossal ill. tulajdonoscsoporttal. Intuitív, ugye? :) (Ez valószínűleg bug a Linuxban; a Solaris 9 üres maszk esetén is "helyesen" viselkedik. Ha lesz időm, jelentem, hátha megjavítják.)

Megjegyzés: az itt leírt algoritmus az, amelyet a Linux ténylegesen megvalósítani látszik; az acl(5) manpage által leírt algoritmus nem pontosan ez. Nem világos, hogy az implementáció vagy a dokumentáció hibás.

Az alábbi táblázat egy egyszerű példán kersztül szemlélteti a maszk működését:

Típus Szöveges forma Jogok
konkrét csoport group:név:r-x r-x
mask mask::rw- rw-
Effektív jogok r--

[szerkesztés] 2.1 ACL leképezése hagyományos jogosultságbitekre

Ha valamilyen hagyományos, tehát ACL-eket nem támogató eszközzel kérdezzük le egy fájl jogosultságbitjeit, valahogyan meg kell bennük jeleníteni az ACL által reprezentált jogokat is; tehát szükségünk van egy leképezésre, ami az ACL tartalmát hagyományos unixos jogosultságbitekre képezi le. Egy ilyen leképezés természetesen nem lehet bijekció, hiszen az ACL-nek nagyobb a kifejezőereje, mint a jogosultságbiteknek; de egyértelmű azért lehet.

Ha fontos lenne, hogy a programok a lekérdezett jogosultságbitek alapján maguk is eldönthessék, van-e joguk írni vagy olvasni egy fájlt, akkor a leképezésnek "személyre szabottnak" kellene lennie, tehát a futó processz EUID-ja, EGID-ja és csoporttagságai ismeretében olyan jogosultságbiteket kellene prezentálni, amelyek az effektív hozzáférési jogosultságokat tükrözik. Tehát például, ha egy fájl ACL-je u::rwx,g::r--,g:csop1:rw,o::---,m::rwx (vagyis csak a tulajdonos és a csop1 csoport számára írható), akkor azon processzeknek, amelyek EGID-ja nem egyezik meg a tulajdonoscsoportéval, de tagjai a csop1 csoportnak, azt kellene mutatnunk, hogy az "other" bitcsoport értéke rw. Szerencsére azonban erre szinte soha nincs szükség, mivel a programoknak alapvetően nem feladata a kernelben amúgy is meglevő jogosultságkezelés reimplementálása (ez mindenképpen csak tökéletlenül sikerülhetne, hiszen lehetetlen transzcendentális módon megállapítani, milyen műveleteket engedélyezne a kernel; vagyis, amíg meg nem próbálunk meg egy műveletet végrehajtani, nem tudjuk megbízhatóan eldönteni, van-e hozzá jogunk).

A POSIX ACL jogosultságbitekre való leképezésére a következő megoldást találták ki:

  1. A tulajdonos jogosultságbitjei megegyeznek a USER_OBJ típusú ACL-bejegyzés tartalmával (ez elég természetes).
  2. Az "egyéb" jogosultságbitjei megegyeznek az OTHER típusú ACL-bejegyzés tartalmával (szintén elég természetes).
  3. A tulajdonoscsoport látszólagos jogosultságbitjei a következőképpen állnak elő:
    1. Ha van MASK típusú bejegyzés az ACL-ben, akkor a tulajdonoscsoport látszólagos jogai a maszk értékével egyeznek meg. Ez egyáltalán nem intuitív, és pl. a find(1) -perm-et is át tudja verni.
    2. Ha nincs MASK típusú bejegyzés az ACL-ben, akkor a tulajdonoscsoport jogai a GROUP_OBJ típusú bejegyzés értékével egyeznek meg.

Ugyanez a leképezés fordítva is működik: ha a chmod paranccsal vagy az azonos nevű rendszerhívással állítjuk a jogosultságbiteket, akkor a csoportra vonatkozó bitek a maszk típusú bejegyzésbe íródnak bele, ha van ilyen a fájlon. Erre jó odafigyelni, mert esetleg nem ezt szeretnénk. Ha ugyanis töröljük valamelyik bitet a maszkból, akkor természetesen hiába szerepel az a bit valamelyik nevesített felhasználóra vagy csoportra vonatkozó bejegyzésben, nem fog érvényre jutni.

Alapértelmezés szerint, amikor módosítjuk az ACL-t egy fájlon vagy könyvtáron, a maszk újraszámolódik és a nevesített felhasználókra és csoportokra vonatkozó jogosultságok összességének VAGY-kapcsolatával fog megegyezni; így, ha pl. egy ls -l kimenetét nézzük, képet kapunk arról, legfeljebb milyen jogokat osztottunk ki ACL-ek formájában.

Azt is jó tudni, hogy a fent leírt leképezés igazából nem a jogok kiolvasásakor, hanem a fájlrendszerben történő rögzítésükkor történik meg (hiszen az inode-ban adottak a jogosultságbitekhez tartozó mezők, ahová valamilyen értéket mindenképpen be kell írni). Ez azért fontos, mert előfordulhatnak (és elő is fordulnak) olyan hibák, amikor a tulajdonoscsoport jogait tartalmazó mezőbe valami miatt nem a maszk értéke kerül (vagy fordítva), és amíg nem nézzük meg közelről a teljes ACL-t, csak tanácstalanul vakarjuk a fejünket és nem értjük, miért nem működnek az ACL-lel beállított jogok. Jelen sorok írásakor (2009. végén) pl. az xfsrestore állít be nullás maszkot úgy, hogy azt az értéket, amelynek a maszkban szerepelnie kellene, a tulajdonoscsoport jogosultságaihoz azért beírja. Így ránézésre látszólag minden rendben van, a gyakorlatban viszont nem jut érvényre az ACL, mert minden bitet kimaszkolunk belőle.

Példa:

% setfacl -m g::rwx,m::--- test
% ls -la test
-rw----r--+  1 root root    0 Nov 20 18:26 test
% getfacl test
# file: test
# owner: root
# group: root
user::rw-
group::rwx                      #effective:---
mask::---
other::r--

% chmod 720 test
% ls -la test
-rwx-w----+ 1 root root 0 Nov 20 18:26 test*
%getfacl test
# file: test
# owner: root
# group: root
user::rwx
group::rwx                      #effective:-w-
mask::-w-
other::---
  • A tulajdonoscsoportnak minden joga megvan, de ezeket a jogokat a maszk kimaszkolja.
  • Az ls kimenetében a maszkot látjuk, nem a tulajdonoscsoport jogait.
  • A chmod a maszkot állította át, nem a tulajdonoscsoport jogait.

[szerkesztés] 3 Hozzáférési ACL

Az eddigiekben bemutatott ACL-ek segítségével viszonylag finoman szabályozhatjuk, hogy létező fájlrendszer-objektumokhoz való hozzáféréskor mely felhasználóknak és mely csoportoknak milyen jogai legyenek. Az ilyen típusú ACL-eket hozzáférési ACL-nek hívják.

Nézzünk egy példát. Állítsuk az umaskunkat 003-ra; ezzel az újonnan létrehozott fájlok és könyvtárak jogosultságbitjeiből kimaszkoltuk az "egyéb" végrehajtási és írási jogát (1-es ill. 2-es bit; a 4-es az olvasás).

% umask 003
% mkdir konyvtar
% ls -dl konyvtar
drwxrwxr-- [...] júzer csoport [...] konyvtar

A pontok helyén levő információk most nem fontosak. Most írassuk ki a getfacl paranccsal az ACL-t. A getfacl paranccsal megjeleníthetjük egy fájl nevét, tulajdonosát, csoportját és a hozzá tartozó ACL-t.

% getfacl konyvtar
# file: konyvtar
# owner: júzer
# group: csoport
user::rwx
group::rwx
other::r--

Az utolsó három sor a szokásos unixos jogosultságbiteket reprezentáló ACL-bejegyzéseket mutatja. Nézzük meg, hogy hogyan tudnánk egy megnevezett felhasználónak, mondjuk Bobnak jogokat biztosítani. Mivel Bobot szeretjük, olvasási, írási és végrehajtási jogot is adunk neki. A -m paraméter segítségével tudjuk módosítani a jogokat.

% setfacl -m u:bob:rwx konyvtar
% getfacl konyvtar
# file: konyvtar
# owner: júzer
# group: csoport
user::rwx
user:bob:rwx
group::rwx
mask::rwx
other::r--

(Vegyük észre, hogy azt, hogy user:bob:rwx rövidíthettük úgy, hogy u:bob:rwx.)

Itt megjelenik ugyebár a Bob nevű felhasználó bejegyzése és a mask típusú bejegyzés. A mask bejegyzés automatikusan létrejön, ha szükséges, és nem adtuk meg külön. Ahogy már említettem, a maszk alapértelmezés szerint a nevesített felhasználókra és csoportokra, valamint a tulajdonoscsoportra vonatkozó jogosultságok összességének VAGY-kapcsolatával fog megegyezni, így biztosan nem maszkol egyetlen jogot sem. Ha megnézzük az ls -dl konyvtar parancs kimenetét, a következőt láthatjuk:

drwxrwx---+ [...] júzer csoport [...] konyvtar

Itt a + jel azt mutatja, hogy konyvtarhoz tartozik bővített ACL. Ugyan nem látszik, de most már a mask bejegyzés tartalma jelenik meg a tulajdonoscsoport jogai helyén; ez elvileg azért hasznos, mert a mask az ACL-ek által biztosított jogok felső korlátja.

Ha megpróbáljuk módosítani a tulajdonoscsoport jogait a chmod segítségével r-x-re, akkor a következő történik:

% chmod g-w konyvtar
% ls -dl konyvtar
drwxr-x---+ [...] júzer csoport [...] konyvtar
% getfacl --omit-header konyvtar
user::rwx
user:bob:rwx            #effective:r-x
group::rwx              #effective:r-x
mask::r-x
other::---

Ezen a példán látható a mask hatása: maszkolja a Bob felhasználó és a tulajdonoscsoport egyes jogait.

Most vegyük el a tulajdonoscsoport írási és végrehajtási jogát a maszk újraszámolása nélkül, majd chmoddal állítsunk be 2770-es jogokat:

% setfacl -n -m g::r konyvtar
% chmod 2770 konyvtar
% ls -dl konyvtar
drwxrws---+ [...] júzer csoport [...] konyvtar
% getfacl konyvtar
# file: konyvtar
# owner: júzer
# group: csoport
# flags: -s-
user::rwx
user:bob:rwx
group::r--
mask::rwx
other::---

Látszik, hogy

  • hiába adna a 2770-es bitkombináció írási és végrehajtási jogot a tulajdonoscsoportnak, csak a maszk módosult;
  • a getfacl kimenetében megjelent az, hogy flags: -s-, ami azt jelenti, hogy a setgid bit be van állítva.

A setgidnek igazából semmi köze az ACL-hez; csak azért van ott, hogy az ACL-ek könnyen lementhetőek és helyreállíthatóak legyenek anélkül, hogy a setuid/setgid/sticky bitek állapota elveszne. A getfacl segítségével ugyanis rekurzívan is kilistázhatjuk egy egész könyvtárfa összes ACL-jét, a setfacl pedig a getfacl kimenetét olvasva vissza tudja ezeket állítani; ha a getfacl kimenete nem tartalmazná a setuid/setgid/sticky bitet, akkor szinte használhatatlan lenne. Sajnos évekig ez volt a helyzet.

[szerkesztés] 4 Alapértelmezett ACL

A hozzáférési ACL-eken túlmenően ún. alapértelmezett ACL-eket is használhatunk. Ha egy könyvtárhoz tartozik alapértelmezett ACL, akkor az adott könyvtárban újonnan létrehozott valamennyi fájlrendszer-objektum hozzáférési ACL-ként ezt az alapértelmezett ACL-t örökli (az új alkönyvtárak alapértelmezett ACL-ként is).

Új fájlrendszer-objektum létrehozásakor, ha a szülőkönyvtárnak van alapértelmezett ACL-je, az alábbi történik:

  • Az új objektum hozzáférési ACL-ként megkapja a szülőkönyvtár alapértelmezett ACL-jét.
  • Ezután a maszkot kivéve az összes ACL-bejegyzésből törlődik minden olyan bit, amely az objektumot létrehozó rendszerhívásnak átadott mode paraméterben (ami a létrehozandó objektum jogosultságbitjeit tartalmazza) nincs beállítva.
  • Az umask nem jut szerephez!

Lássunk egy példát! A setfacl paranccsal kétféleképpen is beállíthatunk default ACL-t; az alábbi két parancssor ekvivalens:

 
setfacl -d -m g:csoport2:r-x konyvtar
setfacl -m d:g:csoport2:r-x konyvtar

(Linuxon az r-x helyett írhatunk csak simán rx-et is, de pl. Solarison nem: ott mindig pontosan három karakterrel kell megadnunk a jogosultságbiteket.)

A második forma előnye akkor mutatkozik meg, ha egyszerre akarunk hozzáférési és alapértelmezett ACL-t is létrehozni; a setfacl -m után ugyanis vesszővel elválasztva több ACL-elemet is felsorolhatunk, és a második szintaxis lehetővé teszi az alapértelmezett és a hozzáférési ACL-ek keverését, míg az első nem.

Nézzük meg, mit csináltunk!

getfacl konyvtar
# file: konyvtar
# owner: júzer
# group: csoport
user::rwx
user:bob:rwx
group::r-x
mask::rwx
other::---
default:user::rwx
default:group::r-x
default:group:csoport2:r-x
default:mask::r-x
default:other::---

A default ACL megjelenítésével és működésével kapcsolatban vannak különbségek az egyes implementációk között; pl. elképzelhető, hogy a default ACL-t csak akkor látjuk, ha -d kapcsolóval hívjuk meg a getfacl. Azt is vegyük észre, hogy a Linux automatikusan létrehozott a hozzáférési ACL alapján néhány alapértelmezett ACL-bejegyzést; ez sem feltétlenül történik ugyanígy minden más oprendszeren.

Hozzunk most létre egy alkönyvtárat az mkdir paranccsal! Az mkdir(1) program 0777-es mode paraméterrel hívja meg az mkdir() rendszerhívást. Lássuk, milyen ACL-t kap az uj alkönyvtár:

mkdir konyvtar/alkonyvtar
getfacl konyvtar/alkonyvtar
# file: konyvtar/alkonyvtar
# owner: júzer
# group: csoport
user::rwx
group::r-x
group:csoport2:r-x
mask::r-x
other::---
default:user::rwx
default:group::r-x
default:group:csoport2:r-x
default:mask::r-x
default:other::---

Látható, hogy az új könyvtár az ACL-t mint hozzáférési és alapértelmezett ACL-t is örökölte.

[szerkesztés] 5 Alkalmazási példák

Tegyük fel, hogy van egy SSL-kulcsunk. Nem szeretnénk, hogy bárki elolvashassa, kivéve a webszervert. A webszerver a www-data nevű felhasználó jogaival fut. Ha a www-data felhasználó tulajdonába helyezzük a fájlt, akkor ő el tudja rajta állítani a jogokat is, amit nem szeretnénk; ACL-lel viszont megoldhatjuk, hogy a root tulajdonában maradjon, de a www-data is el tudja olvasni a tartalmát anélkül, hogy a jogokat elállíthatná. ACL nélküli megoldás is van: legyen saját csoportja a www-data usernek, és birtokolja ez a csoport az SSL-kulcsot. Ha csak a csoportnak van rá olvasási joga, akkor nem tudja elállítani a jogokat.

Ha víruskeresőt futtatunk a bejövő leveleken, általában különböző felhasználóként fut a levelezőszerver és a víruskereső. Azt szeretnénk, ha a levelezőszerver által létrehozott fájlok a víruskereső számára is olvashatóak lennének, de senki más számára nem lennének olvashatóak. Megtehetjük, hogy egy olyan könyvtárba tesszük ezeket a fájlokat, amelyen olyan alapértelmezett ACL van, amely a víruskeresős felhasználónak olvasási jogot biztosít. ACL nélkül megoldás: helyezzük közös csoportba ezt a két felhasználót, és az adott könyvtár legyen ennek a csoportnak a tulajdona, valamint setgid-es. Az is szükséges, hogy a levelezőszerver umaskja megfelelő legyen, tehát ne maszkolja ki a csoport olvasási jogát.

[szerkesztés] 6 Potenciális ZH-kérdések

  • Milyen elemekből áll(hat) egy POSIX ACL? (A szimbolikus azonosítók nem kellenek betű szerint, csak a szerepük/funkciójuk.)
  • Mik a 100-as UID-val, 200-as GID-dal futó, 300-as és 400-as kiegészítő csoporttagsággal rendelkező processz effektív jogai azon a fájlon, amelynek a POSIX ACL-je az alábbi bejegyzéseket tartalmazza? (És itt jönne egy getfacl-kimenet.)
  • Mondjon példát olyan jogosultság-specifikációra, amely hagyományos unixos jogosultságokkal nem írható le ésszerűen, de POSIX ACL-ekkel igen!
  • Hogyan (és milyen esetekben) lehet a POSIX ACL-ek látszólag szükséges alkalmazását mégis elkerülni és hagyományos unixos jogosultságokkal ugyanazt a hatást elérni? Mutassa ezt be egy példán! (Segítség: lehet, hogy csak ésszerűtlen megoldás van.)
  • Használható-e POSIX ACL arra, hogy egy csoport összes tagja számára mindenképpen biztosítsunk hozzáférést egy könyvtár tartalmához, akkor is, ha a csoport tagjai nem működnek ebben együtt? Miért?
  • Mit látunk az ls -l kimenetében a jogosultságbitek helyén olyan könyvtárbejegyzések esetében, amelyekhez bővített POSIX ACL tartozik?
Személyes eszközök