afs_int32 pr_Initialize(IN afs_int32 secLevel, IN const char *confDir, IN char *cell) { afs_int32 code; struct rx_connection *serverconns[MAXSERVERS]; struct rx_securityClass *sc = NULL; static struct afsconf_dir *tdir = (struct afsconf_dir *)NULL; /* only do this once */ static char tconfDir[100] = ""; static char tcell[64] = ""; afs_int32 scIndex; afs_int32 secFlags; static struct afsconf_cell info; afs_int32 i; #if !defined(UKERNEL) char cellstr[64]; #endif afs_int32 gottdir = 0; afs_int32 refresh = 0; initialize_PT_error_table(); initialize_RXK_error_table(); initialize_ACFG_error_table(); initialize_KTC_error_table(); #if defined(UKERNEL) if (!cell) { cell = afs_LclCellName; } #else /* defined(UKERNEL) */ if (!cell) { if (!tdir) tdir = afsconf_Open(confDir); if (!tdir) { if (confDir && strcmp(confDir, "")) fprintf(stderr, "%s: Could not open configuration directory: %s.\n", whoami, confDir); else fprintf(stderr, "%s: No configuration directory specified.\n", whoami); return -1; } gottdir = 1; code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); if (code) { fprintf(stderr, "libprot: Could not get local cell. [%d]\n", code); return code; } cell = cellstr; } #endif /* defined(UKERNEL) */ if (tdir == NULL || strcmp(confDir, tconfDir) || strcmp(cell, tcell)) { /* * force re-evaluation. we either don't have an afsconf_dir, * the directory has changed or the cell has changed. */ if (tdir && !gottdir) { afsconf_Close(tdir); tdir = (struct afsconf_dir *)NULL; } pruclient = (struct ubik_client *)NULL; refresh = 1; } if (refresh) { strncpy(tconfDir, confDir, sizeof(tconfDir)); strncpy(tcell, cell, sizeof(tcell)); #if defined(UKERNEL) tdir = afs_cdir; #else /* defined(UKERNEL) */ if (!gottdir) tdir = afsconf_Open(confDir); if (!tdir) { if (confDir && strcmp(confDir, "")) fprintf(stderr, "libprot: Could not open configuration directory: %s.\n", confDir); else fprintf(stderr, "libprot: No configuration directory specified.\n"); return -1; } #endif /* defined(UKERNEL) */ code = afsconf_GetCellInfo(tdir, cell, "afsprot", &info); if (code) { fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n", cell, confDir, AFSDIR_CELLSERVDB_FILE); return code; } } /* If we already have a client and it is at the security level we * want, don't get a new one. Unless the security level is 2 in * which case we will get one (and re-read the key file). */ if (pruclient && (lastLevel == secLevel) && (secLevel != 2)) { return 0; } code = rx_Init(0); if (code) { fprintf(stderr, "libprot: Could not initialize rx.\n"); return code; } /* Most callers use secLevel==1, however, the fileserver uses secLevel==2 * to force use of the KeyFile. secLevel == 0 implies -noauth was * specified. */ if (secLevel == 2) { code = afsconf_GetLatestKey(tdir, 0, 0); if (code) { afs_com_err(whoami, code, "(getting key from local KeyFile)\n"); } else { /* If secLevel is two assume we're on a file server and use * ClientAuthSecure if possible. */ code = afsconf_ClientAuthSecure(tdir, &sc, &scIndex); if (code) afs_com_err(whoami, code, "(calling client secure)\n"); } } else if (secLevel > 0) { secFlags = 0; if (secLevel > 1) secFlags |= AFSCONF_SECOPTS_ALWAYSENCRYPT; code = afsconf_ClientAuthToken(&info, secFlags, &sc, &scIndex, NULL); if (code) { afs_com_err(whoami, code, "(getting token)"); if (secLevel > 1) return code; } } if (sc == NULL) { sc = rxnull_NewClientSecurityObject(); scIndex = RX_SECIDX_NULL; } if ((scIndex == RX_SECIDX_NULL) && (secLevel != 0)) fprintf(stderr, "%s: Could not get afs tokens, running unauthenticated\n", whoami); memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */ for (i = 0; i < info.numServers; i++) serverconns[i] = rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, info.hostAddr[i].sin_port, PRSRV, sc, scIndex); code = ubik_ClientInit(serverconns, &pruclient); if (code) { afs_com_err(whoami, code, "ubik client init failed."); return code; } lastLevel = scIndex; code = rxs_Release(sc); return code; }
/** * Connects to a server by it's server address. * * @param sap Server address. * @param aport Server port. * @param acell * @param tu Connect as this user. * @param force_if_down * @param create * @param locktype Specifies type of lock to be used for this function. * * @return The new connection. */ struct afs_conn * afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell, struct unixuser *tu, int force_if_down, afs_int32 create, afs_int32 locktype) { struct afs_conn *tc = 0; struct rx_securityClass *csec; /*Security class object */ int isec; /*Security index */ int service; if (!sap || ((sap->sa_flags & SRVR_ISDOWN) && !force_if_down)) { /* sa is known down, and we don't want to force it. */ return NULL; } ObtainSharedLock(&afs_xconn, 15); /* Get conn by port and user. */ for (tc = sap->conns; tc; tc = tc->next) { if (tc->user == tu && tc->port == aport) { break; } } if (!tc && !create) { /* Not found and can't create a new one. */ ReleaseSharedLock(&afs_xconn); return NULL; } if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) { afs_warnuser("afs_ConnBySA: disconnected\n"); ReleaseSharedLock(&afs_xconn); return NULL; } if (!tc) { /* No such connection structure exists. Create one and splice it in. * Make sure the server record has been marked as used (for the purposes * of calculating up & down times, it's now considered to be an * ``active'' server). Also make sure the server's lastUpdateEvalTime * gets set, marking the time of its ``birth''. */ UpgradeSToWLock(&afs_xconn, 37); tc = (struct afs_conn *)afs_osi_Alloc(sizeof(struct afs_conn)); memset(tc, 0, sizeof(struct afs_conn)); tc->user = tu; tc->port = aport; tc->srvr = sap; tc->refCount = 0; /* bumped below */ tc->forceConnectFS = 1; tc->id = (struct rx_connection *)0; tc->next = sap->conns; sap->conns = tc; afs_ActivateServer(sap); ConvertWToSLock(&afs_xconn); } /* end of if (!tc) */ tc->refCount++; if (tu->states & UTokensBad) { /* we may still have an authenticated RPC connection here, * we'll have to create a new, unauthenticated, connection. * Perhaps a better way to do this would be to set * conn->forceConnectFS on all conns when the token first goes * bad, but that's somewhat trickier, due to locking * constraints (though not impossible). */ if (tc->id && (rx_SecurityClassOf(tc->id) != 0)) { tc->forceConnectFS = 1; /* force recreation of connection */ } tu->vid = UNDEFVID; /* forcibly disconnect the authentication info */ } if (tc->forceConnectFS) { UpgradeSToWLock(&afs_xconn, 38); csec = (struct rx_securityClass *)0; if (tc->id) { AFS_GUNLOCK(); rx_DestroyConnection(tc->id); AFS_GLOCK(); } /* * Stupid hack to determine if using vldb service or file system * service. */ if (aport == sap->server->cell->vlport) service = 52; else service = 1; isec = 0; csec = afs_pickSecurityObject(tc, &isec); AFS_GUNLOCK(); tc->id = rx_NewConnection(sap->sa_ip, aport, service, csec, isec); AFS_GLOCK(); if (service == 52) { rx_SetConnHardDeadTime(tc->id, afs_rx_harddead); } /* set to a RX_CALL_TIMEOUT error to allow MTU retry to trigger */ rx_SetServerConnIdleDeadErr(tc->id, RX_CALL_DEAD); rx_SetConnIdleDeadTime(tc->id, afs_rx_idledead); rx_SetMsgsizeRetryErr(tc->id, RX_MSGSIZE); /* * Only do this for the base connection, not per-user. * Will need to be revisited if/when CB gets security. */ if ((isec == 0) && (service != 52) && !(tu->states & UTokensBad) && (tu->vid == UNDEFVID)) rx_SetConnSecondsUntilNatPing(tc->id, 20); tc->forceConnectFS = 0; /* apparently we're appropriately connected now */ if (csec) rxs_Release(csec); ConvertWToSLock(&afs_xconn); } /* end of if (tc->forceConnectFS)*/ ReleaseSharedLock(&afs_xconn); return tc; }
/** * Connects to a server by it's server address. * * @param sap Server address. * @param aport Server port. * @param acell * @param tu Connect as this user. * @param force_if_down * @param create * @param locktype Specifies type of lock to be used for this function. * * @return The new connection. */ struct afs_conn * afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell, struct unixuser *tu, int force_if_down, afs_int32 create, afs_int32 locktype, struct rx_connection **rxconn) { int glocked, foundvec; struct afs_conn *tc = NULL; struct sa_conn_vector *tcv = NULL; struct rx_securityClass *csec; /*Security class object */ int isec; /*Security index */ int service; *rxconn = NULL; /* find cached connection */ ObtainSharedLock(&afs_xconn, 15); foundvec = 0; for (tcv = sap->conns; tcv; tcv = tcv->next) { if (tcv->user == tu && tcv->port == aport) { /* return most eligible conn */ if (!foundvec) foundvec = 1; UpgradeSToWLock(&afs_xconn, 37); tc = find_preferred_connection(tcv, create); ConvertWToSLock(&afs_xconn); break; } } if (!tc && !create) { /* Not found and can't create a new one. */ ReleaseSharedLock(&afs_xconn); return NULL; } if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) { afs_warnuser("afs_ConnBySA: disconnected\n"); ReleaseSharedLock(&afs_xconn); return NULL; } if (!foundvec && create) { /* No such connection vector exists. Create one and splice it in. * Make sure the server record has been marked as used (for the purposes * of calculating up & down times, it's now considered to be an * ``active'' server). Also make sure the server's lastUpdateEvalTime * gets set, marking the time of its ``birth''. */ UpgradeSToWLock(&afs_xconn, 37); new_conn_vector(tcv); tcv->user = tu; tcv->port = aport; tcv->srvr = sap; tcv->next = sap->conns; sap->conns = tcv; /* all struct afs_conn ptrs come from here */ tc = find_preferred_connection(tcv, create); afs_ActivateServer(sap); ConvertWToSLock(&afs_xconn); } /* end of if (!tcv) */ if (!tc) { /* Not found and no alternatives. */ ReleaseSharedLock(&afs_xconn); return NULL; } if (tu->states & UTokensBad) { /* we may still have an authenticated RPC connection here, * we'll have to create a new, unauthenticated, connection. * Perhaps a better way to do this would be to set * conn->forceConnectFS on all conns when the token first goes * bad, but that's somewhat trickier, due to locking * constraints (though not impossible). */ if (tc->id && (rx_SecurityClassOf(tc->id) != 0)) { tc->forceConnectFS = 1; /* force recreation of connection */ } tu->states &= ~UHasTokens; /* remove the authentication info */ } glocked = ISAFS_GLOCK(); if (tc->forceConnectFS) { UpgradeSToWLock(&afs_xconn, 38); csec = (struct rx_securityClass *)0; if (tc->id) { if (glocked) AFS_GUNLOCK(); rx_SetConnSecondsUntilNatPing(tc->id, 0); rx_DestroyConnection(tc->id); if (glocked) AFS_GLOCK(); } /* * Stupid hack to determine if using vldb service or file system * service. */ if (aport == sap->server->cell->vlport) service = 52; else service = 1; isec = 0; csec = afs_pickSecurityObject(tc, &isec); if (glocked) AFS_GUNLOCK(); tc->id = rx_NewConnection(sap->sa_ip, aport, service, csec, isec); if (glocked) AFS_GLOCK(); if (service == 52) { rx_SetConnHardDeadTime(tc->id, afs_rx_harddead); } /* set to a RX_CALL_TIMEOUT error to allow MTU retry to trigger */ rx_SetServerConnIdleDeadErr(tc->id, RX_CALL_DEAD); rx_SetConnIdleDeadTime(tc->id, afs_rx_idledead); /* * Only do this for the base connection, not per-user. * Will need to be revisited if/when CB gets security. */ if ((isec == 0) && (service != 52) && !(tu->states & UTokensBad) && (tu->viceId == UNDEFVID) #ifndef UKERNEL /* ukernel runs as just one uid anyway */ && (tu->uid == 0) #endif ) rx_SetConnSecondsUntilNatPing(tc->id, 20); tc->forceConnectFS = 0; /* apparently we're appropriately connected now */ if (csec) rxs_Release(csec); ConvertWToSLock(&afs_xconn); } /* end of if (tc->forceConnectFS)*/ *rxconn = tc->id; rx_GetConnection(*rxconn); ReleaseSharedLock(&afs_xconn); return tc; }
long rxkst_StartClient(struct clientParms *parms) { long code; long host; long scIndex; struct rx_securityClass *sc; whoami = parms->whoami; /* set this global variable */ host = GetServer(parms->server); if (parms->authentication >= 0) { long kvno = 0; char ticket[MAXKTCTICKETLEN]; int ticketLen; struct ktc_encryptionKey Ksession; if (parms->useTokens) code = GetToken(&kvno, &Ksession, &ticketLen, ticket, parms->cell); else code = GetTicket(&kvno, &Ksession, &ticketLen, ticket, parms->cell); if (code) return code; /* next, we have ticket, kvno and session key, authenticate the conn */ sc = (struct rx_securityClass *) rxkad_NewClientSecurityObject(parms->authentication, &Ksession, kvno, ticketLen, ticket); assert(sc); scIndex = RX_SECIDX_KAD; } else { /* unauthenticated connection */ sc = rxnull_NewClientSecurityObject(); assert(sc); scIndex = RX_SECIDX_NULL; } code = 0; if (!code && parms->callTest) { code = RunCallTest(parms, host, sc, scIndex); } if (!code && parms->hijackTest) { code = RunHijackTest(parms, host, sc, scIndex); } if (!code && (parms->printTiming || parms->fastCalls || parms->slowCalls || parms->copiousCalls)) { struct rx_connection *conn; conn = rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID, sc, scIndex); if (conn) { code = RepeatLoadTest(parms, conn); rx_DestroyConnection(conn); } else code = RXKST_NEWCONNFAILED; } if (!code && parms->stopServer) { struct rx_connection *conn; conn = rx_NewConnection(host, htons(RXKST_SERVICEPORT), RXKST_SERVICEID, sc, scIndex); if (conn) { code = RXKST_Kill(conn); if (code) { afs_com_err(whoami, code, "trying to stop server"); } rx_DestroyConnection(conn); } else code = RXKST_NEWCONNFAILED; } if (parms->printStats) { rx_PrintStats(stdout); #if 0 /* use rxdebug style iteration here */ rx_PrintPeerStats(stdout, rx_PeerOf(conn)); #endif } rxs_Release(sc); rx_Finalize(); if (code) { afs_com_err(parms->whoami, code, "test fails"); exit(13); } else { printf("Test Okay\n"); if (!parms->noExit) exit(0); } return 0; }