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 = renamefile(fpBak, filepath); if (code) { /* can't find .BAK, try .OLD */ code = renamefile(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 = renamefile(fpOld, fpBak); } if (code) code = errno; osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END); free(filepath); return code; }
boolean clayrenamefile (tybrowserspec *fs, hdlheadrecord headnode) { /* 6.2b16 AR. tablesetitemname now takes a headnode param instead of a bigstring */ #if filebrowser bigstring bsnew; opgetheadstring (headnode, bsnew); return (renamefile (fs, bsnew)); #endif #if odbbrowser boolean fl; opstartinternalchange (); fl = tablesetitemname ((*fs).parID, (*fs).name, headnode, true); opendinternalchange (); return (fl); #endif } /*clayrenamefile*/
/* now rename .OLD to .BAK */ if (stat(fpOld, &tstat) == 0) code = renamefile(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 */ code = renamefile(bbuffer, obuffer); } /* finally rename to .BAK extension */ renamefile(aname, bbuffer); }
static int fs_stateCreateDump(struct fs_dump_state * state) { int fd, ret = 0; char savedump[MAXPATHLEN]; struct afs_stat status; afs_snprintf(savedump, sizeof(savedump), "%s.old", state->fn); if (afs_stat(state->fn, &status) == 0) { renamefile(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)) { 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; }
/**************** * release a lock * Returns: 0 := success */ int release_dotlock( DOTLOCK h ) { #if defined (HAVE_DOSISH_SYSTEM) return 0; #else int pid; if( h->disable ) { return 0; } if( !h->locked ) { log_debug("oops, `%s' is not locked\n", h->lockname ); return 0; } pid = read_lockfile( h->lockname ); if( pid == -1 ) { log_error( "release_dotlock: lockfile error\n"); return -1; } if( pid != getpid() ) { log_error( "release_dotlock: not our lock (pid=%d)\n", pid); return -1; } #ifndef __riscos__ if( unlink( h->lockname ) ) { log_error( "release_dotlock: error removing lockfile `%s'", h->lockname); return -1; } #else /* __riscos__ */ if( renamefile(h->lockname, h->tname) ) { log_error( "release_dotlock: error renaming lockfile `%s' to `%s'", h->lockname, h->tname); return -1; } #endif /* __riscos__ */ /* fixme: check that the link count is now 1 */ h->locked = 0; return 0; #endif }
/* 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 = renamefile(tbuffer, aname); if (code) { unlink(tbuffer); return -1; } return 0; }
/* deletes a user from the UserList file */ int afsconf_DeleteUser(struct afsconf_dir *adir, register char *auser) { char tbuffer[1024]; char nbuffer[1024]; register FILE *tf; register FILE *nf; register int flag; char tname[64 + 1]; char *tp; int found; struct stat tstat; register afs_int32 code; LOCK_GLOBAL_MUTEX; strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL); #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; code = sscanf(nbuffer, "%64s", tname); if (code == 1 && strcmp(tname, auser) == 0) { /* found the guy, don't copy to output file */ found = 1; } else { /* otherwise copy original line to output */ fprintf(nf, "%s", nbuffer); } } 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 = renamefile(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 */ }
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) renamefile(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) renamefile(fileName, oldName); tempfd = open(fileName, O_WRONLY | O_TRUNC | O_CREAT | (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 */ (void)freopen(fileName, "a", stdout); (void)freopen(fileName, "a", stderr); #ifdef HAVE_SETVBUF setvbuf(stderr, NULL, _IONBF, 0); #else setbuf(stderr, NULL); #endif #if defined(AFS_PTHREAD_ENV) MUTEX_INIT(&serverLogMutex, "serverlog", MUTEX_DEFAULT, 0); #endif /* AFS_PTHREAD_ENV */ serverLogFD = tempfd; return 0; } /*OpenLog */
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; #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) { rx_enablePeerRPCStats(); } else if (strcmp(argv[code], "-enable_process_stats") == 0) { rx_enableProcessRPCStats(); } 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-interafce <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-interafce <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 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); /* create useful dirs */ CreateDirs(DoCore); /* chdir to AFS log directory */ if (DoCore) chdir(DoCore); else chdir(AFSDIR_SERVER_LOGS_DIRPATH); #if 0 fputs(AFS_GOVERNMENT_MESSAGE, stdout); fflush(stdout); #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 */ 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"); renamefile(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 } #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 /* Write current state of directory permissions to log file */ DirAccessOK(); 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]; } 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); } code = LWP_CreateProcess(BozoDaemon, BOZO_LWP_STACKSIZE, /* priority */ 1, /* param */ NULL , "bozo-the-clown", &bozo_pid); /* 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(bozo_confdir, 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); } } /* read init file, starting up programs */ 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); } bozo_CreateRxBindFile(host); /* for local scripts */ /* opened the cell databse */ bozo_confdir = tdir; /* 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()); } /* Disable jumbograms */ rx_SetNoJumbo(); if (rxMaxMTU != -1) { if (rx_SetMaxMTU(rxMaxMTU) != 0) { bozo_Log("bosserver: rxMaxMTU %d is invalid\n", rxMaxMTU); exit(1); } } 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 = renamefile(AFSDIR_SERVER_BOZINIT_FILEPATH, AFSDIR_SERVER_BOZCONF_FILEPATH); if (code < 0) perror("bosconfig rename"); } if (access(AFSDIR_SERVER_BOZCONFNEW_FILEPATH, 0) == 0) { code = renamefile(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; tfile = (FILE *) 0; if (!aname) aname = (char *)bozo_fileName; tfile = fopen(aname, "r"); if (!tfile) return 0; /* -1 */ instp = malloc(BOZO_BSSIZE); typep = malloc(BOZO_BSSIZE); notifier = 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] = (char *)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; }
/**************** * Do a lock on H. A TIMEOUT of 0 returns immediately, * -1 waits forever (hopefully not), other * values are timeouts in milliseconds. * Returns: 0 on success */ int make_dotlock( DOTLOCK h, long timeout ) { #if defined (HAVE_DOSISH_SYSTEM) return 0; #else int pid; const char *maybe_dead=""; int backoff=0; if( h->disable ) { return 0; } if( h->locked ) { #ifndef __riscos__ log_debug("oops, `%s' is already locked\n", h->lockname ); #endif /* !__riscos__ */ return 0; } for(;;) { #ifndef __riscos__ if( !link(h->tname, h->lockname) ) { /* fixme: better use stat to check the link count */ h->locked = 1; return 0; /* okay */ } if( errno != EEXIST ) { log_error( "lock not made: link() failed: %s\n", strerror(errno) ); return -1; } #else /* __riscos__ */ if( !renamefile(h->tname, h->lockname) ) { h->locked = 1; return 0; /* okay */ } if( errno != EEXIST ) { log_error( "lock not made: rename() failed: %s\n", strerror(errno) ); return -1; } #endif /* __riscos__ */ if( (pid = read_lockfile(h->lockname)) == -1 ) { if( errno != ENOENT ) { log_info("cannot read lockfile\n"); return -1; } log_info( "lockfile disappeared\n"); continue; } else if( pid == getpid() ) { log_info( "Oops: lock already held by us\n"); h->locked = 1; return 0; /* okay */ } else if( kill(pid, 0) && errno == ESRCH ) { #ifndef __riscos__ maybe_dead = " - probably dead"; #if 0 /* we should not do this without checking the permissions */ /* and the hostname */ log_info( "removing stale lockfile (created by %d)", pid ); #endif #else /* __riscos__ */ /* we are *pretty* sure that the other task is dead and therefore we remove the other lock file */ maybe_dead = " - probably dead - removing lock"; unlink(h->lockname); #endif /* __riscos__ */ } if( timeout == -1 ) { struct timeval tv; log_info( "waiting for lock (held by %d%s) %s...\n", pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":""); /* can't use sleep, cause signals may be blocked */ tv.tv_sec = 1 + backoff; tv.tv_usec = 0; select(0, NULL, NULL, NULL, &tv); if( backoff < 10 ) backoff++ ; } else return -1; } /*not reached */ #endif }
/* save core file, if any */ static void SaveCore(struct bnode *abnode, struct bnode_proc *aproc) { char tbuffer[256]; struct stat tstat; afs_int32 code = 0; char *corefile = NULL; #ifdef BOZO_SAVE_CORES struct timeval Start; struct tm *TimeFields; char FileName[256]; #endif /* Linux always appends the PID to core dumps from threaded processes, so * we have to scan the directory to find core files under another name. */ if (DoCore) { strcpy(tbuffer, DoCore); strcat(tbuffer, "/"); strcat(tbuffer, AFSDIR_CORE_FILE); } else code = stat(AFSDIR_SERVER_CORELOG_FILEPATH, &tstat); if (code) { DIR *logdir; struct dirent *file; size_t length; unsigned long pid; const char *coredir = AFSDIR_LOGS_DIR; if (DoCore) coredir = DoCore; logdir = opendir(coredir); if (logdir == NULL) return; while ((file = readdir(logdir)) != NULL) { if (strncmp(file->d_name, "core.", 5) != 0) continue; pid = atol(file->d_name + 5); if (pid == aproc->pid) { length = strlen(coredir) + strlen(file->d_name) + 2; corefile = malloc(length); if (corefile == NULL) { closedir(logdir); return; } snprintf(corefile, length, "%s/%s", coredir, file->d_name); code = 0; break; } } closedir(logdir); } else { corefile = strdup(tbuffer); } if (code) return; bnode_CoreName(abnode, aproc->coreName, tbuffer); #ifdef BOZO_SAVE_CORES FT_GetTimeOfDay(&Start, 0); TimeFields = localtime(&Start.tv_sec); sprintf(FileName, "%s.%d%02d%02d%02d%02d%02d", tbuffer, TimeFields->tm_year + 1900, TimeFields->tm_mon + 1, TimeFields->tm_mday, TimeFields->tm_hour, TimeFields->tm_min, TimeFields->tm_sec); strcpy(tbuffer, FileName); #endif code = renamefile(corefile, tbuffer); free(corefile); }
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 = renamefile(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 */ }
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 = (renamefile(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; }