From 55227d935764a2ca81151513231e9dac010ac1e2 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Mon, 31 Jul 2006 18:15:48 +0000 Subject: [PATCH] STABLE14-fileserver-hates-pruclient-20060626 right now there is one struct ubik_client shared by all threads in the fileserve r, which sucks when one has it locked let's, uh, fix that. (cherry picked from commit 791b2141809fc0ad2da78ab3cd91303ac0ec482d) --- src/ptserver/ptprocs.c | 14 --- src/ptserver/ptuser.c | 11 -- src/util/casestrcpy.c | 22 ++++ src/viced/afsfileprocs.c | 15 ++- src/viced/host.c | 235 ++++++++++++++++++++++++++++++++++++++- src/viced/host.h | 1 + src/viced/viced.c | 9 ++ 7 files changed, 276 insertions(+), 31 deletions(-) diff --git a/src/ptserver/ptprocs.c b/src/ptserver/ptprocs.c index cb006e6ea9..224dcf482a 100644 --- a/src/ptserver/ptprocs.c +++ b/src/ptserver/ptprocs.c @@ -103,7 +103,6 @@ afs_int32 listElements(), listOwned(), isAMemberOf(), idToName(); afs_int32 listSuperGroups(); #endif -static stolower(); extern int IDCmp(); extern int prp_group_default; @@ -2229,19 +2228,6 @@ isAMemberOf(call, uid, gid, flag, cid) return code; } - -static -stolower(s) - register char *s; -{ - register int tc; - while ((tc = *s)) { - if (isupper(tc)) - *s = tolower(tc); - s++; - } -} - #if IP_WILDCARDS afs_int32 addWildCards(tt, alist, host) diff --git a/src/ptserver/ptuser.c b/src/ptserver/ptuser.c index 467a20524b..a0cb12a770 100644 --- a/src/ptserver/ptuser.c +++ b/src/ptserver/ptuser.c @@ -765,14 +765,3 @@ pr_SetFieldsEntry(afs_int32 id, afs_int32 mask, afs_int32 flags, afs_int32 ngrou nusers, 0, 0); return code; } - -int -stolower(char *s) -{ - while (*s) { - if (isupper(*s)) - *s = tolower(*s); - s++; - } - return 0; -} diff --git a/src/util/casestrcpy.c b/src/util/casestrcpy.c index b715ee8665..4645d1f3b1 100644 --- a/src/util/casestrcpy.c +++ b/src/util/casestrcpy.c @@ -67,6 +67,28 @@ ucstring(char *d, char *s, int n) return original_d; } +int +stolower(char *s) +{ + while (*s) { + if (isupper(*s)) + *s = tolower(*s); + s++; + } + return 0; +} + +int +stoupper(char *s) +{ + while (*s) { + if (islower(*s)) + *s = toupper(*s); + s++; + } + return 0; +} + /* strcompose - concatenate strings passed to it. * Input: * buf: storage for the composed string. Any data in it will be lost. diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 94810142b6..74c3a700aa 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -306,6 +306,8 @@ CallPreamble(register struct rx_call *acall, int activecall, int retry_flag = 1; int code = 0; char hoststr[16], hoststr2[16]; + struct ubik_client *uclient; + if (!tconn) { ViceLog(0, ("CallPreamble: unexpected null tconn!\n")); return -1; @@ -329,9 +331,20 @@ CallPreamble(register struct rx_call *acall, int activecall, /* Take down the old connection and re-read the key file */ ViceLog(0, ("CallPreamble: Couldn't get CPS. Reconnect to ptserver\n")); +#ifdef AFS_PTHREAD_ENV + uclient = (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + /* Is it still necessary to drop this? We hit the net, we should... */ H_UNLOCK; - code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0); + if (uclient) + hpr_End(uclient); + code = hpr_Initialize(&uclient); + + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); H_LOCK; +#else + code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0); +#endif if (code) { h_ReleaseClient_r(tclient); h_Release_r(thost); diff --git a/src/viced/host.c b/src/viced/host.c index 49f098b97e..6a14672822 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -255,6 +255,230 @@ FreeHT(register struct host *entry) } /*FreeHT */ +afs_int32 +hpr_Initialize(struct ubik_client **uclient) +{ + afs_int32 code; + struct rx_connection *serverconns[MAXSERVERS]; + struct rx_securityClass *sc[3]; + struct afsconf_dir *tdir; + char tconfDir[100] = ""; + char tcell[64] = ""; + struct ktc_token ttoken; + afs_int32 scIndex; + struct afsconf_cell info; + afs_int32 i; + char cellstr[64]; + + tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); + if (!tdir) { + fprintf(stderr, + "libprot: Could not open configuration directory: %s.\n", + AFSDIR_SERVER_ETC_DIRPATH); + return -1; + } + + code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); + if (code) { + fprintf(stderr, + "libprot: Could not get local cell. [%d]\n", code); + return code; + } + + code = afsconf_GetCellInfo(tdir, cellstr, "afsprot", &info); + if (code) { + fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n", + cellstr, confDir, AFSDIR_CELLSERVDB_FILE); + return code; + } + + afsconf_Close(tdir); + + code = rx_Init(0); + if (code) { + fprintf(stderr, "libprot: Could not initialize rx.\n"); + return code; + } + + scIndex = 2; + sc[0] = 0; + sc[1] = 0; + sc[2] = 0; + /* Most callers use secLevel==1, however, the fileserver uses secLevel==2 + * to force use of the KeyFile. secLevel == 0 implies -noauth was + * specified. */ + if ((afsconf_GetLatestKey(tdir, 0, 0) == 0)) { + code = afsconf_ClientAuthSecure(tdir, &sc[2], &scIndex); + if (code) + fprintf(stderr, + "libprot: clientauthsecure returns %d %s" + " (so trying noauth)\n", code, error_message(code)); + if (code) + scIndex = 0; /* use noauth */ + if (scIndex != 2) + /* if there was a problem, an unauthenticated conn is returned */ + sc[scIndex] = sc[2]; + } else { + struct ktc_principal sname; + strcpy(sname.cell, info.name); + sname.instance[0] = 0; + strcpy(sname.name, "afs"); + code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); + if (code) + scIndex = 0; + else { + if (ttoken.kvno >= 0 && ttoken.kvno <= 256) + /* this is a kerberos ticket, set scIndex accordingly */ + scIndex = 2; + else { + fprintf(stderr, + "libprot: funny kvno (%d) in ticket, proceeding\n", + ttoken.kvno); + scIndex = 2; + } + sc[2] = + rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey, + ttoken.kvno, ttoken.ticketLen, + ttoken.ticket); + } + } + if ((scIndex == 0) && (sc[0] == 0)) + sc[0] = rxnull_NewClientSecurityObject(); + if ((scIndex == 0)) + com_err("fileserver", code, + "Could not get afs tokens, running unauthenticated."); + + 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], + scIndex); + } + + code = ubik_ClientInit(serverconns, uclient); + if (code) { + com_err("fileserver", code, "ubik client init failed."); + } + + code = rxs_Release(sc[scIndex]); + return code; +} + +int +hpr_End(struct ubik_client *uclient) +{ + int code = 0; + + if (uclient) { + code = ubik_ClientDestroy(uclient); + } + return code; +} + +int +hpr_GetHostCPS(afs_int32 host, prlist *CPS) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + afs_int32 over; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + over = 0; + code = ubik_Call(PR_GetHostCPS, uclient, 0, host, CPS, &over); + if (code != PRSUCCESS) + return code; + if (over) { + /* do something about this, probably make a new call */ + /* don't forget there's a hard limit in the interface */ + fprintf(stderr, + "membership list for host id %d exceeds display limit\n", + host); + } + return 0; +#else + return pr_GetHostCPS(host, CPS); +#endif +} + +int +hpr_NameToId(namelist *names, idlist *ids) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + register afs_int32 i; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + for (i = 0; i < names->namelist_len; i++) + stolower(names->namelist_val[i]); + code = ubik_Call(PR_NameToID, uclient, 0, names, ids); + return code; +#else + return pr_NameToId(names, ids); +#endif +} + +int +hpr_IdToName(idlist *ids, namelist *names) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + code = ubik_Call(PR_IDToName, uclient, 0, ids, names); + return code; +#else + return pr_IdToName(ids, names); +#endif +} + +int +hpr_GetCPS(afs_int32 id, prlist *CPS) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + afs_int32 over; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + over = 0; + code = ubik_Call(PR_GetCPS, uclient, 0, id, CPS, &over); + if (code != PRSUCCESS) + return code; + if (over) { + /* do something about this, probably make a new call */ + /* don't forget there's a hard limit in the interface */ + fprintf(stderr, "membership list for id %d exceeds display limit\n", + id); + } + return 0; +#else + return pr_GetCPS(id, CPS); +#endif +} static short consolePort = 0; @@ -452,7 +676,7 @@ h_gethostcps_r(register struct host *host, register afs_int32 now) slept ? (host->cpsCall = FT_ApproxTime()) : (host->cpsCall = now); H_UNLOCK; - code = pr_GetHostCPS(ntohl(host->host), &host->hcps); + code = hpr_GetHostCPS(ntohl(host->host), &host->hcps); H_LOCK; if (code) { /* @@ -1509,7 +1733,7 @@ MapName_r(char *aname, char *acell, afs_int32 * aval) } H_UNLOCK; - code = pr_NameToId(&lnames, &lids); + code = hpr_NameToId(&lnames, &lids); H_LOCK; if (code == 0) { if (lids.idlist_val) { @@ -1624,7 +1848,7 @@ h_FindClient_r(struct rx_connection *tcon) expTime = 0x7fffffff; } else if (authClass == 2) { afs_int32 kvno; - + /* kerberos ticket */ code = rxkad_GetServerInfo(tcon, /*level */ 0, &expTime, tname, tinst, tcell, &kvno); @@ -1721,7 +1945,7 @@ h_FindClient_r(struct rx_connection *tcon) client->CPS.prlist_val = AnonCPS.prlist_val; } else { H_UNLOCK; - code = pr_GetCPS(viceid, &client->CPS); + code = hpr_GetCPS(viceid, &client->CPS); H_LOCK; if (code) { char hoststr[16]; @@ -1888,6 +2112,7 @@ h_UserName(struct client *client) static char User[PR_MAXNAMELEN + 1]; namelist lnames; idlist lids; + afs_int32 code; lids.idlist_len = 1; lids.idlist_val = (afs_int32 *) malloc(1 * sizeof(afs_int32)); @@ -1898,7 +2123,7 @@ h_UserName(struct client *client) lnames.namelist_len = 0; lnames.namelist_val = (prname *) 0; lids.idlist_val[0] = client->ViceId; - if (pr_IdToName(&lids, &lnames)) { + if (hpr_IdToName(&lids, &lnames)) { /* We need to free id we alloced above! */ free(lids.idlist_val); return "*UNKNOWN USER NAME*"; diff --git a/src/viced/host.h b/src/viced/host.h index 0094ca0810..9973df9666 100644 --- a/src/viced/host.h +++ b/src/viced/host.h @@ -25,6 +25,7 @@ extern pthread_mutex_t host_glock_mutex; assert(pthread_mutex_lock(&host_glock_mutex) == 0) #define H_UNLOCK \ assert(pthread_mutex_unlock(&host_glock_mutex) == 0) +extern pthread_key_t viced_uclient_key; #else /* AFS_PTHREAD_ENV */ #define H_LOCK #define H_UNLOCK diff --git a/src/viced/viced.c b/src/viced/viced.c index efd47c2b45..527dcb1284 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -198,6 +198,10 @@ int sendBufSize = 16384; /* send buffer size */ struct timeval tp; +#ifdef AFS_PTHREAD_ENV +pthread_key_t viced_uclient_key; +#endif + /* * FileServer's name and IP address, both network byte order and * host byte order. @@ -1302,6 +1306,11 @@ InitPR() ("Couldn't initialize protection library; code=%d.\n", code)); return code; } + +#ifdef AFS_PTHREAD_ENV + assert(pthread_key_create(&viced_uclient_key, NULL) == 0); +#endif + SystemId = SYSADMINID; SystemAnyUser = ANYUSERID; SystemAnyUserCPS.prlist_len = 0;