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>
46 extern struct ktime bozo_nextRestartKT, bozo_nextDayKT;
48 extern struct afsconf_dir *bozo_confdir;
49 extern int bozo_newKTs;
51 #ifdef BOS_RESTRICTED_MODE
52 extern int bozo_isrestricted;
56 SBOZO_GetRestartTime(acall, atype, aktime)
57 struct rx_call *acall;
59 struct bozo_netKTime *aktime;
61 register afs_int32 code;
63 code = 0; /* assume success */
66 memcpy(aktime, &bozo_nextRestartKT, sizeof(struct ktime));
70 memcpy(aktime, &bozo_nextDayKT, sizeof(struct ktime));
82 SBOZO_SetRestartTime(acall, atype, aktime)
83 struct rx_call *acall;
85 struct bozo_netKTime *aktime;
87 register afs_int32 code;
88 char caller[MAXKTCNAMELEN];
90 /* check for proper permissions */
91 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
96 bozo_Log("%s is executing SetRestartTime\n", caller);
98 code = 0; /* assume success */
101 memcpy(&bozo_nextRestartKT, aktime, sizeof(struct ktime));
105 memcpy(&bozo_nextDayKT, aktime, sizeof(struct ktime));
114 /* try to update the bozo init file */
115 code = WriteBozoFile(0);
120 osi_auditU(acall, BOS_SetRestartEvent, code, AUD_END);
125 SBOZO_Exec(acall, acmd)
126 struct rx_call *acall;
130 char caller[MAXKTCNAMELEN];
133 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
137 #ifdef BOS_RESTRICTED_MODE
138 if (bozo_isrestricted) {
144 bozo_Log("%s is executing the shell command '%s'\n", caller, acmd);
146 /* should copy output to acall, but don't yet cause its hard */
147 /* hard... NOT! Nnow _at least_ return the exit status */
149 osi_auditU(acall, BOS_ExecEvent, code, AUD_STR, acmd, AUD_END);
156 SBOZO_GetDates(acall, aname, atime, abakTime, aoldTime)
157 struct rx_call *acall;
159 afs_int32 *atime, *abakTime, *aoldTime;
163 char tbuffer[AFSDIR_PATH_MAX];
165 *atime = *abakTime = *aoldTime = 0;
167 /* construct local path from canonical (wire-format) path */
168 if (ConstructLocalBinPath(aname, &strp)) {
171 strcpy(tbuffer, strp);
174 strp = tbuffer + strlen(tbuffer);
176 if (!stat(tbuffer, &tstat)) {
177 *atime = tstat.st_mtime;
180 strcpy(strp, ".BAK");
181 if (!stat(tbuffer, &tstat)) {
182 *abakTime = tstat.st_mtime;
185 strcpy(strp, ".OLD");
186 if (!stat(tbuffer, &tstat)) {
187 *aoldTime = tstat.st_mtime;
193 SBOZO_UnInstall(acall, aname)
194 struct rx_call *acall;
195 register char *aname;
198 char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX];
200 char caller[MAXKTCNAMELEN];
203 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
205 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
208 #ifdef BOS_RESTRICTED_MODE
209 if (bozo_isrestricted) {
211 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
216 /* construct local path from canonical (wire-format) path */
217 if (ConstructLocalBinPath(aname, &filepath)) {
222 bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
224 strcpy(fpBak, filepath);
225 strcat(fpBak, ".BAK");
226 strcpy(fpOld, filepath);
227 strcat(fpOld, ".OLD");
229 code = renamefile(fpBak, filepath);
231 /* can't find .BAK, try .OLD */
232 code = renamefile(fpOld, filepath);
233 if (code && errno == ENOENT) /* If doesn't exist don't fail */
236 /* now rename .OLD to .BAK */
237 if (stat(fpOld, &tstat) == 0)
238 code = renamefile(fpOld, fpBak);
243 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
249 #define BOZO_OLDTIME (7*24*3600) /* 7 days old */
251 SaveOldFiles(char *aname)
253 register afs_int32 code;
254 char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX];
256 register afs_int32 now;
257 afs_int32 oldTime, bakTime;
259 strcpy(bbuffer, aname);
260 strcat(bbuffer, ".BAK");
261 strcpy(obuffer, aname);
262 strcat(obuffer, ".OLD");
263 now = FT_ApproxTime();
265 code = stat(aname, &tstat);
267 return; /* can't stat file */
269 code = stat(obuffer, &tstat); /* discover old file's time */
273 oldTime = tstat.st_mtime;
275 code = stat(bbuffer, &tstat); /* discover back file's time */
279 bakTime = tstat.st_mtime;
281 if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
282 /* no .OLD file, or .BAK is at least a week old */
283 code = renamefile(bbuffer, obuffer);
286 /* finally rename to .BAK extension */
287 renamefile(aname, bbuffer);
291 SBOZO_Install(acall, aname, asize, mode, amtime)
292 struct rx_call *acall;
303 struct _utimbuf utbuf;
305 struct timeval tvb[2];
307 char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
308 char caller[MAXKTCNAMELEN];
310 if (!afsconf_SuperUser(bozo_confdir, acall, caller))
312 #ifdef BOS_RESTRICTED_MODE
313 if (bozo_isrestricted)
317 /* construct local path from canonical (wire-format) path */
318 if (ConstructLocalBinPath(aname, &fpp)) {
321 strcpy(filepath, fpp);
325 bozo_Log("%s is executing Install '%s'\n", caller, filepath);
328 fpp = filepath + strlen(filepath);
329 strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */
330 fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
335 len = rx_Read(acall, tbuffer, sizeof(tbuffer));
342 break; /* no more input */
343 code = write(fd, tbuffer, len);
349 total += len; /* track total written for safety check at end */
352 if (asize != total) {
354 return 101; /* wrong size */
358 *fpp = '\0'; /* remove ".NEW" from end of filepath */
359 SaveOldFiles(filepath); /* don't care if it works, still install */
361 /* all done, rename to final name */
362 strcpy(tbuffer, filepath);
363 strcat(tbuffer, ".NEW");
364 code = (renamefile(tbuffer, filepath) ? errno : 0);
366 /* label file with same time for our sanity */
368 utbuf.actime = utbuf.modtime = amtime;
369 _utime(filepath, &utbuf);
371 tvb[0].tv_sec = tvb[1].tv_sec = amtime;
372 tvb[0].tv_usec = tvb[1].tv_usec = 0;
373 utimes(filepath, tvb);
374 #endif /* AFS_NT40_ENV */
377 chmod(filepath, mode);
380 osi_auditU(acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
387 SBOZO_SetCellName(acall, aname)
388 struct rx_call *acall;
391 struct afsconf_cell tcell;
392 register afs_int32 code;
393 char caller[MAXKTCNAMELEN];
394 char clones[MAXHOSTSPERCELL];
396 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
401 bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
404 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
409 /* Check that tcell has enough space for the new cellname. */
410 if (strlen(aname) > sizeof tcell.name - 1) {
412 ("ERROR: SetCellName: cell name '%s' exceeds %ld bytes (cell name not changed)\n",
413 aname, (long)(sizeof tcell.name - 1));
418 strcpy(tcell.name, aname);
420 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
424 osi_auditU(acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
429 SBOZO_GetCellName(acall, aname)
430 struct rx_call *acall;
433 register afs_int32 code;
434 char tname[MAXCELLCHARS];
436 code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
438 /* must set output parameters even if aborting */
439 *aname = (char *)malloc(1);
442 *aname = (char *)malloc(strlen(tname) + 1);
443 strcpy(*aname, tname);
450 SBOZO_GetCellHost(acall, awhich, aname)
451 struct rx_call *acall;
455 register afs_int32 code;
456 struct afsconf_cell tcell;
458 char clones[MAXHOSTSPERCELL];
461 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
466 if (awhich >= tcell.numServers) {
471 tp = tcell.hostName[awhich];
472 *aname = (char *)malloc(strlen(tp) + 3);
473 if (clones[awhich]) {
482 *aname = (char *)malloc(1); /* return fake string */
490 SBOZO_DeleteCellHost(acall, aname)
491 struct rx_call *acall;
494 register afs_int32 code;
495 struct afsconf_cell tcell;
498 char caller[MAXKTCNAMELEN];
499 char clones[MAXHOSTSPERCELL];
501 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
506 bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
509 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
515 for (i = 0; i < tcell.numServers; i++) {
516 if (strcmp(tcell.hostName[i], aname) == 0) {
527 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
528 memset(tcell.hostName[which], 0, MAXHOSTCHARS);
530 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
534 osi_auditU(acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
539 SBOZO_AddCellHost(acall, aname)
540 struct rx_call *acall;
543 register afs_int32 code;
544 struct afsconf_cell tcell;
547 char caller[MAXKTCNAMELEN];
548 char clones[MAXHOSTSPERCELL];
552 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
557 bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
560 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
567 *(n + strlen(n) - 1) = 0;
573 for (i = 0; i < tcell.numServers; i++) {
574 if (strcmp(tcell.hostName[i], n) == 0) {
580 which = tcell.numServers;
584 * Check that tcell has enough space for an additional host.
586 * We assume that tcell.hostAddr[] and tcell.hostName[] have the
587 * same number of entries.
589 if (tcell.numServers >
590 sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]) {
592 ("ERROR: AddCellHost: attempt to add more than %ld database servers (database server '%s' not added)\n",
593 (long)(sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]),
599 /* Check that tcell has enough space for the new hostname. */
600 if (strlen(aname) > sizeof tcell.hostName[0] - 1) {
602 ("ERROR: AddCellHost: host name '%s' exceeds %ld bytes (not added)\n",
603 aname, (long)(sizeof tcell.hostName[0] - 1));
609 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
610 strcpy(tcell.hostName[which], n);
611 clones[which] = isClone;
613 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
617 osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
622 SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
623 struct rx_call *acall;
626 struct bozo_keyInfo *akeyinfo;
627 struct bozo_key *akey;
629 struct afsconf_keys tkeys;
630 register afs_int32 code;
633 char caller[MAXKTCNAMELEN];
634 rxkad_level enc_level = rxkad_clear;
636 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
641 bozo_Log("%s is executing ListKeys\n", caller);
643 code = afsconf_GetKeys(bozo_confdir, &tkeys);
647 if (tkeys.nkeys <= an) {
651 *akvno = tkeys.key[an].kvno;
652 memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
654 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
655 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
657 * only return actual keys in noauth or if this is an encrypted connection
660 if ((noauth) || (enc_level == rxkad_crypt)) {
661 memcpy(akey, tkeys.key[an].key, 8);
665 code = stat(AFSDIR_SERVER_KEY_FILEPATH, &tstat);
667 akeyinfo->mod_sec = tstat.st_mtime;
669 ka_KeyCheckSum(tkeys.key[an].key, &akeyinfo->keyCheckSum);
670 /* only errors is bad key parity */
674 osi_auditU(acall, BOS_UnAuthListKeysEvent, code, AUD_END);
675 osi_auditU(acall, BOS_ListKeysEvent, code, AUD_END);
680 SBOZO_AddKey(acall, an, akey)
681 struct rx_call *acall;
683 struct bozo_key *akey;
685 register afs_int32 code;
686 char caller[MAXKTCNAMELEN];
687 rxkad_level enc_level = rxkad_clear;
690 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
694 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
695 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
696 if ((!noauth) && (enc_level != rxkad_crypt)) {
701 bozo_Log("%s is executing AddKey\n", caller);
703 code = afsconf_AddKey(bozo_confdir, an, akey, 0);
704 if (code == AFSCONF_KEYINUSE)
705 code = BZKEYINUSE; /* Unique code for afs rpc calls */
707 osi_auditU(acall, BOS_AddKeyEvent, code, AUD_END);
712 SBOZO_SetNoAuthFlag(acall, aflag)
713 register struct rx_call *acall;
716 register afs_int32 code = 0;
717 char caller[MAXKTCNAMELEN];
719 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
724 bozo_Log("%s is executing Set No Authentication\n", caller);
726 afsconf_SetNoAuthFlag(bozo_confdir, aflag);
729 osi_auditU(acall, BOS_SetNoAuthEvent, code, AUD_LONG, aflag, AUD_END);
734 SBOZO_DeleteKey(acall, an)
735 struct rx_call *acall;
738 register afs_int32 code;
739 char caller[MAXKTCNAMELEN];
741 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
746 bozo_Log("%s is executing DeleteKey\n", caller);
748 code = afsconf_DeleteKey(bozo_confdir, an);
751 osi_auditU(acall, BOS_DeleteKeyEvent, code, AUD_END);
757 SBOZO_ListSUsers(acall, an, aname)
758 struct rx_call *acall;
760 register char **aname;
762 register afs_int32 code;
765 tp = *aname = (char *)malloc(256);
766 *tp = 0; /* in case getnthuser doesn't null-terminate the string */
767 code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
770 osi_auditU(acall, BOS_ListSUserEvent, code, AUD_END);
775 SBOZO_AddSUser(acall, aname)
776 struct rx_call *acall;
779 register afs_int32 code;
780 char caller[MAXKTCNAMELEN];
782 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
787 bozo_Log("%s is executing Add SuperUser '%s'\n", caller, aname);
789 code = afsconf_AddUser(bozo_confdir, aname);
792 osi_auditU(acall, BOS_AddSUserEvent, code, AUD_END);
797 SBOZO_DeleteSUser(acall, aname)
798 struct rx_call *acall;
801 register afs_int32 code;
802 char caller[MAXKTCNAMELEN];
804 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
810 bozo_Log("%s is executing Delete SuperUser '%s'\n", caller, aname);
812 code = afsconf_DeleteUser(bozo_confdir, aname);
815 osi_auditU(acall, BOS_DeleteSUserEvent, code, AUD_END);
820 SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
821 struct rx_call *acall;
824 char *ap1, *ap2, *ap3, *ap4, *ap5;
829 char caller[MAXKTCNAMELEN];
831 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
835 #ifdef BOS_RESTRICTED_MODE
836 if (bozo_isrestricted) {
837 if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp")
838 || strcmp(ap2, "now")
839 || strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
840 strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
848 bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,
851 bnode_SetStat(tb, BSTAT_NORMAL);
854 osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END);
860 register struct rx_call *acall;
862 register afs_int32 code;
863 char caller[MAXKTCNAMELEN];
865 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
871 bozo_Log("%s is executing Wait for All\n", caller);
873 code = bnode_WaitAll();
876 osi_auditU(acall, BOS_WaitAllEvent, code, AUD_END);
881 SBOZO_DeleteBnode(acall, ainstance)
882 struct rx_call *acall;
885 register afs_int32 code;
886 char caller[MAXKTCNAMELEN];
888 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
892 #ifdef BOS_RESTRICTED_MODE
893 if (bozo_isrestricted) {
899 bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
901 code = bnode_DeleteName(ainstance);
904 osi_auditU(acall, BOS_DeleteBnodeEvent, code, AUD_STR, ainstance,
910 swproc(abnode, arock)
911 register struct bnode *abnode;
914 if (abnode->goal == BSTAT_NORMAL)
915 return 0; /* this one's not shutting down */
916 /* otherwise, we are shutting down */
918 bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
919 bnode_Release(abnode);
920 return 0; /* don't stop apply function early, no matter what */
924 stproc(abnode, arock)
925 struct bnode *abnode;
928 if (abnode->fileGoal == BSTAT_SHUTDOWN)
929 return 0; /* don't do these guys */
932 bnode_SetStat(abnode, BSTAT_NORMAL);
933 bnode_Release(abnode);
938 sdproc(abnode, arock)
939 struct bnode *abnode;
943 bnode_SetStat(abnode, BSTAT_SHUTDOWN);
944 bnode_Release(abnode);
948 /* shutdown and leave down */
950 SBOZO_ShutdownAll(acall)
951 struct rx_call *acall;
953 /* iterate over all bnodes, setting the status to temporarily disabled */
954 register afs_int32 code;
955 char caller[MAXKTCNAMELEN];
957 /* check for authorization */
958 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
963 bozo_Log("%s is executing ShutdownAll\n", caller);
965 code = bnode_ApplyInstance(sdproc, NULL);
968 osi_auditU(acall, BOS_ShutdownAllEvent, code, AUD_END);
972 /* shutdown and restart */
974 SBOZO_RestartAll(acall)
975 struct rx_call *acall;
977 register afs_int32 code;
978 char caller[MAXKTCNAMELEN];
980 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
985 bozo_Log("%s is executing RestartAll\n", caller);
987 /* start shutdown of all processes */
988 code = bnode_ApplyInstance(sdproc, NULL);
992 /* wait for all done */
993 code = bnode_ApplyInstance(swproc, NULL);
997 /* start them up again */
998 code = bnode_ApplyInstance(stproc, NULL);
1001 osi_auditU(acall, BOS_RestartAllEvent, code, AUD_END);
1007 register struct rx_call *acall;
1009 register afs_int32 code;
1010 char caller[MAXKTCNAMELEN];
1012 /* acall is null if called internally to restart bosserver */
1013 if (acall && !afsconf_SuperUser(bozo_confdir, acall, caller)) {
1018 bozo_Log("%s is executing ReBozo\n", caller);
1020 /* start shutdown of all processes */
1021 code = bnode_ApplyInstance(sdproc, NULL);
1025 /* wait for all done */
1026 code = bnode_ApplyInstance(swproc, NULL);
1031 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
1033 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
1036 rx_EndCall(acall, 0); /* try to get it done */
1038 bozo_ReBozo(); /* this reexecs us, and doesn't return, of course */
1041 /* Differentiate between external and internal ReBozo; prevents AFS_Aud_NoCall event */
1043 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
1045 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
1046 return code; /* should only get here in unusual circumstances */
1049 /* make sure all are running */
1051 SBOZO_StartupAll(acall)
1052 struct rx_call *acall;
1054 register afs_int32 code;
1055 char caller[MAXKTCNAMELEN];
1057 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1062 bozo_Log("%s is executing StartupAll\n", caller);
1063 code = bnode_ApplyInstance(stproc, NULL);
1066 osi_auditU(acall, BOS_StartupAllEvent, code, AUD_END);
1071 SBOZO_Restart(acall, ainstance)
1072 struct rx_call *acall;
1073 register char *ainstance;
1075 register struct bnode *tb;
1076 register afs_int32 code;
1077 char caller[MAXKTCNAMELEN];
1079 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1084 bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);
1086 tb = bnode_FindInstance(ainstance);
1092 /* setup return code */
1096 bnode_SetStat(tb, BSTAT_SHUTDOWN);
1097 code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN); /* this can fail */
1098 bnode_SetStat(tb, BSTAT_NORMAL);
1102 osi_auditU(acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
1106 /* set temp status */
1108 SBOZO_SetTStatus(acall, ainstance, astatus)
1109 struct rx_call *acall;
1113 register struct bnode *tb;
1114 register afs_int32 code;
1115 char caller[MAXKTCNAMELEN];
1117 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1122 bozo_Log("%s is executing SetTempStatus '%s'\n", caller, ainstance);
1124 tb = bnode_FindInstance(ainstance);
1130 code = bnode_SetStat(tb, astatus);
1134 osi_auditU(acall, BOS_SetTempStatusEvent, code, AUD_STR, ainstance,
1140 SBOZO_SetStatus(acall, ainstance, astatus)
1141 struct rx_call *acall;
1145 register struct bnode *tb;
1146 register afs_int32 code;
1147 char caller[MAXKTCNAMELEN];
1149 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1154 bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller,
1155 ainstance, astatus);
1157 tb = bnode_FindInstance(ainstance);
1163 bnode_SetFileGoal(tb, astatus);
1164 code = bnode_SetStat(tb, astatus);
1168 osi_auditU(acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
1173 SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
1174 struct rx_call *acall;
1179 register struct bnode *tb;
1180 register afs_int32 code;
1182 tb = bnode_FindInstance(ainstance);
1189 code = bnode_GetStat(tb, astat);
1195 *astatDescr = (char *)malloc(BOZO_BSSIZE);
1196 code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
1199 (*astatDescr)[0] = 0; /* null string means no further info */
1203 *astatDescr = (char *)malloc(1);
1214 eifunc(abnode, arock)
1215 struct bnode *abnode;
1216 struct eidata *arock;
1218 if (arock->counter-- == 0) {
1220 strcpy(arock->iname, abnode->name);
1229 ZapFile(adir, aname)
1230 register char *adir;
1231 register char *aname;
1234 strcpy(tbuffer, adir);
1235 strcat(tbuffer, "/");
1236 strcat(tbuffer, aname);
1237 return unlink(tbuffer);
1241 SBOZO_Prune(acall, aflags)
1242 struct rx_call *acall;
1245 register afs_int32 code;
1247 register struct dirent *tde;
1249 char caller[MAXKTCNAMELEN];
1251 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1255 #ifdef BOS_RESTRICTED_MODE
1256 if (bozo_isrestricted) {
1262 bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
1264 /* first scan AFS binary directory */
1265 dirp = opendir(AFSDIR_SERVER_BIN_DIRPATH);
1267 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1268 i = strlen(tde->d_name);
1269 if (aflags & BOZO_PRUNEOLD) {
1270 if (i >= 4 && strncmp(tde->d_name + i - 4, ".OLD", 4) == 0)
1271 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1273 if (aflags & BOZO_PRUNEBAK) {
1274 if (i >= 4 && strncmp(tde->d_name + i - 4, ".BAK", 4) == 0)
1275 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1281 /* then scan AFS log directory */
1282 dirp = opendir(AFSDIR_SERVER_LOGS_DIRPATH);
1284 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1285 if (aflags & BOZO_PRUNECORE) {
1286 if (strncmp(tde->d_name, AFSDIR_CORE_FILE, 4) == 0)
1287 ZapFile(AFSDIR_SERVER_LOGS_DIRPATH, tde->d_name);
1295 osi_auditU(acall, BOS_PruneLogs, code, AUD_END);
1300 SBOZO_EnumerateInstance(acall, anum, ainstance)
1301 struct rx_call *acall;
1305 struct eidata tdata;
1307 *ainstance = (char *)malloc(BOZO_BSSIZE);
1309 tdata.counter = anum;
1310 tdata.iname = *ainstance;
1311 bnode_ApplyInstance(eifunc, &tdata);
1312 if (tdata.counter >= 0)
1313 return BZDOM; /* anum > # of actual instances */
1318 struct bozo_bosEntryStats bozo_bosEntryStats[] = {
1319 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH */
1320 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH */
1321 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH */
1322 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH */
1323 {NULL, 1, 0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
1324 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_DB_DIRPATH */
1325 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_LOCAL_DIRPATH */
1326 {NULL, 0, 1, 0600, 07}, /* AFSDIR_SERVER_KEY_FILEPATH */
1327 {NULL, 0, 1, 0600, 03}
1328 }; /* AFSDIR_SERVER_ULIST_FILEPATH */
1329 int bozo_nbosEntryStats =
1330 sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
1332 /* This function performs initialization of the bozo_bosEntrystats[]
1333 * array. This array contains the list of dirs that the bosserver
1334 * is interested in along with their recommended permissions
1335 * NOTE: This initialization is a bit ugly. This was caused because
1336 * the path names require procedural as opposed to static initialization.
1337 * The other fields in the struct are however, statically initialized.
1342 bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
1343 bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
1344 bozo_bosEntryStats[2].path = AFSDIR_SERVER_BIN_DIRPATH;
1345 bozo_bosEntryStats[3].path = AFSDIR_SERVER_LOGS_DIRPATH;
1346 bozo_bosEntryStats[4].path = AFSDIR_SERVER_BACKUP_DIRPATH;
1347 bozo_bosEntryStats[5].path = AFSDIR_SERVER_DB_DIRPATH;
1348 bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
1349 bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
1350 bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
1355 /* StatEachEntry - If it's not there, it is okay. If anything else goes wrong
1356 * complain. Otherwise check permissions: shouldn't allow write or (usually)
1360 StatEachEntry(stats)
1361 IN struct bozo_bosEntryStats *stats;
1364 if (stat(stats->path, &info)) {
1365 if (errno == ENOENT)
1366 return 1; /* no such entry: just ignore it */
1367 return 0; /* something else went wrong */
1370 if (((info.st_mode & S_IFDIR) != 0) != stats->dir)
1371 return 0; /* not expected type */
1372 if (stats->rootOwner && (info.st_uid != 0))
1373 return 0; /* not owned by root */
1374 rights = (info.st_mode & 0000777);
1375 if ((rights & stats->reqPerm) != stats->reqPerm)
1376 return 0; /* required permissions not present */
1377 if ((rights & stats->proPerm) != 0)
1378 return 0; /* prohibited permissions present */
1383 /* DirAccessOK - checks the mode bits on the AFS dir and decendents and
1384 * returns 0 if some are not OK and 1 otherwise. For efficiency, it doesn't do
1385 * this check more often than every 5 seconds. */
1391 /* underlying filesystem may not support directory protection */
1394 static afs_uint32 lastTime = 0;
1395 afs_uint32 now = FT_ApproxTime();
1396 static int lastResult = -1;
1400 if ((now - lastTime) < 5)
1405 for (i = 0; i < bozo_nbosEntryStats; i++) {
1406 struct bozo_bosEntryStats *e = &bozo_bosEntryStats[i];
1407 if (!StatEachEntry(e)) {
1408 bozo_Log("unhappy with %s which is a %s that should "
1409 "have at least rights %o, at most rights %o %s\n",
1410 e->path, e->dir ? "dir" : "file", e->reqPerm,
1411 (~e->proPerm & 0777),
1412 e->rootOwner ? ", owned by root" : "");
1418 if (result != lastResult) { /* log changes */
1419 bozo_Log("Server directory access is %sokay\n",
1420 (result ? "" : "not "));
1422 lastResult = result;
1424 #endif /* AFS_NT40_ENV */
1428 GetRequiredDirPerm(path)
1432 for (i = 0; i < bozo_nbosEntryStats; i++)
1433 if (strcmp(path, bozo_bosEntryStats[i].path) == 0)
1434 return bozo_bosEntryStats[i].reqPerm;
1439 SBOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
1440 IN struct rx_call *acall;
1443 OUT struct bozo_status *astatus;
1445 register struct bnode *tb;
1447 tb = bnode_FindInstance(ainstance);
1448 *atype = (char *)malloc(BOZO_BSSIZE);
1453 strcpy(*atype, tb->type->name);
1455 (*atype)[0] = 0; /* null string */
1456 memset(astatus, 0, sizeof(struct bozo_status)); /* good defaults */
1457 astatus->goal = tb->goal;
1458 astatus->fileGoal = tb->fileGoal;
1459 astatus->procStartTime = tb->procStartTime;
1460 astatus->procStarts = tb->procStarts;
1461 astatus->lastAnyExit = tb->lastAnyExit;
1462 astatus->lastErrorExit = tb->lastErrorExit;
1463 astatus->errorCode = tb->errorCode;
1464 astatus->errorSignal = tb->errorSignal;
1465 if (tb->flags & BNODE_ERRORSTOP)
1466 astatus->flags |= BOZO_ERRORSTOP;
1467 if (bnode_HasCore(tb))
1468 astatus->flags |= BOZO_HASCORE;
1470 astatus->flags |= BOZO_BADDIRACCESS;
1475 SBOZO_GetInstanceParm(acall, ainstance, anum, aparm)
1476 struct rx_call *acall;
1481 register struct bnode *tb;
1483 register afs_int32 code;
1485 tp = (char *)malloc(BOZO_BSSIZE);
1487 *tp = 0; /* null-terminate string in error case */
1488 tb = bnode_FindInstance(ainstance);
1494 memcpy(tp, tb->notifier, strlen(tb->notifier) + 1);
1497 code = BZNOENT; /* XXXXX */
1499 code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
1502 /* Not Currently Audited */
1507 SBOZO_GetLog(acall, aname)
1508 register struct rx_call *acall;
1511 register afs_int32 code;
1516 char caller[MAXKTCNAMELEN];
1518 /* Check access since 'aname' could specify a file outside of the
1519 * AFS log directory (which is bosserver's working directory).
1521 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1525 #ifdef BOS_RESTRICTED_MODE
1526 if (bozo_isrestricted && strchr(aname, '/')
1527 && strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
1533 /* construct local path from canonical (wire-format) path */
1534 if (ConstructLocalLogPath(aname, &logpath)) {
1538 bozo_Log("%s is executing GetLog '%s'\n", caller, logpath);
1539 tfile = fopen(logpath, "r");
1549 continue; /* our termination condition on other end */
1553 if (rx_Write(acall, &buffer, 1) != 1) {
1560 /* all done, cleanup and return */
1563 /* write out the end delimeter */
1565 if (rx_Write(acall, &buffer, 1) != 1)
1570 osi_auditU(acall, BOS_GetLogsEvent, code, AUD_END);
1575 SBOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
1576 struct rx_call *acall;
1578 char **as1, **as2, **as3, **as4;
1580 register struct bnode *tb;
1582 *as2 = (char *)malloc(1);
1584 *as3 = (char *)malloc(1);
1586 *as4 = (char *)malloc(1);
1588 tb = bnode_FindInstance(abnodeName);
1592 /* now, return the appropriate error string, if any */
1593 if (tb->lastErrorName) {
1594 *as1 = (char *)malloc(strlen(tb->lastErrorName) + 1);
1595 strcpy(*as1, tb->lastErrorName);
1597 *as1 = (char *)malloc(1);
1603 *as1 = (char *)malloc(1);
1608 #ifdef BOS_RESTRICTED_MODE
1610 SBOZO_GetRestrictedMode(acall, arestmode)
1611 struct rx_call *acall;
1612 afs_int32 *arestmode;
1614 *arestmode = bozo_isrestricted;
1619 SBOZO_SetRestrictedMode(acall, arestmode)
1620 struct rx_call *acall;
1621 afs_int32 arestmode;
1624 char caller[MAXKTCNAMELEN];
1626 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1629 if (bozo_isrestricted) {
1632 if (arestmode != 0 && arestmode != 1) {
1635 bozo_isrestricted = arestmode;
1636 code = WriteBozoFile(0);
1642 SBOZO_GetRestrictedMode(acall, arestmode)
1643 struct rx_call *acall;
1644 afs_int32 *arestmode;
1646 return RXGEN_OPCODE;
1650 SBOZO_SetRestrictedMode(acall, arestmode)
1651 struct rx_call *acall;
1652 afs_int32 arestmode;
1654 return RXGEN_OPCODE;
1659 bozo_ShutdownAndExit(int asignal)
1664 ("Shutdown of BOS server and processes in response to signal %d\n",
1667 /* start shutdown of all processes */
1668 if ((code = bnode_ApplyInstance(sdproc, NULL)) == 0) {
1669 /* wait for shutdown to complete */
1670 code = bnode_ApplyInstance(swproc, NULL);
1674 bozo_Log("Shutdown incomplete (code = %d); manual cleanup required\n",