/* * cfgutil_HostHandleBosInit() -- initialize bosserver handle in host * configuration handle. * * RETURN CODES: 1 success, 0 failure */ int cfgutil_HostHandleBosInit(cfg_host_p cfg_host, afs_status_p st) { int rc = 1; afs_status_t tst = 0; if (pthread_mutex_lock(&cfg_host->mutex)) { tst = ADMMUTEXLOCK; } else { if (cfg_host->bosHandle == NULL) { /* initialize bosserver handle for host */ void *bosHandle; afs_status_t tst2; if (bos_ServerOpen (cfg_host->cellHandle, cfg_host->hostName, &bosHandle, &tst2)) { cfg_host->bosHandle = bosHandle; } else { tst = tst2; } } if (pthread_mutex_unlock(&cfg_host->mutex)) { /* can only return one status; mutex failure is critical */ tst = ADMMUTEXUNLOCK; } } if (tst != 0) { /* indicate failure */ rc = 0; } if (st != NULL) { *st = tst; } return rc; }
static DWORD WINAPI Salvage(LPVOID param) { afs_status_t nStatus; void *hServer; int nResult; nResult = bos_ServerOpen(g_hCell, GetHostnameA(), &hServer, &nStatus); if (!nResult) { ShowError(hDlg, nStatus, IDS_BOS_OPEN_FAILED); return FALSE; } nResult = bos_Salvage(g_hCell, hServer, S2A(pszPartitionName), S2A(pszVolumeName), nNumProcesses, S2A(szTempDir), 0, VOS_NORMAL, BOS_SALVAGE_DAMAGED_VOLUMES, BOS_SALVAGE_DONT_WRITE_INODES, BOS_SALVAGE_DONT_WRITE_ROOT_INODES, BOS_SALVAGE_DONT_FORCE_DIRECTORIES, BOS_SALVAGE_DONT_FORCE_BLOCK_READS, &nStatus); if (!nResult) ShowError(hDlg, nStatus, IDS_SALVAGE_ERROR); bos_ServerClose(hServer, &nStatus); g_CfgData.bReuseAdminInfo = nResult; return nResult; }
/* * UpdateWorkerThread() -- thread for updating CellServDB of servers in * a single name block. */ static void * UpdateWorkerThread(void *argp) { afs_status_t sync_tst = 0; cfg_csdb_update_name_t *nameBlockp = (cfg_csdb_update_name_t *) argp; int opDisposition; /* Pthread mutex and condition variable functions should never fail, * but if they do make a best effort attempt to report the problem; * will not be able to avoid race conditions in the face of such failures. */ if (pthread_mutex_lock(&nameBlockp->ctrl->mutex)) { sync_tst = ADMMUTEXLOCK; } while ((opDisposition = nameBlockp->ctrl->disposition) == CSDB_WAIT) { /* wait for start/abort signal */ if (pthread_cond_wait (&nameBlockp->ctrl->event, &nameBlockp->ctrl->mutex)) { /* avoid tight loop if condition variable wait fails */ cfgutil_Sleep(1); } } if (pthread_mutex_unlock(&nameBlockp->ctrl->mutex)) { sync_tst = ADMMUTEXUNLOCK; } if (opDisposition == CSDB_GO) { /* proceed with CellServDB update */ int i; for (i = 0; i < nameBlockp->serverCount; i++) { cfg_cellServDbStatus_t *statusp; /* alloc memory for status information (including host name) */ while ((statusp = (cfg_cellServDbStatus_t *) malloc(sizeof(*statusp) + AFS_MAX_SERVER_NAME_LEN)) == NULL) { /* avoid tight loop while waiting for status storage */ cfgutil_Sleep(1); } statusp->fsDbHost = ((char *)statusp + sizeof(*statusp)); /* make update and set status information */ strcpy(statusp->fsDbHost, nameBlockp->serverName[i]); if (sync_tst != 0) { /* report pthread problem */ statusp->status = sync_tst; } else { /* attempt update and report update status */ void *bosHandle; afs_status_t tst2, tst = 0; if (!bos_ServerOpen (nameBlockp->ctrl->cfg_host->cellHandle, nameBlockp->serverName[i], &bosHandle, &tst2)) { tst = tst2; } else { char *opHost = nameBlockp->ctrl->opHostAlias; if (nameBlockp->ctrl->op == CSDB_OP_ADD) { if (!bos_HostCreate(bosHandle, opHost, &tst2)) { tst = tst2; } } else { if (!bos_HostDelete(bosHandle, opHost, &tst2)) { if (tst2 != BZNOENT) { tst = tst2; } } } if (!bos_ServerClose(bosHandle, &tst2)) { tst = tst2; } } statusp->status = tst; } /* make call back to return update status */ (*nameBlockp->ctrl->callBack) (nameBlockp->ctrl->callBackId, statusp, 0); } } /* last worker makes termination call back and deallocates control block */ if (pthread_mutex_lock(&nameBlockp->ctrl->mutex)) { sync_tst = ADMMUTEXLOCK; } nameBlockp->ctrl->workersActive--; if (nameBlockp->ctrl->workersActive == 0) { if (opDisposition == CSDB_GO) { (*nameBlockp->ctrl->callBack) (nameBlockp->ctrl->callBackId, NULL, sync_tst); } free(nameBlockp->ctrl); } if (pthread_mutex_unlock(&nameBlockp->ctrl->mutex)) { sync_tst = ADMMUTEXUNLOCK; } /* all workers deallocate their own name block */ free(nameBlockp); return NULL; }
/* * cfg_CellServDbEnumerate() -- Enumerate database machines known to the * specified database or fileserver machine. Enumeration is returned * as a multistring. */ int ADMINAPI cfg_CellServDbEnumerate(const char *fsDbHost, /* fileserver or database host */ char **cellName, /* cell name for cellDbHosts */ char **cellDbHosts, /* cell database hosts */ afs_status_p st) { /* completion status */ int rc = 1; afs_status_t tst2, tst = 0; /* validate parameters */ if (fsDbHost == NULL || *fsDbHost == '\0') { tst = ADMCFGHOSTNAMENULL; } else if (cellName == NULL) { tst = ADMCFGCELLNAMENULL; } else if (cellDbHosts == NULL) { tst = ADMCFGCELLDBHOSTSNULL; } /* enumerate server CellServDB on specified host, along with cell name */ if (tst == 0) { void *cellHandle; void *bosHandle; char dbhostName[MAXHOSTSPERCELL][BOS_MAX_NAME_LEN]; char dbhostCell[BOS_MAX_NAME_LEN]; int dbhostCount = 0; if (!afsclient_NullCellOpen(&cellHandle, &tst2)) { tst = tst2; } else { if (!bos_ServerOpen(cellHandle, fsDbHost, &bosHandle, &tst2)) { tst = tst2; } else { void *dbIter; if (!bos_HostGetBegin(bosHandle, &dbIter, &tst2)) { tst = tst2; } else { for (dbhostCount = 0;; dbhostCount++) { char dbhostNameTemp[BOS_MAX_NAME_LEN]; if (!bos_HostGetNext(dbIter, dbhostNameTemp, &tst2)) { /* no more entries (or failure) */ if (tst2 != ADMITERATORDONE) { tst = tst2; } break; } else if (dbhostCount >= MAXHOSTSPERCELL) { /* more entries than expected */ tst = ADMCFGCELLSERVDBTOOMANYENTRIES; break; } else { strcpy(dbhostName[dbhostCount], dbhostNameTemp); } } if (!bos_HostGetDone(dbIter, &tst2)) { tst = tst2; } if (tst == 0) { /* got database servers; now get cell name */ if (!bos_CellGet(bosHandle, dbhostCell, &tst2)) { tst = tst2; } } } if (!bos_ServerClose(bosHandle, &tst2)) { tst = tst2; } } if (!afsclient_CellClose(cellHandle, &tst2)) { tst = tst2; } } if (tst == 0) { /* return database hosts to caller */ int i; size_t bufSize = 0; for (i = 0; i < dbhostCount; i++) { bufSize += strlen(dbhostName[i]) + 1; } bufSize++; /* end multistring */ *cellDbHosts = (char *)malloc(bufSize); if (*cellDbHosts == NULL) { tst = ADMNOMEM; } else { char *bufp = *cellDbHosts; for (i = 0; i < dbhostCount; i++) { strcpy(bufp, dbhostName[i]); bufp += strlen(bufp) + 1; } *bufp = '\0'; } /* return cell name to caller */ if (tst == 0) { *cellName = (char *)malloc(strlen(dbhostCell) + 1); if (*cellName == NULL) { free(*cellDbHosts); *cellDbHosts = NULL; tst = ADMNOMEM; } else { strcpy(*cellName, dbhostCell); } } } } if (tst != 0) { /* indicate failure */ rc = 0; } if (st != NULL) { *st = tst; } return rc; }
/* * cfgutil_HostNameGetCellServDbAlias() -- Get alias for given host name * as listed in the server CellServDB on the specified host. If no * alias is found then hostNameAlias is set to the empty string. * * Note: hostNameAlias is presumed to be a buffer of size MAXHOSTCHARS. * * RETURN CODES: 1 success, 0 failure */ int cfgutil_HostNameGetCellServDbAlias(const char *fsDbHost, const char *hostName, char *hostNameAlias, afs_status_p st) { int rc = 1; afs_status_t tst2, tst = 0; void *cellHandle; void *bosHandle; if (!afsclient_NullCellOpen(&cellHandle, &tst2)) { tst = tst2; } else { if (!bos_ServerOpen(cellHandle, fsDbHost, &bosHandle, &tst2)) { tst = tst2; } else { void *dbIter; if (!bos_HostGetBegin(bosHandle, &dbIter, &tst2)) { tst = tst2; } else { short dbhostDone = 0; short dbhostFound = 0; while (!dbhostDone) { short isAlias; if (!bos_HostGetNext(dbIter, hostNameAlias, &tst2)) { /* no more entries (or failure) */ if (tst2 != ADMITERATORDONE) { tst = tst2; } dbhostDone = 1; } else if (!cfgutil_HostNameIsAlias (hostName, hostNameAlias, &isAlias, &tst2)) { tst = tst2; dbhostDone = 1; } else if (isAlias) { dbhostFound = 1; dbhostDone = 1; } } if (!dbhostFound) { *hostNameAlias = '\0'; } if (!bos_HostGetDone(dbIter, &tst2)) { tst = tst2; } } if (!bos_ServerClose(bosHandle, &tst2)) { tst = tst2; } } if (!afsclient_CellClose(cellHandle, &tst2)) { tst = tst2; } } if (tst != 0) { /* indicate failure */ rc = 0; } if (st != NULL) { *st = tst; } return rc; }
/* * cfg_HostSetAfsPrincipal() -- Put AFS server principal (afs) key in * host's KeyFile; principal is created if it does not exist. * * If first server host in cell, passwd must be initial password for * the afs principal; the afs principal is created. * * If additional server host, passwd can be specified or NULL; the * afs principal must already exist by definition. If passwd is NULL * then an attempt is made to fetch the afs key. If the key fetch fails * because pre 3.5 database servers are in use (which will only return a * key checksum) then the function fails with a return status of * ADMCFGAFSKEYNOTAVAILABLE; in this case the function should be called * again with passwd specified. If passwd is specified (not NULL) but the * password key fails a checksum comparison with the current afs key * then the function fails with a return status of ADMCFGAFSPASSWDINVALID. * * ASSUMPTIONS: Client configured and BOS server started; if first host in * cell then Authentication server must be started as well. */ int ADMINAPI cfg_HostSetAfsPrincipal(void *hostHandle, /* host config handle */ short isFirst, /* first server in cell flag */ const char *passwd, /* afs initial password */ afs_status_p st) { /* completion status */ int rc = 1; afs_status_t tst2, tst = 0; cfg_host_p cfg_host = (cfg_host_p) hostHandle; /* validate parameters */ if (!cfgutil_HostHandleValidate(cfg_host, &tst2)) { tst = tst2; } else if ((isFirst && passwd == NULL) || (passwd != NULL && *passwd == '\0')) { tst = ADMCFGPASSWDNULL; } /* put afs key in host's KeyFile */ if (tst == 0) { kas_identity_t afsIdentity; kas_encryptionKey_t afsKey; int afsKvno = 0; strcpy(afsIdentity.principal, "afs"); afsIdentity.instance[0] = '\0'; if (isFirst) { /* create afs principal */ if (!kas_PrincipalCreate (cfg_host->cellHandle, NULL, &afsIdentity, passwd, &tst2) && tst2 != KAEXIST) { /* failed to create principal (and not because existed) */ tst = tst2; } } if (tst == 0) { /* retrive afs principal information to verify or obtain key */ kas_principalEntry_t afsEntry; if (!kas_PrincipalGet (cfg_host->cellHandle, NULL, &afsIdentity, &afsEntry, &tst2)) { tst = tst2; } else { if (passwd != NULL) { /* password given; form key and verify as most recent */ kas_encryptionKey_t passwdKey; unsigned int passwdKeyCksum; if (!kas_StringToKey (cfg_host->cellName, passwd, &passwdKey, &tst2) || !kas_KeyCheckSum(&passwdKey, &passwdKeyCksum, &tst2)) { /* failed to form key or key checksum */ tst = tst2; } else if (passwdKeyCksum != afsEntry.keyCheckSum) { /* passwd string does not generate most recent key; * check if passwd string embeds key directly. */ if (KasKeyEmbeddedInString(passwd, &passwdKey)) { /* passwd string embeds kas key */ if (!kas_KeyCheckSum (&passwdKey, &passwdKeyCksum, &tst2)) { tst = tst2; } else if (passwdKeyCksum != afsEntry.keyCheckSum) { /* passwd string does not embed valid key */ tst = ADMCFGAFSPASSWDINVALID; } } else { /* passwd string does NOT embed key */ tst = ADMCFGAFSPASSWDINVALID; } } if (tst == 0) { /* passwd seems to generate/embed most recent key */ afsKey = passwdKey; afsKvno = afsEntry.keyVersion; } } else { /* password NOT given; check if key retrieved since * pre 3.5 database servers only return key checksum */ if (KasKeyIsZero(&afsEntry.key)) { tst = ADMCFGAFSKEYNOTAVAILABLE; } else { afsKey = afsEntry.key; afsKvno = afsEntry.keyVersion; } } } } if (tst == 0) { /* add key to host's KeyFile; RPC must be unauthenticated; * bosserver is presumed to be in noauth mode. */ void *cellHandle, *bosHandle; if (!afsclient_NullCellOpen(&cellHandle, &tst2)) { tst = tst2; } else { if (!bos_ServerOpen (cellHandle, cfg_host->hostName, &bosHandle, &tst2)) { tst = tst2; } else { if (!bos_KeyCreate(bosHandle, afsKvno, &afsKey, &tst2) && tst2 != BZKEYINUSE) { /* failed to add key (and not because existed) */ tst = tst2; } if (!bos_ServerClose(bosHandle, &tst2)) { tst = tst2; } } if (!afsclient_CellClose(cellHandle, &tst2)) { tst = tst2; } } } } if (tst != 0) { rc = 0; } if (st != NULL) { *st = tst; } return rc; }