/*! * \brief So that intermittent failures that cause connections to die * don't kill whole ubik connection, refresh them when the connection is in * error. */ struct rx_connection * ubik_RefreshConn(struct rx_connection *tc) { afs_uint32 host; u_short port; u_short service; struct rx_securityClass *sc; int si; struct rx_connection *newTc; host = rx_HostOf(rx_PeerOf(tc)); port = rx_PortOf(rx_PeerOf(tc)); service = rx_ServiceIdOf(tc); sc = rx_SecurityObjectOf(tc); si = rx_SecurityClassOf(tc); /* * destroy old one after creating new one so that refCount on security * object cannot reach zero. */ newTc = rx_NewConnection(host, port, service, sc, si); rx_DestroyConnection(tc); return newTc; }
int SPAGCB_GetCreds(struct rx_call *a_call, afs_int32 a_uid, CredInfos *a_creds) { struct unixuser *tu; CredInfo *tci; int bucket, count, i = 0, clen; char *cellname; RX_AFS_GLOCK(); memset(a_creds, 0, sizeof(struct CredInfos)); if ((rx_HostOf(rx_PeerOf(rx_ConnectionOf(a_call))) != afs_nfs_server_addr || rx_PortOf(rx_PeerOf(rx_ConnectionOf(a_call))) != htons(7001)) #if 0 /* for debugging ONLY! */ && rx_PortOf(rx_PeerOf(rx_ConnectionOf(a_call))) != htons(7901) #endif ) { RX_AFS_GUNLOCK(); return UAEPERM; } ObtainWriteLock(&afs_xuser, 823); /* count them first */ bucket = UHash(a_uid); for (count = 0, tu = afs_users[bucket]; tu; tu = tu->next) { if (tu->uid == a_uid) count++; } if (!count) { ReleaseWriteLock(&afs_xuser); RX_AFS_GUNLOCK(); return UAESRCH; } a_creds->CredInfos_val = (CredInfo *)afs_osi_Alloc(count * sizeof(CredInfo)); if (!a_creds->CredInfos_val) goto out; a_creds->CredInfos_len = count; memset(a_creds->CredInfos_val, 0, count * sizeof(CredInfo)); for (i = 0, tu = afs_users[bucket]; tu; tu = tu->next, i++) { if (tu->uid == a_uid && tu->cellinfo && (tu->states & UHasTokens) && !(tu->states & UTokensBad)) { tci = &a_creds->CredInfos_val[i]; tci->vid = tu->vid; tci->ct.AuthHandle = tu->ct.AuthHandle; memcpy(tci->ct.HandShakeKey, tu->ct.HandShakeKey, 8); tci->ct.ViceId = tu->ct.ViceId; tci->ct.BeginTimestamp = tu->ct.BeginTimestamp; tci->ct.EndTimestamp = tu->ct.EndTimestamp; cellname = ((struct afspag_cell *)(tu->cellinfo))->cellname; clen = strlen(cellname) + 1; tci->cellname = afs_osi_Alloc(clen); if (!tci->cellname) goto out; memcpy(tci->cellname, cellname, clen); tci->st.st_len = tu->stLen; tci->st.st_val = afs_osi_Alloc(tu->stLen); if (!tci->st.st_val) { afs_osi_Free(tci->cellname, clen); goto out; } memcpy(tci->st.st_val, tu->stp, tu->stLen); if (tu->states & UPrimary) tci->states |= UPrimary; } } ReleaseWriteLock(&afs_xuser); RX_AFS_GUNLOCK(); return 0; out: if (a_creds->CredInfos_val) { while (i-- > 0) { afs_osi_Free(a_creds->CredInfos_val[i].st.st_val, a_creds->CredInfos_val[i].st.st_len); afs_osi_Free(a_creds->CredInfos_val[i].cellname, strlen(a_creds->CredInfos_val[i].cellname) + 1); } afs_osi_Free(a_creds->CredInfos_val, count * sizeof(CredInfo)); } ReleaseWriteLock(&afs_xuser); RX_AFS_GUNLOCK(); return UAENOMEM; }
static int Main(struct cmd_syndesc *as, void *arock) { int code; char name[MAXKTCNAMELEN]; char instance[MAXKTCNAMELEN]; char newCell[MAXKTCREALMLEN]; char *cell; long serverList[MAXSERVERS]; extern struct passwd *getpwuid(); struct passwd *pw; struct ktc_encryptionKey key; char passwd[BUFSIZ]; int cellSpecified; int i; int verbose = (as->parms[1].items != 0); int hostUsage = (as->parms[2].items != 0); int waitReap = (as->parms[4].items != 0); int doAuth = (as->parms[5].items != 0); int number; /* number of iterations */ int callsPerSecond; /* to allow conn GC to run */ unsigned long lo, hi; /* mem usage */ unsigned long highWater; /* mem usage after reap period */ unsigned long lastWater; /* mem usage after last msg */ int serversUse[MAXSERVERS]; /* usage of each server */ long serversHost[MAXSERVERS]; /* host addr */ unsigned long startTime; unsigned long now; lo = 0; whoami = as->a0name; newCell[0] = 0; if (as->parms[0].items) number = atoi(as->parms[0].items->data); else number = 100; if (as->parms[3].items) callsPerSecond = atoi(as->parms[3].items->data); else callsPerSecond = 1; if (doAuth && hostUsage) { fprintf(stderr, "Can't report host usage when calling UserAuthenticate\n"); return -1; } if (as->parms[12].items) { /* if username specified */ code = ka_ParseLoginName(as->parms[12].items->data, name, instance, newCell); if (code) { afs_com_err(whoami, code, "parsing user's name '%s'", as->parms[12].items->data); return code; } if (strlen(newCell) > 0) cellSpecified = 1; } else { /* No explicit name provided: use Unix uid. */ pw = getpwuid(getuid()); if (pw == 0) { printf("Can't figure out your name from your user id.\n"); return KABADCMD; } strncpy(name, pw->pw_name, sizeof(name)); strcpy(instance, ""); strcpy(newCell, ""); } if (strcmp(as->parms[14].name, "-cell") == 0) { if (as->parms[14].items) { /* if cell specified */ if (cellSpecified) printf("Duplicate cell specification not allowed\n"); else strncpy(newCell, as->parms[14].items->data, sizeof(newCell)); } } code = ka_ExpandCell(newCell, newCell, 0 /*local */ ); if (code) { afs_com_err(whoami, code, "Can't expand cell name"); return code; } cell = newCell; if (as->parms[13].items) { /* if password specified */ strncpy(passwd, as->parms[13].items->data, sizeof(passwd)); memset(as->parms[13].items->data, 0, strlen(as->parms[13].items->data)); } else { char msg[sizeof(name) + 15]; if (as->parms[12].items) strcpy(msg, "Admin Password: "******"Password for %s: ", name); code = read_pw_string(passwd, sizeof(passwd), msg, 0); if (code) code = KAREADPW; else if (strlen(passwd) == 0) code = KANULLPASSWORD; if (code) { afs_com_err(whoami, code, "reading password"); return code; } } if (as->parms[15].items) { struct cmd_item *ip; char *ap[MAXSERVERS + 2]; for (ip = as->parms[15].items, i = 2; ip; ip = ip->next, i++) ap[i] = ip->data; ap[0] = ""; ap[1] = "-servers"; code = ubik_ParseClientList(i, ap, serverList); if (code) { afs_com_err(whoami, code, "could not parse server list"); return code; } ka_ExplicitCell(cell, serverList); } if (!doAuth) { ka_StringToKey(passwd, cell, &key); memset(passwd, 0, sizeof(passwd)); } if (hostUsage) { memset(serversUse, 0, sizeof(serversUse)); memset(serversHost, 0, sizeof(serversHost)); } startTime = time(0); for (i = 0; i < number; i++) { if (doAuth) { char *reason; code = ka_UserAuthenticateLife(0, name, instance, cell, passwd, 0, &reason); if (code) { fprintf(stderr, "Unable to authenticate to AFS because %s.\n", reason); return code; } } else { struct ktc_token token; struct ktc_token *pToken; struct ubik_client *ubikConn; struct kaentryinfo tentry; int c; code = ka_GetAdminToken(name, instance, cell, &key, 3600, &token, 1 /*new */ ); if (code) { afs_com_err(whoami, code, "getting admin token"); return code; } pToken = &token; if (token.ticketLen == 0) { fprintf("Can't get admin token\n"); return -1; } code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, pToken, &ubikConn); if (code) { afs_com_err(whoami, code, "Getting AuthServer ubik conn"); return code; } if (verbose) for (c = 0; c < MAXSERVERS; c++) { struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn, c); struct rx_peer *peer; if (rxConn == 0) break; peer = rx_PeerOf(rxConn); printf("conn to %s:%d secObj:%x\n", inet_ntoa(rx_HostOf(peer)), ntohs(rx_PortOf(peer)), rxConn->securityObject); } code = ubik_Call(KAM_GetEntry, ubikConn, 0, name, instance, KAMAJORVERSION, &tentry); if (code) { afs_com_err(whoami, code, "getting information for %s.%s", name, instance); return code; } for (c = 0; c < MAXSERVERS; c++) { struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn, c); int d; if (rxConn == 0) break; if (rxConn->serial > 0) { long host = rx_HostOf(rx_PeerOf(rxConn)); for (d = 0; d < MAXSERVERS; d++) { if (serversHost[d] == 0) serversHost[d] = host; if (host == serversHost[d]) { serversUse[d]++; break; } } } if (verbose) printf("serial is %d\n", rxConn->serial); } ubik_ClientDestroy(ubikConn); } now = time(0); if (!lo) lo = sbrk(0); if (i && ((i & 0x3f) == 0)) { unsigned long this = sbrk(0); printf(" mem after %d: lo=%x, cur=%x => %d (@ %d)\n", i, lo, this, this - lo, (this - lo) / i); if (highWater && (lastWater != this)) { lastWater = this; printf(" core leaking (after %d) should be %x, is %x\n", i, highWater, this); } } if ((highWater == 0) && ((now - startTime) > 61)) { highWater = sbrk(0); lastWater = highWater; printf(" mem highWater mark (after %d) should be %x\n", i, highWater); } if (callsPerSecond) { long target; if (callsPerSecond > 0) target = i / callsPerSecond; else /* if negative interpret as seconds per call */ target = i * (-callsPerSecond); target = (startTime + target) - now; if (target > 0) IOMGR_Sleep(target); } }
int SRXAFSCB_InitCallBackState(struct rx_call *a_call) { int i; struct vcache *tvc; struct rx_connection *tconn; struct rx_peer *peer; struct server *ts; int code = 0; XSTATS_DECLS; RX_AFS_GLOCK(); XSTATS_START_CMTIME(AFS_STATS_CM_RPCIDX_INITCALLBACKSTATE); AFS_STATCNT(SRXAFSCB_InitCallBackState); /* * Find the address of the host making this call */ if ((tconn = rx_ConnectionOf(a_call)) && (peer = rx_PeerOf(tconn))) { afs_allCBs++; afs_oddCBs++; /*Including any missed via create race */ afs_evenCBs++; /*Including any missed via create race */ ts = afs_FindServer(rx_HostOf(peer), rx_PortOf(peer), (afsUUID *) 0, 0); if (ts) { for (i = 0; i < VCSIZE; i++) for (tvc = afs_vhashT[i]; tvc; tvc = tvc->hnext) { if (tvc->callback == ts) { ObtainWriteLock(&afs_xcbhash, 451); afs_DequeueCallback(tvc); tvc->callback = NULL; tvc->f.states &= ~(CStatd | CUnique | CBulkFetching); ReleaseWriteLock(&afs_xcbhash); } } /* capabilities need be requested again */ ObtainWriteLock(&afs_xserver, 877); ts->flags &= ~SCAPS_KNOWN; ReleaseWriteLock(&afs_xserver); } /* find any volumes residing on this server and flush their state */ { struct volume *tv; int j; for (i = 0; i < NVOLS; i++) for (tv = afs_volumes[i]; tv; tv = tv->next) { for (j = 0; j < AFS_MAXHOSTS; j++) if (tv->serverHost[j] == ts) afs_ResetVolumeInfo(tv); } } osi_dnlc_purge(); /* may be a little bit extreme */ } XSTATS_END_TIME; RX_AFS_GUNLOCK(); return (0); } /*SRXAFSCB_InitCallBackState */