/* * cfg_HostQueryStatus() -- Query status of static server configuration * on host, i.e., status of required configuration files, etc. * Upon successful completion *configStP is set to the server * configuration status, with a value of zero (0) indicating that * the configuration is valid. * * If server configuration is not valid then *cellNameP is set to NULL; * otherwise, *cellNameP is an allocated buffer containing server cell. * * Warning: in determining if server configuration is valid, no check * is made for consistency with other servers in cell; also, the * internal consistency of configuration files may not be verified. */ int ADMINAPI cfg_HostQueryStatus(const char *hostName, /* name of host */ afs_status_p configStP, /* server config status */ char **cellNameP, /* server's cell */ afs_status_p st) { /* completion status */ int rc = 1; afs_status_t tst2, tst = 0; afs_status_t serverSt = 0; char *serverCellName = NULL; /* validate parameters */ if (hostName == NULL || *hostName == '\0') { tst = ADMCFGHOSTNAMENULL; } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) { tst = ADMCFGHOSTNAMETOOLONG; } else if (configStP == NULL) { tst = ADMCFGCONFIGSTATUSPNULL; } else if (cellNameP == NULL) { tst = ADMCFGCELLNAMEPNULL; } /* remote configuration not yet supported; hostName must be local host */ if (tst == 0) { short isLocal; if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) { tst = tst2; } else if (!isLocal) { tst = ADMCFGNOTSUPPORTED; } } /* check for existence and readability of required server config files */ if (tst == 0) { int i; const char *cfgfile[4]; cfgfile[0] = AFSDIR_SERVER_THISCELL_FILEPATH; cfgfile[1] = AFSDIR_SERVER_CELLSERVDB_FILEPATH; cfgfile[2] = AFSDIR_SERVER_KEY_FILEPATH; cfgfile[3] = AFSDIR_SERVER_ULIST_FILEPATH; for (i = 0; i < 4; i++) { int fd; if ((fd = open(cfgfile[i], O_RDONLY)) < 0) { break; } (void)close(fd); } if (i < 4) { if (errno == EACCES) { tst = ADMNOPRIV; } else { serverSt = ADMCFGSERVERBASICINFOINVALID; } } } /* verify the required server config files to the degree possible */ if (tst == 0 && serverSt == 0) { struct afsconf_dir *confdir; if ((confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH)) == NULL) { /* one or more config files appears to be invalid */ serverSt = ADMCFGSERVERBASICINFOINVALID; } else { struct afsconf_entry *cellentry; if (confdir->cellName == NULL || *confdir->cellName == '\0') { /* no cell set for server */ serverSt = ADMCFGSERVERNOTINCELL; } else if (confdir->keystr == NULL || confdir->keystr->nkeys == 0) { /* no server keys */ serverSt = ADMCFGSERVERNOKEYS; } else { for (cellentry = confdir->entries; cellentry != NULL; cellentry = cellentry->next) { if (!strcasecmp (confdir->cellName, cellentry->cellInfo.name)) { break; } } if (cellentry == NULL) { serverSt = ADMCFGSERVERCELLNOTINDB; } else if (cellentry->cellInfo.numServers <= 0) { serverSt = ADMCFGSERVERCELLHASNODBENTRIES; } } if (tst == 0 && serverSt == 0) { /* everything looks good; malloc cell name buffer to return */ serverCellName = (char *)malloc(strlen(cellentry->cellInfo.name) + 1); if (serverCellName == NULL) { tst = ADMNOMEM; } else { strcpy(serverCellName, cellentry->cellInfo.name); } } (void)afsconf_Close(confdir); } } if (tst == 0) { /* return server status and cell name */ *configStP = serverSt; if (serverSt == 0) { *cellNameP = serverCellName; } else { *cellNameP = NULL; } } else { /* indicate failure */ rc = 0; /* free cell name if allocated before failure */ if (serverCellName != NULL) { free(serverCellName); } } if (st != NULL) { *st = tst; } return rc; }
/* * cfg_ClientQueryStatus() -- Query status of static client configuration * on host, i.e., status of required configuration files, etc. * Upon successful completion *configStP is set to the client * configuration status, with a value of zero (0) indicating that * the configuration is valid. * * If client configuration is not valid then *cellNameP is set to NULL; * otherwise, *cellNameP is an allocated buffer containing client cell. * * If client software (cache-manager) is not installed then *versionP is * undefined; otherwise *versionP is 34 for 3.4, 35 for 3.5, etc. * * Note: Client configuration is checked even if the client software * is not installed. This is useful for tools that require * client configuration information but NOT the actual * client (cache-manager); for example, the AFS Server Manager. */ int ADMINAPI cfg_ClientQueryStatus(const char *hostName, /* name of host */ short *isInstalledP, /* client software installed */ unsigned *versionP, /* client software version */ afs_status_p configStP, /* client config status */ char **cellNameP, /* client's cell */ afs_status_p st) { /* completion status */ int rc = 1; afs_status_t tst2, tst = 0; afs_status_t clientSt = 0; char *clientCellName = NULL; short cmInstalled = 0; unsigned cmVersion = 0; /* validate parameters */ if (hostName == NULL || *hostName == '\0') { tst = ADMCFGHOSTNAMENULL; } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) { tst = ADMCFGHOSTNAMETOOLONG; } else if (isInstalledP == NULL) { tst = ADMCFGINSTALLEDFLAGPNULL; } else if (versionP == NULL) { tst = ADMCFGVERSIONPNULL; } else if (configStP == NULL) { tst = ADMCFGCONFIGSTATUSPNULL; } else if (cellNameP == NULL) { tst = ADMCFGCELLNAMEPNULL; } /* remote configuration not yet supported; hostName must be local host */ if (tst == 0) { short isLocal; if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) { tst = tst2; } else if (!isLocal) { tst = ADMCFGNOTSUPPORTED; } } /* determine if client software (CM) is installed and if so what version */ #ifdef AFS_NT40_ENV /* Windows - cache manager is a service */ if (tst == 0) { DWORD svcState; if (!cfgutil_WindowsServiceQuery (AFSREG_CLT_SVC_NAME, &svcState, &tst2)) { /* CM not installed, or insufficient privilege to check */ if (tst2 == ADMNOPRIV) { tst = tst2; } else { cmInstalled = 0; } } else { /* CM installed, get version */ unsigned major, minor, patch; cmInstalled = 1; if (afssw_GetClientVersion(&major, &minor, &patch)) { /* failed to retrieve version information */ if (errno == EACCES) { tst = ADMNOPRIV; } else { tst = ADMCFGCLIENTVERSIONNOTREAD; } } else { cmVersion = (major * 10) + minor; } } } #else if (tst == 0) { /* function not yet implemented for Unix */ tst = ADMCFGNOTSUPPORTED; } #endif /* AFS_NT40_ENV */ /* check static client configuration; not necessary that client * software (CM) be installed for this information to be valid and useable. */ if (tst == 0) { struct afsconf_dir *confdir; if ((confdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH)) == NULL) { /* the client configuration appears to be missing/invalid */ clientSt = ADMCFGCLIENTBASICINFOINVALID; } else { struct afsconf_entry *cellentry; if (confdir->cellName == NULL || *confdir->cellName == '\0') { /* no cell set for client */ clientSt = ADMCFGCLIENTNOTINCELL; } else { for (cellentry = confdir->entries; cellentry != NULL; cellentry = cellentry->next) { if (!strcasecmp (confdir->cellName, cellentry->cellInfo.name)) { break; } } if (cellentry == NULL) { clientSt = ADMCFGCLIENTCELLNOTINDB; } else if (cellentry->cellInfo.numServers <= 0) { clientSt = ADMCFGCLIENTCELLHASNODBENTRIES; } } if (tst == 0 && clientSt == 0) { /* everything looks good; malloc cell name buffer to return */ clientCellName = strdup(cellentry->cellInfo.name); if (clientCellName == NULL) tst = ADMNOMEM; } (void)afsconf_Close(confdir); } } /* return result of query */ if (tst == 0) { /* return client status and cell name */ *isInstalledP = cmInstalled; *versionP = cmVersion; *configStP = clientSt; if (clientSt == 0) { *cellNameP = clientCellName; } else { *cellNameP = NULL; } } else { /* indicate failure */ rc = 0; /* free cell name if allocated before failure */ if (clientCellName != NULL) { free(clientCellName); } } if (st != NULL) { *st = tst; } return rc; }
/* * cfg_HostOpen() -- Obtain host configuration handle. */ int ADMINAPI cfg_HostOpen(void *cellHandle, /* cell handle */ const char *hostName, /* name of host to configure */ void **hostHandleP, /* host config handle */ afs_status_p st) { /* completion status */ int rc = 1; afs_status_t tst2, tst = 0; cfg_host_p cfg_host; char fullHostName[MAXHOSTCHARS]; /* validate parameters and resolve host name to fully qualified name */ if (!CellHandleIsValid(cellHandle, &tst2)) { tst = tst2; } else if (hostName == NULL || *hostName == '\0') { tst = ADMCFGHOSTNAMENULL; } else if (strlen(hostName) > (MAXHOSTCHARS - 1)) { tst = ADMCFGHOSTNAMETOOLONG; } else if (hostHandleP == NULL) { tst = ADMCFGHOSTHANDLEPNULL; } else if (!cfgutil_HostNameGetFull(hostName, fullHostName, &tst2)) { tst = tst2; } /* remote configuration not yet supported; hostName must be local host */ if (tst == 0) { short isLocal; if (!cfgutil_HostNameIsLocal(hostName, &isLocal, &tst2)) { tst = tst2; } else if (!isLocal) { tst = ADMCFGNOTSUPPORTED; } } /* allocate a host configuration handle */ if (tst == 0) { char *localHostName; if ((cfg_host = (cfg_host_p) malloc(sizeof(cfg_host_t))) == NULL) { tst = ADMNOMEM; } else if ((localHostName = (char *)malloc(strlen(fullHostName) + 1)) == NULL) { free(cfg_host); tst = ADMNOMEM; } else { /* initialize handle */ cfg_host->begin_magic = BEGIN_MAGIC; cfg_host->is_valid = 1; cfg_host->hostName = localHostName; cfg_host->is_local = 1; /* not yet supporting remote config */ cfg_host->cellHandle = cellHandle; cfg_host->bosHandle = NULL; cfg_host->end_magic = END_MAGIC; strcpy(localHostName, fullHostName); if (!afsclient_CellNameGet (cfg_host->cellHandle, &cfg_host->cellName, &tst2)) { tst = tst2; } else if (pthread_mutex_init(&cfg_host->mutex, NULL)) { tst = ADMMUTEXINIT; } if (tst != 0) { /* cell name lookup or mutex initialization failed */ free(localHostName); free(cfg_host); } } } if (tst == 0) { /* success; return host config handle to user */ *hostHandleP = cfg_host; } else { /* indicate failure */ rc = 0; } if (st != NULL) { *st = tst; } return rc; }