Dostęp do plików w Linuksie 21


Linux wywodzi się w prostej linii z Uniksa, który był od początku projektowany, jako system wieloużytkownikowy. W takim systemie nie do pomyślenia jest aby jeden użytkownik mógł innemu kasować pliki, bądź nawet przeglądać ich zawartość bez jego pozwolenia. Aby zapobiec takim działaniom, wszystkie systemy plików stworzone dla Uniksa (np. ext3, reiserfs, ufs, xfs) umożliwiają właścicielom plików określenie pewnych zasad, na jakich inni użytkownicy systemu mogą używać ich plików. W tym przewodniku postaram się wyjaśnić, jak działają prawa dostępu w systemach z rodziny Unix i jak z nich korzystać.

Jeden sytem, wielu użytkowników

Na początku musimy wiedzieć, że każdy plik posiada swojego właściciela i grupę. Kiedy tworzymy jakiś plik, to na dysku, poza zawartością pliku, są zapisywane też informacje, kto jest właścicielem tego pliku i jaką grupa ten plik posiada. Kiedy tworzymy nowy plik, automatycznie stajemy się jego właścicielem. Plik ten będzie należał do naszej głównej grupy. Możemy zatem określić na jakich prawach właściciel i grupa i – co chyba najważniejsze – pozostali użytkownicy systemu będą mogli uzyskać dostęp do naszego pliku. Wyjątkiem tutaj jest użytkownik root, a konkretniej każdy użytkownik o dowolnej nazwie i numerze indentyfikacyjnym UID równym zero. W tym przypadku prawa go nie dotyczą, chyba, że sam je sobie nada.

Jakie mamy prawa?

Żeby odpowiedzieć sobie na pytanie, jakie prawa dostępu mają pliki, najpierw musimy wiedzieć, co w ogóle możemy zrobić z plikami? Czasem możemy chcieć otworzyć jakiś plik pdf, albo html, żeby coś przeczytać, czasem chcemy posłuchać jakiegoś pliku ogg, czy mp3, czasem oglądamy pliki graficzne, albo filmy. Zdaje się, że to różne czynności, ale tak na prawdę wszystkie łączy jedno: możliwość odczytu (ang. read). Jeśli nie możemy odczytać zawartości pliku, to nie będziemy w stanie z nim nic zrobić.

Oczywiście, żeby odczytać jakiś plik, trzeba móc go najpierw stworzyć. Jak już mamy stworzony jakiś plik, to przydałoby się móc w przyszłości zmienić jego zawartość, bądź skasować, kiedy nie jest nam już potrzebny. Do tego służy nam prawo zapisu (ang. write).

Niektóre pliki mogą być programami zapisanymi w specjalnym kodzie maszynowym (w przypadku Linuksa jest to format ELF, oraz – rzadziej już spotykany format a.out), bądź zwykłymi plikami tekstowymi, których zawartość jest napisana w języku programowania zrozumiałym dla jednego z interpreterów, np. Perla, Pythona, czy też dla powłoki bash, zsh, lub podobnej. W innym popularnym systemie operacyjnym o tym, czy dany plik jest programem, który możemy wykonać decyduje jego rozszerzenie (.exe, bądź .bat, a dla innych interpreterów .pl, .py, .rb), natomiast w systemach uniksopodobnych o tym, czy można dany plik (program) uruchomić decyduje trzeci atrybut – wykonywalność (ang. execute).

Wiemy już, jakie mamy prawa – read, write, execute. Możemy je przydzielać osobno dla właściciela pliku (ang. user), grupy (ang. group), oraz dla pozostałych użytkowników (ang. others). Dodatkowo atrybut wykonywalności ma specjalne znaczenie dla katalogów. Mianowicie oznacza on możliwość wejścia do katalogu. Jest to niezwykle ważne, bo jeśli nie możemy wejść do katalogu, to nie możemy w nim także nic zapisać.

Przeglądanie praw dostępu

Zobaczmy zatem, jak prezentują się omówione przez nas prawa w systemie. Oczywiście przeróżne graficzne menadżery plików oferują nam możliwość przeglądania praw dostępu, ale łatwiej wyświetlić je za pomocą polecenia ls -l. W wyniku powinniśmy otrzymać coś takiego:

razem 4
drwxr-xr-x 2 kwalo kwalo 4096 sie  4 17:01 katalog
-rw-r--r-- 1 kwalo kwalo    0 sie  4 17:00 plik

Opcja -l sprawia, że program ls wyświetla trochę więcej informacji, ale nas będzie interesowało, oczywiście poza nazwą pliku to, co się znajduje w kolumnach pierwszej, trzeciej i czwartej. Kolumny trzecia i czwarta pokazują nam właściciela pliku i nazwę grupy danego pliku. Pierwsza kolumna to właśnie nasze uprawnienia. Zawsze ma ona długość dziesięciu znaków. Pierwszy znak może przyjąć następujące wartości:

  • d – katalog (ang. directory)
  • – zwykły plik
  • b – urządzenie blokowe
  • c – urządzenie znakowe
  • C – ciągłe dane (ang. contigous data)
  • l – link symboliczny
  • p – kolejka FIFO (ang. named pipe)
  • s – gniazdo (ang. socket)
  • ? – inny, nieznany rodzaj pliku

Zdawałoby się, że typ pliku to rzecz zupełnie odmienna od praw dostępu do pliku, ale de facto są ze sobą blisko związane, np. katalog bez prawa do wykonywalności (czyt. możliwości wejścia do niego) staje się bezużyteczny, a linki symboliczne nie mają praw same w sobie. Odwołują się do praw pliku, do którego prowadzą. Kolejne dziewięć znaków należy podzielić na trzy grupy po trzy znaki. Pierwsza grupa to zbiór praw dla właściciela pliku, druga to prawa dla grupy, a trzecia dla pozostałych użytkowników systemu. Literki w każdej grupie mają swoje przypisane znaczenia, np. pierwsza grupa dla katalogu katalog to rwx. Każda literka oznacza jeden z wymienionych wcześniej atrybutów. Pierwsza to prawo odczytu – read, druga to prawo zapisu – write, a trzecia to atrybut wykonywalności – execute. Każda literka ma swoje przypisane miejsce. Np. r nie może się znajdować na trzecim miejscu, a x na drugim. Jeśli odebraliśmy któreś prawo, to zamiast odpowiadającej mu literki, występuje znak ’-’, np. w pliku plik druga, oraz trzecia grupa mają postać: r–. Oznacza to, że ten plik ma nadany atrybut odczytu, a zapis i wykonywanie dla grupy i pozostałych użytkowników systemu jest niemożliwy.

Zmiana praw – chmod

Skoro już wiemy, jak można wyświetlić dane prawa, to wypadałoby wiedzieć, jak je zmienić. Oczywiście możesz się posłużyć graficznym menadżerem plików, którego używasz na co dzień, ale polecenie chmod jest wygodną i zawsze dostępną metodą. Pozwala ono dodawać, i/lub odbierać atrybuty właścicielowi, grupie i pozostałym użytkownikom. Wystarczy poznać tylko format tego polecenia.

Format polecenia chmod ma postać:

chmod [ugoa...][[+-=][rwxXs-tugo...]...][,...] plik...

Kombinacja liter ugoa oznacza, komu chcemy zmienić uprawnienia: sobie (u), grupie (g), innym użytkownikom (o), lub wszystkim naraz (a). W tej części może pojawić się więcej niż jedna litera, np. go będzie oznaczało zmianę uprawnień dla grupy i pozostałych użytkowników. Litera a odpowiada kombinacji ugo, z pewnym wyjątkiem – mianowicie bity ustawione w umask są pomijane. O tym, co to jest umask będzie później.

Po tym, komu chcemy zmienić uprawnienia, musi występować jeden ze znaków +, -, lub =. Operator + oznacza nadanie atrybutu występującego po nim, – to odebranie atrybutu, natomiast = powoduje ustawienie dokładnie takich praw, jakie wybrano.

Ostatnia część to są prawa, jakie nadajemy. Znaki rwx- są nam znane z polecenia ls i wiadomo, co oznaczają. Znaku można użyć, jeśli operatorem jest =, ale nie jest on konieczny. Zamiast g=rw-, można napisać g=rw. Efekt będzie taki sam. Litera X oznacza nadanie praw wykonywalności tylko dla katalogów, lub plików, które już mają atrybut wykonywalności dla użytkownika. Pozostałe litery (tugo) oznaczają dodatkowe atrybuty, które omówię później.

Zdaje się, że ten format jest trochę pogmatwany, ale to nic strasznego. Kilka przykładów powinno rozjaśnić sytuację.chmod go-w plikTo polecenie odbiera prawo do zapisu grupie i pozostałym użytkownikom.

chmod u=rwx,go=rx plik
chmod u+rwx,go+rx,go-w plik
Te dwa polecenia robią to samo: Nadają właścicielowi pełne uprawnienia (odczyt, zapis i wykonanie), a grupie i pozostałym użytkownikom dają prawa tylko do odczytu i wykonania. Jeśli chcemy zmienić więcej niż jedną regułę na raz, to możemy to zrobić oddzielając je przecinkiem (bez spacji).

W tym przykładzie, zamiast wyjaśnień, proponuję wpisać w konsoli następujące polecenia i zobaczyć, co wyświetla polecenie ls -l. Zwłaszcza warto zwrócić uwagę na atrybut wykonywalności.touch plik1 plik2
mkdir katalog
chmod u+x plik1
chmod -x katalog
ls -l
chmod +X plik1 plik2 katalog
ls -l

Polecenie chmod przyjmuje kilka dodatkowych opcji, szczególnie użyteczną jest opcja rekurencyjnej zmiany uprawnień dla całego drzewa katalogów (-R). Jednak należy być szczególnie ostrożnym podczas zmiany uprawnień dla całego drzewa. Zazwyczaj należy wtedy dodawać, lub usuwać tylko pewne uprawnienia, a nie ustawiać „na sztywno” jakieś prawa dla całych drzew katalogów, np. polecenie chmod -R +X katalog ma sens. Jeśli odebraliśmy sobie, bądź innym uprawnienia wykonywania dla całej grupy katalogów, to zostaną one przywrócone, natomiast polecenie chmod -R go=rX katalogMoże okazać się zgubne. Nadaje ono na sztywno uprawnienia całemu drzewu, przez co inne zostają utracone. Niektóre pliki mogą zawierać atrybuty rozszerzone (o których będzie mowa poniżej) i takie polecenie może spowodować błędy w systemie. Należy zachować szczególną ostrożność przy rekurencyjnej zmianie uprawnień. Szczególnie, gdy wykonujemy to z poziomu superużytkownika (root).

Ósemkowy zapis praw dosępu

Wiemy już, jak przeglądać prawa dostępu i jak je zmieniać za pomocą polecenia chmod, ale warto wiedzieć, że istnieje inny sposób zapisywania tychże praw. Chodzi tu o zapis ósemkowy. Brzmi groźnie, ale jest on krótszy i wiele osób używa go, zwłaszcza przy ustalaniu praw w poleceniu chmod.

Zapis ósemkowy składa się z trzech liczb z zakresu 0-7. Każda liczba reprezentuje zestaw uprawnień dla odpowiednio: właściciela, grupy i pozostałych użytkowników, podobnie jak w formacie prezentowanym przez ls. Tylko co każda z liczb oznacza?

Mamy trzy prawa, które możemy modyfikować: odczyt (r), zapis (w) i wykonanie (x). W poleceniu ls -l widzimy formę znakową rwx. Jeśli jakieś prawo nie jest ustawione, to zamiast odpowiadającej mu literki jest znak -. Jest do dość czytelne, ale dla komputera, który jak wiadomo lubi liczby, zwłaszcza binarne zapis ten można uprościć do właśnie trzybitowej liczby. Pierwszy bit, podobnie jak r w ls -l, odpowiada za prawo do odczytu, dalej drugi za zapis, a trzeci za wykonanie. Zatem zastąpienie literek jedynkami, a – zerami daje nam binarny zapis praw. W przypadku praw rwx będzie to 111, a dla praw r-x to jest 101. Te trzybitowe liczby mogą zostać zamienione na odpowiadające im cyfry w systemie ósemkowym. Brzmi strasznie, ale w praktyce dostajemy liczby z zakresu 0-7, czyli możemy się posługiwać formatem dziesiętnym. Tak więc prawo rwx tłumaczymy na 111, a zatem mamy zapis ósemkowy 7. Dla prawa r–, mamy liczbę 100. W reprezentacji ósemkowej odpowiada to liczbie 4.

Jeśli nie wiesz, jak się zamienia liczby z formatu binarnego na ósemkowy, albo dziesiętny, to spróbuj innego podejścia. Nadajmy każdemu z praw odpowiednią wartość liczbową. Suma tych wartości będzie odpowiednim zestawem uprawnień:

  • r = 4 = 100 binarnie
  • w = 2 = 010 binarnie
  • x = 1 = 001 binarnie


Dla przykładu – zsumujmy zestaw uprawnień r-x. Prawo do odczytu ma wartość 4, a wykonanie 1, zatem 4 + 1 = 5. Dla uprawnień rwx mamy 4 + 2 + 1 = 7, czyli największą możliwą wartość.

Umask

Wartość umask jest wykorzystywana przez programy do nadawania domyślnych praw dostępu dla plików i katalogów. Możemy ją ustawić w naszej powłoce i wszystkie pliki, jakie będziemy tworzyć będą zawierały domyślny zestaw uprawnień wyliczany na podstawie wartości umask.

Wartość umask ma postać trzycyfrowej liczby zapisanej w postaci ósemkowej i zawiera te prawa, które powinny być usunięte przy tworzeniu pliku bądź katalogu. Domyślnymi uprawnieniami przy tworzeniu pliku są uprawnienia 666, czyli odczyt i zapis dla wszystkich, a dla katalogów jest to 777, czyli odczyt, zapis i wykonanie (wejście do katalogu). Jeśli np. mamy ustawioną maskę 022 (jest to wartość domyślna, zapisana w pliku /etc/profile), to np. dla plików wykonywana jest następująca operacja:

0666 AND NOT 0022

W wyniku otrzymamy uprawnienia 644, czyli rw-r–r–. Tak się też dzieje, kiedy tworzymy jakiś plik za pomocą polecenia touch, czy też przy użyciu edytora (zarówno zwykłego tekstowego, jak i np. OpenOffice.org).

Dodatkowe prawa

Wiemy już, jak wyglądają podstawowe prawa w systemach z rodziny Unix, ale to nie wszystko, co ma nam do zaoferowania ten system. Dodatkowo możemy zmusić system plików, aby:

  • Ustawił efektywny identyfikator użytkownika na identyfikator właściciela pliku (bit set-user-ID)
  • Ustawił efektywny identyfikator grupy (bit set-group-ID)
  • Uniemożliwił użytkownikom (poza rootem i właścicielem) kasowania, bądź zmieniania nazwy pliku w katalogu. Odpowiada za to tzw. „lepki bit” (ang. „sticky bit”). Dodatkowo na niektórych systemach, jeśli ten bit jest ustawiony na zwykłym pliku, to sprawia on, że zawartość tego pliku jest ładowana do pamięci swap i przez to plik jest szybciej wczytywany.

Bit set-user-ID najczęściej jest nadawany programom, które muszą być wykonane z uprawnieniami administratora, ale nie jest to zalecane i raczej się tego unika, gdyż może to poważnie zagrozić bezpieczeństwu naszego systemu. Oczywiście są wyjątki, które nie mogą się obejść bez tego atrybutu. Są to np. programy, które zmieniają identyfikator użytkownika (sudo, su, sg).

Zmiana właściciela pliku

Wiemy już jak zmieniać atrybuty plików, ale czasem okazuje się konieczna zmiana właściciela, lub grupę dla pliku. Jeśli należymy do pewnej grupy i chcemy, aby pewni jej członkowie mieli dostęp do określonych plików, musimy zmienić identyfikator grupy dla pliku. Podobnie, jak wszystkie uprawnienia jesteśmy w stanie ustawić jednym poleceniem chmod, tak identyfikator użytkownika i grupy możemy ustawić jednym poleceniem chown. Ma ono bardzo prostą składnię.

chown [użytkownik][:grupa] plik ...

Jeśli ustawiamy właściciela pliku, po prostu piszemy chown użytkownik plik. Nazwę grupy poprzedzamy dwukropkiem: chown :grupa plik, lub możemy to zrobić na raz: chown użytkownik:grupa plik. Warto tu wspomnieć o poleceniach su i sg, które odpowiednio zmieniają identyfikator użytkownika i domyślnej grupy. Aby zobaczyć, jaki mamy domyślny identyfikator grupy, posłużymy się poleceniem id nazwa_użtkownika. Polecenia te, choć wykonują podobną rzecz, różnią się nieco. Su zmienia identyfikator użytkownika na stałe, natomiast sg wykonuje polecenie z zmienionym domyślnym identyfikatorem grupy. Następujące komendy zobrazują działanie tego polecenia.id $(whoami)
sg cdrom id $(whoami)
Zwróćcie uwagę na pole gid, które otrzymacie przy obu poleceniach. Jest to właśnie domyślny identyfikator grupy.

Podsumowanie

Dla nowego użytkownika prawa dostępu mogą przysporzyć trochę kłopotów, ale warto poświęcić chwilę na poznanie podstaw, a okaże się, że jest to niezwykle proste i intuicyjne, a w przypadku systemu wieloużytkownikowego – konieczne. Oczywiście podejście stricte uniksowe nasuwa pewne ograniczenia. Np. nie można nadać prawa zapisu konkretnej osobie bez wcześniejszego utworzenia grupy, a czasem, kiedy nie mamy uprawnień administratora a prośby o utworzenie specjalnej grupy spotykają się z zdecydowaną odmową, to jest to bariera nie do przejścia. Taką możliwość oferują Access Control Listy, ale o tym w kolejnym artykule.


Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

21 komentarzy do “Dostęp do plików w Linuksie

  • szmergiell

    kwalo takie pytanie.
    Mam katalog i chcę żeby dostęp do niego mieli inni użytkownicy. Ale stawiam warunek. Mogą w nim zapisać plik, ale nie mają prawa nic z tego katalogu usuwać. Jak to zrobić?

  • c2p

    [quote comment=”11409″]kwalo takie pytanie.
    Mam katalog i chcę żeby dostęp do niego mieli inni użytkownicy. Ale stawiam warunek. Mogą w nim zapisać plik, ale nie mają prawa nic z tego katalogu usuwać. Jak to zrobić?[/quote]
    Kwalo o tym pisał, użyj „sticky bit”.

  • kwalo Autor wpisu

    [quote post=”540″]Mam katalog i chcę żeby dostęp do niego mieli inni użytkownicy. Ale stawiam warunek. Mogą w nim zapisać plik, ale nie mają prawa nic z tego katalogu usuwać. Jak to zrobić?[/quote]

    Ciekawe pytanie. Próbowałem się bawić z bitami setuid i setgid, ale to niestety nie działa. Jeśli dajesz prawo do zapisu dla katalogu określonej grupie użytkowników, to mogą oni tam tworzyć pliki i stają się ich właścicielami, mogą zatem kasować i modyfikować wszystkie swoje pliki. Nie znalazłem metody na to, aby właściciel pliku się zmienił, chociaż setuid na katalogu powinno to robić, ale widocznie ma on zastosowanie wyłącznie z programami, bądź skryptami. Być może ktoś inny znajdzie rozwiązanie przy użyciu standardowych praw dostępu?

    Istnieje jednak inna metoda, której nie próbowałem, ale powinna zadziałać:
    Istnieje taka biblioteka, jak inotify pozwala ona na śledzenia zmian w plikach, lub katalogach i ma wygodny interfejs w pythonie – pyinotify. Jeśli jakiś program „obserwuje” dany plik, to będzie on powiadamiany o zmianach, jakie w danym pliku (katalogu) zachodzą. Możesz zatem sprawdzać, czy w danym katalogu został utworzony jakiś plik i zmienić jego właściciela na samego siebie, oraz ustawić mu odpowiednie prawa, aby nikt nie mógł tego pliku usunąć.

    Program taki powinien działać przez cały czas, jak maszyna jest włączona i być uruchomiony z poziomu superużytkownika (albo mieć ustawiony bit setuid).

    Ewentualnie, gdybyś miał z tym jakieś problemy, to napisz wątek na forum i powiadom mnie o nim przez PW, to postaram się Ci pomóc.

  • zyga

    [quote post=”540″]Zdaje się, że ten format jest trochę pogmatwany, ale to nic strasznego. Kilka przykładów powinno rozjaśnić sytuację.
    chmod go-w plik
    To polecenie odbiera prawo do odczytu grupie i pozostałym użytkownikom.[/quote]

    chyba sie pozwole sobie nie zgodzic 😉

  • kwalo Autor wpisu

    @zyga, mógłbyś nieco rozwinąć swoją wypowiedź? Konstruktywna krytyka jest zawsze mile widziana, ale w tym momencie nie wiem, o co Ci chodzi. Twój komentarz nic nie wnosi do dyskusji.

  • zyga

    chmod go-w plik – odbiera prawo do ZAPISU (w – write) a nie do ODCZYTU

    magda@papio:/home/tmp$ touch 1
    magda@papio:/home/tmp$ ls -la 1
    -rw-r–r– 1 magda magda 0 2007-09-07 10:59 1
    magda@papio:/home/tmp$ chmod 777 1
    magda@papio:/home/tmp$ ls -la 1
    -rwxrwxrwx 1 magda magda 0 2007-09-07 10:59 1
    magda@papio:/home/tmp$ chmod go-w 1
    magda@papio:/home/tmp$ ls -la 1
    -rwxr-xr-x 1 magda magda 0 2007-09-07 10:59 1
    magda@papio:/home/tmp$

    czyli zniknal bit zapisu (w) a nie odczytu (r) dla g i o

    no chyba ze ubuntu „umie” inaczej 😉

  • LordD

    A jak zmienić właściciela katalogu/katalogów? Nie chce sie bawic w zmienianie własciciela pojedynczych plikow, chce, zebym mogl zmienic wlasciciela dla calego folderu i calej zawartosci (pliki i podfoldery).

  • LordD

    Dzięki. Kiedyś nie byłem przekonany do wklepywania czegokolwiek w terminal, ale teraz widzę wyraźnie jak czasem bardzo to ułatwia sprawę, jest szybciej, jest większa przejrzystość, jest lepiej. 🙂

  • vampire

    [quote comment=”11409″]kwalo takie pytanie.
    Mam katalog i chcę żeby dostęp do niego mieli inni użytkownicy. Ale stawiam warunek. Mogą w nim zapisać plik, ale nie mają prawa nic z tego katalogu usuwać. Jak to zrobić?[/quote]

    Po glowie mi chodzi haslo „ACL”. Nie bawilem sie tym dlugo, ale warto byloby zerknac mozliwosci tego rozszerzenia.

  • Amonit

    Witam
    Mam wątpliwości czy moje pytanie jest na temat, ale problem nietypowy.
    Potrzebuję dodatkową partycję poza /home. Założyłem takową, jest w podglądzie, ale jest nienazwana i nie mam do niej dostępu. Jak założyć tam katalog? Da się?
    Pozdrawiam

  • nowy

    Mam pytanie: jak usunąć z kosza plik, do którego nie ma się atrybutu rwx???? Przy próbie wychodzi błąd „Error removing file: Permission denied”. Pomocy!

  • zielony

    Pytanie od zielonego użytkownika …starałem się zrozumieć co tutaj napisane ale nic z tego 🙁 Więc mam proste pytanie jak zmienić uprawnienia dla tego pliku /usr/share/pixmaps/pidgin/emotes tak abym mógł wkleić katalog ze swoimi emotkami . .Proszę o prostą komendę .
    Ps . Nie mam nautilusa i nie mogę zainstalować …nie działa 🙁 (więc proszę o nim nie pisać .;) Mam ubuntu 12.04 .Pozdr.