2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
20 #include <sys/utime.h>
23 #include <netinet/in.h>
24 #endif /* AFS_NT40_ENV */
29 #include <afs/cellconfig.h>
35 #include <afs/afsutil.h>
36 #include <afs/fileutil.h>
37 #include <afs/ktime.h>
38 #include <afs/audit.h>
44 extern struct ktime bozo_nextRestartKT, bozo_nextDayKT;
46 extern struct afsconf_dir *bozo_confdir;
47 extern struct rx_securityClass *bozo_rxsc[2];
48 extern int bozo_newKTs;
50 #ifdef BOS_RESTRICTED_MODE
51 extern int bozo_isrestricted;
54 BOZO_GetRestartTime(acall, atype, aktime)
55 struct rx_call *acall;
57 struct ktime *aktime; {
58 register afs_int32 code;
60 code = 0; /* assume success */
63 memcpy(aktime, &bozo_nextRestartKT, sizeof(struct ktime));
67 memcpy(aktime, &bozo_nextDayKT, sizeof(struct ktime));
78 BOZO_SetRestartTime(acall, atype, aktime)
79 struct rx_call *acall;
81 struct ktime *aktime; {
82 register afs_int32 code;
83 char caller[MAXKTCNAMELEN];
85 /* check for proper permissions */
86 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
90 if (DoLogging) bozo_Log("%s is executing SetRestartTime\n", caller);
92 code = 0; /* assume success */
95 memcpy(&bozo_nextRestartKT, aktime, sizeof(struct ktime));
99 memcpy(&bozo_nextDayKT, aktime, sizeof(struct ktime));
108 /* try to update the bozo init file */
109 code = WriteBozoFile(0);
114 osi_auditU (acall, BOS_SetRestartEvent, code, AUD_END);
118 BOZO_Exec(acall, acmd)
119 struct rx_call *acall;
122 char caller[MAXKTCNAMELEN];
125 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
129 #ifdef BOS_RESTRICTED_MODE
130 if (bozo_isrestricted) {
135 if (DoLogging) bozo_Log("%s is executing the shell command '%s'\n", caller, acmd);
137 /* should copy output to acall, but don't yet cause its hard */
138 /* hard... NOT! Nnow _at least_ return the exit status */
140 osi_auditU (acall, BOS_ExecEvent, code, AUD_STR, acmd, AUD_END);
146 BOZO_GetDates(acall, aname, atime, abakTime, aoldTime)
147 struct rx_call *acall;
149 afs_int32 *atime, *abakTime, *aoldTime; {
152 char tbuffer[AFSDIR_PATH_MAX];
154 *atime = *abakTime = *aoldTime = 0;
156 /* construct local path from canonical (wire-format) path */
157 if (ConstructLocalBinPath(aname, &strp)) {
160 strcpy(tbuffer, strp);
163 strp = tbuffer + strlen(tbuffer);
165 if (!stat(tbuffer, &tstat)) {
166 *atime = tstat.st_mtime;
169 strcpy(strp, ".BAK");
170 if (!stat(tbuffer, &tstat)) {
171 *abakTime = tstat.st_mtime;
174 strcpy(strp, ".OLD");
175 if (!stat(tbuffer, &tstat)) {
176 *aoldTime = tstat.st_mtime;
181 BOZO_UnInstall(acall, aname)
182 struct rx_call *acall;
183 register char *aname; {
185 char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX];
187 char caller[MAXKTCNAMELEN];
190 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
192 osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
195 #ifdef BOS_RESTRICTED_MODE
196 if (bozo_isrestricted) {
198 osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
203 /* construct local path from canonical (wire-format) path */
204 if (ConstructLocalBinPath(aname, &filepath)) {
208 if (DoLogging) bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
210 strcpy(fpBak, filepath);
211 strcat(fpBak, ".BAK");
212 strcpy(fpOld, filepath);
213 strcat(fpOld, ".OLD");
215 code = renamefile(fpBak, filepath);
217 /* can't find .BAK, try .OLD */
218 code = renamefile(fpOld, filepath);
219 if (code && errno == ENOENT) /* If doesn't exist don't fail */
222 /* now rename .OLD to .BAK */
223 if (stat(fpOld, &tstat) == 0)
224 code = renamefile(fpOld, fpBak);
229 osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
235 #define BOZO_OLDTIME (7*24*3600) /* 7 days old */
236 static void SaveOldFiles(char *aname)
238 register afs_int32 code;
239 char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX];
241 register afs_int32 now;
242 afs_int32 oldTime, bakTime;
244 strcpy(bbuffer, aname);
245 strcat(bbuffer, ".BAK");
246 strcpy(obuffer, aname);
247 strcat(obuffer, ".OLD");
248 now = FT_ApproxTime();
250 code = stat(aname, &tstat);
251 if (code < 0) return; /* can't stat file */
253 code = stat(obuffer, &tstat); /* discover old file's time */
254 if (code) oldTime = 0;
255 else oldTime = tstat.st_mtime;
257 code = stat(bbuffer, &tstat); /* discover back file's time */
258 if (code) bakTime = 0;
259 else bakTime = tstat.st_mtime;
261 if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
262 /* no .OLD file, or .BAK is at least a week old */
263 code = renamefile(bbuffer, obuffer);
266 /* finally rename to .BAK extension */
267 renamefile(aname, bbuffer);
270 BOZO_Install(acall, aname, asize, mode, amtime)
271 struct rx_call *acall;
281 struct _utimbuf utbuf;
283 struct timeval tvb[2];
285 char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
286 char caller[MAXKTCNAMELEN];
288 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) return BZACCESS;
289 #ifdef BOS_RESTRICTED_MODE
290 if (bozo_isrestricted) return BZACCESS;
293 /* construct local path from canonical (wire-format) path */
294 if (ConstructLocalBinPath(aname, &fpp)) {
297 strcpy(filepath, fpp);
300 if (DoLogging) bozo_Log("%s is executing Install '%s'\n", caller, filepath);
303 fpp = filepath + strlen(filepath);
304 strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */
305 fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
306 if (fd < 0) return errno;
309 len = rx_Read(acall, tbuffer, sizeof(tbuffer));
315 if (len == 0) break; /* no more input */
316 code = write(fd, tbuffer, len);
322 total += len; /* track total written for safety check at end */
325 if (asize != total) {
327 return 101; /* wrong size */
331 *fpp = '\0'; /* remove ".NEW" from end of filepath */
332 SaveOldFiles(filepath); /* don't care if it works, still install */
334 /* all done, rename to final name */
335 strcpy(tbuffer, filepath);
336 strcat(tbuffer, ".NEW");
337 code = (renamefile(tbuffer, filepath) ? errno : 0);
339 /* label file with same time for our sanity */
341 utbuf.actime = utbuf.modtime = amtime;
342 _utime(filepath, &utbuf);
344 tvb[0].tv_sec = tvb[1].tv_sec = amtime;
345 tvb[0].tv_usec = tvb[1].tv_usec = 0;
346 utimes(filepath, tvb);
347 #endif /* AFS_NT40_ENV */
350 chmod(filepath, mode);
353 osi_auditU (acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
359 BOZO_SetCellName(acall, aname)
360 struct rx_call *acall;
362 struct afsconf_cell tcell;
363 register afs_int32 code;
364 char caller[MAXKTCNAMELEN];
365 char clones[MAXHOSTSPERCELL];
367 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
371 if (DoLogging) bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
373 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
377 /* Check that tcell has enough space for the new cellname. */
378 if (strlen(aname) > sizeof tcell.name - 1) {
379 bozo_Log("ERROR: SetCellName: cell name '%s' exceeds %ld bytes (cell name not changed)\n",
380 aname, (long)(sizeof tcell.name - 1));
385 strcpy(tcell.name, aname);
386 code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
389 osi_auditU (acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
393 BOZO_GetCellName(acall, aname)
394 struct rx_call *acall;
396 register afs_int32 code;
397 char tname[MAXCELLCHARS];
399 code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
401 /* must set output parameters even if aborting */
402 *aname = (char *) malloc(1);
406 *aname = (char *) malloc(strlen(tname)+1);
407 strcpy(*aname, tname);
413 BOZO_GetCellHost(acall, awhich, aname)
414 struct rx_call *acall;
417 register afs_int32 code;
418 struct afsconf_cell tcell;
420 char clones[MAXHOSTSPERCELL];
422 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
425 if (awhich >= tcell.numServers) {
430 tp = tcell.hostName[awhich];
431 *aname = (char *) malloc(strlen(tp)+3);
432 if (clones[awhich]) {
441 *aname = (char *) malloc(1); /* return fake string */
448 BOZO_DeleteCellHost(acall, aname)
449 struct rx_call *acall;
451 register afs_int32 code;
452 struct afsconf_cell tcell;
455 char caller[MAXKTCNAMELEN];
456 char clones[MAXHOSTSPERCELL];
458 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
463 bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
465 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
470 for(i=0;i<tcell.numServers;i++) {
471 if (strcmp(tcell.hostName[i], aname) == 0) {
482 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
483 memset(tcell.hostName[which], 0, MAXHOSTCHARS);
484 code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
487 osi_auditU( acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
491 BOZO_AddCellHost(acall, aname)
492 struct rx_call *acall;
494 register afs_int32 code;
495 struct afsconf_cell tcell;
498 char caller[MAXKTCNAMELEN];
499 char clones[MAXHOSTSPERCELL];
503 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
508 bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
510 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
516 *(n + strlen(n) -1) = 0;
522 for(i=0;i<tcell.numServers;i++) {
523 if (strcmp(tcell.hostName[i], n) == 0) {
529 which = tcell.numServers;
533 * Check that tcell has enough space for an additional host.
535 * We assume that tcell.hostAddr[] and tcell.hostName[] have the
536 * same number of entries.
538 if (tcell.numServers > sizeof tcell.hostAddr/sizeof tcell.hostAddr[0]) {
539 bozo_Log("ERROR: AddCellHost: attempt to add more than %ld database servers (database server '%s' not added)\n",
540 (long)(sizeof tcell.hostAddr/sizeof tcell.hostAddr[0]), aname);
545 /* Check that tcell has enough space for the new hostname. */
546 if (strlen(aname) > sizeof tcell.hostName[0] - 1) {
547 bozo_Log("ERROR: AddCellHost: host name '%s' exceeds %ld bytes (not added)\n",
548 aname, (long)(sizeof tcell.hostName[0] - 1));
554 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
555 strcpy(tcell.hostName[which], n);
556 clones[which] = isClone;
557 code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
560 osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
564 BOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
565 struct rx_call *acall;
568 struct bozo_keyInfo *akeyinfo;
569 struct bozo_key *akey;
571 struct afsconf_keys tkeys;
572 register afs_int32 code;
575 char caller[MAXKTCNAMELEN];
576 rxkad_level enc_level = rxkad_clear;
578 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
582 if (DoLogging) bozo_Log("%s is executing ListKeys\n", caller);
584 code = afsconf_GetKeys(bozo_confdir, &tkeys);
588 if (tkeys.nkeys <= an) {
592 *akvno = tkeys.key[an].kvno;
593 memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
595 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
596 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
598 * only return actual keys in noauth or if this is an encrypted connection
601 if ((noauth) || (enc_level == rxkad_crypt)) {
602 memcpy(akey, tkeys.key[an].key, 8);
604 else memset(akey, 0, 8);
606 code = stat(AFSDIR_SERVER_KEY_FILEPATH, &tstat);
608 akeyinfo->mod_sec = tstat.st_mtime;
610 ka_KeyCheckSum (tkeys.key[an].key, &akeyinfo->keyCheckSum);
611 /* only errors is bad key parity */
615 osi_auditU(acall, BOS_UnAuthListKeysEvent, code, AUD_END);
616 osi_auditU(acall, BOS_ListKeysEvent, code, AUD_END);
620 BOZO_AddKey(acall, an, akey)
621 struct rx_call *acall;
623 struct bozo_key *akey; {
624 register afs_int32 code;
625 char caller[MAXKTCNAMELEN];
626 rxkad_level enc_level = rxkad_clear;
629 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
633 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
634 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
635 if ((!noauth) && (enc_level != rxkad_crypt)) {
639 if (DoLogging) bozo_Log("%s is executing AddKey\n", caller);
641 code = afsconf_AddKey(bozo_confdir, an, akey, 0);
642 if (code == AFSCONF_KEYINUSE)
643 code = BZKEYINUSE; /* Unique code for afs rpc calls */
645 osi_auditU(acall, BOS_AddKeyEvent, code, AUD_END);
649 BOZO_SetNoAuthFlag(acall, aflag)
650 register struct rx_call *acall;
652 register afs_int32 code = 0;
653 char caller[MAXKTCNAMELEN];
655 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
659 if (DoLogging) bozo_Log("%s is executing Set No Authentication\n", caller);
661 afsconf_SetNoAuthFlag(bozo_confdir, aflag);
664 osi_auditU(acall, BOS_SetNoAuthEvent, code, AUD_LONG, aflag, AUD_END);
668 BOZO_DeleteKey(acall, an)
669 struct rx_call *acall;
671 register afs_int32 code;
672 char caller[MAXKTCNAMELEN];
674 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
678 if (DoLogging) bozo_Log("%s is executing DeleteKey\n", caller);
680 code = afsconf_DeleteKey(bozo_confdir, an);
683 osi_auditU(acall, BOS_DeleteKeyEvent, code, AUD_END);
688 BOZO_ListSUsers(acall, an, aname)
689 struct rx_call *acall;
691 register char **aname; {
692 register afs_int32 code;
695 tp = *aname = (char *) malloc(256);
696 *tp = 0; /* in case getnthuser doesn't null-terminate the string */
697 code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
700 osi_auditU(acall, BOS_ListSUserEvent, code, AUD_END);
704 BOZO_AddSUser(acall, aname)
705 struct rx_call *acall;
707 register afs_int32 code;
708 char caller[MAXKTCNAMELEN];
710 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
715 bozo_Log("%s is executing Add SuperUser '%s'\n", caller, aname);
717 code = afsconf_AddUser(bozo_confdir, aname);
720 osi_auditU(acall, BOS_AddSUserEvent, code, AUD_END);
724 BOZO_DeleteSUser(acall, aname)
725 struct rx_call *acall;
727 register afs_int32 code;
728 char caller[MAXKTCNAMELEN];
730 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
736 bozo_Log("%s is executing Delete SuperUser '%s'\n", caller, aname);
738 code = afsconf_DeleteUser(bozo_confdir, aname);
741 osi_auditU(acall, BOS_DeleteSUserEvent, code, AUD_END);
745 BOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
746 struct rx_call *acall;
749 char *ap1, *ap2, *ap3, *ap4, *ap5;
753 char caller[MAXKTCNAMELEN];
755 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
759 #ifdef BOS_RESTRICTED_MODE
760 if (bozo_isrestricted) {
761 if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp") ||
762 strcmp(ap2, "now") ||
763 strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
764 strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
771 code = bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,BSTAT_NORMAL);
773 bnode_SetStat(tb, BSTAT_NORMAL);
776 osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END);
781 register struct rx_call *acall; {
782 register afs_int32 code;
783 char caller[MAXKTCNAMELEN];
785 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
790 if (DoLogging) bozo_Log("%s is executing Wait for All\n", caller);
792 code = bnode_WaitAll();
795 osi_auditU(acall, BOS_WaitAllEvent, code, AUD_END);
799 BOZO_DeleteBnode(acall, ainstance)
800 struct rx_call *acall;
802 register afs_int32 code;
803 char caller[MAXKTCNAMELEN];
805 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
809 #ifdef BOS_RESTRICTED_MODE
810 if (bozo_isrestricted) {
815 if (DoLogging) bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
817 code = bnode_DeleteName(ainstance);
820 osi_auditU(acall, BOS_DeleteBnodeEvent, code, AUD_STR, ainstance, AUD_END);
824 static swproc(abnode, arock)
825 register struct bnode *abnode;
827 if (abnode->goal == BSTAT_NORMAL) return 0; /* this one's not shutting down */
828 /* otherwise, we are shutting down */
830 bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
831 bnode_Release(abnode);
832 return 0; /* don't stop apply function early, no matter what */
835 static stproc(abnode, arock)
836 struct bnode *abnode;
838 if (abnode->fileGoal == BSTAT_SHUTDOWN) return 0; /* don't do these guys */
841 bnode_SetStat(abnode, BSTAT_NORMAL);
842 bnode_Release(abnode);
846 static sdproc(abnode, arock)
847 struct bnode *abnode;
850 bnode_SetStat(abnode, BSTAT_SHUTDOWN);
851 bnode_Release(abnode);
855 /* shutdown and leave down */
856 BOZO_ShutdownAll(acall)
857 struct rx_call *acall; {
858 /* iterate over all bnodes, setting the status to temporarily disabled */
859 register afs_int32 code;
860 char caller[MAXKTCNAMELEN];
862 /* check for authorization */
863 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
867 if (DoLogging) bozo_Log("%s is executing ShutdownAll\n", caller);
869 code = bnode_ApplyInstance(sdproc, (char *) 0);
872 osi_auditU (acall, BOS_ShutdownAllEvent, code, AUD_END);
876 /* shutdown and restart */
877 BOZO_RestartAll(acall)
878 struct rx_call *acall; {
879 register afs_int32 code;
880 char caller[MAXKTCNAMELEN];
882 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
886 if (DoLogging) bozo_Log("%s is executing RestartAll\n", caller);
888 /* start shutdown of all processes */
889 code = bnode_ApplyInstance(sdproc, (char *) 0);
892 /* wait for all done */
893 code = bnode_ApplyInstance(swproc, (char *) 0);
896 /* start them up again */
897 code = bnode_ApplyInstance(stproc, (char *) 0);
900 osi_auditU (acall, BOS_RestartAllEvent, code, AUD_END);
905 register struct rx_call *acall; {
906 register afs_int32 code;
907 char caller[MAXKTCNAMELEN];
909 /* acall is null if called internally to restart bosserver */
910 if (acall && !afsconf_SuperUser(bozo_confdir, acall, caller)) {
914 if (DoLogging) bozo_Log("%s is executing ReBozo\n", caller);
916 /* start shutdown of all processes */
917 code = bnode_ApplyInstance(sdproc, (char *) 0);
920 /* wait for all done */
921 code = bnode_ApplyInstance(swproc, (char *) 0);
924 if (acall) osi_auditU (acall, BOS_RebozoEvent, code, AUD_END);
925 else osi_audit (BOS_RebozoIntEvent, code, AUD_END);
927 if (acall) rx_EndCall(acall, 0); /* try to get it done */
929 bozo_ReBozo(); /* this reexecs us, and doesn't return, of course */
932 /* Differentiate between external and internal ReBozo; prevents AFS_Aud_NoCall event */
933 if (acall) osi_auditU (acall, BOS_RebozoEvent, code, AUD_END);
934 else osi_audit (BOS_RebozoIntEvent, code, AUD_END);
935 return code; /* should only get here in unusual circumstances */
938 /* make sure all are running */
939 BOZO_StartupAll(acall)
940 struct rx_call *acall; {
941 register afs_int32 code;
942 char caller[MAXKTCNAMELEN];
944 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
948 if (DoLogging) bozo_Log("%s is executing StartupAll\n", caller);
949 code = bnode_ApplyInstance(stproc, (char *) 0);
952 osi_auditU (acall, BOS_StartupAllEvent, code, AUD_END);
956 BOZO_Restart(acall, ainstance)
957 struct rx_call *acall;
958 register char *ainstance; {
959 register struct bnode *tb;
960 register afs_int32 code;
961 char caller[MAXKTCNAMELEN];
963 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
967 if (DoLogging) bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);
969 tb = bnode_FindInstance(ainstance);
975 /* setup return code */
979 bnode_SetStat(tb, BSTAT_SHUTDOWN);
980 code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN); /* this can fail */
981 bnode_SetStat(tb, BSTAT_NORMAL);
985 osi_auditU (acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
989 /* set temp status */
990 BOZO_SetTStatus(acall, ainstance, astatus)
991 struct rx_call *acall;
994 register struct bnode *tb;
995 register afs_int32 code;
996 char caller[MAXKTCNAMELEN];
998 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1002 if (DoLogging) bozo_Log("%s is executing SetTempStatus '%s'\n", caller, ainstance);
1004 tb = bnode_FindInstance(ainstance);
1010 code = bnode_SetStat(tb, astatus);
1014 osi_auditU (acall, BOS_SetTempStatusEvent, code, AUD_STR, ainstance, AUD_END);
1018 BOZO_SetStatus(acall, ainstance, astatus)
1019 struct rx_call *acall;
1021 afs_int32 astatus; {
1022 register struct bnode *tb;
1023 register afs_int32 code;
1024 char caller[MAXKTCNAMELEN];
1026 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1030 if (DoLogging) bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller, ainstance, astatus);
1032 tb = bnode_FindInstance(ainstance);
1038 bnode_SetFileGoal(tb, astatus);
1039 code = bnode_SetStat(tb, astatus);
1043 osi_auditU (acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
1047 BOZO_GetStatus(acall, ainstance, astat, astatDescr)
1048 struct rx_call *acall;
1051 char **astatDescr; {
1052 register struct bnode *tb;
1053 register afs_int32 code;
1055 tb = bnode_FindInstance(ainstance);
1062 code = bnode_GetStat(tb, astat);
1068 *astatDescr = (char *) malloc(BOZO_BSSIZE);
1069 code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
1071 if (code) (*astatDescr)[0] = 0; /* null string means no further info */
1075 *astatDescr = (char *) malloc(1);
1085 static eifunc(abnode, arock)
1086 struct bnode *abnode;
1087 struct eidata *arock; {
1088 if (arock->counter-- == 0) {
1090 strcpy(arock->iname, abnode->name);
1099 static ZapFile(adir, aname)
1100 register char *adir;
1101 register char *aname; {
1103 strcpy(tbuffer, adir);
1104 strcat(tbuffer, "/");
1105 strcat(tbuffer, aname);
1106 return unlink(tbuffer);
1109 BOZO_Prune(acall, aflags)
1110 struct rx_call *acall;
1112 register afs_int32 code;
1114 register struct dirent *tde;
1116 char caller[MAXKTCNAMELEN];
1118 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1122 #ifdef BOS_RESTRICTED_MODE
1123 if (bozo_isrestricted) {
1128 if (DoLogging) bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
1130 /* first scan AFS binary directory */
1131 dirp = opendir(AFSDIR_SERVER_BIN_DIRPATH);
1133 for(tde=readdir(dirp);tde;tde=readdir(dirp)) {
1134 i = strlen(tde->d_name);
1135 if (aflags & BOZO_PRUNEOLD) {
1136 if(i >= 4 && strncmp(tde->d_name+i-4, ".OLD", 4)==0)
1137 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1139 if (aflags & BOZO_PRUNEBAK) {
1140 if(i >= 4 && strncmp(tde->d_name+i-4, ".BAK", 4)==0)
1141 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1147 /* then scan AFS log directory */
1148 dirp = opendir(AFSDIR_SERVER_LOGS_DIRPATH);
1150 for(tde=readdir(dirp);tde;tde=readdir(dirp)) {
1151 if (aflags & BOZO_PRUNECORE) {
1152 if(strncmp(tde->d_name, AFSDIR_CORE_FILE, 4)==0)
1153 ZapFile(AFSDIR_SERVER_LOGS_DIRPATH, tde->d_name);
1161 osi_auditU ( acall, BOS_PruneLogs, code, AUD_END);
1165 BOZO_EnumerateInstance(acall, anum, ainstance)
1166 struct rx_call *acall;
1169 struct eidata tdata;
1171 *ainstance = (char *) malloc(BOZO_BSSIZE);
1173 tdata.counter = anum;
1174 tdata.iname = *ainstance;
1175 bnode_ApplyInstance(eifunc, &tdata);
1176 if (tdata.counter >= 0) return BZDOM; /* anum > # of actual instances */
1180 struct bozo_bosEntryStats bozo_bosEntryStats[] = {
1181 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH */
1182 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH */
1183 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH */
1184 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH */
1185 {NULL, 1,0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
1186 {NULL, 1,1, 0700, 07}, /* AFSDIR_SERVER_DB_DIRPATH */
1187 {NULL, 1,1, 0700, 07}, /* AFSDIR_SERVER_LOCAL_DIRPATH */
1188 {NULL, 0,1, 0600, 07}, /* AFSDIR_SERVER_KEY_FILEPATH */
1189 {NULL, 0,1, 0600, 03}};/* AFSDIR_SERVER_ULIST_FILEPATH */
1190 int bozo_nbosEntryStats =
1191 sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
1193 /* This function performs initialization of the bozo_bosEntrystats[]
1194 * array. This array contains the list of dirs that the bosserver
1195 * is interested in along with their recommended permissions
1196 * NOTE: This initialization is a bit ugly. This was caused because
1197 * the path names require procedural as opposed to static initialization.
1198 * The other fields in the struct are however, statically initialized.
1200 int initBosEntryStats()
1202 bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
1203 bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
1204 bozo_bosEntryStats[2].path = AFSDIR_SERVER_BIN_DIRPATH;
1205 bozo_bosEntryStats[3].path = AFSDIR_SERVER_LOGS_DIRPATH;
1206 bozo_bosEntryStats[4].path = AFSDIR_SERVER_BACKUP_DIRPATH;
1207 bozo_bosEntryStats[5].path = AFSDIR_SERVER_DB_DIRPATH;
1208 bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
1209 bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
1210 bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
1214 /* StatEachEntry - If it's not there, it is okay. If anything else goes wrong
1215 * complain. Otherwise check permissions: shouldn't allow write or (usually)
1218 static int StatEachEntry (stats)
1219 IN struct bozo_bosEntryStats *stats;
1222 if (stat (stats->path, &info)) {
1223 if (errno == ENOENT) return 1; /* no such entry: just ignore it */
1224 return 0; /* something else went wrong */
1227 if (((info.st_mode & S_IFDIR) != 0) != stats->dir)
1228 return 0; /* not expected type */
1229 if (stats->rootOwner && (info.st_uid != 0))
1230 return 0; /* not owned by root */
1231 rights = (info.st_mode & 0000777);
1232 if ((rights & stats->reqPerm) != stats->reqPerm)
1233 return 0; /* required permissions not present */
1234 if ((rights & stats->proPerm) != 0)
1235 return 0; /* prohibited permissions present */
1240 /* DirAccessOK - checks the mode bits on the AFS dir and decendents and
1241 * returns 0 if some are not OK and 1 otherwise. For efficiency, it doesn't do
1242 * this check more often than every 5 seconds. */
1247 /* underlying filesystem may not support directory protection */
1250 static afs_uint32 lastTime = 0;
1251 afs_uint32 now = FT_ApproxTime();
1252 static int lastResult = -1;
1256 if ((now-lastTime) < 5) return lastResult;
1260 for (i=0; i<bozo_nbosEntryStats; i++) {
1261 struct bozo_bosEntryStats *e = &bozo_bosEntryStats[i];
1262 if (!StatEachEntry (e)) {
1268 if (result != lastResult) { /* log changes */
1269 bozo_Log ("Server directory access is %sokay\n",
1270 (result ? "" : "not "));
1272 lastResult = result;
1274 #endif /* AFS_NT40_ENV */
1277 int GetRequiredDirPerm (path)
1281 for (i=0; i<bozo_nbosEntryStats; i++)
1282 if (strcmp (path, bozo_bosEntryStats[i].path) == 0)
1283 return bozo_bosEntryStats[i].reqPerm;
1287 BOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
1288 IN struct rx_call *acall;
1291 OUT struct bozo_status *astatus;
1293 register struct bnode *tb;
1295 tb = bnode_FindInstance(ainstance);
1296 *atype = (char *) malloc(BOZO_BSSIZE);
1298 if (!tb) return BZNOENT;
1300 strcpy(*atype, tb->type->name);
1302 (*atype)[0] = 0; /* null string */
1303 memset(astatus, 0, sizeof(struct bozo_status)); /* good defaults */
1304 astatus->goal = tb->goal;
1305 astatus->fileGoal = tb->fileGoal;
1306 astatus->procStartTime = tb->procStartTime;
1307 astatus->procStarts = tb->procStarts;
1308 astatus->lastAnyExit = tb->lastAnyExit;
1309 astatus->lastErrorExit = tb->lastErrorExit;
1310 astatus->errorCode = tb->errorCode;
1311 astatus->errorSignal = tb->errorSignal;
1312 if (tb->flags & BNODE_ERRORSTOP)
1313 astatus->flags |= BOZO_ERRORSTOP;
1314 if (bnode_HasCore(tb))
1315 astatus->flags |= BOZO_HASCORE;
1317 astatus->flags |= BOZO_BADDIRACCESS;
1321 BOZO_GetInstanceParm(acall, ainstance, anum, aparm)
1322 struct rx_call *acall;
1326 register struct bnode *tb;
1328 register afs_int32 code;
1330 tp = (char *) malloc(BOZO_BSSIZE);
1332 *tp = 0; /* null-terminate string in error case */
1333 tb = bnode_FindInstance(ainstance);
1334 if (!tb) return BZNOENT;
1338 memcpy(tp, tb->notifier, strlen(tb->notifier)+1);
1341 code = BZNOENT; /* XXXXX */
1343 code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
1346 /* Not Currently Audited */
1350 BOZO_GetLog(acall, aname)
1351 register struct rx_call *acall;
1353 register afs_int32 code;
1358 char caller[MAXKTCNAMELEN];
1360 /* Check access since 'aname' could specify a file outside of the
1361 * AFS log directory (which is bosserver's working directory).
1363 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1367 #ifdef BOS_RESTRICTED_MODE
1368 if (bozo_isrestricted && strchr(aname, '/') &&
1369 strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
1375 /* construct local path from canonical (wire-format) path */
1376 if (ConstructLocalLogPath(aname, &logpath)) {
1379 if (DoLogging) bozo_Log("%s is executing GetLog '%s'\n", caller, logpath);
1380 tfile = fopen(logpath, "r");
1389 if (tc == 0) continue; /* our termination condition on other end */
1390 if (tc == EOF) break;
1392 if (rx_Write(acall, &buffer, 1) != 1) {
1399 /* all done, cleanup and return */
1402 /* write out the end delimeter */
1404 if (rx_Write(acall, &buffer, 1) != 1) return BZNET;
1408 osi_auditU( acall, BOS_GetLogsEvent, code, AUD_END);
1412 BOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
1413 struct rx_call *acall;
1415 char **as1, **as2, **as3, **as4; {
1416 register struct bnode *tb;
1418 *as2 = (char *) malloc(1);
1420 *as3 = (char *) malloc(1);
1422 *as4 = (char *) malloc(1);
1424 tb = bnode_FindInstance(abnodeName);
1427 /* now, return the appropriate error string, if any */
1428 if (tb->lastErrorName) {
1429 *as1 = (char *) malloc(strlen(tb->lastErrorName)+1);
1430 strcpy(*as1, tb->lastErrorName);
1433 *as1 = (char *) malloc(1);
1439 *as1 = (char *) malloc(1);
1444 #ifdef BOS_RESTRICTED_MODE
1445 BOZO_GetRestrictedMode(acall, arestmode)
1446 struct rx_call *acall;
1447 afs_int32 *arestmode;
1449 *arestmode=bozo_isrestricted;
1453 BOZO_SetRestrictedMode(acall, arestmode)
1454 struct rx_call *acall;
1455 afs_int32 arestmode;
1458 char caller[MAXKTCNAMELEN];
1460 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1463 if (bozo_isrestricted) {
1466 if (arestmode !=0 && arestmode !=1) {
1469 bozo_isrestricted=arestmode;
1470 code = WriteBozoFile(0);
1475 BOZO_GetRestrictedMode(acall, arestmode)
1476 struct rx_call *acall;
1477 afs_int32 *arestmode;
1479 return RXGEN_OPCODE;
1482 BOZO_SetRestrictedMode(acall, arestmode)
1483 struct rx_call *acall;
1484 afs_int32 arestmode;
1486 return RXGEN_OPCODE;
1490 void bozo_ShutdownAndExit(int asignal)
1494 bozo_Log("Shutdown of BOS server and processes in response to signal %d\n",
1497 /* start shutdown of all processes */
1498 if ((code = bnode_ApplyInstance(sdproc, (char *) 0)) == 0) {
1499 /* wait for shutdown to complete */
1500 code = bnode_ApplyInstance(swproc, (char *) 0);
1504 bozo_Log("Shutdown incomplete (code = %d); manual cleanup required\n",