afs_int32 SBOZO_UnInstall(struct rx_call *acall, char *aname) { char *filepath; char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX]; afs_int32 code; char caller[MAXKTCNAMELEN]; struct stat tstat; if (!afsconf_SuperUser(bozo_confdir, acall, caller)) { code = BZACCESS; osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END); return code; } if (bozo_isrestricted) { code = BZACCESS; osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END); return code; } /* construct local path from canonical (wire-format) path */ if (ConstructLocalBinPath(aname, &filepath)) { return BZNOENT; } if (DoLogging) bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath); strcpy(fpBak, filepath); strcat(fpBak, ".BAK"); strcpy(fpOld, filepath); strcat(fpOld, ".OLD"); code = rk_rename(fpBak, filepath); if (code) { /* can't find .BAK, try .OLD */ code = rk_rename(fpOld, filepath); if (code && errno == ENOENT) /* If doesn't exist don't fail */ code = 0; } else { /* now rename .OLD to .BAK */ if (stat(fpOld, &tstat) == 0) code = rk_rename(fpOld, fpBak); } if (code) code = errno; osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END); free(filepath); return code; }
/* now rename .OLD to .BAK */ if (stat(fpOld, &tstat) == 0) code = rk_rename(fpOld, fpBak); } if (code) code = errno; osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END); free(filepath); return code; } #define BOZO_OLDTIME (7*24*3600) /* 7 days old */ static void SaveOldFiles(char *aname) { afs_int32 code; char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX]; struct stat tstat; afs_int32 now; afs_int32 oldTime, bakTime; strcpy(bbuffer, aname); strcat(bbuffer, ".BAK"); strcpy(obuffer, aname); strcat(obuffer, ".OLD"); now = FT_ApproxTime(); code = stat(aname, &tstat); if (code < 0) return; /* can't stat file */ code = stat(obuffer, &tstat); /* discover old file's time */ if (code) oldTime = 0; else oldTime = tstat.st_mtime; code = stat(bbuffer, &tstat); /* discover back file's time */ if (code) bakTime = 0; else bakTime = tstat.st_mtime; if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) { /* no .OLD file, or .BAK is at least a week old */ rk_rename(bbuffer, obuffer); } /* finally rename to .BAK extension */ rk_rename(aname, bbuffer); }
static int fs_stateCreateDump(struct fs_dump_state * state) { int fd, ret = 0; char savedump[MAXPATHLEN]; struct afs_stat status; snprintf(savedump, sizeof(savedump), "%s.old", state->fn); if (afs_stat(state->fn, &status) == 0) { rk_rename(state->fn, savedump); } if (((fd = afs_open(state->fn, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) || (afs_fstat(fd, &status) == -1)) { ViceLog(0, ("fs_stateCreateDump: failed to create state dump file '%s'\n", state->fn)); ret = 1; goto done; } state->fd = fd; state->mode = FS_STATE_DUMP_MODE; memset(state->hdr, 0, sizeof(struct fs_state_header)); fs_stateIncEOF(state, sizeof(struct fs_state_header)); #ifdef FS_STATE_USE_MMAP if (fs_stateSizeFile(state)) { ViceLog(0, ("fs_stateCreateDump: failed to resize state dump file '%s'\n", state->fn)); ret = 1; goto done; } if (fs_stateMapFile(state, 0)) { ViceLog(0, ("fs_stateCreateDump: failed to memory map state dump file '%s'\n", state->fn)); ret = 1; goto done; } #endif ret = fs_stateInvalidateDump(state); done: return ret; }
/*! * Move the current log file out of the way so a new one can be started. * * The format of the new name depends on the logging style. The traditional * Transarc style appends ".old" to the log file name. When MR-AFS style * logging is in effect, a time stamp is appended to the log file name instead * of ".old". * * \bug Unfortunately, no check is made to avoid overwriting * old logs in the traditional Transarc mode. * * \param fileName fully qualified log file path */ static void RenameLogFile(const char *fileName) { int code; char *nextName = NULL; int tries; time_t t; struct stat buf; struct tm *timeFields; switch (serverLogOpts.lopt_rotateStyle) { case logRotate_none: break; case logRotate_old: code = asprintf(&nextName, "%s.old", fileName); if (code < 0) { nextName = NULL; } break; case logRotate_timestamp: time(&t); for (tries = 0; nextName == NULL && tries < 100; t++, tries++) { timeFields = localtime(&t); code = asprintf(&nextName, "%s.%d%02d%02d%02d%02d%02d", fileName, timeFields->tm_year + 1900, timeFields->tm_mon + 1, timeFields->tm_mday, timeFields->tm_hour, timeFields->tm_min, timeFields->tm_sec); if (code < 0) { nextName = NULL; break; } if (lstat(nextName, &buf) == 0) { /* Avoid clobbering a log. */ free(nextName); nextName = NULL; } } break; default: opr_Assert(0); } if (nextName != NULL) { rk_rename(fileName, nextName); /* Don't check the error code. */ free(nextName); } }
static void write_master_down(krb5_context context) { char str[100]; time_t t = time(NULL); FILE *fp = NULL; if (slave_stats_temp_file != NULL) fp = fopen(slave_stats_temp_file, "w"); if (fp == NULL) return; krb5_format_time(context, t, str, sizeof(str), TRUE); fprintf(fp, "master down at %s\n", str); if (fclose(fp) != EOF) rk_rename(slave_stats_temp_file, slave_stats_file); }
/* write a new bozo file */ int WriteBozoFile(char *aname) { FILE *tfile; char tbuffer[AFSDIR_PATH_MAX]; afs_int32 code; struct bztemp btemp; if (!aname) aname = (char *)bozo_fileName; strcpy(tbuffer, aname); strcat(tbuffer, ".NBZ"); tfile = fopen(tbuffer, "w"); if (!tfile) return -1; btemp.file = tfile; fprintf(tfile, "restrictmode %d\n", bozo_isrestricted); fprintf(tfile, "restarttime %d %d %d %d %d\n", bozo_nextRestartKT.mask, bozo_nextRestartKT.day, bozo_nextRestartKT.hour, bozo_nextRestartKT.min, bozo_nextRestartKT.sec); fprintf(tfile, "checkbintime %d %d %d %d %d\n", bozo_nextDayKT.mask, bozo_nextDayKT.day, bozo_nextDayKT.hour, bozo_nextDayKT.min, bozo_nextDayKT.sec); code = bnode_ApplyInstance(bzwrite, &btemp); if (code || (code = ferror(tfile))) { /* something went wrong */ fclose(tfile); unlink(tbuffer); return code; } /* close the file, check for errors and snap new file into place */ if (fclose(tfile) == EOF) { unlink(tbuffer); return -1; } code = rk_rename(tbuffer, aname); if (code) { unlink(tbuffer); return -1; } return 0; }
int afsconf_DeleteIdentity(struct afsconf_dir *adir, struct rx_identity *user) { char *filename, *nfilename; char *buffer; char *copy; FILE *tf; FILE *nf; int flag; char *tp; int found; struct stat tstat; struct rx_identity identity; afs_int32 code; memset(&identity, 0, sizeof(struct rx_identity)); buffer = malloc(AFSDIR_PATH_MAX); if (buffer == NULL) return ENOMEM; filename = malloc(AFSDIR_PATH_MAX); if (filename == NULL) { free(buffer); return ENOMEM; } LOCK_GLOBAL_MUTEX; UserListFileName(adir, filename, AFSDIR_PATH_MAX); #ifndef AFS_NT40_ENV { /* * We attempt to fully resolve this pathname, so that the rename * of the temporary file will work even if UserList is a symlink * into a different filesystem. */ nfilename = malloc(AFSDIR_PATH_MAX); if (nfilename == NULL) { UNLOCK_GLOBAL_MUTEX; free(filename); free(buffer); return ENOMEM; } if (realpath(filename, nfilename)) { free(filename); filename = nfilename; } else { free(nfilename); } } #endif /* AFS_NT40_ENV */ if (asprintf(&nfilename, "%s.NXX", filename) < 0) { UNLOCK_GLOBAL_MUTEX; free(filename); free(buffer); return -1; } tf = fopen(filename, "r"); if (!tf) { UNLOCK_GLOBAL_MUTEX; free(filename); free(nfilename); free(buffer); return -1; } code = stat(filename, &tstat); if (code < 0) { UNLOCK_GLOBAL_MUTEX; free(filename); free(nfilename); free(buffer); return code; } nf = fopen(nfilename, "w+"); if (!nf) { fclose(tf); UNLOCK_GLOBAL_MUTEX; free(filename); free(nfilename); free(buffer); return EIO; } flag = 0; found = 0; while (1) { /* check for our user id */ tp = fgets(buffer, AFSDIR_PATH_MAX, tf); if (tp == NULL) break; copy = strdup(buffer); if (copy == NULL) { flag = 1; break; } code = ParseLine(copy, &identity); if (code == 0 && rx_identity_match(user, &identity)) { /* found the guy, don't copy to output file */ found = 1; } else { /* otherwise copy original line to output */ fprintf(nf, "%s", buffer); } free(copy); rx_identity_freeContents(&identity); } fclose(tf); free(buffer); if (ferror(nf)) flag = 1; if (fclose(nf) == EOF) flag = 1; if (flag == 0) { /* try the rename */ flag = rk_rename(nfilename, filename); if (flag == 0) flag = chmod(filename, tstat.st_mode); } else unlink(nfilename); /* finally, decide what to return to the caller */ UNLOCK_GLOBAL_MUTEX; free(filename); free(nfilename); if (flag) return EIO; /* something mysterious went wrong */ if (!found) return ENOENT; /* entry wasn't found, no changes made */ return 0; /* everything was fine */ }
int main(int argc, char **argv, char **envp) { struct rx_service *tservice; afs_int32 code; struct afsconf_dir *tdir; int noAuth = 0; int i; char namebuf[AFSDIR_PATH_MAX]; int rxMaxMTU = -1; afs_uint32 host = htonl(INADDR_ANY); char *auditFileName = NULL; struct rx_securityClass **securityClasses; afs_int32 numClasses; int DoPeerRPCStats = 0; int DoProcessRPCStats = 0; #ifndef AFS_NT40_ENV int nofork = 0; struct stat sb; #endif #ifdef AFS_AIX32_ENV struct sigaction nsa; /* for some reason, this permits user-mode RX to run a lot faster. * we do it here in the bosserver, so we don't have to do it * individually in each server. */ tweak_config(); /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGSEGV, &nsa, NULL); sigaction(SIGABRT, &nsa, NULL); #endif osi_audit_init(); signal(SIGFPE, bozo_insecureme); #ifdef AFS_NT40_ENV /* Initialize winsock */ if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); fprintf(stderr, "%s: Couldn't initialize winsock.\n", argv[0]); exit(2); } #endif /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } /* some path inits */ bozo_fileName = AFSDIR_SERVER_BOZCONF_FILEPATH; DoCore = AFSDIR_SERVER_LOGS_DIRPATH; /* initialize the list of dirpaths that the bosserver has * an interest in monitoring */ initBosEntryStats(); #if defined(AFS_SGI_ENV) /* offer some protection if AFS isn't loaded */ if (syscall(AFS_SYSCALL, AFSOP_ENDLOG) < 0 && errno == ENOPKG) { printf("bosserver: AFS doesn't appear to be configured in O.S..\n"); exit(1); } #endif #ifndef AFS_NT40_ENV /* save args for restart */ bozo_argc = argc; bozo_argv = malloc((argc+1) * sizeof(char*)); if (!bozo_argv) { fprintf(stderr, "%s: Failed to allocate argument list.\n", argv[0]); exit(1); } bozo_argv[0] = (char*)AFSDIR_SERVER_BOSVR_FILEPATH; /* expected path */ bozo_argv[bozo_argc] = NULL; /* null terminate list */ #endif /* AFS_NT40_ENV */ /* parse cmd line */ for (code = 1; code < argc; code++) { #ifndef AFS_NT40_ENV bozo_argv[code] = argv[code]; #endif /* AFS_NT40_ENV */ if (strcmp(argv[code], "-noauth") == 0) { /* set noauth flag */ noAuth = 1; } else if (strcmp(argv[code], "-log") == 0) { /* set extra logging flag */ DoLogging = 1; } #ifndef AFS_NT40_ENV else if (strcmp(argv[code], "-syslog") == 0) { /* set syslog logging flag */ DoSyslog = 1; } else if (strncmp(argv[code], "-syslog=", 8) == 0) { DoSyslog = 1; DoSyslogFacility = atoi(argv[code] + 8); } else if (strncmp(argv[code], "-cores=", 7) == 0) { if (strcmp((argv[code]+7), "none") == 0) DoCore = 0; else DoCore = (argv[code]+7); } else if (strcmp(argv[code], "-nofork") == 0) { nofork = 1; } #endif else if (strcmp(argv[code], "-enable_peer_stats") == 0) { DoPeerRPCStats = 1; } else if (strcmp(argv[code], "-enable_process_stats") == 0) { DoProcessRPCStats = 1; } else if (strcmp(argv[code], "-restricted") == 0) { bozo_isrestricted = 1; } else if (strcmp(argv[code], "-rxbind") == 0) { rxBind = 1; } else if (strcmp(argv[code], "-allow-dotted-principals") == 0) { rxkadDisableDotCheck = 1; } else if (!strcmp(argv[code], "-rxmaxmtu")) { if ((code + 1) >= argc) { fprintf(stderr, "missing argument for -rxmaxmtu\n"); exit(1); } rxMaxMTU = atoi(argv[++code]); } else if (strcmp(argv[code], "-auditlog") == 0) { auditFileName = argv[++code]; } else if (strcmp(argv[code], "-audit-interface") == 0) { char *interface = argv[++code]; if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); exit(1); } } else if (strncmp(argv[code], "-pidfiles=", 10) == 0) { DoPidFiles = (argv[code]+10); } else if (strncmp(argv[code], "-pidfiles", 9) == 0) { DoPidFiles = AFSDIR_BOSCONFIG_DIR; } else { /* hack to support help flag */ #ifndef AFS_NT40_ENV printf("Usage: bosserver [-noauth] [-log] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] " "[-syslog[=FACILITY]] " "[-restricted] " "[-enable_peer_stats] [-enable_process_stats] " "[-cores=<none|path>] \n" "[-pidfiles[=path]] " "[-nofork] " "[-help]\n"); #else printf("Usage: bosserver [-noauth] [-log] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] " "[-restricted] " "[-enable_peer_stats] [-enable_process_stats] " "[-cores=<none|path>] \n" "[-pidfiles[=path]] " "[-help]\n"); #endif fflush(stdout); exit(0); } } if (auditFileName) { osi_audit_file(auditFileName); } #ifndef AFS_NT40_ENV if (geteuid() != 0) { printf("bosserver: must be run as root.\n"); exit(1); } #endif if ((!DoSyslog) #ifndef AFS_NT40_ENV && ((lstat(AFSDIR_BOZLOG_FILE, &sb) == 0) && !(S_ISFIFO(sb.st_mode))) #endif ) { strcpy(namebuf, AFSDIR_BOZLOG_FILE); strcat(namebuf, ".old"); rk_rename(AFSDIR_BOZLOG_FILE, namebuf); /* try rename first */ bozo_logFile = fopen(AFSDIR_BOZLOG_FILE, "a"); if (!bozo_logFile) { printf("bosserver: can't initialize log file (%s).\n", AFSDIR_SERVER_BOZLOG_FILEPATH); exit(1); } /* keep log closed normally, so can be removed */ fclose(bozo_logFile); } else { #ifndef AFS_NT40_ENV openlog("bosserver", LOG_PID, DoSyslogFacility); #endif } /* * go into the background and remove our controlling tty, close open * file desriptors */ #ifndef AFS_NT40_ENV if (!nofork) daemon(1, 0); #endif /* ! AFS_NT40_ENV */ /* create useful dirs */ CreateDirs(DoCore); /* Write current state of directory permissions to log file */ DirAccessOK(); /* chdir to AFS log directory */ if (DoCore) chdir(DoCore); else chdir(AFSDIR_SERVER_LOGS_DIRPATH); /* try to read the key from the config file */ tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!tdir) { /* try to create local cell config file */ struct afsconf_cell tcell; strcpy(tcell.name, "localcell"); tcell.numServers = 1; code = gethostname(tcell.hostName[0], MAXHOSTCHARS); if (code) { bozo_Log("failed to get hostname, code %d\n", errno); exit(1); } if (tcell.hostName[0][0] == 0) { bozo_Log("host name not set, can't start\n"); bozo_Log("try the 'hostname' command\n"); exit(1); } memset(tcell.hostAddr, 0, sizeof(tcell.hostAddr)); /* not computed */ code = afsconf_SetCellInfo(NULL, AFSDIR_SERVER_ETC_DIRPATH, &tcell); if (code) { bozo_Log ("could not create cell database in '%s' (code %d), quitting\n", AFSDIR_SERVER_ETC_DIRPATH, code); exit(1); } tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!tdir) { bozo_Log ("failed to open newly-created cell database, quitting\n"); exit(1); } } /* opened the cell databse */ bozo_confdir = tdir; code = bnode_Init(); if (code) { printf("bosserver: could not init bnode package, code %d\n", code); exit(1); } bnode_Register("fs", &fsbnode_ops, 3); bnode_Register("dafs", &dafsbnode_ops, 4); bnode_Register("simple", &ezbnode_ops, 1); bnode_Register("cron", &cronbnode_ops, 2); #if defined(RLIMIT_CORE) && defined(HAVE_GETRLIMIT) { struct rlimit rlp; getrlimit(RLIMIT_CORE, &rlp); if (!DoCore) rlp.rlim_cur = 0; else rlp.rlim_max = rlp.rlim_cur = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlp); getrlimit(RLIMIT_CORE, &rlp); bozo_Log("Core limits now %d %d\n",(int)rlp.rlim_cur,(int)rlp.rlim_max); } #endif /* Read init file, starting up programs. Also starts watcher threads. */ if ((code = ReadBozoFile(0))) { bozo_Log ("bosserver: Something is wrong (%d) with the bos configuration file %s; aborting\n", code, AFSDIR_SERVER_BOZCONF_FILEPATH); exit(code); } 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]; } for (i = 0; i < 10; i++) { if (rxBind) { code = rx_InitHost(host, htons(AFSCONF_NANNYPORT)); } else { code = rx_Init(htons(AFSCONF_NANNYPORT)); } if (code) { bozo_Log("can't initialize rx: code=%d\n", code); sleep(3); } else break; } if (i >= 10) { bozo_Log("Bos giving up, can't initialize rx\n"); exit(code); } /* Set some rx config */ if (DoPeerRPCStats) rx_enablePeerRPCStats(); if (DoProcessRPCStats) rx_enableProcessRPCStats(); /* Disable jumbograms */ rx_SetNoJumbo(); if (rxMaxMTU != -1) { if (rx_SetMaxMTU(rxMaxMTU) != 0) { bozo_Log("bosserver: rxMaxMTU %d is invalid\n", rxMaxMTU); exit(1); } } code = LWP_CreateProcess(BozoDaemon, BOZO_LWP_STACKSIZE, /* priority */ 1, /* param */ NULL , "bozo-the-clown", &bozo_pid); if (code) { bozo_Log("Failed to create daemon thread\n"); exit(1); } /* initialize audit user check */ osi_audit_set_user_check(bozo_confdir, bozo_IsLocalRealmMatch); bozo_CreateRxBindFile(host); /* for local scripts */ /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(bozo_rxstat_userok); afsconf_SetNoAuthFlag(tdir, noAuth); afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses); if (DoPidFiles) { bozo_CreatePidFile("bosserver", NULL, getpid()); } tservice = rx_NewServiceHost(host, 0, /* service id */ 1, "bozo", securityClasses, numClasses, BOZO_ExecuteRequest); rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); rx_SetStackSize(tservice, BOZO_LWP_STACKSIZE); /* so gethostbyname works (in cell stuff) */ if (rxkadDisableDotCheck) { rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); } tservice = rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); rx_StartServer(1); /* donate this process */ return 0; }
int ReadBozoFile(char *aname) { FILE *tfile; char tbuffer[BOZO_BSSIZE]; char *tp; char *instp, *typep, *notifier, *notp; afs_int32 code; afs_int32 ktmask, ktday, kthour, ktmin, ktsec; afs_int32 i, goal; struct bnode *tb; char *parms[MAXPARMS]; char *thisparms[MAXPARMS]; int rmode; /* rename BozoInit to BosServer for the user */ if (!aname) { /* if BozoInit exists and BosConfig doesn't, try a rename */ if (access(AFSDIR_SERVER_BOZINIT_FILEPATH, 0) == 0 && access(AFSDIR_SERVER_BOZCONF_FILEPATH, 0) != 0) { code = rk_rename(AFSDIR_SERVER_BOZINIT_FILEPATH, AFSDIR_SERVER_BOZCONF_FILEPATH); if (code < 0) perror("bosconfig rename"); } if (access(AFSDIR_SERVER_BOZCONFNEW_FILEPATH, 0) == 0) { code = rk_rename(AFSDIR_SERVER_BOZCONFNEW_FILEPATH, AFSDIR_SERVER_BOZCONF_FILEPATH); if (code < 0) perror("bosconfig rename"); } } /* don't do server restarts by default */ bozo_nextRestartKT.mask = KTIME_NEVER; bozo_nextRestartKT.hour = 0; bozo_nextRestartKT.min = 0; bozo_nextRestartKT.day = 0; /* restart processes at 5am if their binaries have changed */ bozo_nextDayKT.mask = KTIME_HOUR | KTIME_MIN; bozo_nextDayKT.hour = 5; bozo_nextDayKT.min = 0; for (code = 0; code < MAXPARMS; code++) parms[code] = NULL; if (!aname) aname = (char *)bozo_fileName; tfile = fopen(aname, "r"); if (!tfile) return 0; /* -1 */ instp = malloc(BOZO_BSSIZE); typep = malloc(BOZO_BSSIZE); notp = malloc(BOZO_BSSIZE); while (1) { /* ok, read lines giving parms and such from the file */ tp = fgets(tbuffer, sizeof(tbuffer), tfile); if (tp == (char *)0) break; /* all done */ if (strncmp(tbuffer, "restarttime", 11) == 0) { code = sscanf(tbuffer, "restarttime %d %d %d %d %d", &ktmask, &ktday, &kthour, &ktmin, &ktsec); if (code != 5) { code = -1; goto fail; } /* otherwise we've read in the proper ktime structure; now assign * it and continue processing */ bozo_nextRestartKT.mask = ktmask; bozo_nextRestartKT.day = ktday; bozo_nextRestartKT.hour = kthour; bozo_nextRestartKT.min = ktmin; bozo_nextRestartKT.sec = ktsec; continue; } if (strncmp(tbuffer, "checkbintime", 12) == 0) { code = sscanf(tbuffer, "checkbintime %d %d %d %d %d", &ktmask, &ktday, &kthour, &ktmin, &ktsec); if (code != 5) { code = -1; goto fail; } /* otherwise we've read in the proper ktime structure; now assign * it and continue processing */ bozo_nextDayKT.mask = ktmask; /* time to restart the system */ bozo_nextDayKT.day = ktday; bozo_nextDayKT.hour = kthour; bozo_nextDayKT.min = ktmin; bozo_nextDayKT.sec = ktsec; continue; } if (strncmp(tbuffer, "restrictmode", 12) == 0) { code = sscanf(tbuffer, "restrictmode %d", &rmode); if (code != 1) { code = -1; goto fail; } if (rmode != 0 && rmode != 1) { code = -1; goto fail; } bozo_isrestricted = rmode; continue; } if (strncmp("bnode", tbuffer, 5) != 0) { code = -1; goto fail; } notifier = notp; code = sscanf(tbuffer, "bnode %s %s %d %s", typep, instp, &goal, notifier); if (code < 3) { code = -1; goto fail; } else if (code == 3) notifier = NULL; memset(thisparms, 0, sizeof(thisparms)); for (i = 0; i < MAXPARMS; i++) { /* now read the parms, until we see an "end" line */ tp = fgets(tbuffer, sizeof(tbuffer), tfile); if (!tp) { code = -1; goto fail; } StripLine(tbuffer); if (!strncmp(tbuffer, "end", 3)) break; if (strncmp(tbuffer, "parm ", 5)) { code = -1; goto fail; /* no "parm " either */ } if (!parms[i]) /* make sure there's space */ parms[i] = malloc(BOZO_BSSIZE); strcpy(parms[i], tbuffer + 5); /* remember the parameter for later */ thisparms[i] = parms[i]; } /* ok, we have the type and parms, now create the object */ code = bnode_Create(typep, instp, &tb, thisparms[0], thisparms[1], thisparms[2], thisparms[3], thisparms[4], notifier, goal ? BSTAT_NORMAL : BSTAT_SHUTDOWN, 0); if (code) goto fail; /* bnode created in 'temporarily shutdown' state; * check to see if we are supposed to run this guy, * and if so, start the process up */ if (goal) { bnode_SetStat(tb, BSTAT_NORMAL); /* set goal, taking effect immediately */ } else { bnode_SetStat(tb, BSTAT_SHUTDOWN); } } /* all done */ code = 0; fail: if (instp) free(instp); if (typep) free(typep); for (i = 0; i < MAXPARMS; i++) if (parms[i]) free(parms[i]); if (tfile) fclose(tfile); return code; }
static void write_stats(krb5_context context, slave *slaves, uint32_t current_version) { char str[100]; rtbl_t tbl; time_t t = time(NULL); FILE *fp = NULL; if (slave_stats_temp_file != NULL) fp = fopen(slave_stats_temp_file, "w"); if (fp == NULL) return; krb5_format_time(context, t, str, sizeof(str), TRUE); fprintf(fp, "Status for slaves, last updated: %s\n\n", str); fprintf(fp, "Master version: %lu\n\n", (unsigned long)current_version); tbl = rtbl_create(); if (tbl == NULL) { fclose(fp); return; } rtbl_add_column(tbl, SLAVE_NAME, 0); rtbl_add_column(tbl, SLAVE_ADDRESS, 0); rtbl_add_column(tbl, SLAVE_VERSION, RTBL_ALIGN_RIGHT); rtbl_add_column(tbl, SLAVE_STATUS, 0); rtbl_add_column(tbl, SLAVE_SEEN, 0); rtbl_set_prefix(tbl, " "); rtbl_set_column_prefix(tbl, SLAVE_NAME, ""); while (slaves) { krb5_address addr; krb5_error_code ret; rtbl_add_column_entry(tbl, SLAVE_NAME, slaves->name); ret = krb5_sockaddr2address (context, (struct sockaddr*)&slaves->addr, &addr); if(ret == 0) { krb5_print_address(&addr, str, sizeof(str), NULL); krb5_free_address(context, &addr); rtbl_add_column_entry(tbl, SLAVE_ADDRESS, str); } else rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>"); snprintf(str, sizeof(str), "%u", (unsigned)slaves->version); rtbl_add_column_entry(tbl, SLAVE_VERSION, str); if (slaves->flags & SLAVE_F_DEAD) rtbl_add_column_entry(tbl, SLAVE_STATUS, "Down"); else rtbl_add_column_entry(tbl, SLAVE_STATUS, "Up"); ret = krb5_format_time(context, slaves->seen, str, sizeof(str), TRUE); rtbl_add_column_entry(tbl, SLAVE_SEEN, str); slaves = slaves->next; } rtbl_format(tbl, fp); rtbl_destroy(tbl); if (fclose(fp) != EOF) rk_rename(slave_stats_temp_file, slave_stats_file); }
int OpenLog(const char *fileName) { /* * This function should allow various libraries that inconsistently * use stdout/stderr to all go to the same place */ int tempfd, isfifo = 0; char oldName[MAXPATHLEN]; struct timeval Start; struct tm *TimeFields; char FileName[MAXPATHLEN]; #ifndef AFS_NT40_ENV struct stat statbuf; if (serverLogSyslog) { openlog(serverLogSyslogTag, LOG_PID, serverLogSyslogFacility); return (0); } /* Support named pipes as logs by not rotating them */ if ((lstat(fileName, &statbuf) == 0) && (S_ISFIFO(statbuf.st_mode))) { isfifo = 1; } #endif if (mrafsStyleLogs) { time_t t; struct stat buf; gettimeofday(&Start, NULL); t = Start.tv_sec; TimeFields = localtime(&t); if (fileName) { if (strncmp(fileName, (char *)&ourName, strlen(fileName))) strcpy((char *)&ourName, (char *)fileName); } makefilename: snprintf(FileName, MAXPATHLEN, "%s.%d%02d%02d%02d%02d%02d", ourName, TimeFields->tm_year + 1900, TimeFields->tm_mon + 1, TimeFields->tm_mday, TimeFields->tm_hour, TimeFields->tm_min, TimeFields->tm_sec); if(lstat(FileName, &buf) == 0) { /* avoid clobbering a log */ TimeFields->tm_sec++; goto makefilename; } if (!isfifo) rk_rename(fileName, FileName); /* don't check error code */ tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | (isfifo?O_NONBLOCK:0), 0666); } else { strcpy(oldName, fileName); strcat(oldName, ".old"); /* don't check error */ if (!isfifo) rk_rename(fileName, oldName); tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | O_APPEND | (isfifo?O_NONBLOCK:0), 0666); } if (tempfd < 0) { printf("Unable to open log file %s\n", fileName); return -1; } /* redirect stdout and stderr so random printf's don't write to data */ if (freopen(fileName, "a", stdout) == NULL) ; /* don't care */ if (freopen(fileName, "a", stderr) != NULL) { #ifdef HAVE_SETVBUF setvbuf(stderr, NULL, _IONBF, 0); #else setbuf(stderr, NULL); #endif } #if defined(AFS_PTHREAD_ENV) opr_Verify(pthread_mutex_init(&serverLogMutex, NULL) == 0); #endif /* AFS_PTHREAD_ENV */ serverLogFD = tempfd; return 0; } /*OpenLog */
afs_int32 SBOZO_Install(struct rx_call *acall, char *aname, afs_int32 asize, afs_int32 mode, afs_int32 amtime) { afs_int32 code; int fd; afs_int32 len; afs_int32 total; #ifdef AFS_NT40_ENV struct _utimbuf utbuf; #else struct timeval tvb[2]; #endif char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp; char caller[MAXKTCNAMELEN]; if (!afsconf_SuperUser(bozo_confdir, acall, caller)) return BZACCESS; if (bozo_isrestricted) return BZACCESS; /* construct local path from canonical (wire-format) path */ if (ConstructLocalBinPath(aname, &fpp)) { return BZNOENT; } strcpy(filepath, fpp); free(fpp); if (DoLogging) bozo_Log("%s is executing Install '%s'\n", caller, filepath); /* open file */ fpp = filepath + strlen(filepath); strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */ fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777); if (fd < 0) return errno; total = 0; while (1) { len = rx_Read(acall, tbuffer, sizeof(tbuffer)); if (len < 0) { close(fd); unlink(filepath); return 102; } if (len == 0) break; /* no more input */ code = write(fd, tbuffer, len); if (code != len) { close(fd); unlink(filepath); return 100; } total += len; /* track total written for safety check at end */ } close(fd); if (asize != total) { unlink(filepath); return 101; /* wrong size */ } /* save old files */ *fpp = '\0'; /* remove ".NEW" from end of filepath */ SaveOldFiles(filepath); /* don't care if it works, still install */ /* all done, rename to final name */ strcpy(tbuffer, filepath); strcat(tbuffer, ".NEW"); code = (rk_rename(tbuffer, filepath) ? errno : 0); /* label file with same time for our sanity */ #ifdef AFS_NT40_ENV utbuf.actime = utbuf.modtime = amtime; _utime(filepath, &utbuf); #else tvb[0].tv_sec = tvb[1].tv_sec = amtime; tvb[0].tv_usec = tvb[1].tv_usec = 0; utimes(filepath, tvb); #endif /* AFS_NT40_ENV */ if (mode) chmod(filepath, mode); if (code < 0) { osi_auditU(acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END); return errno; } else return 0; }
int afsconf_DeleteIdentity(struct afsconf_dir *adir, struct rx_identity *user) { char tbuffer[1024]; char nbuffer[1024]; char *copy; FILE *tf; FILE *nf; int flag; char *tp; int found; struct stat tstat; struct rx_identity identity; afs_int32 code; memset(&identity, 0, sizeof(struct rx_identity)); LOCK_GLOBAL_MUTEX; UserListFileName(adir, tbuffer, sizeof tbuffer); #ifndef AFS_NT40_ENV { /* * We attempt to fully resolve this pathname, so that the rename * of the temporary file will work even if UserList is a symlink * into a different filesystem. */ char resolved_path[1024]; if (realpath(tbuffer, resolved_path)) { strcpy(tbuffer, resolved_path); } } #endif /* AFS_NT40_ENV */ tf = fopen(tbuffer, "r"); if (!tf) { UNLOCK_GLOBAL_MUTEX; return -1; } code = stat(tbuffer, &tstat); if (code < 0) { UNLOCK_GLOBAL_MUTEX; return code; } strcpy(nbuffer, tbuffer); strcat(nbuffer, ".NXX"); nf = fopen(nbuffer, "w+"); if (!nf) { fclose(tf); UNLOCK_GLOBAL_MUTEX; return EIO; } flag = 0; found = 0; while (1) { /* check for our user id */ tp = fgets(nbuffer, sizeof(nbuffer), tf); if (tp == NULL) break; copy = strdup(nbuffer); if (copy == NULL) { flag = 1; break; } code = ParseLine(copy, &identity); if (code == 0 && rx_identity_match(user, &identity)) { /* found the guy, don't copy to output file */ found = 1; } else { /* otherwise copy original line to output */ fprintf(nf, "%s", nbuffer); } free(copy); rx_identity_freeContents(&identity); } fclose(tf); if (ferror(nf)) flag = 1; if (fclose(nf) == EOF) flag = 1; strcpy(nbuffer, tbuffer); strcat(nbuffer, ".NXX"); /* generate new file name again */ if (flag == 0) { /* try the rename */ flag = rk_rename(nbuffer, tbuffer); if (flag == 0) flag = chmod(tbuffer, tstat.st_mode); } else unlink(nbuffer); /* finally, decide what to return to the caller */ UNLOCK_GLOBAL_MUTEX; if (flag) return EIO; /* something mysterious went wrong */ if (!found) return ENOENT; /* entry wasn't found, no changes made */ return 0; /* everything was fine */ }