/* GetConfigParams */ static afs_int32 GetConfigParams(char *filename, afs_int32 port) { char paramFile[256]; FILE *devFile = 0; char line[LINESIZE], cmd[LINESIZE], value[LINESIZE]; afs_int32 code = 0; int cnt; /* DEFAULT SETTINGS FOR GLOBAL PARAMETERS */ dump_namecheck = 1; /* check tape name on dumps */ queryoperator = 1; /* can question operator */ autoQuery = 1; /* prompt for first tape */ isafile = 0; /* Do not dump to a file */ opencallout = NULL; /* open callout routine */ closecallout = NULL; /* close callout routine */ tapemounted = 0; /* tape is not mounted */ #ifdef xbsa BufferSize = (CONF_XBSA ? XBSADFLTBUFFER : BUTM_BLOCKSIZE); dumpRestAuthnLevel = rpc_c_protect_level_default; xbsaObjectOwner = NULL; /* bsaObjectOwner */ appObjectOwner = NULL; /* appObjectOwner */ adsmServerName = NULL; /* TSM server name - same as ADSM */ xbsaSecToken = NULL; /* XBSA sercurity token */ xbsalGName = NULL; /* XBSA IGName */ #else BufferSize = BUTM_BLOCKSIZE; #endif /*xbsa */ centralLogFile = NULL; /* Log for all butcs */ centralLogIO = 0; /* Log for all butcs */ statusSize = 0; /* size before status message */ maxpass = PASSESDFLT; /* dump passes */ lastLog = 0; /* separate log for last pass */ lastLogIO = 0; /* separate log for last pass */ groupId = 0; /* Group id for multiple dumps */ /* Try opening the CFG_<port> file */ sprintf(paramFile, "%s_%d", filename, port); devFile = fopen(paramFile, "r"); if (devFile) { /* Set log names to TL_<port>, TL_<port>.lp and TE_<port> */ sprintf(logFile, "%s_%d", lFile, port); sprintf(lastLogFile, "%s_%d.lp", lFile, port); sprintf(ErrorlogFile, "%s_%d", eFile, port); } else if (CONF_XBSA) { /* If configured as XBSA, a configuration file CFG_<port> must exist */ printf("Cannot open configuration file %s", paramFile); ERROR_EXIT(1); } else { /* Try the CFG_<device> name as the device file */ strcpy(paramFile, filename); stringNowReplace(paramFile, globalTapeConfig.device); /* Set log names to TL_<device>, TL_<device> and TE_<device> */ strcpy(logFile, lFile); stringNowReplace(logFile, globalTapeConfig.device); strcpy(lastLogFile, lFile); stringNowReplace(lastLogFile, globalTapeConfig.device); strcat(lastLogFile, ".lp"); strcpy(ErrorlogFile, eFile); stringNowReplace(ErrorlogFile, globalTapeConfig.device); /* Now open the device file */ devFile = fopen(paramFile, "r"); if (!devFile) ERROR_EXIT(0); /* CFG file doesn't exist for non-XBSA and that's ok */ } /* Read each line of the Configuration file */ while (fgets(line, LINESIZE - 1, devFile)) { cnt = sscanf(line, "%s %s", cmd, value); if (cnt != 2) { if (cnt > 0) printf("Bad line in %s: %s\n", paramFile, line); continue; } for (cnt = 0; cnt < strlen(cmd); cnt++) if (islower(cmd[cnt])) cmd[cnt] = toupper(cmd[cnt]); if (!strcmp(cmd, "NAME_CHECK")) { if (CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a Backup Service\n", cmd); continue; } for (cnt = 0; cnt < strlen(value); cnt++) if (islower(value[cnt])) value[cnt] = toupper(value[cnt]); if (!strcmp(value, "NO")) { printf("Dump tape name check is disabled\n"); dump_namecheck = 0; } else { printf("Dump tape name check is enabled\n"); dump_namecheck = 1; } } else if (!strcmp(cmd, "MOUNT")) { if (CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a Backup Service\n", cmd); continue; } opencallout = (char *)malloc(strlen(value) + 1); strcpy(opencallout, value); printf("Tape mount callout routine is %s\n", opencallout); } else if (!strcmp(cmd, "UNMOUNT")) { if (CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a Backup Service\n", cmd); continue; } closecallout = (char *)malloc(strlen(value) + 1); strcpy(closecallout, value); printf("Tape unmount callout routine is %s\n", closecallout); } else if (!strcmp(cmd, "ASK")) { for (cnt = 0; cnt < strlen(value); cnt++) if (islower(value[cnt])) value[cnt] = toupper(value[cnt]); if (!strcmp(value, "NO")) { printf("Operator queries are disabled\n"); queryoperator = 0; } else { printf("Operator queries are enabled\n"); queryoperator = 1; } } else if (!strcmp(cmd, "FILE")) { if (CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a Backup Service\n", cmd); continue; } for (cnt = 0; cnt < strlen(value); cnt++) if (islower(value[cnt])) value[cnt] = toupper(value[cnt]); if (!strcmp(value, "YES")) { printf("Will dump to a file\n"); isafile = 1; } else { printf("Will not dump to a file\n"); isafile = 0; } } else if (!strcmp(cmd, "AUTOQUERY")) { if (CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a Backup Service\n", cmd); continue; } for (cnt = 0; cnt < strlen(value); cnt++) if (islower(value[cnt])) value[cnt] = toupper(value[cnt]); if (!strcmp(value, "NO")) { printf("Auto query is disabled\n"); autoQuery = 0; } else { printf("Auto query is enabled\n"); autoQuery = 1; } } else if (!strcmp(cmd, "BUFFERSIZE")) { afs_int32 size; afs_int32 tapeblocks; if (!CONF_XBSA) { if (atocl(value, 'K', &size)) { fprintf(stderr, "BUFFERSIZE parse error\n"); size = 0; } /* A tapeblock is 16KB. Determine # of tapeblocks. Then * determine BufferSize needed for that many tapeblocks. */ tapeblocks = size / 16; if (tapeblocks <= 0) tapeblocks = 1; printf("BUFFERSIZE is %u KBytes\n", (tapeblocks * 16)); BufferSize = tapeblocks * BUTM_BLOCKSIZE; } else { #ifdef xbsa if (atocl(value, 'B', &size)) { fprintf(stderr, "BUFFERSIZE parse error\n"); size = 0; } if (size < XBSAMINBUFFER) size = XBSAMINBUFFER; if (size > XBSAMAXBUFFER) size = XBSAMAXBUFFER; printf("XBSA buffer size is %u Bytes\n", size); BufferSize = size; #endif } } #ifndef xbsa /* All the xbsa spacific parameters */ else if (!strcmp(cmd, "TYPE") || !strcmp(cmd, "NODE") || !strcmp(cmd, "SERVER") || !strcmp(cmd, "PASSWORD") || !strcmp(cmd, "PASSFILE") || !strcmp(cmd, "MGMTCLASS")) { printf("This binary does not have XBSA support\n"); return 1; } #else else if (!strcmp(cmd, "TYPE")) { /* required for XBSA */ if (!CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a tape drive\n", cmd); continue; } for (cnt = 0; (size_t) cnt < strlen(value); cnt++) if (islower(value[cnt])) value[cnt] = toupper(value[cnt]); if (strcmp(value, "TSM") == 0) { xbsaType = XBSA_SERVER_TYPE_ADSM; /* Known XBSA server type */ } else { printf("Configuration file error, %s %s is not recognized\n", cmd, value); xbsaType = XBSA_SERVER_TYPE_UNKNOWN; } printf("XBSA type is %s\n", ((xbsaType == XBSA_SERVER_TYPE_UNKNOWN) ? "Unknown" : value)); } else if (!strcmp(cmd, "NODE")) { if (!CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a tape drive\n", cmd); continue; } xbsaObjectOwner = malloc(strlen(value) + 1); strcpy(xbsaObjectOwner, value); printf("XBSA node is %s\n", xbsaObjectOwner); } else if (!strcmp(cmd, "SERVER")) { /* required for XBSA */ if (!CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a tape drive\n", cmd); continue; } adsmServerName = malloc(strlen(value) + 1); strcpy(adsmServerName, value); printf("XBSA server is %s\n", adsmServerName); } else if (!strcmp(cmd, "PASSWORD")) { /* This or PASSFILE required for XBSA */ if (!CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a tape drive\n", cmd); continue; } if (xbsaSecToken) { printf ("Warning: The %s parameter is ignored. Already read password\n", cmd); continue; } xbsaSecToken = malloc(strlen(value) + 1); strcpy(xbsaSecToken, value); printf("XBSA Password has been read\n"); } else if (!strcmp(cmd, "PASSFILE")) { /* This or PASSWORD required for XBSA */ FILE *pwdFile; if (!CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a tape drive\n", cmd); continue; } if (xbsaSecToken) { printf ("Warning: The %s parameter is ignored. Already read password\n", cmd); continue; } pwdFile = fopen(value, "r"); if (!pwdFile) { printf ("Configuration file error, cannot open password file %s\n", value); ERROR_EXIT(1); } xbsaSecToken = malloc(LINESIZE); if (!fscanf(pwdFile, "%s", xbsaSecToken)) { printf ("Configuration file error, cannot read password file %s\n", value); ERROR_EXIT(1); } printf("XBSA password retrieved from password file\n"); } else if (!strcmp(cmd, "MGMTCLASS")) { /* XBSA */ if (!CONF_XBSA) { printf ("Warning: The %s parameter is ignored with a tape drive\n", cmd); continue; } xbsalGName = malloc(strlen(value) + 1); strcpy(xbsalGName, value); printf("XBSA management class is %s\n", xbsalGName); } #endif else if (!strcmp(cmd, "MAXPASS")) { maxpass = SafeATOL(value); if (maxpass < PASSESMIN) maxpass = PASSESMIN; if (maxpass > PASSESMAX) maxpass = PASSESMAX; printf("MAXPASS is %d\n", maxpass); } else if (!strcmp(cmd, "GROUPID")) { groupId = SafeATOL(value); if ((groupId < MINGROUPID) || (groupId > MAXGROUPID)) { printf("Configuration file error, %s %s is invalid\n", cmd, value); ERROR_EXIT(1); } printf("Group Id is %d\n", groupId); } else if (!strcmp(cmd, "LASTLOG")) { for (cnt = 0; (size_t) cnt < strlen(value); cnt++) if (islower(value[cnt])) value[cnt] = toupper(value[cnt]); lastLog = (strcmp(value, "YES") == 0); printf("Will %sgenerate a last log\n", (lastLog ? "" : "not ")); } else if (!strcmp(cmd, "CENTRALLOG")) { centralLogFile = malloc(strlen(value) + 1); strcpy(centralLogFile, value); printf("Central log file is %s\n", centralLogFile); } else if (!strcmp(cmd, "STATUS")) { if (atocl(value, 'B', &statusSize)) { fprintf(stderr, "STATUS parse error\n"); statusSize = 0; } if (statusSize < MINSTATUS) statusSize = MINSTATUS; if (statusSize > MAXSTATUS) statusSize = MAXSTATUS; } else { printf("Warning: Unrecognized configuration parameter: %s", line); } } /*fgets */ if (statusSize) { /* Statussize is in bytes and requires that BufferSize be set first */ statusSize *= BufferSize; if (statusSize < 0) statusSize = 0x7fffffff; /*max size */ printf("Status every %ld Bytes\n", afs_printable_int32_ld(statusSize)); } error_exit: if (devFile) fclose(devFile); /* If the butc is configured as XBSA, check for required parameters */ #ifdef xbsa if (!code && CONF_XBSA) { if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("Configuration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, port); code = 1; } if (!adsmServerName) { printf ("Configuration file error, the SERVER parameter must be specified\n"); code = 1; } if (!xbsaSecToken) { printf ("Configuration file error, the PASSWORD or PASSFILE parameter must be specified\n"); code = 1; } } #endif /*xbsa */ return (code); }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code; struct rx_securityClass *(securityObjects[3]); struct rx_service *service; time_t tokenExpires; char cellName[64]; int localauth; /*process arguments */ afs_int32 portOffset = 0; #ifdef AFS_PTHREAD_ENV pthread_t dbWatcherPid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS dbWatcherPid; #endif afs_uint32 host = htonl(INADDR_ANY); debugLevel = 0; /*initialize the error tables */ initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_BUTC_error_table(); #ifdef xbsa initialize_BUTX_error_table(); #endif /*xbs */ initialize_VOLS_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); if (as->parms[0].items) { portOffset = SafeATOL(as->parms[0].items->data); if (portOffset == -1) { fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data); exit(1); } else if (portOffset > BC_MAXPORTOFFSET) { fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET); exit(1); } } xbsaType = XBSA_SERVER_TYPE_NONE; /* default */ if (as->parms[3].items) { /* -device */ globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */ globalTapeConfig.fileMarkSize = 0; globalTapeConfig.portOffset = portOffset; strncpy(globalTapeConfig.device, as->parms[3].items->data, 100); xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */ } else { /* Search for an entry in tapeconfig file */ code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset); if (code == -1) { fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile); exit(1); } /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so * it's an XBSA server. Don't know if its ADSM or not so its unknown. */ xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE); } if (as->parms[6].items) { /* -restoretofile */ int s = strlen(as->parms[6].items->data); restoretofile = malloc(s + 1); strncpy(restoretofile, as->parms[6].items->data, s + 1); printf("Restore to file '%s'\n", restoretofile); } /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set * the exact xbsaType within the call (won't be unknown) - double check. */ code = GetConfigParams(pFile, portOffset); if (code) exit(code); #ifdef xbsa if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("\nConfiguration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset); exit(1); } #else /* Not compiled for XBSA code so we can't support it */ if (CONF_XBSA) { printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset); printf("This binary does not have XBSA support\n"); exit(1); } #endif /* Open the log files. The pathnames were set in GetConfigParams() */ logIO = fopen(logFile, "a"); if (!logIO) { fprintf(stderr, "Failed to open %s\n", logFile); exit(1); } ErrorlogIO = fopen(ErrorlogFile, "a"); if (!ErrorlogIO) { fprintf(stderr, "Failed to open %s\n", ErrorlogFile); exit(1); } if (lastLog) { lastLogIO = fopen(lastLogFile, "a"); if (!lastLogIO) { fprintf(stderr, "Failed to open %s\n", lastLogFile); exit(1); } } if (centralLogFile) { struct stat sbuf; afs_int32 statcode; #ifndef AFS_NT40_ENV char path[AFSDIR_PATH_MAX]; #endif statcode = stat(centralLogFile, &sbuf); centralLogIO = fopen(centralLogFile, "a"); if (!centralLogIO) { fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile, errno); exit(1); } #ifndef AFS_NT40_ENV /* Make sure it is not in AFS, has to have been created first */ if (!realpath(centralLogFile, path)) { fprintf(stderr, "Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno); } else { if (strncmp(path, "/afs/", 5) == 0) { fprintf(stderr, "The central log '%s' should not be in AFS\n", centralLogFile); exit(1); } } #endif /* Write header if created it */ if (statcode) { char *h1 = "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n"; char *h2 = "----- ------------------- ------------------- -------- ---------\n"; /* File didn't exist before so write the header lines */ fwrite(h1, strlen(h1), 1, centralLogIO); fwrite(h2, strlen(h2), 1, centralLogIO); fflush(centralLogIO); } } if (as->parms[1].items) { debugLevel = SafeATOL(as->parms[1].items->data); if (debugLevel == -1) { TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data); exit(1); } } #ifdef xbsa /* Setup XBSA library interface */ if (CONF_XBSA) { afs_int32 rc; rc = xbsa_MountLibrary(&butxInfo, xbsaType); if (rc != XBSA_SUCCESS) { TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n"); return (1); } forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */ if (forcemultiple) printf("Force XBSA multiple server support\n"); rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName); if (rc != XBSA_SUCCESS) return (1); } #endif /*xbsa */ /* cell switch */ if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName)); else cellName[0] = '\0'; if (as->parms[4].items) autoQuery = 0; localauth = (as->parms[5].items ? 1 : 0); rxBind = (as->parms[8].items ? 1 : 0); if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = parseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)); if (code) { TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset); exit(1); } rx_SetRxDeadTime(150); /* Establish connection with the vldb server */ code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires); if (code) { TapeLog(0, 0, code, 0, "Can't access vldb\n"); return code; } strcpy(globalCellName, cellName); /*initialize the dumpNode list */ InitNodeList(portOffset); deviceLatch = (struct deviceSyncNode *)(malloc(sizeof(struct deviceSyncNode))); Lock_Init(&(deviceLatch->lock)); deviceLatch->flags = 0; /* initialize database support, volume support, and logs */ /* Create a single security object, in this case the null security * object, for unauthenticated connections, which will be used to control * security on connections made to this server */ securityObjects[0] = rxnull_NewServerSecurityObject(); securityObjects[1] = (struct rx_securityClass *)0; /* don't bother with rxvab */ if (!securityObjects[0]) { TLog(0, "rxnull_NewServerSecurityObject"); exit(1); } service = rx_NewServiceHost(host, 0, 1, "BUTC", securityObjects, 3, TC_ExecuteRequest); if (!service) { TLog(0, "rx_NewService"); exit(1); } rx_SetMaxProcs(service, 4); /* Establish connection to the backup database */ code = udbClientInit(0, localauth, cellName); if (code) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } /* This call is here to verify that we are authentiated. * The call does nothing and will return BUDB_NOTPERMITTED * if we don't belong. */ code = bcdb_deleteDump(0, 0, 0, 0); if (code == BUDB_NOTPERMITTED) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } initStatus(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task"); exit(1); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task"); exit(1); } AFS_SIGSET_CLEAR(); code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "dbWatcher", &dbWatcherPid); #endif if (code) { TapeLog(0, 0, code, 0, "Can't create database monitor task"); exit(1); } TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); exit(1); }
static int WorkerBee(struct cmd_syndesc *as, void *arock) { afs_int32 code, numClasses; struct rx_securityClass *(nullObjects[1]), **secObjs, **allObjs; struct rx_service *service; time_t tokenExpires; char cellName[64]; int localauth; /*process arguments */ afs_int32 portOffset = 0; #ifdef AFS_PTHREAD_ENV pthread_t dbWatcherPid; pthread_attr_t tattr; AFS_SIGSET_DECL; #else PROCESS dbWatcherPid; #endif char hoststr[16]; afs_uint32 host = htonl(INADDR_ANY); char *auditFileName = NULL; char *auditInterface = NULL; debugLevel = 0; /*initialize the error tables */ initialize_KA_error_table(); initialize_RXK_error_table(); initialize_KTC_error_table(); initialize_ACFG_error_table(); initialize_CMD_error_table(); initialize_VL_error_table(); initialize_BUTM_error_table(); initialize_BUTC_error_table(); #ifdef xbsa initialize_BUTX_error_table(); #endif /*xbs */ initialize_VOLS_error_table(); initialize_BUDB_error_table(); initialize_BUCD_error_table(); if (as->parms[0].items) { portOffset = SafeATOL(as->parms[0].items->data); if (portOffset == -1) { fprintf(stderr, "Illegal port offset '%s'\n", as->parms[0].items->data); exit(1); } else if (portOffset > BC_MAXPORTOFFSET) { fprintf(stderr, "%u exceeds max port offset %u\n", portOffset, BC_MAXPORTOFFSET); exit(1); } } xbsaType = XBSA_SERVER_TYPE_NONE; /* default */ if (as->parms[3].items) { /* -device */ globalTapeConfig.capacity = 0x7fffffff; /* 2T for max tape capacity */ globalTapeConfig.fileMarkSize = 0; globalTapeConfig.portOffset = portOffset; strncpy(globalTapeConfig.device, as->parms[3].items->data, 100); xbsaType = XBSA_SERVER_TYPE_NONE; /* Not XBSA */ } else { /* Search for an entry in tapeconfig file */ code = GetDeviceConfig(tapeConfigFile, &globalTapeConfig, portOffset); if (code == -1) { fprintf(stderr, "Problem in reading config file %s\n", tapeConfigFile); exit(1); } /* Set xbsaType. If code == 1, no entry was found in the tapeconfig file so * it's an XBSA server. Don't know if its ADSM or not so its unknown. */ xbsaType = ((code == 1) ? XBSA_SERVER_TYPE_UNKNOWN : XBSA_SERVER_TYPE_NONE); } if (as->parms[6].items) { /* -restoretofile */ restoretofile = strdup(as->parms[6].items->data); printf("Restore to file '%s'\n", restoretofile); } /* Go and read the config file: CFG_<device> or CFG_<port>. We will also set * the exact xbsaType within the call (won't be unknown) - double check. */ code = GetConfigParams(pFile, portOffset); if (code) exit(code); #ifdef xbsa if (xbsaType == XBSA_SERVER_TYPE_UNKNOWN) { printf ("\nConfiguration file error, the TYPE parameter must be specified, or\n"); printf("an entry must exist in %s for port %d\n", tapeConfigFile, portOffset); exit(1); } #else /* Not compiled for XBSA code so we can't support it */ if (CONF_XBSA) { printf("\nNo entry found in %s for port %d\n", tapeConfigFile, portOffset); printf("This binary does not have XBSA support\n"); exit(1); } #endif /* Open the log files. The pathnames were set in GetConfigParams() */ logIO = fopen(logFile, "a"); if (!logIO) { fprintf(stderr, "Failed to open %s\n", logFile); exit(1); } ErrorlogIO = fopen(ErrorlogFile, "a"); if (!ErrorlogIO) { fprintf(stderr, "Failed to open %s\n", ErrorlogFile); exit(1); } if (lastLog) { lastLogIO = fopen(lastLogFile, "a"); if (!lastLogIO) { fprintf(stderr, "Failed to open %s\n", lastLogFile); exit(1); } } if (centralLogFile) { struct stat sbuf; afs_int32 statcode; #ifndef AFS_NT40_ENV char *path; #endif statcode = stat(centralLogFile, &sbuf); centralLogIO = fopen(centralLogFile, "a"); if (!centralLogIO) { fprintf(stderr, "Failed to open %s; error %d\n", centralLogFile, errno); exit(1); } #ifndef AFS_NT40_ENV /* Make sure it is not in AFS, has to have been created first */ path = malloc(AFSDIR_PATH_MAX); if (path == NULL || !realpath(centralLogFile, path)) { fprintf(stderr, "Warning: can't determine real path of '%s' (%d)\n", centralLogFile, errno); } else { if (strncmp(path, "/afs/", 5) == 0) { fprintf(stderr, "The central log '%s' should not be in AFS\n", centralLogFile); exit(1); } } free(path); #endif /* Write header if created it */ if (statcode) { char *h1 = "TASK START DATE/TIME END DATE/TIME ELAPSED VOLUMESET\n"; char *h2 = "----- ------------------- ------------------- -------- ---------\n"; /* File didn't exist before so write the header lines */ fwrite(h1, strlen(h1), 1, centralLogIO); fwrite(h2, strlen(h2), 1, centralLogIO); fflush(centralLogIO); } } /* Open the configuration directory */ butc_confdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (butc_confdir == NULL) { TLog(0, "Failed to open server configuration directory"); exit(1); } /* Start auditing */ osi_audit_init(); if (as->parms[9].items) { auditFileName = as->parms[9].items->data; } if (auditFileName != NULL) osi_audit_file(auditFileName); if (as->parms[10].items) { auditInterface = as->parms[10].items->data; if (osi_audit_interface(auditInterface)) { TLog(0, "Invalid audit interface '%s'\n", auditInterface); exit(1); } } osi_audit(TC_StartEvent, 0, AUD_END); osi_audit_set_user_check(butc_confdir, tc_IsLocalRealmMatch); if (as->parms[1].items) { debugLevel = SafeATOL(as->parms[1].items->data); if (debugLevel == -1) { TLog(0, "Illegal debug level '%s'\n", as->parms[1].items->data); exit(1); } } #ifdef xbsa /* Setup XBSA library interface */ if (CONF_XBSA) { afs_int32 rc; rc = xbsa_MountLibrary(&butxInfo, xbsaType); if (rc != XBSA_SUCCESS) { TapeLog(0, 0, rc, 0, "Unable to mount the XBSA library\n"); return (1); } forcemultiple = (as->parms[7].items ? 1 : 0);/*-xbsaforcemultiple */ if (forcemultiple) printf("Force XBSA multiple server support\n"); rc = InitToServer(0 /*taskid */ , &butxInfo, adsmServerName); if (rc != XBSA_SUCCESS) return (1); (void)signal(SIGINT, xbsa_shutdown); (void)signal(SIGHUP, xbsa_shutdown); } #endif /*xbsa */ /* cell switch */ if (as->parms[2].items) strncpy(cellName, as->parms[2].items->data, sizeof(cellName)); else cellName[0] = '\0'; if (as->parms[4].items) autoQuery = 0; localauth = (as->parms[5].items ? 1 : 0); rxBind = (as->parms[8].items ? 1 : 0); allow_unauth = (as->parms[11].items ? 1 : 0); if (!allow_unauth && !localauth) { const char *errstr = "Neither -localauth nor -allow_unauthenticated was provided; refusing to start in unintended insecure configuration\n"; TLog(0, "%s", (char *)errstr); exit(1); } if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) host = SHostAddrs[0]; } TLog(0, "butc binding rx to %s:%d\n", afs_inet_ntoa_r(host, hoststr), BC_TAPEPORT + portOffset); code = rx_InitHost(host, htons(BC_TAPEPORT + portOffset)); if (code) { TapeLog(0, 0, code, 0, "rx init failed on port %u\n", BC_TAPEPORT + portOffset); exit(1); } rx_SetRxDeadTime(150); /* Establish connection with the vldb server */ code = vldbClientInit(0, localauth, cellName, &cstruct, &tokenExpires); if (code) { TapeLog(0, 0, code, 0, "Can't access vldb\n"); return code; } strcpy(globalCellName, cellName); /*initialize the dumpNode list */ InitNodeList(portOffset); deviceLatch = malloc(sizeof(struct deviceSyncNode)); Lock_Init(&(deviceLatch->lock)); deviceLatch->flags = 0; /* initialize database support, volume support, and logs */ /* * Create security objects for the Rx server functionality. Historically * this was a single rxnull security object, since the tape controller was * run by an operator that had local access to the tape device and some * administrative privilege in the cell (to be able to perform volume-level * accesses), but on a machine that was not necessarily trusted to hold the * cell-wide key. * * Such a configuration is, of course, insecure because anyone can make * inbound RPCs and manipulate the database, including creating bogus * dumps and restoring them! Additionally, in modern usage, butc is * frequently run with -localauth to authenticate its outbound connections * to the volservers and budb with the cell-wide key, in which case the * cell-wide key is present and could be used to authenticate incoming * connections as well. * * If -localauth is in use, create the full barrage of server security * objects, including rxkad, so that inbound connections can be verified * to only be made by authenticated clients. Otherwise, only the rxnull * class is in use with a single server security object. Note that butc * will refuse to start in this configuration unless the * "-allow_unauthenticated" flag is provided, indicating that the operator * has ensured that incoming connections are appropriately restricted by * firewall configuration or network topology. */ if (allow_unauth) { nullObjects[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject(); if (!nullObjects[RX_SECIDX_NULL]) { TLog(0, "rxnull_NewServerSecurityObject"); exit(1); } numClasses = 1; secObjs = nullObjects; } else { /* Must be -localauth, so the cell keys are available. */ afsconf_BuildServerSecurityObjects(butc_confdir, &allObjs, &numClasses); secObjs = allObjs; } service = rx_NewServiceHost(host, 0, 1, "BUTC", secObjs, numClasses, TC_ExecuteRequest); if (!service) { TLog(0, "rx_NewService"); exit(1); } rx_SetMaxProcs(service, 4); /* Establish connection to the backup database */ code = udbClientInit(0, localauth, cellName); if (code) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } /* This call is here to verify that we are authentiated. * The call does nothing and will return BUDB_NOTPERMITTED * if we don't belong. */ code = bcdb_deleteDump(0, 0, 0, 0); if (code == BUDB_NOTPERMITTED) { TapeLog(0, 0, code, 0, "Can't access backup database\n"); exit(1); } initStatus(); #ifdef AFS_PTHREAD_ENV code = pthread_attr_init(&tattr); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_init database monitor task"); exit(1); } code = pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); if (code) { TapeLog(0, 0, code, 0, "Can't pthread_attr_setdetachstate database monitor task"); exit(1); } AFS_SIGSET_CLEAR(); code = pthread_create(&dbWatcherPid, &tattr, dbWatcher, (void *)2); AFS_SIGSET_RESTORE(); #else code = LWP_CreateProcess(dbWatcher, 20480, LWP_NORMAL_PRIORITY, (void *)2, "dbWatcher", &dbWatcherPid); #endif if (code) { TapeLog(0, 0, code, 0, "Can't create database monitor task"); exit(1); } TLog(0, "Starting Tape Coordinator: Port offset %u Debug level %u\n", portOffset, debugLevel); TLog(0, "Token expires: %s\n", cTIME(&tokenExpires)); rx_StartServer(1); /* Donate this process to the server process pool */ TLog(0, "Error: StartServer returned"); exit(1); }