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>
17 #include <sys/types.h>
21 #include <sys/utime.h>
24 #include <netinet/in.h>
25 #endif /* AFS_NT40_ENV */
30 #include <afs/cellconfig.h>
36 #include <afs/afsutil.h>
37 #include <afs/fileutil.h>
38 #include <afs/ktime.h>
39 #include <afs/audit.h>
53 extern struct ktime bozo_nextRestartKT, bozo_nextDayKT;
55 extern struct afsconf_dir *bozo_confdir;
56 extern int bozo_newKTs;
58 #ifdef BOS_RESTRICTED_MODE
59 extern int bozo_isrestricted;
63 SBOZO_GetRestartTime(acall, atype, aktime)
64 struct rx_call *acall;
66 struct bozo_netKTime *aktime;
68 register afs_int32 code;
70 code = 0; /* assume success */
73 memcpy(aktime, &bozo_nextRestartKT, sizeof(struct ktime));
77 memcpy(aktime, &bozo_nextDayKT, sizeof(struct ktime));
89 SBOZO_SetRestartTime(acall, atype, aktime)
90 struct rx_call *acall;
92 struct bozo_netKTime *aktime;
94 register afs_int32 code;
95 char caller[MAXKTCNAMELEN];
97 /* check for proper permissions */
98 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
103 bozo_Log("%s is executing SetRestartTime\n", caller);
105 code = 0; /* assume success */
108 memcpy(&bozo_nextRestartKT, aktime, sizeof(struct ktime));
112 memcpy(&bozo_nextDayKT, aktime, sizeof(struct ktime));
121 /* try to update the bozo init file */
122 code = WriteBozoFile(0);
127 osi_auditU(acall, BOS_SetRestartEvent, code, AUD_END);
132 SBOZO_Exec(acall, acmd)
133 struct rx_call *acall;
137 char caller[MAXKTCNAMELEN];
140 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
144 #ifdef BOS_RESTRICTED_MODE
145 if (bozo_isrestricted) {
151 bozo_Log("%s is executing the shell command '%s'\n", caller, acmd);
153 /* should copy output to acall, but don't yet cause its hard */
154 /* hard... NOT! Nnow _at least_ return the exit status */
156 osi_auditU(acall, BOS_ExecEvent, code, AUD_STR, acmd, AUD_END);
163 SBOZO_GetDates(acall, aname, atime, abakTime, aoldTime)
164 struct rx_call *acall;
166 afs_int32 *atime, *abakTime, *aoldTime;
170 char tbuffer[AFSDIR_PATH_MAX];
172 *atime = *abakTime = *aoldTime = 0;
174 /* construct local path from canonical (wire-format) path */
175 if (ConstructLocalBinPath(aname, &strp)) {
178 strcpy(tbuffer, strp);
181 strp = tbuffer + strlen(tbuffer);
183 if (!stat(tbuffer, &tstat)) {
184 *atime = tstat.st_mtime;
187 strcpy(strp, ".BAK");
188 if (!stat(tbuffer, &tstat)) {
189 *abakTime = tstat.st_mtime;
192 strcpy(strp, ".OLD");
193 if (!stat(tbuffer, &tstat)) {
194 *aoldTime = tstat.st_mtime;
200 SBOZO_UnInstall(acall, aname)
201 struct rx_call *acall;
202 register char *aname;
205 char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX];
207 char caller[MAXKTCNAMELEN];
210 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
212 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
215 #ifdef BOS_RESTRICTED_MODE
216 if (bozo_isrestricted) {
218 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
223 /* construct local path from canonical (wire-format) path */
224 if (ConstructLocalBinPath(aname, &filepath)) {
229 bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
231 strcpy(fpBak, filepath);
232 strcat(fpBak, ".BAK");
233 strcpy(fpOld, filepath);
234 strcat(fpOld, ".OLD");
236 code = renamefile(fpBak, filepath);
238 /* can't find .BAK, try .OLD */
239 code = renamefile(fpOld, filepath);
240 if (code && errno == ENOENT) /* If doesn't exist don't fail */
243 /* now rename .OLD to .BAK */
244 if (stat(fpOld, &tstat) == 0)
245 code = renamefile(fpOld, fpBak);
250 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
256 #define BOZO_OLDTIME (7*24*3600) /* 7 days old */
258 SaveOldFiles(char *aname)
260 register afs_int32 code;
261 char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX];
263 register afs_int32 now;
264 afs_int32 oldTime, bakTime;
266 strcpy(bbuffer, aname);
267 strcat(bbuffer, ".BAK");
268 strcpy(obuffer, aname);
269 strcat(obuffer, ".OLD");
270 now = FT_ApproxTime();
272 code = stat(aname, &tstat);
274 return; /* can't stat file */
276 code = stat(obuffer, &tstat); /* discover old file's time */
280 oldTime = tstat.st_mtime;
282 code = stat(bbuffer, &tstat); /* discover back file's time */
286 bakTime = tstat.st_mtime;
288 if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
289 /* no .OLD file, or .BAK is at least a week old */
290 code = renamefile(bbuffer, obuffer);
293 /* finally rename to .BAK extension */
294 renamefile(aname, bbuffer);
298 SBOZO_Install(acall, aname, asize, mode, amtime)
299 struct rx_call *acall;
310 struct _utimbuf utbuf;
312 struct timeval tvb[2];
314 char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
315 char caller[MAXKTCNAMELEN];
317 if (!afsconf_SuperUser(bozo_confdir, acall, caller))
319 #ifdef BOS_RESTRICTED_MODE
320 if (bozo_isrestricted)
324 /* construct local path from canonical (wire-format) path */
325 if (ConstructLocalBinPath(aname, &fpp)) {
328 strcpy(filepath, fpp);
332 bozo_Log("%s is executing Install '%s'\n", caller, filepath);
335 fpp = filepath + strlen(filepath);
336 strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */
337 fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
342 len = rx_Read(acall, tbuffer, sizeof(tbuffer));
349 break; /* no more input */
350 code = write(fd, tbuffer, len);
356 total += len; /* track total written for safety check at end */
359 if (asize != total) {
361 return 101; /* wrong size */
365 *fpp = '\0'; /* remove ".NEW" from end of filepath */
366 SaveOldFiles(filepath); /* don't care if it works, still install */
368 /* all done, rename to final name */
369 strcpy(tbuffer, filepath);
370 strcat(tbuffer, ".NEW");
371 code = (renamefile(tbuffer, filepath) ? errno : 0);
373 /* label file with same time for our sanity */
375 utbuf.actime = utbuf.modtime = amtime;
376 _utime(filepath, &utbuf);
378 tvb[0].tv_sec = tvb[1].tv_sec = amtime;
379 tvb[0].tv_usec = tvb[1].tv_usec = 0;
380 utimes(filepath, tvb);
381 #endif /* AFS_NT40_ENV */
384 chmod(filepath, mode);
387 osi_auditU(acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
394 SBOZO_SetCellName(acall, aname)
395 struct rx_call *acall;
398 struct afsconf_cell tcell;
399 register afs_int32 code;
400 char caller[MAXKTCNAMELEN];
401 char clones[MAXHOSTSPERCELL];
403 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
408 bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
411 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
416 /* Check that tcell has enough space for the new cellname. */
417 if (strlen(aname) > sizeof tcell.name - 1) {
419 ("ERROR: SetCellName: cell name '%s' exceeds %ld bytes (cell name not changed)\n",
420 aname, (long)(sizeof tcell.name - 1));
425 strcpy(tcell.name, aname);
427 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
431 osi_auditU(acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
436 SBOZO_GetCellName(acall, aname)
437 struct rx_call *acall;
440 register afs_int32 code;
441 char tname[MAXCELLCHARS];
443 code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
445 /* must set output parameters even if aborting */
446 *aname = (char *)malloc(1);
449 *aname = (char *)malloc(strlen(tname) + 1);
450 strcpy(*aname, tname);
457 SBOZO_GetCellHost(acall, awhich, aname)
458 struct rx_call *acall;
462 register afs_int32 code;
463 struct afsconf_cell tcell;
465 char clones[MAXHOSTSPERCELL];
468 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
473 if (awhich >= tcell.numServers) {
478 tp = tcell.hostName[awhich];
479 *aname = (char *)malloc(strlen(tp) + 3);
480 if (clones[awhich]) {
489 *aname = (char *)malloc(1); /* return fake string */
497 SBOZO_DeleteCellHost(acall, aname)
498 struct rx_call *acall;
501 register afs_int32 code;
502 struct afsconf_cell tcell;
505 char caller[MAXKTCNAMELEN];
506 char clones[MAXHOSTSPERCELL];
508 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
513 bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
516 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
522 for (i = 0; i < tcell.numServers; i++) {
523 if (strcmp(tcell.hostName[i], aname) == 0) {
534 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
535 memset(tcell.hostName[which], 0, MAXHOSTCHARS);
537 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
541 osi_auditU(acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
546 SBOZO_AddCellHost(acall, aname)
547 struct rx_call *acall;
550 register afs_int32 code;
551 struct afsconf_cell tcell;
554 char caller[MAXKTCNAMELEN];
555 char clones[MAXHOSTSPERCELL];
559 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
564 bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
567 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
574 *(n + strlen(n) - 1) = 0;
580 for (i = 0; i < tcell.numServers; i++) {
581 if (strcmp(tcell.hostName[i], n) == 0) {
587 which = tcell.numServers;
591 * Check that tcell has enough space for an additional host.
593 * We assume that tcell.hostAddr[] and tcell.hostName[] have the
594 * same number of entries.
596 if (tcell.numServers >
597 sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]) {
599 ("ERROR: AddCellHost: attempt to add more than %ld database servers (database server '%s' not added)\n",
600 (long)(sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]),
606 /* Check that tcell has enough space for the new hostname. */
607 if (strlen(aname) > sizeof tcell.hostName[0] - 1) {
609 ("ERROR: AddCellHost: host name '%s' exceeds %ld bytes (not added)\n",
610 aname, (long)(sizeof tcell.hostName[0] - 1));
616 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
617 strcpy(tcell.hostName[which], n);
618 clones[which] = isClone;
620 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
624 osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
629 SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
630 struct rx_call *acall;
633 struct bozo_keyInfo *akeyinfo;
634 struct bozo_key *akey;
636 struct afsconf_keys tkeys;
637 register afs_int32 code;
640 char caller[MAXKTCNAMELEN];
641 rxkad_level enc_level = rxkad_clear;
643 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
648 bozo_Log("%s is executing ListKeys\n", caller);
650 code = afsconf_GetKeys(bozo_confdir, &tkeys);
654 if (tkeys.nkeys <= an) {
658 *akvno = tkeys.key[an].kvno;
659 memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
661 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
662 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
664 * only return actual keys in noauth or if this is an encrypted connection
667 if ((noauth) || (enc_level == rxkad_crypt)) {
668 memcpy(akey, tkeys.key[an].key, 8);
672 code = stat(AFSDIR_SERVER_KEY_FILEPATH, &tstat);
674 akeyinfo->mod_sec = tstat.st_mtime;
676 ka_KeyCheckSum(tkeys.key[an].key, &akeyinfo->keyCheckSum);
677 /* only errors is bad key parity */
681 osi_auditU(acall, BOS_UnAuthListKeysEvent, code, AUD_END);
682 osi_auditU(acall, BOS_ListKeysEvent, code, AUD_END);
687 SBOZO_AddKey(acall, an, akey)
688 struct rx_call *acall;
690 struct bozo_key *akey;
692 register afs_int32 code;
693 char caller[MAXKTCNAMELEN];
694 rxkad_level enc_level = rxkad_clear;
697 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
701 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
702 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
703 if ((!noauth) && (enc_level != rxkad_crypt)) {
708 bozo_Log("%s is executing AddKey\n", caller);
710 code = afsconf_AddKey(bozo_confdir, an, akey, 0);
711 if (code == AFSCONF_KEYINUSE)
712 code = BZKEYINUSE; /* Unique code for afs rpc calls */
714 osi_auditU(acall, BOS_AddKeyEvent, code, AUD_END);
719 SBOZO_SetNoAuthFlag(acall, aflag)
720 register struct rx_call *acall;
723 register afs_int32 code = 0;
724 char caller[MAXKTCNAMELEN];
726 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
731 bozo_Log("%s is executing Set No Authentication\n", caller);
733 afsconf_SetNoAuthFlag(bozo_confdir, aflag);
736 osi_auditU(acall, BOS_SetNoAuthEvent, code, AUD_LONG, aflag, AUD_END);
741 SBOZO_DeleteKey(acall, an)
742 struct rx_call *acall;
745 register afs_int32 code;
746 char caller[MAXKTCNAMELEN];
748 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
753 bozo_Log("%s is executing DeleteKey\n", caller);
755 code = afsconf_DeleteKey(bozo_confdir, an);
758 osi_auditU(acall, BOS_DeleteKeyEvent, code, AUD_END);
764 SBOZO_ListSUsers(acall, an, aname)
765 struct rx_call *acall;
767 register char **aname;
769 register afs_int32 code;
772 tp = *aname = (char *)malloc(256);
773 *tp = 0; /* in case getnthuser doesn't null-terminate the string */
774 code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
777 osi_auditU(acall, BOS_ListSUserEvent, code, AUD_END);
782 SBOZO_AddSUser(acall, aname)
783 struct rx_call *acall;
786 register afs_int32 code;
787 char caller[MAXKTCNAMELEN];
789 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
794 bozo_Log("%s is executing Add SuperUser '%s'\n", caller, aname);
796 code = afsconf_AddUser(bozo_confdir, aname);
799 osi_auditU(acall, BOS_AddSUserEvent, code, AUD_END);
804 SBOZO_DeleteSUser(acall, aname)
805 struct rx_call *acall;
808 register afs_int32 code;
809 char caller[MAXKTCNAMELEN];
811 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
817 bozo_Log("%s is executing Delete SuperUser '%s'\n", caller, aname);
819 code = afsconf_DeleteUser(bozo_confdir, aname);
822 osi_auditU(acall, BOS_DeleteSUserEvent, code, AUD_END);
827 SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
828 struct rx_call *acall;
831 char *ap1, *ap2, *ap3, *ap4, *ap5;
836 char caller[MAXKTCNAMELEN];
838 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
842 #ifdef BOS_RESTRICTED_MODE
843 if (bozo_isrestricted) {
844 if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp")
845 || strcmp(ap2, "now")
846 || strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
847 strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
855 bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,
858 bnode_SetStat(tb, BSTAT_NORMAL);
861 osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END);
867 register struct rx_call *acall;
869 register afs_int32 code;
870 char caller[MAXKTCNAMELEN];
872 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
878 bozo_Log("%s is executing Wait for All\n", caller);
880 code = bnode_WaitAll();
883 osi_auditU(acall, BOS_WaitAllEvent, code, AUD_END);
888 SBOZO_DeleteBnode(acall, ainstance)
889 struct rx_call *acall;
892 register afs_int32 code;
893 char caller[MAXKTCNAMELEN];
895 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
899 #ifdef BOS_RESTRICTED_MODE
900 if (bozo_isrestricted) {
906 bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
908 code = bnode_DeleteName(ainstance);
911 osi_auditU(acall, BOS_DeleteBnodeEvent, code, AUD_STR, ainstance,
917 swproc(abnode, arock)
918 register struct bnode *abnode;
921 if (abnode->goal == BSTAT_NORMAL)
922 return 0; /* this one's not shutting down */
923 /* otherwise, we are shutting down */
925 bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
926 bnode_Release(abnode);
927 return 0; /* don't stop apply function early, no matter what */
931 stproc(abnode, arock)
932 struct bnode *abnode;
935 if (abnode->fileGoal == BSTAT_SHUTDOWN)
936 return 0; /* don't do these guys */
939 bnode_SetStat(abnode, BSTAT_NORMAL);
940 bnode_Release(abnode);
945 sdproc(abnode, arock)
946 struct bnode *abnode;
950 bnode_SetStat(abnode, BSTAT_SHUTDOWN);
951 bnode_Release(abnode);
955 /* shutdown and leave down */
957 SBOZO_ShutdownAll(acall)
958 struct rx_call *acall;
960 /* iterate over all bnodes, setting the status to temporarily disabled */
961 register afs_int32 code;
962 char caller[MAXKTCNAMELEN];
964 /* check for authorization */
965 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
970 bozo_Log("%s is executing ShutdownAll\n", caller);
972 code = bnode_ApplyInstance(sdproc, NULL);
975 osi_auditU(acall, BOS_ShutdownAllEvent, code, AUD_END);
979 /* shutdown and restart */
981 SBOZO_RestartAll(acall)
982 struct rx_call *acall;
984 register afs_int32 code;
985 char caller[MAXKTCNAMELEN];
987 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
992 bozo_Log("%s is executing RestartAll\n", caller);
994 /* start shutdown of all processes */
995 code = bnode_ApplyInstance(sdproc, NULL);
999 /* wait for all done */
1000 code = bnode_ApplyInstance(swproc, NULL);
1004 /* start them up again */
1005 code = bnode_ApplyInstance(stproc, NULL);
1008 osi_auditU(acall, BOS_RestartAllEvent, code, AUD_END);
1014 register struct rx_call *acall;
1016 register afs_int32 code;
1017 char caller[MAXKTCNAMELEN];
1019 /* acall is null if called internally to restart bosserver */
1020 if (acall && !afsconf_SuperUser(bozo_confdir, acall, caller)) {
1025 bozo_Log("%s is executing ReBozo\n", caller);
1027 /* start shutdown of all processes */
1028 code = bnode_ApplyInstance(sdproc, NULL);
1032 /* wait for all done */
1033 code = bnode_ApplyInstance(swproc, NULL);
1038 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
1040 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
1043 rx_EndCall(acall, 0); /* try to get it done */
1045 bozo_ReBozo(); /* this reexecs us, and doesn't return, of course */
1048 /* Differentiate between external and internal ReBozo; prevents AFS_Aud_NoCall event */
1050 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
1052 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
1053 return code; /* should only get here in unusual circumstances */
1056 /* make sure all are running */
1058 SBOZO_StartupAll(acall)
1059 struct rx_call *acall;
1061 register afs_int32 code;
1062 char caller[MAXKTCNAMELEN];
1064 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1069 bozo_Log("%s is executing StartupAll\n", caller);
1070 code = bnode_ApplyInstance(stproc, NULL);
1073 osi_auditU(acall, BOS_StartupAllEvent, code, AUD_END);
1078 SBOZO_Restart(acall, ainstance)
1079 struct rx_call *acall;
1080 register char *ainstance;
1082 register struct bnode *tb;
1083 register afs_int32 code;
1084 char caller[MAXKTCNAMELEN];
1086 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1091 bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);
1093 tb = bnode_FindInstance(ainstance);
1099 /* setup return code */
1103 bnode_SetStat(tb, BSTAT_SHUTDOWN);
1104 code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN); /* this can fail */
1105 bnode_SetStat(tb, BSTAT_NORMAL);
1109 osi_auditU(acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
1113 /* set temp status */
1115 SBOZO_SetTStatus(acall, ainstance, astatus)
1116 struct rx_call *acall;
1120 register struct bnode *tb;
1121 register afs_int32 code;
1122 char caller[MAXKTCNAMELEN];
1124 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1129 bozo_Log("%s is executing SetTempStatus '%s'\n", caller, ainstance);
1131 tb = bnode_FindInstance(ainstance);
1137 code = bnode_SetStat(tb, astatus);
1141 osi_auditU(acall, BOS_SetTempStatusEvent, code, AUD_STR, ainstance,
1147 SBOZO_SetStatus(acall, ainstance, astatus)
1148 struct rx_call *acall;
1152 register struct bnode *tb;
1153 register afs_int32 code;
1154 char caller[MAXKTCNAMELEN];
1156 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1161 bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller,
1162 ainstance, astatus);
1164 tb = bnode_FindInstance(ainstance);
1170 bnode_SetFileGoal(tb, astatus);
1171 code = bnode_SetStat(tb, astatus);
1175 osi_auditU(acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
1180 SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
1181 struct rx_call *acall;
1186 register struct bnode *tb;
1187 register afs_int32 code;
1189 tb = bnode_FindInstance(ainstance);
1196 code = bnode_GetStat(tb, astat);
1202 *astatDescr = (char *)malloc(BOZO_BSSIZE);
1203 code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
1206 (*astatDescr)[0] = 0; /* null string means no further info */
1210 *astatDescr = (char *)malloc(1);
1221 eifunc(abnode, arock)
1222 struct bnode *abnode;
1223 struct eidata *arock;
1225 if (arock->counter-- == 0) {
1227 strcpy(arock->iname, abnode->name);
1236 ZapFile(adir, aname)
1237 register char *adir;
1238 register char *aname;
1241 strcpy(tbuffer, adir);
1242 strcat(tbuffer, "/");
1243 strcat(tbuffer, aname);
1244 return unlink(tbuffer);
1248 SBOZO_Prune(acall, aflags)
1249 struct rx_call *acall;
1252 register afs_int32 code;
1254 register struct dirent *tde;
1256 char caller[MAXKTCNAMELEN];
1258 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1262 #ifdef BOS_RESTRICTED_MODE
1263 if (bozo_isrestricted) {
1269 bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
1271 /* first scan AFS binary directory */
1272 dirp = opendir(AFSDIR_SERVER_BIN_DIRPATH);
1274 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1275 i = strlen(tde->d_name);
1276 if (aflags & BOZO_PRUNEOLD) {
1277 if (i >= 4 && strncmp(tde->d_name + i - 4, ".OLD", 4) == 0)
1278 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1280 if (aflags & BOZO_PRUNEBAK) {
1281 if (i >= 4 && strncmp(tde->d_name + i - 4, ".BAK", 4) == 0)
1282 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1288 /* then scan AFS log directory */
1289 dirp = opendir(AFSDIR_SERVER_LOGS_DIRPATH);
1291 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1292 if (aflags & BOZO_PRUNECORE) {
1293 if (strncmp(tde->d_name, AFSDIR_CORE_FILE, 4) == 0)
1294 ZapFile(AFSDIR_SERVER_LOGS_DIRPATH, tde->d_name);
1302 osi_auditU(acall, BOS_PruneLogs, code, AUD_END);
1307 SBOZO_EnumerateInstance(acall, anum, ainstance)
1308 struct rx_call *acall;
1312 struct eidata tdata;
1314 *ainstance = (char *)malloc(BOZO_BSSIZE);
1316 tdata.counter = anum;
1317 tdata.iname = *ainstance;
1318 bnode_ApplyInstance(eifunc, &tdata);
1319 if (tdata.counter >= 0)
1320 return BZDOM; /* anum > # of actual instances */
1325 struct bozo_bosEntryStats bozo_bosEntryStats[] = {
1326 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH */
1327 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH */
1328 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH */
1329 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH */
1330 {NULL, 1, 0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
1331 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_DB_DIRPATH */
1332 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_LOCAL_DIRPATH */
1333 {NULL, 0, 1, 0600, 07}, /* AFSDIR_SERVER_KEY_FILEPATH */
1334 {NULL, 0, 1, 0600, 03}
1335 }; /* AFSDIR_SERVER_ULIST_FILEPATH */
1336 int bozo_nbosEntryStats =
1337 sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
1339 /* This function performs initialization of the bozo_bosEntrystats[]
1340 * array. This array contains the list of dirs that the bosserver
1341 * is interested in along with their recommended permissions
1342 * NOTE: This initialization is a bit ugly. This was caused because
1343 * the path names require procedural as opposed to static initialization.
1344 * The other fields in the struct are however, statically initialized.
1349 bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
1350 bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
1351 bozo_bosEntryStats[2].path = AFSDIR_SERVER_BIN_DIRPATH;
1352 bozo_bosEntryStats[3].path = AFSDIR_SERVER_LOGS_DIRPATH;
1353 bozo_bosEntryStats[4].path = AFSDIR_SERVER_BACKUP_DIRPATH;
1354 bozo_bosEntryStats[5].path = AFSDIR_SERVER_DB_DIRPATH;
1355 bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
1356 bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
1357 bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
1362 /* StatEachEntry - If it's not there, it is okay. If anything else goes wrong
1363 * complain. Otherwise check permissions: shouldn't allow write or (usually)
1367 StatEachEntry(stats)
1368 IN struct bozo_bosEntryStats *stats;
1371 if (stat(stats->path, &info)) {
1372 if (errno == ENOENT)
1373 return 1; /* no such entry: just ignore it */
1374 return 0; /* something else went wrong */
1377 if (((info.st_mode & S_IFDIR) != 0) != stats->dir)
1378 return 0; /* not expected type */
1379 if (stats->rootOwner && (info.st_uid != 0))
1380 return 0; /* not owned by root */
1381 rights = (info.st_mode & 0000777);
1382 if ((rights & stats->reqPerm) != stats->reqPerm)
1383 return 0; /* required permissions not present */
1384 if ((rights & stats->proPerm) != 0)
1385 return 0; /* prohibited permissions present */
1390 /* DirAccessOK - checks the mode bits on the AFS dir and decendents and
1391 * returns 0 if some are not OK and 1 otherwise. For efficiency, it doesn't do
1392 * this check more often than every 5 seconds. */
1398 /* underlying filesystem may not support directory protection */
1401 static afs_uint32 lastTime = 0;
1402 afs_uint32 now = FT_ApproxTime();
1403 static int lastResult = -1;
1407 if ((now - lastTime) < 5)
1412 for (i = 0; i < bozo_nbosEntryStats; i++) {
1413 struct bozo_bosEntryStats *e = &bozo_bosEntryStats[i];
1414 if (!StatEachEntry(e)) {
1415 bozo_Log("unhappy with %s which is a %s that should "
1416 "have at least rights %o, at most rights %o %s\n",
1417 e->path, e->dir ? "dir" : "file", e->reqPerm,
1418 (~e->proPerm & 0777),
1419 e->rootOwner ? ", owned by root" : "");
1425 if (result != lastResult) { /* log changes */
1426 bozo_Log("Server directory access is %sokay\n",
1427 (result ? "" : "not "));
1429 lastResult = result;
1431 #endif /* AFS_NT40_ENV */
1435 GetRequiredDirPerm(path)
1439 for (i = 0; i < bozo_nbosEntryStats; i++)
1440 if (strcmp(path, bozo_bosEntryStats[i].path) == 0)
1441 return bozo_bosEntryStats[i].reqPerm;
1446 SBOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
1447 IN struct rx_call *acall;
1450 OUT struct bozo_status *astatus;
1452 register struct bnode *tb;
1454 tb = bnode_FindInstance(ainstance);
1455 *atype = (char *)malloc(BOZO_BSSIZE);
1460 strcpy(*atype, tb->type->name);
1462 (*atype)[0] = 0; /* null string */
1463 memset(astatus, 0, sizeof(struct bozo_status)); /* good defaults */
1464 astatus->goal = tb->goal;
1465 astatus->fileGoal = tb->fileGoal;
1466 astatus->procStartTime = tb->procStartTime;
1467 astatus->procStarts = tb->procStarts;
1468 astatus->lastAnyExit = tb->lastAnyExit;
1469 astatus->lastErrorExit = tb->lastErrorExit;
1470 astatus->errorCode = tb->errorCode;
1471 astatus->errorSignal = tb->errorSignal;
1472 if (tb->flags & BNODE_ERRORSTOP)
1473 astatus->flags |= BOZO_ERRORSTOP;
1474 if (bnode_HasCore(tb))
1475 astatus->flags |= BOZO_HASCORE;
1477 astatus->flags |= BOZO_BADDIRACCESS;
1482 SBOZO_GetInstanceParm(acall, ainstance, anum, aparm)
1483 struct rx_call *acall;
1488 register struct bnode *tb;
1490 register afs_int32 code;
1492 tp = (char *)malloc(BOZO_BSSIZE);
1494 *tp = 0; /* null-terminate string in error case */
1495 tb = bnode_FindInstance(ainstance);
1501 memcpy(tp, tb->notifier, strlen(tb->notifier) + 1);
1504 code = BZNOENT; /* XXXXX */
1506 code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
1509 /* Not Currently Audited */
1514 SBOZO_GetLog(acall, aname)
1515 register struct rx_call *acall;
1518 register afs_int32 code;
1523 char caller[MAXKTCNAMELEN];
1525 /* Check access since 'aname' could specify a file outside of the
1526 * AFS log directory (which is bosserver's working directory).
1528 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1532 #ifdef BOS_RESTRICTED_MODE
1533 if (bozo_isrestricted && strchr(aname, '/')
1534 && strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
1540 /* construct local path from canonical (wire-format) path */
1541 if (ConstructLocalLogPath(aname, &logpath)) {
1545 bozo_Log("%s is executing GetLog '%s'\n", caller, logpath);
1546 tfile = fopen(logpath, "r");
1556 continue; /* our termination condition on other end */
1560 if (rx_Write(acall, &buffer, 1) != 1) {
1567 /* all done, cleanup and return */
1570 /* write out the end delimeter */
1572 if (rx_Write(acall, &buffer, 1) != 1)
1577 osi_auditU(acall, BOS_GetLogsEvent, code, AUD_END);
1582 SBOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
1583 struct rx_call *acall;
1585 char **as1, **as2, **as3, **as4;
1587 register struct bnode *tb;
1589 *as2 = (char *)malloc(1);
1591 *as3 = (char *)malloc(1);
1593 *as4 = (char *)malloc(1);
1595 tb = bnode_FindInstance(abnodeName);
1599 /* now, return the appropriate error string, if any */
1600 if (tb->lastErrorName) {
1601 *as1 = (char *)malloc(strlen(tb->lastErrorName) + 1);
1602 strcpy(*as1, tb->lastErrorName);
1604 *as1 = (char *)malloc(1);
1610 *as1 = (char *)malloc(1);
1615 #ifdef BOS_RESTRICTED_MODE
1617 SBOZO_GetRestrictedMode(acall, arestmode)
1618 struct rx_call *acall;
1619 afs_int32 *arestmode;
1621 *arestmode = bozo_isrestricted;
1626 SBOZO_SetRestrictedMode(acall, arestmode)
1627 struct rx_call *acall;
1628 afs_int32 arestmode;
1631 char caller[MAXKTCNAMELEN];
1633 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1636 if (bozo_isrestricted) {
1639 if (arestmode != 0 && arestmode != 1) {
1642 bozo_isrestricted = arestmode;
1643 code = WriteBozoFile(0);
1649 SBOZO_GetRestrictedMode(acall, arestmode)
1650 struct rx_call *acall;
1651 afs_int32 *arestmode;
1653 return RXGEN_OPCODE;
1657 SBOZO_SetRestrictedMode(acall, arestmode)
1658 struct rx_call *acall;
1659 afs_int32 arestmode;
1661 return RXGEN_OPCODE;
1666 bozo_ShutdownAndExit(int asignal)
1671 ("Shutdown of BOS server and processes in response to signal %d\n",
1674 /* start shutdown of all processes */
1675 if ((code = bnode_ApplyInstance(sdproc, NULL)) == 0) {
1676 /* wait for shutdown to complete */
1677 code = bnode_ApplyInstance(swproc, NULL);
1681 bozo_Log("Shutdown incomplete (code = %d); manual cleanup required\n",