Listy kontroli dostępu - ACL

Krzysztof Bałażyk

Wstęp

Standardowo, w oferowanych przez systemy z rodziny Linux systemach plików (ext2/ext3/ext4) z każdym plikiem/katalogiem na dysku związane są 3 kategorie dostępu - dla właściciela pliku, grupy właściciela oraz pozostałych użytkowników. Dla każdej z tych kategorii możemy przypisać następujące atrybuty:

[kb262487@students public_html]$ ls -l
total 23060
drwxr-xr-x  5 kb262487 inf      103 May 10  2009 ProgramowanieWWW
drwx---r-x  2 kb262487 inf       35 May  6  2009 a
drwxr-xr-x  5 kb262487 inf       91 Apr  7 15:29 applet
-rw----r--  1 kb262487 inf 23420613 Sep  4  2009 asterisk.tar.gz
drwxr-xr-x  2 kb262487 inf      152 Sep  1  2009 b

Wydawać by się mogło, że za pomocą takiego systemu kontroli możemy dość dobrze zarządzać prawami dostępu dla konkretnych użytkowników (wszakże dla kontrastu systemy z rodziny Windows 9x w ogóle nie umożliwiały kontroli na poziomie odczytu/uruchamiania plików, a dostępne tam szczątkowe atrybuty i tak każdy użytkownik mógł sobie dowolnie zmieniać).

Jednak co zrobić, jeżeli chcemy dać jakiemuś konkretnemu użytkownikowi (użytkownikom) dostęp do naszego pliku? Jeśli do dyspozycji mamy tylko standardowy mechanizm uprawnień, to mamy właściwie dwie możliwości: dodanie go do naszej grupy i umożliwienie wszystkim jej członkom dostępu do pliku lub udostępnienie tego pliku wszystkim. Tutaj z pomocą przychodzi ACL - listy kontroli dostępu do plików.

Listy kontroli, początkowo dostępne tylko jako nakładka na system plików ext2fs, a teraz już jako integralna część jądra Linuksa pozwalają (oprócz tego, co zwykłe uprawnienia), także na ustawienie praw dostępu dla dowolnego użytkownika / grupy, a także maski uprawnień dla dowolnego pliku:

Uprawnienia zdefiniowane dla właściciela i pozostałych są zawsze efektywne. Pozostałe zależą od zdefiniowanej maski. Efektywne uprawnienia do pliku (lub katalogu) są koniunkcją bitową uprawnień zdefiniowanych w odpowiedniej pozycji (dla nazwanego użytkownika, grupy właściciela lub nazwanej grupy) i maski.

Algorytm sprawdzania uprawnień

Jak to włączyć

Po pierwsze należy wkompilować do jądra obsługę ACL dla systemu plików, z którego zamierzamy korzystać:

acl1

Po drugie należy podczas montowania systemu plików włączyć obsługę ACL, inaczej system przy każdej próbie ustawienia atrybutu ACL będzie wyświetlał:

kb262487@students:~/a$ setfacl -m user:testowy:rwx plik_testowy
setfacl: plik_testowy: Operation not supported

W tym celu w pliku /etc/fstab należy przy odpowiednim systemie plików dopisać acl:

/dev/sdb1 /mnt/dysk-debian ext3    relatime,errors=remount-ro,acl 0       1

Jak z tego korzystać?

Do wyświetlenia atrybutów ACL jakiegoś pliku służy polecenie:

getfacl nazwa_pliku

Przykładowo:

 $ getfacl plik.txt
 # file: plik.txt
 # owner: user
 # group: group
 user::rw-
 group::r--
 other::r--

Aby ustawić ACL dla jakiegoś pliku, korzystamy z polecenia:

setfacl nazwa_pliku

Przykładowo:

% setfacl -m u:testowy:rwx plik.txt

Jeżeli natomiast wypiszemy zawartość katalogu, to przy atrybutach pliku, który ma ACL pojawi się plusik:

% ls -l
-rw-rwxr--+ 1 user group 1000 2009-09-09 09:09 plik.txt

Jak to działa w środku?

Jak już wiemy, system Linux wszystkie informacje o danym pliku (oprócz nazwy!) trzyma w specjalnej strukturze inode, zdefiniowanej w pliku "linux/fs.h". Podkreślam tutaj, że jest to struktura, w której trzymane są dane o pliku w pamięci komputera. Na dysku dane te zapisane są inaczej! Struktura ta wygląda tak:

struct inode {
        struct hlist_node       i_hash;
        struct list_head        i_list;
        struct list_head        i_sb_list;
        umode_t                 i_mode;
        ...
        void                    *i_private; /* fs or device private pointer */
}

W polu i_mode zapisane są zwykłe atrybuty pliku. Przyglądając się bliżej polu umode_t można dostrzec, że jest to tak naprawdę typ unsigned_32. Co nas nie powinno dziwić, bo do zapisania 9 atrybutów wystarczy takie pole. A gdzie są zapisane ACL-e?

Ostatnie pole tej struktury zawiera wskaźnik do obszaru pamięci, który może być wykorzystany na własny użytek systemu plików.

System plików ext2fs, którego moduł obsługi jest zdefiniowany w pliku "fs/ext2/ext2.h" zawiera specjalną strukturę rozszerzającą:

struct ext2_inode_info {
        __le32  i_data[15];
        __u32   i_flags;
        __u32   i_faddr;
        ...
#ifdef CONFIG_EXT2_FS_POSIX_ACL
        struct posix_acl        *i_acl;
        struct posix_acl        *i_default_acl;
#endif
        ...
}

oraz funkcję, która otrzymawszy jako argument i-węzeł potrafi zwrocić nam wskaźnik na wspomnianą strukturę rozszerzającą.

static inline struct ext2_inode_info *EXT2_I(struct inode *inode)
{
        return container_of(inode, struct ext2_inode_info, vfs_inode);
}

Zatem na pewno w polu i_acl kryją się nasze rozszerzone atrybuty. Przyjrzyjmy się bliżej jak zbudowana jest struktura posix_acl.

struct posix_acl {
        atomic_t                a_refcount;
        unsigned int            a_count;
        struct posix_acl_entry  a_entries[0];
};

struct posix_acl_entry {
        short                   e_tag;
        unsigned short          e_perm;
        unsigned int            e_id;
};

/* e_tag entry in struct posix_acl_entry */
#define ACL_USER_OBJ            (0x01)
#define ACL_USER                (0x02)
#define ACL_GROUP_OBJ           (0x04)
#define ACL_GROUP               (0x08)
#define ACL_MASK                (0x10)
#define ACL_OTHER               (0x20)

/* permissions in the e_perm field */
#define ACL_READ                (0x04)
#define ACL_WRITE               (0x02)
#define ACL_EXECUTE             (0x01)

Jak widzimy jest to lista wpisów (struktur posix_acl_entry). W polu e_tag zapisana jest informacja, jakiej kategorii są to uprawnienia (uzytkownika/grupy/innych), w polu e_perm zapisane są odpowiednie uprawnienia, a w polu e_id zapisany jest identyfikator użykownika/grupy do którego odnoszą się te uprawnienia.


Janina Mincer-Daszkiewicz