login e su internals


10

Sto cercando di capire come funzionano le autorizzazioni utente in Linux. Il kernel si avvia e inizia initcome root, giusto? Init quindi esegue gli script di avvio ed esegue getty( agetty), di nuovo come root. Agetty legge solo il nome utente ed esegue login, sempre come root, credo. Niente di interessante ancora. Ma cosa fa il login ? Non sono riuscito a trovare niente di meglio di "tenta di accedere". Supponiamo che il login trovi che la password corrisponde (e stiamo provando ad accedere come al solito utente), come cambia l'ID utente? Ho pensato che ci sarebbe dovuto essere una richiesta di sistema, ma non sono riuscito a trovarlo (forse sono solo cieco?)


Inoltre, circa su. suha il bit 'setuid' impostato, quindi quando lo eseguiamo, funziona sempre come root. Ma quando gli diciamo di accedere come al solito utente, deve nuovamente cambiare l'ID utente. Capisco correttamente che accade la stessa "magia" in sue loginquando devono cambiare utente? In tal caso, perché avere due programmi diversi? Ci sono altri tipi di seri affari in corso durante l'esecuzione dell'accesso?

Risposte:


9

Esistono diverse parti di ciò che fanno i programmi di accesso. I programmi di accesso differiscono nel modo in cui interagiscono con l'utente che sta tentando di accedere. Ecco alcuni esempi:

  • login: legge l'input su un terminale di testo
  • su: invocato da utenti già connessi, ottiene la maggior parte dei dati dai suoi argomenti della riga di comando, oltre a dati di autenticazione (password) da un terminale
  • gksu: simile a su, ma legge i dati di autenticazione in X
  • rlogind: ottiene l'input tramite una connessione TCP tramite il protocollo rlogin
  • sshd: ottiene l'input tramite una connessione TCP tramite il protocollo SSH
  • Gestori di display X (xdm, gdm, kdm, ...): simili a login, ma leggi input su un display X

Questi programmi funzionano in modo simile.

  1. La prima parte è l' autenticazione : il programma legge alcuni input dell'utente e decide se l'utente è autorizzato ad accedere. Il metodo tradizionale consiste nel leggere un nome utente e una password e verificare che l'utente sia menzionato nel database degli utenti del sistema e che la password digitata dall'utente è quella nel database. Ma ci sono molte altre possibilità (password singole, autenticazione biometrica, trasferimento di autorizzazioni, ...).

  2. Una volta stabilito che l'utente è autorizzato ad accedere e in quale account, il programma di accesso stabilisce l'autorizzazione dell'utente, ad esempio a quali gruppi apparterrà l'utente in questa sessione.

  3. Il programma di accesso può anche verificare le restrizioni dell'account. Ad esempio, potrebbe imporre un tempo di accesso o un numero massimo di utenti connessi o rifiutare determinati utenti su determinate connessioni.

  4. Finalmente il programma di login imposta la sessione dell'utente. Esistono diversi passaggi secondari:

    1. Impostare le autorizzazioni di processo su ciò che è stato deciso nell'autorizzazione: utente, gruppi, limiti, ... Qui puoi vedere un semplice esempio di questa sottofase (gestisce solo utenti e gruppi). L'idea di base è che il programma di login sia ancora in esecuzione come root a questo punto, quindi ha i massimi privilegi; rimuove innanzitutto tutti i privilegi diversi dall'essere l'utente root e infine chiama setuidper eliminare l'ultimo, ma non meno importante privilegio.
    2. Possibilmente montare la home directory dell'utente, visualizzare un messaggio "hai posta", ecc.
    3. Richiamare un programma come utente, in genere la shell dell'utente (per logine su, o sshdse non è stato specificato alcun comando; un display manager X invoca un gestore sessioni X o un gestore finestre).

Oggigiorno la maggior parte degli unice utilizza PAM (Pluggable Authentication Modules) per fornire un modo uniforme di gestire i servizi di accesso. PAM divide la sua funzionalità in 4 parti : "auth" comprende sia l'autenticazione (1 sopra) sia l'autorizzazione (2 sopra); "Account" e "sessione" sono come 3 e 4 sopra; e c'è anche "password", che non viene utilizzata per gli accessi ma per aggiornare i token di autenticazione (ad es. password).


4

Le chiamate di sistema che stai cercando si chiamano cose del genere setuide seteuidanche se in realtà esiste un'intera famiglia di orli a seconda di quali varianti dell'identità utente stai cercando di cambiare.

Ci sono anche chiamate parallele come setgidper cambiare il gruppo in cui viene eseguito un processo.


4

loginlascerà cadere i privilegi di root quando necessario. Molti programmi che necessitano solo inizialmente dei privilegi di root verranno avviati come root, eseguiranno ciò che devono fare e quindi passeranno a un normale account utente in modo da non doversi preoccupare di qualcuno che utilizza un bug nel file binario per accedere a un shell radice. loginmantiene naturalmente i privilegi più a lungo, ma il principio è lo stesso.

Abbandonare effettivamente i privilegi di root è abbastanza banale. POSIX definisce setuid()e setgid()funzioni, che cambiano rispettivamente gli ID utente e di gruppo (reale ed efficace, se inizi come root). loginchiama entrambi, nonché initgroups()per configurare eventuali gruppi supplementari che potresti avere (poiché setgidserve solo per impostare l'ID del gruppo principale)

Naturalmente è il kernel che gestisce effettivamente la modifica del processo 'UID / GID. Come posso trovare le implementazioni delle chiamate di sistema del kernel Linux? spiega molto su syscalls; nel mio sorgente del kernel ho:

#define __NR_setgid 144
__SYSCALL(__NR_setgid, sys_setgid)
#define __NR_setuid 146
__SYSCALL(__NR_setuid, sys_setuid)

quindi 144 e 146 sono i numeri di chiamata del sistema per quelle funzioni sulla mia macchina


Non ho controllato l' suorigine per vedere cosa fa, ma sospetto che abbassi anche i privilegi di root prima di exec()creare una shell, usando lo stesso metodo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.