/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ /* These routines provide an interface to the token cache maintained by the kernel. Principally it handles cache misses by requesting the desired token from the AuthServer. */ #include #include #ifdef UKERNEL # include "afsincludes.h" #endif #include #include #include #include #ifdef AFS_NT40_ENV #include #else #include #include #endif #include /* netinet/in.h and cellconfig.h are needed together */ #include /* these are needed together */ #include #include #include "kauth.h" #include "kautils.h" #include afs_int32 ka_GetAuthToken(char *name, char *instance, char *cell, struct ktc_encryptionKey * key, afs_int32 lifetime, afs_int32 * pwexpires) { afs_int32 code; struct ubik_client *conn; afs_int32 now = time(0); struct ktc_token token; char cellname[MAXKTCREALMLEN]; char realm[MAXKTCREALMLEN]; struct ktc_principal client, server; LOCK_GLOBAL_MUTEX; code = ka_ExpandCell(cell, cellname, 0 /*local */ ); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } cell = cellname; /* get an unauthenticated connection to desired cell */ code = ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } code = ka_Authenticate(name, instance, cell, conn, KA_TICKET_GRANTING_SERVICE, key, now, now + lifetime, &token, pwexpires); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } code = ubik_ClientDestroy(conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } code = ka_CellToRealm(cell, realm, 0 /*local */ ); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } strcpy(client.name, name); strcpy(client.instance, instance); strncpy(client.cell, cell, sizeof(client.cell)); strcpy(server.name, KA_TGS_NAME); strcpy(server.instance, realm); strcpy(server.cell, cell); code = ktc_SetToken(&server, &token, &client, 0); UNLOCK_GLOBAL_MUTEX; return code; } afs_int32 ka_GetServerToken(char *name, char *instance, char *cell, Date lifetime, struct ktc_token * token, int new, int dosetpag) { afs_int32 code; struct ubik_client *conn; afs_int32 now = time(0); struct ktc_token auth_token; struct ktc_token cell_token; struct ktc_principal server, auth_server, client; char *localCell = ka_LocalCell(); char cellname[MAXKTCREALMLEN]; char realm[MAXKTCREALMLEN]; char authDomain[MAXKTCREALMLEN]; int local; LOCK_GLOBAL_MUTEX; code = ka_ExpandCell(cell, cellname, 0 /*local */ ); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } cell = cellname; strcpy(server.name, name); strcpy(server.instance, instance); lcstring(server.cell, cell, sizeof(server.cell)); if (!new) { code = ktc_GetToken(&server, token, sizeof(struct ktc_token), &client); if (!code) { UNLOCK_GLOBAL_MUTEX; return 0; } } code = ka_CellToRealm(cell, realm, &local); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } /* get TGS ticket for proper realm */ strcpy(auth_server.name, KA_TGS_NAME); strcpy(auth_server.instance, realm); lcstring(auth_server.cell, realm, sizeof(auth_server.cell)); strcpy(authDomain, realm); code = ktc_GetToken(&auth_server, &auth_token, sizeof(auth_token), &client); if (code && !local) { /* try for remotely authenticated ticket */ strcpy(auth_server.cell, localCell); strcpy(authDomain, ""); code = ktc_GetToken(&auth_server, &auth_token, sizeof(auth_token), &client); } if (code && local) { UNLOCK_GLOBAL_MUTEX; return code; } else if (code) { /* here we invoke the inter-cell mechanism */ /* get local auth ticket */ ucstring(auth_server.instance, localCell, sizeof(auth_server.instance)); strcpy(auth_server.cell, localCell); code = ktc_GetToken(&auth_server, &cell_token, sizeof(cell_token), &client); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } /* get a connection to the local cell */ if ((code = ka_AuthServerConn(localCell, KA_TICKET_GRANTING_SERVICE, 0, &conn))) { UNLOCK_GLOBAL_MUTEX; return code; } /* get foreign auth ticket */ if ((code = ka_GetToken(KA_TGS_NAME, realm, localCell, client.name, client.instance, conn, now, now + lifetime, &cell_token, "" /* local auth domain */ , &auth_token))) { UNLOCK_GLOBAL_MUTEX; return code; } code = ubik_ClientDestroy(conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } conn = 0; /* save foreign auth ticket */ strcpy(auth_server.instance, realm); lcstring(auth_server.cell, localCell, sizeof(auth_server.cell)); ucstring(authDomain, localCell, sizeof(authDomain)); if ((code = ktc_SetToken(&auth_server, &auth_token, &client, 0))) { UNLOCK_GLOBAL_MUTEX; return code; } } if ((code = ka_AuthServerConn(cell, KA_TICKET_GRANTING_SERVICE, 0, &conn))) { UNLOCK_GLOBAL_MUTEX; return code; } if ((code = ka_GetToken(name, instance, cell, client.name, client.instance, conn, now, now + lifetime, &auth_token, authDomain, token))) { UNLOCK_GLOBAL_MUTEX; return code; } code = ubik_ClientDestroy(conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } if ((code = ktc_SetToken(&server, token, &client, dosetpag ? AFS_SETTOK_SETPAG : 0))) { UNLOCK_GLOBAL_MUTEX; return code; } UNLOCK_GLOBAL_MUTEX; return 0; } afs_int32 ka_GetAdminToken(char *name, char *instance, char *cell, struct ktc_encryptionKey * key, afs_int32 lifetime, struct ktc_token * token, int new) { int code; struct ubik_client *conn; afs_int32 now = time(0); struct ktc_principal server, client; struct ktc_token localToken; char cellname[MAXKTCREALMLEN]; LOCK_GLOBAL_MUTEX; code = ka_ExpandCell(cell, cellname, 0 /*local */ ); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } cell = cellname; if (token == 0) token = &localToken; /* in case caller doesn't want token */ strcpy(server.name, KA_ADMIN_NAME); strcpy(server.instance, KA_ADMIN_INST); strncpy(server.cell, cell, sizeof(server.cell)); if (!new) { code = ktc_GetToken(&server, token, sizeof(struct ktc_token), &client); if (code == 0) { UNLOCK_GLOBAL_MUTEX; return 0; } } if ((name == 0) || (key == 0)) { /* just lookup in cache don't get new one */ UNLOCK_GLOBAL_MUTEX; return KANOTICKET; } /* get an unauthenticated connection to desired cell */ code = ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } code = ka_Authenticate(name, instance, cell, conn, KA_MAINTENANCE_SERVICE, key, now, now + lifetime, token, 0); (void)ubik_ClientDestroy(conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } strcpy(client.name, name); strcpy(client.instance, instance); strncpy(client.cell, cell, sizeof(client.cell)); code = ktc_SetToken(&server, token, &client, 0); UNLOCK_GLOBAL_MUTEX; return code; } afs_int32 ka_VerifyUserToken(char *name, char *instance, char *cell, struct ktc_encryptionKey * key) { afs_int32 code; struct ubik_client *conn; afs_int32 now = time(0); struct ktc_token token; char cellname[MAXKTCREALMLEN]; afs_int32 pwexpires; LOCK_GLOBAL_MUTEX; code = ka_ExpandCell(cell, cellname, 0 /*local */ ); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } cell = cellname; /* get an unauthenticated connection to desired cell */ code = ka_AuthServerConn(cell, KA_AUTHENTICATION_SERVICE, 0, &conn); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } code = ka_Authenticate(name, instance, cell, conn, KA_TICKET_GRANTING_SERVICE, key, now, now + MAXKTCTICKETLIFETIME, &token, &pwexpires); if (code) { UNLOCK_GLOBAL_MUTEX; return code; } code = ubik_ClientDestroy(conn); UNLOCK_GLOBAL_MUTEX; return code; }