CommonUsers 1.2

Gemensamma användaridentiteter på Rydnet
Kent Engström, 17 mars 1994

INNEHÅLL

BAKGRUND

Om NFS-montering av varandras diskar ska kunna fungera någorlunda smidigt, krävs det att vi har gemensamma användaridentiteter på våra maskiner. Samtidigt vill ingen ge upp rätten att själv bestämma vilka som ska få logga in och liknande.

Att köra någon variant av YP/NIS skulle vara en lösning. Detta skulle innebära att våra maskiner blev beroende av en eller flera YP-servrar, samt att det blev ännu en sak att förklara för nytillkomna Rydnetister.

Som en ersättning har jag utvecklat en lösning som består av ett skalprogram (shell script), fyra AWK-program och ett NFS-monterat bibliotek på commonusers (commonusers är just nu ett alias för winona). Biblioteket på commonusers behövs bara för uppdatering, inte för att överhuvudtaget kunna logga in.

AMIGA-VERSION (21/4 1995)

Förutom Unix-versionen finns även en Amiga-version omhackad av Andreas Johansson på samma ställe.

ANVÄNDARE

Varje användare i UNIX har ett nummer, UID. Det är detta nummer, inte användarnamnet, som lagras i filsystemet för att markera vem som äger filer. På många andra ställen, men inte alla, används UID istället för användarnamnet. Det är oftast ingen lyckad lösning att ha flera användarnamn med samma UID.

För det gemensamma användarsystemet på Rydnet har jag reserverat UID i området 1000..1999. Meningen är att var och en som vill vara med i systemet skriver till mig och får ett ledigt användarnummer (egna önskemål om UID är välkomna, så länge de inte är upptagna).

UID utanför området 1000..1999 är lokala. Lokala användare är både systemets standardanvändare (root, daemon, bin, disk osv) samt användare som inte är med i det gemensamma systemet.

EGNA GRUPPER FÖR VARJE ANVÄNDARE

Till varje gemensam användare finns en motsvarande grupp. Gruppens identitetsnummer, GID, har samma numeriska värde som användarens UID. Gruppens namn är identiskt med användarnamnet. Meningen med detta är att det i det gemensamma systemet alltid ska finnas en väldefinierad hemgrupp för användaren. Om man vill ha det annorlunda på den lokala maskinen kan man det.

Varför skulle man då vilja låta varje användare på sin maskin ha en egen grupp, istället för att låta de som får logga in vara med i gruppen users, other, myfriends eller liknande? Är det inte onödigt att kent är med i gruppen kent, nisse i gruppe nisse, och så vidare?

Nej, det finns en trevlig finess med detta system. Normalt är umask satt till något i stil med 022, vilket innebär att det filskydd som de flesta filer får tillåter läs/skriv för användaren, och bara läs för gruppen/andra. Det är OK, om man är med i en slags gemensam grupp som "other", som inte innebär något egentligt samarbete utan bara är ett sätt att samla ihop användare.

Antag nu att kent och nisse vill samarbeta om ett projekt på datorn. De fixar en grupp i /etc/group som heter foo med hjälp av följande rad:

    foo::500:kent,nisse
Detta innebär att bara kent och nisse är med i gruppen, som har GID 500. Inga andra kan bli med genom att ge ett lösen (tomt lösenfält). Observera att gruppen foo inte är "hemgrupp" för någon. Den finns alltså inte inlagd som grupp för någon i /etc/passwd.

Det gemensamma biblioteket (foodir) skapas nu på följande sätt:

    mkdir foodir
    chgrp foo foodir
    chmod g+w foodir
Andra raden gör så att den gemensamma gruppen äger biblioteket, medan den tredje ger skrivrättighet åt gruppen. Utan dessa två rader kan inte andra gruppmedlemmar än skaparen komma ut biblioteket.

När kent och nisse börjar skapa filer i det gemensamma biblioteket, så märker de snart följande problem:

Det finns i en del UNIX:ar en finess som aktiveras då man sätter SETGID-flaggan på ett bibliotek. Egentligen har ju SETUID och SETGID bara mening för körbara filer, så SunOS, Linux och andra har valt att låta denna bit extraknäcka i ett annat syfte då man sätter den på ett bibliotek: alla filer som skapas i biblioteket blir automagiskt ägda av den grupp som äger biblioteket. Alltså fixar vi till det hela med:
    chmod g+s foodir
Nu fungerar det bättre. Men snart, när en av dem ska ändra en fil som den andra skrivit, kommer nästa problem:

En dålig lösning är att med jämna mellanrum köra "chmod g+w *" i biblioteket för att ge skrivrättighet på sina egna filer till alla andra i gruppen. Man glömmer alltid bort det efter ett tag, särskilt innan man ser till att vara oanträffbar. Sedan ska någon ändra i en gemensam fil...

En bättre lösning är att ändra umask till 002, så att standardskyddet är att användare och grupp för läsa och skriva, medan andra bara får läsa. Då får man emellertid problem i sitt vanliga bibliotek. Om man skriver där så är det ju gruppen other (eller motsvarande "hopsamlingsgrupp") som äger filerna. Förmodligen vill man inte ge alla i den gruppen skrivrättighet på alla ens egna filer...

Att hålla på att ändra umask hela tiden fungerar inte bra. Ute i skalet kanske det skulle gå, men tänk om du sitter och kör Emacs... Finns det då inget sätt att klara det?

Jo, tänk om den "normala" gruppen för användaren kent inte var other, utan en speciell grupp för bara kent. Då skulle umask kunna vara 002 hela tiden, för det gör inget om gruppen kent får skrivrättigheter som användaren kent redan har. Det är inte heller hela världen om gruppen kent ibland skulle råka tappa skrivrättighet till vissa filer (umask 022), eftersom användaren kent fortfarande har det. Samtidigt fungerar det utmärkt i det delade biblioteket foodir.

Hela den här långa utläggningen är ett försök att motivera varför hemgrupper med samma namn och ID som användarna är en *bra sak*. Förmodligen har du under tiden lärt dig en hel del nyttigt om grupper i allmänhet. Sänd i så fall en tacksam tanke till Thomas Bellman, som var den som påpekade finessen med umask/setgid för mig.

GEMENSAMMA GRUPPER

Utöver lokala grupper och de gemensamma användarnas hemgrupper kan man vilja ha gemensamma grupper i Rydnet. För detta ändamål har GID 2000..2999 reserverats. Tillsammans med "användargrupperna" som behandlas ovan innebär detta alltså att GID 1000..2999 är reserverade.

Bland de gemensamma grupperna finns en med särskild funktion. Det är gruppen rydnet, med GID 2000. I den är alla gemensamma användare medlemmar. Definitionen ser ut som följer:

    rydnet::2000:kent,maxell,....
Punkterna betyder att uppräkningen av användare fortsätter.

FUNKTION

Jag lägger in gemensamma användare i en fil. Varje rad ser ut som exempelraden nedan:
    kent:*:1001:1001:Kent Engstrom (razor):/home/kent:/bin/bash
Lösenordsfältet är ifyllt med en stjärna, vilket innebär att användaren inte kan logga in. UID och GID sammanfaller. I fältet för övrig information står namnet och den egna maskinen. Hembiblioteket sätts alltid till /home/<username>. Skalfältet sätts till /bin/bash, om inget annat har önskats.

När uppdateringsprogrammet körs för första gången på din maskin läggs en rad som ser ut precis som ovan till i /etc/passwd. Detta gör att din maskin känner till att UID 1001 är kent. Detta är av vikt då man använder NFS för att montera en disk där det står att en fil ägs av UID 1001. Utan denna information i /etc/passwd vet din dator inte vem som avses med 1001, eller så tror den i värsta fall att 1001 är de lokale användare hos dig som råkat få UID 1001.

Varje gång du körs uppdateringsprogrammet plockas de gemensamma användarna bort ur din /etc/passwd, för att sedan ersättas av nya kopior från filerna på commonusers.

Hur gör du då om du vill ge kent rätt att logga in på din maskin? Jo, du kör "passwd kent" som root för att sätta dit ett riktigt lösenord istället för stjärnan. Då kan kent logga in på din maskin, förutsatt att du skapar ett hembibliotek ägt av honom.

Men kommer inte din lokala variant av kent-raden att ersättas av en vanlig rad (med stjärna i lösenordsfältet) nästa gång du uppdaterar? Nej, uppdateringsprogrammet låter sådana användare vara ifred som den anser är lokalt ändrade. Det räcker med att ett av nedanstående villkor är uppfyllt för att användaren ska få vara ifred:

Ändringar som bara berör informationsfältet, hembiblioteksfältet eller skalfältet påverkar inte programmets uppfattning om vad som är en lokal användare. Det är ju inte heller så meningsfullt att ändra exv. hembibliotek om användaren ändå inte kan logga in.

Gruppfilen /etc/group uppdateras parallellt med /etc/passwd. För varje användare skapas en grupprad, som i exemplet ovan blir:

    kent::1001:
Detta är en normal definition av en grupp kent, med GID 1001. Det tomma lösenordsfältet betyder att det inte går att bli medlem av gruppen genom att ge ett grupplösenord till newgrp. Det tomma medlemsfältet innebär att det bara är användare som har GID 1001 i /etc/passswd som är medlemmar i gruppen.

Utöver dessa automatiska grupper skapas de grupper som anges i den gemensamma gruppfilen.

INSTALLATION

Logga in som root!

Innan du kan installera måste du skaffa dig filen commonusers-1.2.tar t.ex. genom att temporärt montera commonusers bibliotek någonstans med exempelvis kommandot:

    mount commonusers:/export/commonusers /mnt
Detta bibliotek kan du avmontera så fort du har packat upp commonusers-1.2.tar.

Packa upp filen commonusers-1.2.tar i rotbiblioteket, medan du är inloggad som root. Om vi antar att filen ligger i /mnt blir alltså kommandona:

    cd /
    tar xf /mnt/commonusers-1.2.tar
Biblioteket /etc/commonusers skapas nu. Där ligger programfilerna samt ett tomt underbibliotek /etc/commonusers/public. Detta underbibliotek är platsen där commonuserss bibliotek ska monteras. För att göra detta lägger du in följande rad i /etc/fstab:
    commonusers:/export/commonusers /etc/commonusers/public  nfs  defaults
För att omedelbart montera detta bibliotek (och alla andra NFS- bibliotek i din /etc/fstab) utan att starta om datorn ger du kommandot:
    mount -a -t nfs
Nu återstår det en sak: säkerhetskopering av /etc/passwd och /etc/group. Visserligen ska ingen kunna gå snett, men det har vi hört förut, eller hur? Stoppa undan kopior på dessa två filer någonstans, för säkerhets skull.

KÖRNING

För att uppdatera dina lokala filer med gemensamma användare och grupper kör du skalfilen /etc/commonusers/updatecommon. Då skapas först /etc/passwd.bak och /etc/group.bak som är kopior av motsvarande filer innan ändringarna. Därefter plockar programmet ut lokala data ur filerna och lägger på de gemensamma data som finns i /etc/commonusers/public (dvs på commonusers). Resultatet läggs tillbaka i /etc/passwd och /etc/group.

Programmet är väldigt pratsamt och talar hela tiden om vad det gör. Vill du slippa det får du omdirigera till fil eller /dev/null. Fil är att föredra, eftersom du då kan kolla vad som gjordes ifall något går snett.

ANPASSNING AV FILER OCH BIBLIOTEK

En sak måste göras manuellt då du lägger in en användare i det gemensamma systemet ifall användaren tidigare har haft ett lokalt UID - du måste ändra ägarinformationen i filsystemet.

Antag att användaren kent hade UID 100 innan det gemensamma systemet fanns. Då ligger 100 lagrat som ägare för alla filer som kent äger. Om nu kent får UID 1001 så äger han inte längre sina egna filer. Istället visas deras ägare som 100 i ls-listor, eftersom det inte finns någon användare med UID 100 längre.

För att åtgärda detta måste root ändra ägar-UID på alla filer som ägs av kent. Lättast görs det med chown-kommandot, som kan byta ägare på alla filer i ett underbibliotek med flaggan -R:

    chown -R kent /home/kent
Raden ovan bytte ägare på alla filer i hembiblioteket. Filer som finns på andra ställen måste också åtgärdas. Ett exempel är brevlådan, som innehåller oläst post (och som inte finns om oläst post saknas). Följande kommando används här:
    chown kent /var/spool/mail/kent
För att leta efter övriga filer och åtgärda dem kan find-kommandot användas. Hur man gör lämnas som en övningsuppgift åt läsaren.

Den kan vara bra att inte återanvända det gamla UID som blir ledigt. Jag föreslår att du låter den gamla posten vara kvar i /etc/passwd med ändrat namn och inloggning omöjliggjord. På så sätt slipper du undra vem som var UID 100 innan ändringen, om du skulle stöta på en fil du har missat vid ägarbytena ovan. Följande rad lämnade jag kvar för min gamla kent-användare:

    oldkent:*:100:110:Kent Engstrom (obsolete login):/tmp:/bin/false
För att underlätta rådet ovan har jag på Dejans inrådan skrivit ett litet program (fixusers) som fixar old-användare. Du kör det en gång för att fixa dina användare. Sedan behövs det inte mer. När det körs läser det /etc/passwd, kollar mot passd.common och skriver en uppdaterad passwd-fil i /etc/commonusers/passwd.fixed. Den kan du titta på och eventuellt fixa till manuellt innan du lägger upp den som /etc/passwd.

Om passwd.fixed visar sig bli en identisk kopia av /etc/passwd (inga ändringar), så tas den bort. Om det finns en passwd.fixed efter körning av fixusers, så skiljer sig alltså något mellan /etc/passwd och passwd.fixed.

Givet följande rad i /etc/passwd:

    kent:GaGgagGaga:100:110:Kent Engstrom:/home/kent:/bin/bash
så genereras följande två rader i /etc/commonusers/passwd.fixed, om kent är en gemensam användare (med i passwd.common):
    oldkent:*:100:110:Kent Engstrom <obsolete>:/tmp:/bin/false
    kent:GaGgagGaga:1001:110:Kent Engstrom:/home/kent:/bin/bash
Märk att oldkent bara är till för att ge namn åt UID 100. Det går som du ser inte att logga in på den användaren. Användaren kent har fått korrekt UID och går att logga in på.

Som du ser ovan har kents GID inte ändrats. Om du vill fixa till även GID (och alltså accepterar systemet med egna hemgrupper som förklarats utförligt längre upp i dokumentet) så ger du argumentet fixgid till fixusers när du kör, alltså:

    cd /etc/commonusers
    ./fixusers fixgid
Raderna som skrivs i vårt exempel blir då:
    oldkent:*:100:110:Kent Engstrom <obsolete>:/tmp:/bin/false
    kent:GaGgagGaga:1001:1001:Kent Engstrom:/home/kent:/bin/bash

AUTOMATISK UPPDATERING

För att slippa tänka på att uppdatera dina lokala filer lite då och då kan du låta cron göra det åt dig. För att t.ex. få filerna uppdaterade klockan 12.00 varje tisdag så lägger du in följande i /etc/crontab:
    #Update commonusers
    00 12 * * 2 root /etc/commonusers/updatecommon
(Detta förutsätter naturligtvis att du har din dator igång på tisdagar klockan 12.00.)

HISTORIA

SLUTORD

Rapportera alla buggar och förbättringsförslag till mig! Skriv i LysKOM-mötet RydNet Teknik, skicka LysKOM-brev till Kent Engström eller skicka elpost till kent@lysator.liu.se.

Lycka till med gemensamma användare!

(Uppdaterad, kompletterad och HTMLfierad av Erik Sundkvist 17 januari 1996)