Finnish Linux User Group FLUG ry
Suomen Linux-käyttäjien yhdistys

Toiminta Linux-ohjeita Tiedosto-oikeudet

Tämä kirjoitus kertoo Linuxin tavasta hallita käyttäjien oikeuksia käsitellä tiedostoja. Esimerkit on tehty Red Hat Linuxin versiolla 7.2, mutta eroja muihin Linux-jakelupaketteihin ei pitäisi käytännössä olla, ja teksti sopii lähes sellaisenaan myös muiden Unix-tyyppisten järjestelmien käytännön kuvaamiseen.

Teksti etenee esimerkkien kautta. Esimerkit edellyttävät, että sinulla on pääkäyttäjän oikeudet koneellesi. Tekstissä käytetään muutamia peruskomentoja joita ei selitetä, mutta muutoin on pyritty vääntämään asia paksusta rautalangasta tekstin tiiviyden kustannuksella. Tätä tekstiä ei kannata pelkästään lukea, vaan myös kokeilla komentoja itse.

Sisällys

Alkuvalmistelu: käyttäjien ja ryhmien luonti

Aloitetaan luomalla käyttäjät aku, iines ja mikki. Tehdään sitten ryhmä miehet, johon tulevat aku ja mikki, sekä ryhmä ankat, johon tietysti kuuluvat aku ja iines. Anna komennot rootin tunnuksella.

[root@kone root]# adduser aku
[root@kone root]# adduser iines
[root@kone root]# adduser mikki
[root@kone root]# groupadd miehet
[root@kone root]# groupadd ankat

[root@kone root]# gpasswd -a aku ankat
Adding user aku to group ankat
[root@kone root]# gpasswd -a iines ankat
Adding user iines to group ankat
[root@kone root]# gpasswd -a aku miehet
Adding user aku to group miehet
[root@kone root]# gpasswd -a mikki miehet
Adding user mikki to group miehet

Halutessasi voit nyt tarkistaa, että käyttäjät ja ryhmät todella on luotu katsomalla tiedostojen /etc/passwd/etc/group loppua:

[root@kone root]# tail -3 /etc/passwd
aku:x:504:505::/home/aku:/bin/bash
iines:x:505:506::/home/iines:/bin/bash
mikki:x:506:507::/home/mikki:/bin/bash

[root@kone root]# tail -2 /etc/group
miehet:x:508:aku,mikki
ankat:x:509:aku,iines

Luvut riippuvat siitä, montako käyttäjää ja ryhmää testikoneessa entuudestaan on.

Uusille käyttäjille tarvitaan salasanat. Komennolla passwd aku voit asettaa akun salasanan, ja tietysti muille käyttäjille salasanat tulevat vastaavasti.

Perusasia: käyttäjät, ryhmät ja oikeudet

Tiedoston luku- ja kirjoitusoikeus

Kirjaudu sisään tunnuksella aku ja siirry hakemistoon /tmp cd-komennolla. Anna komento
umask 777
(Komennon merkitys selitetään myöhemmin, älä mieti sitä vielä.) Luo tiedosto kirje.txt esimerkiksi komennolla
echo "Hei Iines" > kirje.txt
Tuloksena on tiedosto, jota ei edes aku itse voi käsitellä. Katsotaan tiedostolistaus:

[aku@kone tmp]$ ls -l kirje.txt
----------    1 aku     aku           10 syys  15 15:23 kirje.txt

Ja yritetään tulostaa tiedoston sisältö:

[aku@kone tmp]$ cat kirje.txt
cat: kirje.txt: Permission denied

Lukuoikeus annetaan chmod

[aku@kone tmp]$ chmod u=r kirje.txt
[aku@kone tmp]$ ls -l kirje.txt
-r--------    1 aku     aku           36 syys  15 15:30 kirje.txt
[aku@kone tmp]$ cat kirje.txt Hei Iines

Esimerkin chmod-komento tarkoittaa "aseta tiedoston omistajalle oikeus lukea tiedostoa, mutta ei mitään muuta oikeutta". Lukuoikeuden näkee r-kirjaimesta tiedostolistauksessa. cat-komento tulostaa tiedoston nyt, kun lukuoikeus on annettu.

Yritetään lisätä rivi tiedostoon:

[aku@kone tmp]$ echo "Olen pohtinut suhdettamme" >> kirje.txt

bash: kirje.txt: Permission denied

Lisätään kirjoitusoikeuskin:

[aku@kone tmp]$ chmod u=rw kirje.txt
[root@kone tmp]# ls -l kirje.txt
-rw-------    1 aku     aku           36 syys  15 15:30 kirje.txt
[aku@kone tmp]$ echo "Olen pohtinut suhdettamme" >> kirje.txt

[aku@kone tmp]$ cat kirje.txt
Hei Iines
Olen pohtinut suhdettamme

Mahdollista on myös antaa tiedostolle pelkästään kirjoitusoikeus, vaikkei tätä käytännössä paljonkaan käytetä. Esimerkin vuoksi, kokeilkaamme:

[aku@kone tmp]$ chmod u=w kirje.txt
[aku@kone tmp]$ ls -l kirje.txt
--w-------    1 aku     aku           36 syys  15 15:30 kirje.txt

[aku@kone tmp]$ echo "ja tullut siihen tulokseen" >> kirje.txt
[aku@kone tmp]$ cat kirje.txt
cat: kirje.txt: Permission denied

Tiedoston suoritusoikeus

Nyt tarvitaan ohjelmatiedosto, ja sopiva sellainen on pwd, joka vain tulostaa työhakemiston. Kopioidaan se vaikka nimelle "tyohak".

[aku@kone tmp]$ cp /bin/pwd tyohak
[aku@kone tmp]$ ls -l tyohak
----------    1 aku     aku        10428 syys   5 13:29 tyohak

Yritetään ajaa ohjelma, lisätään suoritusoikeus ja yritetään uudelleen.

[aku@kone tmp]$ ./tyohak
bash: ./tyohak: Permission denied

[aku@kone tmp]$ chmod u=x tyohak
[aku@kone tmp]$ ls -l tyohak
---x------    1 aku     aku        10428 syys   5 13:29 tyohak
[aku@kone tmp]$ ./tyohak
/tmp

Ohjelmatiedoston sisältöä ei silti pysty tulostamaan, kokeile vaikka less-komennolla. (Ohjelmatiedosto näyttää epämääräiseltä mössöltä, ja joskus sen tulostaminen cat-komennolla sekoittaa konsolin merkistön, siksi less-komento on parempi.) Kokeile lisätä lukuoikeus (u=rx) ja varmista vielä, että lukuoikeus ja suoritusoikeus ovat toisistaan riippumattomia. Myös kirjoitusoikeus on erillinen oikeus; sitäkin voit kokeilla, mutta muutetun ohjelmatiedoston ajaminen ei ole hyvä idea.

Tässä vaiheessa siis näet, että pitkän tiedostolistauksen alussa olevan kymmenen merkin toinen, kolmas ja neljäs merkki kuvaavat luku-, kirjoitus- ja suoritusoikeuksia kirjaimilla r, w ja x.

Hakemistojen oikeudet

Seuraavana vuorossa: oikeudet hakemistoille. Jotta Linuxin käyttö ei olisi liian helppoa, on hakemistoilla samat r-, w- ja x-oikeudet, mutta niiden merkitys on aivan muu kuin tiedostoilla. Aloitetaan tekemällä hakemisto kirjeet, ja vaihteeksi edetään toisinpäin poistamalla oikeuksia.

[aku@kone tmp]$ mkdir kirjeet
[aku@kone tmp]$ chmod u=rwx kirjeet/
[aku@kone tmp]$ ls -ld kirjeet
drwx------    2 aku     aku         1024 syys  15 16:08 kirjeet

Komento ls toimii normaalisti niin, että ls xx näyttää tiedoston xx, jos xx on tiedosto, ja hakemiston xx sisältämät tiedostot, jos xx on hakemisto. d-valitsin muuttaa toimintaa niin, että tulostetaan pelkästään hakemiston nimi eikä sisältöä.

Jos ensimmäinen merkki tiedostolistauksessa on d-kirjain, on kyse hakemistosta eikä tavallisesta tiedostosta.

Luodaan hakemistoon kirje, annetaan sille luku- ja kirjoitusoikeus, tulostetaan kirjeet-hakemiston sisältö ja vielä tulostetaan kirje:

[aku@kone tmp]$ echo "Moi Hessu" > kirjeet/hessulle.txt
[aku@kone tmp]$ chmod u=rw kirjeet/hessulle.txt

[aku@kone tmp]$ ls -l kirjeet
total 1
-rw-------    1 aku     aku           10 syys  15 16:31 hessulle.txt
[aku@kone tmp]$ cat kirjeet/hessulle.txt
Moi Hessu

Poistamalla hakemistolta suoritusoikeus poistuu oikeus käsitellä hakemiston joko suoraan tai alihakemistojen kautta sisältämiä tiedostoja. Siis

[aku@kone tmp]$ chmod u=rw kirjeet

[aku@kone tmp]$ ls -ld kirjeet
drw-------    2 aku     aku         1024 syys  15 16:31 kirjeet
[aku@kone tmp]$ cat kirjeet/hessulle.txt
cat: kirjeet/hessulle.txt: Permission denied

Jos taas suoritusoikeus on, mutta lukuoikeus puuttuu, niin...

[aku@kone tmp]$ chmod u=xw kirjeet

[aku@kone tmp]$ ls -ld kirjeet
d-wx------    2 aku     aku         1024 syys  15 16:31 kirjeet
[aku@kone tmp]$ cat kirjeet/hessulle.txt
Moi Hessu
aku@kone tmp]$ ls -l kirjeet
ls: kirjeet: Permission denied

...hakemiston sisältämiä tiedostoja voi käsitellä, mutta hakemiston sisältöä ei saa listattua. Käytännössä siis tiedoston käyttö onnistuu vain, jos tiedoston nimen tietää etukäteen. (Tosin mikään ei estä kokeilemasta järjestyksessä cat aaa, cat aab, cat aac ... cat zzz. Aikaa saattaa kyllä kulua aika kauan.)

Uusia tiedostoja saa tehdä (ja vanhoja poistaa) hakemistoon, johon on kirjoitusoikeus ja suoritusoikeus. Kokeilemme:

[aku@kone tmp]$ chmod u=rwx kirjeet

[aku@kone tmp]$ ls -ld kirjeet
drwx------    2 aku     aku         1024 syys  15 16:31 kirjeet
[aku@kone tmp]$ echo "Moi Minni" > kirjeet/minnille.txt
[aku@kone tmp]$ chmod u=rx kirjeet
[aku@kone tmp]$ ls -ld kirjeet
dr-x------    2 aku     aku         1024 syys  15 16:41 kirjeet

[aku@kone tmp]$ echo "Moi Iines" > kirjeet/iinekselle.txt
bash: kirjeet/iinekselle.txt: Permission denied

Käyttäjät ja ryhmät (ja kaikki muut)

Nyt päästään vihdoin asiaan. Kuten noin 7000 merkkiä sitten muistat, luotiin aluksi ryhmä ankat, johon tuli käyttäjät aku ja iines. Red Hat Linux toimii niin, että jokainen käyttäjä kuuluu omaan henkilökohtaiseen ryhmäänsä. Siksi tiedostolistauskin näyttää käyttäjätunnuksen kahteen kertaan:

----------    1 aku     aku           10 syys   1 21:54 kirje.txt

Vaihdetaan tiedoston ryhmäksi ankat komennolla chgrp, ja annetaan ryhmälle lukuoikeus sekä akulle itselleen luku- ja kirjoitusoikeus:

[aku@kone tmp]$ chgrp ankat kirje.txt
[aku@kone tmp]$ chmod g=r kirje.txt
[aku@kone tmp]$ chmod u=rw kirje.txt
[aku@kone tmp]$ ls -l kirje.txt

-rw-r-----    1 aku     ankat         10 syys   1 21:54 kirje.txt

Kirjaudu toisista virtuaalikonsoleista tunnuksilla iines ja mikki ja kokeile miten tiedostoa voi käsitellä:

[iines@kone tmp]$ cat kirje.txt
Hei Iines
[iines@kone tmp]$ echo "Tekstiä kirjeeseen" > kirje.txt

bash: kirje.txt: Permission denied

[mikki@kone tmp]$ cat kirje.txt
cat: kirje.txt: Permission denied

Siis: ankat-ryhmään kuuluu akun lisäksi iines, ja ryhmälle on annettu chmod-komennolla lukuoikeus (siis g=group ja r=read), mutta ei kirjoitusoikeutta. Siksi iines voi lukea tiedoston sisällön ja vaikka kopioida sen itselleen vaan ei kirjoittaa tiedostoon. Mikillä ei ole mitään asiaa käpälöidä tiedostoa.

Tiedostolla on aina tasan yksi ryhmä, samaa tiedostoa ei aku siis voi antaa sekä ankat- että miehet-ryhmän käsiteltäväksi.

Tiedoston omistajan ja ryhmän lisäksi oikeuksia voi antaa myös kaikille käyttäjille. Jos esimerkiksi aku ja mikki kirjoittavat yhdessä julistusta miesten sorsimisesta, ja pitävät jutun kirjoitusaikanakin kaikkien luettavissa, se onnistuu näin:

[aku@kone tmp]$ echo "Miesten asema nykyään:" > julistus.txt
[aku@kone tmp]$ chgrp miehet julistus.txt
[aku@kone tmp]$ chmod u=rw julistus.txt
[aku@kone tmp]$ chmod g=rw julistus.txt
[aku@kone tmp]$ chmod o=r julistus.txt

[aku@kone tmp]$ ls -l julistus.txt
-rw-rw-r--    1 aku     miehet        23 syys   1 22:08 julistus.txt

Viimeisessä chmod-komennossa o-kirjain tulee sanasta "others", siis "muut". Nyt tiedostoon voivat kirjoittaa aku ja mikki, ja iines (ja kaikki muutkin koneen käyttäjät) voivat lukea tiedostoa. Kokeile!

Tiedostolistauksessa näkyy siis alussa kymmenen merkkiä. Ensimmäinen kuvaa tiedoston tyyppiä, viiva tarkoittaa tiedostoa ja d-kirjain hakemistoa, ja loput yhdeksän merkkiä jakautuvat kolmeen ryhmään, joista kussakin on kolme merkkiä. Ensimmäinen kolmikko kuvaa omistajan itsensä oikeuksia tiedostoon, toinen kolmikko ryhmän oikeuksia ja viimeinen kolmikko kaikkien oikeuksia. Jokaisessa ryhmässä samat oikeudet merkitään kirjaimilla r, w ja x.

Kaikki mitä aiemmin opit suoritusoikeuksista ja hakemistojen oikeuksista pätee yhä. Esimerkiksi aku voi lukea tiedoston /tmp/aa/bee/cee.txt sisällön, jos hakemistolla /tmp on kaikille suoritusoikeus, hakemiston /tmp/aa ryhmä on miehet ja ryhmällä on suoritusoikeus, hakemiston /tmp/aa/bee ryhmä on ankat ja ryhmällä on suoritusoikeus, ja tiedoston cee.txt omistaja on aku ja akulla on lukuoikeus tiedostoon. Monimutkaista? Ei oikeastaan, mutta kannattaa oikeasti harjoitella kunnes tuntee osaavansa asian. Kokeillessa kannattaa kirjautua sisään useista virtuaalikonsoleista eri tunnuksilla ja sanoa aina ensimmäisenä umask 777. (Usko pois, kyllä se umask-komentokin vielä selitetään. :=) )

Hakemistojen suoritusoikeus (x) on helpoin mieltää kauttakulkuoikeudeksi: tarvitset suoritusoikeuden jokaiseen käsiteltävän tiedoston polussa olevaan hakemistoon.

chmodista lisää

Edellä on käytetty chmod-komennosta vain muotoa, joka asettaa oikeudet. On mahdollista käyttää myös plusmerkkiä oikeuden lisäämiseen ja miinusmerkkiä oikeuden poistamiseen. On mahdollista antaa yhdellä kertaa oikeuksia sekä omistajalle, ryhmälle että muille. Lisäksi a-kirjain tarkoittaa "all" eli kaikkia. Esimerkki valaissee parhaiten:

[aku@kone tmp]$ ls -l julistus.txt
-rw-rw-r--    1 aku     miehet        23 syys   1 22:08 julistus.txt

[aku@kone tmp]$ chmod g-w julistus.txt
[aku@kone tmp]$ ls -l julistus.txt
-rw-r--r--    1 aku     miehet        23 syys   1 22:08 julistus.txt
[aku@kone tmp]$ chmod a=w julistus.txt
[aku@kone tmp]$ ls -l julistus.txt

--w--w--w-    1 aku     miehet        23 syys   1 22:08 julistus.txt
[aku@kone tmp]$ chmod u+r,go-w julistus.txt
[aku@kone tmp]$ ls -l julistus.txt
-rw-------    1 aku     miehet         2 syys   5 12:30 julistus.txt

chmod tuntee valitsimen -r, pidemmälti sanottuna --recursive. Se tarkoittaa, että oikeudet muutetaan kaikkien alihakemistojenkin tiedostoihin. Sama valitsin toimii myös chgrp-komennossa.

chmod tuntee vielä myös ison X-kirjaimen. Se tarkoittaa suoritusoikeutta kaikille hakemistoille ja niille tiedostoille, joilla jo suoritusoikeus on. Käytännössä root testaa ensin jonkun hakemiston haaran toiminnan ja sanoo sitten
chmod --recursive a+rX hakemistonnimi
jolloin kaikille tulee oikeus lukea tiedostoja ja listata kaikkien tiedostojen sisältö, sekä oikeus ajaa kaikkia niitä ohjelmatiedostoja, joihin suoritusoikeus oli.

root on kaikkivaltias; chown-komento

Vain omistamansa tiedoston ryhmän voi vaihtaa, ja ryhmäksi voi laittaa vain sellaisen ryhmän, jonka jäsen on. Siis aku voi vaihtaa vain omien (eli yleensä itse luomiensa) tiedostojen oikeuksia, ja vain ryhmiin ankat tai miehet, Red Hat Linuxin tapauksessa myös ryhmään aku. root on kuitenkin aina kaikkivaltias, ja voi vaihtaa minkä tahansa tiedoston ryhmän miksi tahtoo, ja voi myös vaihtaa kaikkien tiedostojen oikeuksia.

chown-komennolla voi vaihtaa tiedoston omistajan. Komentoa voi käyttää vain root. Samalla komennolla voi vaihtaa sekä omistajan että ryhmän erottamalla ne pisteellä. Esimerkki:

[root@kone tmp]# ls -l kirje.txt julistus.txt
-rw-r-----    1 aku     ankat         10 syys   1 21:54 kirje.txt
-rw-rw-rw-    1 mikki   miehet        23 syys   1 22:08 julistus.txt
[root@kone tmp]# chown iines kirje.txt

[root@kone tmp]# chown aku.ankat julistus.txt
[root@kone tmp]# ls -l kirje.txt julistus.txt
-rw-r-----    1 iines   ankat         10 syys   1 21:54 kirje.txt
-rw-rw-rw-    1 aku     ankat         23 syys   1 22:08 julistus.txt

umask ja hassut numeroarvot

Jos ihmisellä olisi kahdeksan sormea, niin käyttäisimme kai numeroita nollasta seitsemään. Kahdeksanlukujärjestelmä sopii kivasti kolmen kyllä/ei -arvon esittämiseen: kun määritellään r-oikeuden arvoksi neljä, w-oikeuden arvoksi kaksi ja x-oikeuden arvoksi yksi, saadaan summaksi luku nollasta seitsemään. Kolmella tällaisella luvulla saadaan kuvattua kaikki oikeudet, ja chmod hyväksyy numeroarvotkin.

Esimerkiksi omistajalle luku- ja suoritusoikeus tekee neljä ynnä yksi tekee viisi, ryhmälle kirjoitusoikeus tekee kaksi ja muille ei mitään oikeuksia tekee nolla, eli:

[aku@kone tmp]$ chmod 520 kirje.txt

[aku@kone tmp]$ ls -l kirje.txt
-r-x-w----    1 aku     aku            4 syys   1 22:53 kirje.txt

Numeroarvot ovat epäkäteviä, mutta umask-komento toimii vain numeroilla. Umask tarkoittaa mitä oikeuksia luotavat tiedostot oletusarvoisesti eivät saa. umask 777 tarkoittaa ettei tiedostoille tule mitään oikeuksia kenelläkään, ja esimerkiksi aika käyttökelpoinen umask 027 antaa oletusarvoisesti tiedoston omistajalle kaikki oikeudet (0=ei mitään, siis jää kaikki) ja ryhmälle luku- ja suoritusoikeuden (2=kirjoitus, siis jää luku ja suoritus) ja muille ei mitään (7=1+2+4=kaikki, siis ei jää mitään).

Jälleen kerran: kokeile! Vaihda umask, luo uusi tiedosto ja katso mitä oikeuksia se saa. Antamalla pelkän umask-komennon näet mikä on maskin arvo tällä hetkellä.

Edelliset kappaleet olivat huijausta. Oikeasti umask toimii myös symbolisessa muodossa, kokeile vaikka komentoa

umask -S u=rwx,g=rx,o=
Sen sijaan esimerkiksi samban (palvelu, joka jakaa Linux-palvelimen levyjä windows-työasemille) asetustiedostoon umask-arvot pitää syöttää oktaalinumeroina.

>Edistyneempi asia: erikoisokeudet

Erikoisempia oikeuksia tiedostoille

Edellä tuli kerrottua "tavalliset" oikeudet. Lisäksi on vielä kolme erikoisempaa oikeutta.

Normaalisti käyttäjän oikeudet periytyvät käynnistettäville ohjelmille, eli ellei akulla ole lukuoikeutta tiedostoon, ei mikään akun käynnistämä ohjelmakaan tiedostoa voi lukea. setuid-oikeus tarkoittaa, että ohjelmatiedosto suoritetaan tiedoston omistajan oikeuksilla. Asia on helpoin esittää esimerkillä.

Aloitetaan tekemällä ohjelma "tulosta", joka tulostaa ensimmäisen merkin hakemiston /tmp/aku sisältämästä tiedostosta. Kopioi seuraava ohjelma tiedostoon nimeltä tulosta.c++

#include 
#include 

int main(int argc, char * argv[]) {
  char tiedostonnimi[100]="/tmp/aku/";
  int polunpituus=strlen("/tmp/aku/");
  if (argc < 2) {
    cout << "Virhe. Anna tiedostonnimi.\n";
  }
  else {
    if (strlen(argv[1]) >= 100-polunpituus) {
      cout << "Virhe. Anna lyhyempi tiedostonnimi.\n";
    }
    else {
      strcpy(tiedostonnimi+polunpituus, argv[1]);
      ifstream tiedosto(tiedostonnimi);
      if (tiedosto.good())
        {
          char merkki;
          tiedosto >> merkki;
          cout << merkki << "\n";
        }
      else {
        cout << "Virhe. Tiedostoa ei löydy tai ei voi lukea.\n";
      }
    }
  }
}

Vaihda ensin umask, jotta kääntäjä voi lukea väliaikaisia tiedostojaan. Käännä tulosta.c++ g++ -komennolla, jolloin tuloksena on ajettava ohjelma nimeltään "tulosta". Tee hakemisto "aku" ja laita hakemistoon tiedosto, jonka sisältönä on vaikka "xyz".

[aku@kone tmp]$ umask 077
[aku@kone tmp]$ g++ -o tulosta tulosta.c++
[aku@kone tmp]$ mkdir aku
[aku@kone tmp]$ echo "xyz" > aku/jee

[aku@kone tmp]$ ls -l aku/jee
samp>-rw-------    1 aku     aku            4 syys   5 15:45 aku/jee

Anna tulosta-ohjelmalle suoritusoikeus kaikille käyttäjille ja kokeile ohjelman toimintaa eri käyttäjätunnuksilla. Lisää sitten setuid-oikeus ja kokeile uudelleen:

[aku@kone tmp]$ chmod a+x tulosta
[aku@kone tmp]$ ./tulosta jee
x

[iines@kone tmp]$ ./tulosta jee
Virhe. Tiedostoa ei löydy tai ei voi lukea.

[aku@kone tmp]$ chmod u+s tulosta
[aku@kone tmp]$ ls -l tulosta
-rws--x--x    1 aku     aku        15791 syys   5 15:44 tulosta

[iines@kone tmp]$ ./tulosta jee
x

Siis nyt ohjelma "tulosta" suoritetaan aina käyttäjän "aku" oikeuksilla, ja ohjelma voi siis lukea ja kirjoittaa niitä tiedostoja joihin akulla on oikeus, siirtyä vastaavasti hakemistoihin jne, ja ohjelman mahdollisesti edelleen käynnistämät ohjelmat saavat myös samat oikeudet. Edelläoleva esimerkki on tyhmä, mutta osoittaa perusidean: käyttäjä voi sallia tiedostojen käytön muille jollain rajatulla tavalla.

b>setuid on vaarallinen! Mitä tapahtuu, jos iines käyttää komentoa
/tmp/tulosta ../../home/aku/salainen-tiedosto ?

Käytännössä setuid-oikeutta käyttää lähinnä root. Esimerkiksi tiedostoihin /etc/passwd ja /etc/shadow pääsee kirjoittamaan vain root,

[aku@kone tmp]$ ls -l /etc/passwd /etc/shadow
-rw-r--r--    1 root    root        1352 syys  15 15:18 /etc/passwd
-rw-------    1 root    root        1202 syys  15 15:18 /etc/shadow

mutta käyttäjienhän pitää päästä vaihtamaan oma salasanansa. Se onnistuu, sillä passwd-ohjelmalla on setuid-oikeus päällä:

[aku@kone tmp]$ ls -l /usr/bin/passwd
-r-s--x--x    1 root     root      13476 elo     7 07:03 /usr/bin/passwd

passwd-ohjelma taas rajoittaa toimintaa niin, että jokainen käyttäjä voi vaihtaa vain oman salasanansa. Jos passwd-ohjelmasta löytyisi sopiva virhe, niin käyttäjät voisivat vaikka vaihtaa rootin salasanan, ja päästä näin tuhoamaan koko järjestelmän! Voit kokeilla itsekin setuid-bittiä tässä:

[root@kone tmp]# chmod u-s /usr/bin/passwd
[root@kone tmp]# ls -l /usr/bin/passwd

-r-x--x--x    1 root     root      13476 elo     7 07:03 /usr/bin/passwd

[mikki@kone tmp]$ passwd
passwd: Authentication token manipulation error

[root@kone tmp]# chmod u+s /usr/bin/passwd

[mikki@kone tmp]$ passwd
Changing password for mikki
(current) UNIX password:

Aivan samoin kuin setuid-oikeus toimii myös setgid-oikeus, joka tekee ohjelman ajettavaksi ryhmän oikeuksilla. Kokeile tätäkin itse, komento on chmod g+s

Mikään ei estä antamasta samalle ohjelmalle sekä setuid- että setgid-oikeuksia.

setuid ja setgid eivät toimi shell-skripteillä. Syy tähän on turvallisuus, shell-skriptiä olisi liian helppo väärinkäyttää. (Kun ohjelma alkaa #!/bin/bash se suoritetaan käynnistämällä ensin bash ja sitten bash lukee shelliskriptin ja toimii sen mukaan. Tässä välissä voisi käyttäjä vaihtaa skriptin sisältöä (onnistuu sopivalla symbolisella linkillä), ja pääsisi suorittamaan omaa koodiaan jonkun toisen tunnuksilla.)

(setgid-oikeus ilman suoritusoikeutta ryhmälle tarkoittaa mandatory lockingia, aihetta ei käsitellä tässä.)

Ohjelmatiedostolle voi asettaa kolmannenkin erikoisoikeuden, ns. sticky bitin eli tahmabitin, komennolla
chmod o+t tiedostonnimi
mutta Linuxissa se ei vaikuta mitään, vaikka ainakin Reh Hat Linuxin sisältämä chmod-komennon manuaalisivu niin väittääkin.

Ohjelmakoodia ei siirretä sivutustiedostoon muistin loppuessa samalla tavoin kuin dataa, ohjelmakoodihan voidaan aina ladata levyltä uudelleen. t-bitti ohjelmatiedostossa muuttaa tätä joissakin Unixeissa niin että ohjelmakoodikin voidaan sivuttaa. Tästä olisi teoreettista hyötyä jos ohjelma sijaitsisi hitaalla levyllä ja sivutustiedosto nopealla levyllä, mutta Linux siis ei ominaisuutta tue.

Erikoisempia oikeuksia hakemistoille

Kuten "tavallisten" oikeuksienkin kohdalla, on hakemistoilla muodollisesti samat erikoisoikeudet kuin tiedostoilla, mutta merkitys on aivan muu.

Hakemistollekin voi asettaa setuid-oikeuden, mutta se ei vaikuta mitenkään.

setgid-oikeus hakemistolla tarkoittaa, että hakemistoon luotavat tiedostot saavat saman ryhmän kuin hakemistolla on. Eli esimerkiksi:

[aku@kone tmp]$ mkdir juttuja
[aku@kone tmp]$ chgrp ankat juttuja
[aku@kone tmp]$ chmod 770 juttuja

[aku@kone tmp]$ ls -ld juttuja
drwxrwx---    2 aku     ankat       1024 syys   2 00:40 juttuja

[iines@kone tmp]$ echo "juu" > juttuja/ekajuttu

[aku@kone tmp]$ chmod g+s juttuja

[iines@kone tmp]$ echo "joo" > juttuja/tokajuttu
[iines@kone tmp]$ ls -l juttuja
total 2
-rw-rw-r--    1 iines   iines          4 syys   2 00:42 ekajuttu
-rw-rw-r--    1 iines   ankat          4 syys   2 00:43 tokajuttu

Setgid hakemistoille periytyy:

[iines@kone juttuja]$ mkdir alihakemisto
[iines@kone juttuja]$ ls -ld alihakemisto
drwxrwsr-x    2 iines   ankat       1024 syys   2 00:45 alihakemisto

Lopuksi on vielä sticky bit, epävirallisesti suomennettuna tahmabitti, hakemistoille. Se tarkoittaa, että vain tiedoston omistaja saa poistaa tiedoston - normaalistihan kirjoitusoikeus hakemistolle antaa oikeuden poistaa hakemistosta kaikkia tiedostoja. Esimerkki:

[aku@kone tmp]$ mkdir tekstit

[aku@kone tmp]$ chgrp ankat tekstit
[aku@kone tmp]$ chmod 770 tekstit
[aku@kone tmp]$ echo "moi" > tekstit/eka
[aku@kone tmp]$ echo "hei" > tekstit/toka
[aku@kone tmp]$ chgrp ankat tekstit/*
[aku@kone tmp]$ ls -ld tekstit

drwxrwx---    2 aku     ankat       1024 syys   2 00:59 tekstit

[iines@kone tmp]$ cd tekstit
[iines@kone tekstit]$ ls -l
total 2
----------    1 aku     ankat          4 syys   2 00:59 eka
----------    1 aku     ankat          4 syys   2 00:59 toka
[iines@kone tekstit]$ rm eka
rm: remove write-protected file `eka'? y

[aku@kone tmp]$ chmod o+t tekstit
[aku@kone tmp]$ ls -ld tekstit
drwxrwx--T    2 aku     ankat       1024 syys   2 01:00 tekstit

[iines@kone tekstit]$ rm toka

rm: remove write-protected file `toka'? y
rm: cannot unlink `toka': Operation not permitted

Katso juurihakemiston tiedostolistaus pitkässä muodossa (ls -l /). Millä hakemistolla on tahmabitti päällä? Miksi?

Tiedostolistauksessahan s- ja t-kirjain voi peittää x-kirjaimen. Jos "alla" on oikeus päällä, näkyy s- tai t-kirjain pienenä, muutoin suurena. Vielä esimerkki:

[aku@kone tmp]$ chmod g+x tulosta

[aku@kone tmp]$ ls -l tulosta
-rwxr-s--x    1 aku     ankat      15341 syys   1 23:59 tulosta
[aku@kone tmp]$ chmod g-x tulosta
[aku@kone tmp]$ ls -l tulosta
-rwxr-S--x    1 aku     ankat      15341 syys   1 23:59 tulosta

Muuta asiaa sivuavaa

Laitetiedostot ja pseudokäyttäjät ja pseudoryhmät

Unixissa kaikki on tiedostoja. Esimerkiksi tavallista korppuasemaa vastaa tiedosto /dev/fd0 ja levykkeen alkua voi lukea komennolla
less -f /dev/fd0
ja tulostinportteja vastaavat tiedostot /dev/lp0, /dev/lp1 ja /dev/lp2 ja tekstitiedoston saa tulostettua (yleensä) komennolla
cp tiedostonnimi /dev/lp0

Myös laitetiedostoilla on oikeudet, esimerkiksi

[aku@kone aku]$ ls -l /dev/hda /dev/lp0
brw-rw----    1 root    disk       3,  0 elo    30 23:30 /dev/hda

crw-rw----    1 root    lp         6,  0 elo    30 23:30 /dev/lp0

tarkoittaa, että vain root ja ryhmään disk kuuluvat käyttäjät voivat käsitellä suoraan ensimmäisen IDE-väylän master-levyn (DOS/Win-puolella C-aseman sisältävä levy) levypintaa, ja että root ja ryhmään lp kuuluvat käyttäjät voivat kirjoittaa ja lukea tulostinporttia.

Yleensä näitä oikeuksia ei joudu muuttamaan. Eräs poikkeus on levykkeen käsittely mtools-paketilla, joka onnistuu muiltakin kuin pääkäyttäjältä kun joko annetaan /dev/fd0 -laitetiedostolle sopivat oikeudet tai asetetaan setuid-bitti paketin sisältämille ohjelmille.

Tiedostolistauksen alussa näkyvä b-kirjain tarkoittaa lohkolaitetta (engl. block device) ja c-kirjain merkkilaitetta (engl. character device). Lohkolaite lukee ja kirjoittaa aina kerralla esimerkiksi 512 tai 1024 tavun lohkon, merkkilaite käsittelee yksittäisiä merkkejä. Oikeuksien kannalta erolla ei ole merkitystä, luku- ja kirjoitusoikeus sekä käyttäjä ja ryhmä määritellään samalla tavoin.

Laitetiedostoilla on muodollisesti myös suoritusoikeus sekä setuid- ja setgid-oikeudet sekä tahmabitti, ja nämä oikeudet voidaan myös antaa chmod-komennolla. Niillä ei kuitenkaan ole mitään vaikutusta, sillä laitetiedostoa ei voi suorittaa.

On olemassa myös nimettyjä putkia (engl. named pipe), jotka merkitään tiedostolistauksessa p-kirjaimella, ja unix domain socketteja (suomennos??), joilla vastaava kirjain on s. Niitä ei käsitellä tässä enempää, mutta oikeudet määritellään niillekin samoin kuin laitetiedostoille.

Käyttäjällä ja ryhmällä on yleensä vastine reaalimaailmassa, vaikka Ville Virtanen ja palkanlaskennan henkilökunta. Jonkin verran käytetään myös pseudokäyttäjiä kuten "mail" ja "news", joilla voidaan säädellä tarkemmin mitä jotkut ohjelmat saavat tehdä. Pseudoryhmiä ovat esimerkiksi yllä näkyvät "disk" ja "lp".