In uno scorso articolo abbiamo introdotto il funzionamento dei moduli in Linux-PAM, questa volta implementaremo una semplicissima applicazione in linguaggio C che consente di autenticarsi attraverso il meccanismo dei moduli della libreria. Dal punto di vista del programmatore di un’applicazione, Linux-PAM permette di ignorare lo schema di autenticazione, in quanto sarà l’amministratore a configurarlo, lo sviluppatore si limita soltanto a caricare dinamicamente i moduli di autenticazione della libreria.
Ogni applicazione che intenda far uso della libreria, deve richiamare la funzione pam_authenticate che serve da interfaccia al meccanismo di autenticazione del modulo caricato. L’argomento principale della funzione è la struttura pam_handle_t che non deve mai essere modificata direttamente dal programma, ma accedervi attraverso le altre funzioni disponibili, per gli altri argomenti vi rimando alle pagine man, info o doc della libreria. Se l’autenticazione ha avuto successo la funzione restituisce PAM_SUCCESS, altrimenti un altro valore di fallimento. La gestione dell’accesso è gestita attraverso la funzione pam_acct_mgmt e viene richiamata dopo che l’utente è stato autenticato e permette l’accesso dell’utente al sistema. Dopo queste premesse vediamo in pratica l’uso della libreria Linux-PAM in un’applicazione di esempio con il file veruser.c:
#include <security/pam_appl.h> #include <security/pam_misc.h> #include <stdio.h> static struct pam_conv conv = { misc_conv, NULL }; int main(int argc, char** argv) { pam_handle_t* pamh = NULL; int retVal; const char* user = "nobody"; if (argc == 2) user = argv[1]; if (argc > 2) { fprintf(stderr, "Uso: veruser [nomeutente]\n"); exit(1); } retVal = pam_start("veruser", user, &conv, &pamh); if (retVal == PAM_SUCCESS) retVal = pam_authenticate(pamh, 0); else fprintf(stderr, "Fallimento di pam_start\n"); if (retVal == PAM_SUCCESS) retVal = pam_acct_mgmt(pamh, 0); else fprintf(stderr, "Fallimento di pam_authenticate\n"); if (retVal == PAM_SUCCESS) printf("Autenticato!\n"); else printf("Non Autenticato!\n"); if (pam_end(pamh, retVal) != PAM_SUCCESS) { pamh = NULL; fprintf(stderr, "veruser: fallimento nella terminazione!\n"); exit(1); } return (retVal == PAM_SUCCESS) ? 0 : 1; }
Per compilare il programma occorre dare questo comando:
gcc -o veruser -lpam -lpam_misc -ldl veruser.c
Dopo il controllo dei parametri passati da linea di comando, il codice provvede ad inizializzare l’interfaccia PAM con la funzione pam_start alla quale sono passati nell’ordine: il nome del servizio che deve essere uguale al modulo di configurazione nella cartella /etc/pam.d, il nome utente da autenticare. In caso di successo viene chiamata pam_authenticate che verifica l’identità dell’utente chiedendogli di immettere la password, quindi in caso di successo viene chiamata la funzione pam_acct_mgmt che si occupa di verificare le condizioni che consentono l’accesso all’utente.