# Meerdere gebruikers activeren

## Analyse

Tot nu toe functioneerde het besturingssysteem in single-user modus. Er is geen loginproces en iedereen die het systeem boot komt rechtsstreeks terecht in een shell met rootprivileges. Uiteraard is dit bij de GNU/Linux distributies niet de normale besturingsmodus. De meeste systemen hebben een multi-user mogelijkheid waarbij veel gebruikers het systeem tegelijkertijd met verschillende privilege niveaus kunnen benaderen. Deze multi-user systemen ondersteunen ook virtuele consoles zodat het toetsenbord en de videoweergave tussen verscheidene terminalsessies kunnen worden gedeeld. Dus in deze fase zouden we graag de volgende verbeteringen aan het systeem toe willen voegen:

- Mogelijkheid van multi-user activeren.

- Meerdere, virtuele consoles aanmaken.

## Ontwerp

### Het loginproces

De From-Powerup-To-BASH-Prompt-HOWTO verricht een goede taak in het uiteenzetten van de stappen in het loginproces. Eigenlijk werkt het als volgt:

1. De `init` daemon start een `getty` proces op de terminal.

2. Het `getty` programma toont de inhoud van `/etc/issue` en toont een prompt voor de gebruikersnaam.

3. Wanneer de gebruikersnaam is ingevoerd, wordt de besturing overhandigd aan het programma `login`.

4. Het programma `login` vraagt om een wachtwoord en verifieert de geloofwaardigheid aan de hand van `/etc/passwd`, `/etc/group` en mogelijk `/etc/shadow`.

5. Als alles in orde is, dan wordt de shell gestart.

### Verkrijgen van de broncode

De programma's `getty` en `login` werden reeds als onderdeel van util-linux geïnstalleerd.

### Aanmaken van ondersteuningsbestanden

#### Device nodes

Details over virtuele console devicebestanden zijn te vinden in een bestand genaamd `devices.txt` in de directory `Documentation` van de Linux kernelbroncode. We zullen `tty1` tot en met `tty6` voor de virtuele consoles aan moeten maken als ook `tty0` en `tty` die de huidige virtuele console voorstellen.

#### /etc/issue

Het `/etc/issue` bestand is tamelijk eenvoudig te construeren. Iedere willekeurige tekst kan erin worden opgenomen waarvan we willen dat het op het scherm wordt weergegeven voor de verschijning van de loginprompt. Het kan iets vriendelijks zijn zoals "Welkom bij Pocket Linux", iets bedreigends zoals "Alleen geauthoriseerde gebruikers!" of iets informatiefs zoals "Verbonden met tty1 op 9600bps". In de agetty(8) manpage wordt uitgelegd hoe informatie zoals de ttylijn en baud rate met behulp van escape codes weer te geven.

#### /etc/passwd

Het formaat van `/etc/passwd` kan worden verkregen door het lezen van de passwd(5) manpage. We kunnen makkelijk een gebruikersaccount aanmaken door een regel als "root::0:0:superuser:/root:/bin/sh" aan het bestand toe te voegen.

Het onderhouden van wachtwoorden is een uitdaging omdat het systeem in ramdisk wordt geladen. Alle wijzigingen aan `/etc/passwd` zullen verloren gaan wanneer het systeem wordt afgesloten. Dus om het makkelijk te maken, zullen we voor alle gebruikers nul wachtwoorden aanmaken.

#### /etc/group

De structuur van `/etc/group` is beschikbaar uit de group(5) manpage. Een regel als "root::0:root" definieert een groep genaamd "root" zonder wachtwoord, een groepsid nul en de gebruiker root als enige deelnemer eraan toegekend.

#### Conventies

Namen en id's van gebruikers en groepen worden gewoonlijk niet willekeurig gekozen. De meeste Linux systemen hebben zeer vergelijkbaar uitziende `/etc/passwd` en `/etc/group` bestanden. Definities die worden gebruikt voor het toekennen van gebruikers- en groepsid's zijn op één van de volgende lokaties te vinden:

- De bestanden `/etc/passwd` en `/etc/group` in elke populaire GNU/Linux distributie.

- De Debian Policy Manual -- online beschikbaar op http://www.debian.org/doc/debian-policy.

- De Linux Standard Base specificatie -- in meerdere formaten te downloaden vanaf http://www.linuxbase.org/spec/index.shtml.

- Essential System Administration, 3rd Edition door Aeleen Frisch -- beschikbaar bij boekwinkels of direct bij O'Reilly Publishing op http://www.oreilly.com/.

### Afhankelijkheden

De uitvoering van `ldd` op het `login` programma uit util-linux zal bekendmaken dat het is gelinkt met de library `libcrypt.so.1`. In aanvulling op libcrypt, is er nog een ander minder vanzelfsprekende library afhankelijkheid op `libnss_files.so.2`. De name service switch library `libnss_files.so.2` is nodig voor het login programma om het `/etc/passwd` bestand te kunnen benaderen. Zonder libnss zullen alle logins, op mysterieuze wijze mislukken.

### Eigenaar en permissies toekennen

Voorheen was het met het single user systeem niet nodig ons druk te maken om permissies bij de installatie van directory's, bestanden en devicenodes. De shell was effectief werkzaam als root, dus alles was toegankelijk. Het werd wat complexer na het toevoegen van de mogelijkheid voor meerdere gebruikers. Nu moeten we ervoor zorgen dat elke gebruiker toegang heeft tot wat hij/zij nodig heeft en tegelijkertijd worden geblokkeerd in wat hij/zij niet nodig heeft.

Een goede richtlijn voor het toekennen van eigenaars en permissies is het minimaal vereiste toegangsniveau toe te kennen. Neem als voorbeeld de directory `/bin`. Het Filesystem Hierarchy (FHS) document zegt, "`/bin` bevat opdrachten die door zowel de systeembeheerder als de gebruikers kunnen worden gebruikt. Uit die bewering kunnen we concluderen dat `/bin` voor iedereen lees- en uitvoerpermissie zou moeten hebben. Aan de andere kant bevat de directory `/boot` bestanden voor de bootloader. De kans is groot dat reguliere gebruikers niets zullen benaderen in de directory `/boot`. Dus het minimale toegangsniveau zou leespermissies zijn voor de rootgebruiker en andere beheerders die deelnemer zijn van de groep root. Voor normale gebruikers zouden aan de directory `/boot` geen permissies worden toegekend.

Meestal kunnen we vergelijkbare permissies aan alle opdrachten in een directory toekennen, maar er zijn een aantal programma's die bewijzen een uitzondering op de regel te zijn. De opdracht `su` is hiervan een goed voorbeeld. Andere opdrachten in de directory /bin hebben de minimumvereisten om te lezen en uit te voeren, maar de opdracht `su` moet voor de juiste werking worden ingesteld op setuid root. Aangezien het een setuid binary is, zou het een goed idee kunnen zijn niet iedereen toe te staan het uit te voeren. De eigenaar 0:0 (root gebruiker, groep root) en permissies rwsr-x--- (octaal 1750) zou goed passend zijn voor `su`.

Dezelfde logica kan worden toegepast op andere directory's en bestanden in het root bestandssysteem door het doorlopen van de volgende stappen:

1. Ken als eigenaar de root gebruiker en de root groep toe.

2. Stel de meest beperkende permissies in die mogelijk zijn.

3. Pas de eigenaar en permissies aan "wanneer nodig".

## Constructie

### Verifieer de aanwezigheid van getty en login

    bash# ls ~/fase/sbin/getty
    bash# ls ~/fase/bin/login

### Pas inittab voor de multi-user modus aan

Pas `~/fase/etc/inittab` aan door het standaardrunlevel te wijzigen en `getty` regels zoals hieronder getoond toe te voegen.

    # /etc/inittab - init daemon configuratiebestand
    #
    # Standaardrunlevel
    id:2:initdefault:
    #
    # Systeeminitialisatie
    si:S:sysinit:/etc/init.d/rc S
    #
    # Runlevel scripts
    r0:0:wait:/etc/init.d/rc 0
    r1:1:respawn:/bin/sh
    r2:2:wait:/etc/init.d/rc 2
    r3:3:wait:/etc/init.d/rc 3
    r4:4:wait:/etc/init.d/rc 4
    r5:5:wait:/etc/init.d/rc 5
    r6:6:wait:/etc/init.d/rc 6
    #
    # Breng virtuele terminals voort
    1:235:respawn:/sbin/getty 9600 tty1 linux
    2:235:respawn:/sbin/getty 9600 tty2 linux
    3:235:respawn:/sbin/getty 9600 tty3 linux
    4:235:respawn:/sbin/getty 9600 tty4 linux
    5:235:respawn:/sbin/getty 9600 tty5 linux
    6:2345:respawn:/sbin/getty 9600 tty6 linux
    #
    # einde van /etc/inittab

### Maak tty devices aan

    bash# cd ~/fase/dev
    bash# mknod tty0 c 4 0
    bash# mknod tty1 c 4 1
    bash# mknod tty2 c 4 2
    bash# mknod tty3 c 4 3
    bash# mknod tty4 c 4 4
    bash# mknod tty5 c 4 5
    bash# mknod tty6 c 4 6
    bash# mknod tty c 5 0

### Maak ondersteuningsbestanden aan in /etc

#### /etc/issue

Maak het bestand `~/fase/etc/issue` aan door gebruik te maken van onderstaand voorbeeld of ontwerp een aangepaste melding.

    Verbonden met \l op \b bps.

Noot: "\l" is een kleine letter L, niet het getal één.

#### /etc/passwd

Gebruik een teksteditor om een minimaal passwd bestand conformerend aan het Linux Standards Base (LSB) document aan te maken. Sla het bestand op als `~/fase/etc/passwd`

    root::0:0:Super User:/root:/bin/sh
    bin:x:1:1:Legacy UID:/bin:/bin/false
    daemon:x:2:2:Legacy UID:/sbin:/bin/false

#### /etc/group

Gebruik een teksteditor om een LSB conformerend group bestand aan te maken en sla het op als `~/fase/etc/group`

    root::0:root
    bin:x:1:root,bin,daemon
    daemon:x:2:root,bin,daemon

### Kopieer de benodigde library's

    bash# cp /lib/libnss_files.so.2 ~/fase/lib

### Stel de directory- en bestandspermissies in

Stel minimale privileges in op alle bestanden en directory's onder `~/fase`. De root gebruiker en groep root zijn overal eigenaar van. Permissies zijn read-write voor de eigenaar en read-only voor de groep. Uitzonderingen op de allesomvattende permissies worden van geval tot geval afgehandeld.

    bash#cd ~/fase
    bash#chown -R 0:0 *
    bash#chmod -R 640 *

Stel de uitvoerpermissie in op alle directory's. (Noot: hoofdletter "X")

    bash#chmod -R +X *

Bestanden in `/bin` kunnen door iedereen worden gelezen en uitgevoerd, maar `su` is daarop een uitzondering.

    bash#chmod 755 bin/*
    bash#chmod 4750 bin/su

Bestanden in `/dev` hebben diverse permissies. Diskdevices zouden alleen toegankelijk moeten zijn voor beheerders. Op andere bestanden zoals `/dev/null` zouden volledige privileges moeten worden toegestaan voor alle gebruikers.

    bash#chmod 660 /dev/fd0 /dev/ram0
    bash#chmod 666 dev/null
    bash#chmod 622 dev/console
    bash#chmod 600 dev/initctl
    bash#chmod 622 dev/tty
    bash#chmod 622 dev/tty?

De `passwd` en `group` bestanden moeten door iedereen kunnen worden gelezen.

    bash#chmod 644 etc/passwd
    bash#chmod 644 etc/group

De scripts in `/etc/init.d` moeten worden ingesteld op lezen en uitvoeren voor beheerders.

    bash#chmod 750 etc/init.d/*

Library's moeten door iedereen kunnen worden gelezen en uitgevoerd.

    bash#chmod 755 lib/*

Alleen root mag toegang krijgen tot de directory `/root`.

    bash#chmod 700 root

Zorg dat bestanden in `/sbin` door de beheerders kunnen worden gelezen en uitgevoerd.

    bash#chmod 750 sbin/*

Temp moet door iedereen kunnen worden gelezen en beschreven met het sticky bit ingesteld.

    bash#chmod 1777 tmp

### Maak het rootdiskimage aan

    bash# cd /
    bash# dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
    bash# mke2fs -m0 /dev/ram7
    bash# mount /dev/ram7 /mnt
    bash# cp -dpR ~/fase/* /mnt
    bash# umount /dev/ram7
    bash# dd if=/dev/ram7 of=~/phase6-image bs=1k
    bash# gzip -9 ~/phase6-image

### Kopieer de image naar diskette

Doe de diskette met het label "rootdisk" in diskettestation fd0.

    bash# dd if=~/phase6-image.gz of=/dev/fd0 bs=1k

## Implementatie

### Systeemstart

Als alles goed gaat, dan zou de weergave van de virtuele console er uit moeten zien als in het volgende voorbeeld:

    Verbonden met tty1 op 9600 bps.
    gnu-linux login:

### Een nieuwe gebruiker aan het systeem toevoegen

Log in als root.

Maak een nieuwe niet bevoorrechte gebruiker en groep aan door een regel aan respectievelijk de bestanden `/etc/passwd` en `/etc/group` toe te voegen. Zorg dat je een dubbel groter-dan teken (>>) gebruikt om te voorkomen dat je de bestanden per ongeluk overschrijft.

    bash# echo "floyd::501:500:User:/home/floyd:/bin/sh" >> /etc/passwd
    bash# echo "users::500:" >> /etc/group
    bash# mkdir /home/floyd
    bash# chown floyd.users /home/floyd
    bash# chmod 700 /home/floyd

### Test de nieuwe gebruikersmogelijkheid om het systeem te gebruiken

Schakel over naar de virtuele terminal tty2 door het indrukken van ALT+F2.

Log in als floyd.

Probeer de volgende opdrachten en verifieer dat ze werken.

    bash$ pwd
    bash$ ls -l /
    bash$ cat /etc/passwd

Probeer de volgende opdrachten en verifieer dat ze niet werken.

    bash$ ls /root
    bash$ /sbin/shutdown -h now
    bash$ su -

### Systeem afsluiten

Keer terug naar tty1 waar root is ingelogd.

    bash# shutdown -h now