Un server deve poter acquisire le credenziali di un client. La funzione rpc_gss_getcred(), mostrata nell'Esempio 8-5, permette al server di ottenere le credenziali UNIX o le credenziali RPCSEC_GSS (o entrambe). A tale scopo, esso utilizza due argomenti che vengono impostati se la funzione viene eseguita. Uno è un puntatore a una struttura rpc_gss_ucred_t, che contiene le credenziali UNIX del chiamante:
typedef struct { uid_t uid; /* ID utente */ gid_t gid; /* ID gruppo */ short gidlen; git_t *gidlist; /* elenco gruppi */ } rpc_gss_ucred_t;
L'altro argomento è un puntatore a una struttura rpc_gss_raw_cred_t, che ha la forma seguente:
typedef struct { u_int version; /* versione programma RPCSEC_GSS */ char *mechanism; char *qop; rpc_gss_principal_t client_principal; /* nome principale client */ char *svc_principal; /* nome principale server */ rpc_gss_service_t service; /* enum riservatezza integrità */ } rpc_gss_rawcred_t;(Per una descrizione della struttura rpc_gss_principal_t e del modo in cui viene creata, vedere "Generazione dei nomi principali dei client".) Poiché rpc_gss_rawcred_t contiene i nomi principali sia del client che del server, rpc_gss_getcred() può restituirli entrambi.
L'Esempio 8-5 mostra una procedura di spedizione semplice sul lato server, in cui il server riceve le credenziali per il chiamante. La procedura ottiene le credenziali UNIX del chiamante e quindi verifica l'identità dell'utente usando il meccanismo, il QOP e il tipo di servizio specificato nell'argomento rpc_gss_rcred_t.
static void server_prog(struct svc_req *rqstp, SVCXPRT *xprt) { rpc_gss_ucred_t *ucred; rpc_gss_rawcred_t *rcred; if (rqst->rq_proq == NULLPROC) { svc_sendreply(xprt, xdr_void, NULL); return; } /* * autentica tutte le altre richieste */ */ switch (rqstp->rq_cred.oa_flavor) { case RPCSEC_GSS: /* * ottiene le informazioni sulle credenziali */ rpc_gss_getcred(rqstp, &rcred, &ucred, NULL); /* * verifica che l'utente sia autorizzato all'accesso * usando i parametri di sicurezza ricevuti * controllando il file di configurazione */ if (!authenticate_user(ucred->uid, rcred->mechanism, rcred->qop, rcred->service)) { svcerr_weakauth(xprt); return; } break; /* consente l'accesso */ default: svcerr_weakauth(xprt); return; } /* end switch */ switch (rqstp->rq_proq) { case SERV_PROC1: . . . } /* elaborazione normale della richiesta; invio risposta ... */ return; } |
Per maggiori informazioni, vedere la pagina man rpc_gss_getcred(3N).
Nell'Esempio 8-5, l'ultimo argomento per rpc_gss_getcred() (in questo caso, NULL) è un cookie definito dall'utente, che avrà il valore specificato dal server al momento della creazione del contesto. Questo cookie, un valore di quattro byte, può essere usato in qualunque modo appropriato per l'applicazione: RPC non lo interpreta. Ad esempio, il cookie può essere un puntatore o un indice di una struttura che rappresenta l'origine del contesto; invece di calcolare questo valore per ogni richiesta, il server lo calcola al momento della creazione del contesto (risparmiando tempo nell'elaborazione della richiesta).