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 struct rx_securityClass *bozo_rxsc[2];
57 extern int bozo_newKTs;
59 #ifdef BOS_RESTRICTED_MODE
60 extern int bozo_isrestricted;
64 SBOZO_GetRestartTime(acall, atype, aktime)
65 struct rx_call *acall;
67 struct bozo_netKTime *aktime;
69 register afs_int32 code;
71 code = 0; /* assume success */
74 memcpy(aktime, &bozo_nextRestartKT, sizeof(struct ktime));
78 memcpy(aktime, &bozo_nextDayKT, sizeof(struct ktime));
90 SBOZO_SetRestartTime(acall, atype, aktime)
91 struct rx_call *acall;
93 struct bozo_netKTime *aktime;
95 register afs_int32 code;
96 char caller[MAXKTCNAMELEN];
98 /* check for proper permissions */
99 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
104 bozo_Log("%s is executing SetRestartTime\n", caller);
106 code = 0; /* assume success */
109 memcpy(&bozo_nextRestartKT, aktime, sizeof(struct ktime));
113 memcpy(&bozo_nextDayKT, aktime, sizeof(struct ktime));
122 /* try to update the bozo init file */
123 code = WriteBozoFile(0);
128 osi_auditU(acall, BOS_SetRestartEvent, code, AUD_END);
133 SBOZO_Exec(acall, acmd)
134 struct rx_call *acall;
138 char caller[MAXKTCNAMELEN];
141 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
145 #ifdef BOS_RESTRICTED_MODE
146 if (bozo_isrestricted) {
152 bozo_Log("%s is executing the shell command '%s'\n", caller, acmd);
154 /* should copy output to acall, but don't yet cause its hard */
155 /* hard... NOT! Nnow _at least_ return the exit status */
157 osi_auditU(acall, BOS_ExecEvent, code, AUD_STR, acmd, AUD_END);
164 SBOZO_GetDates(acall, aname, atime, abakTime, aoldTime)
165 struct rx_call *acall;
167 afs_int32 *atime, *abakTime, *aoldTime;
171 char tbuffer[AFSDIR_PATH_MAX];
173 *atime = *abakTime = *aoldTime = 0;
175 /* construct local path from canonical (wire-format) path */
176 if (ConstructLocalBinPath(aname, &strp)) {
179 strcpy(tbuffer, strp);
182 strp = tbuffer + strlen(tbuffer);
184 if (!stat(tbuffer, &tstat)) {
185 *atime = tstat.st_mtime;
188 strcpy(strp, ".BAK");
189 if (!stat(tbuffer, &tstat)) {
190 *abakTime = tstat.st_mtime;
193 strcpy(strp, ".OLD");
194 if (!stat(tbuffer, &tstat)) {
195 *aoldTime = tstat.st_mtime;
201 SBOZO_UnInstall(acall, aname)
202 struct rx_call *acall;
203 register char *aname;
206 char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX];
208 char caller[MAXKTCNAMELEN];
211 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
213 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
216 #ifdef BOS_RESTRICTED_MODE
217 if (bozo_isrestricted) {
219 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
224 /* construct local path from canonical (wire-format) path */
225 if (ConstructLocalBinPath(aname, &filepath)) {
230 bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
232 strcpy(fpBak, filepath);
233 strcat(fpBak, ".BAK");
234 strcpy(fpOld, filepath);
235 strcat(fpOld, ".OLD");
237 code = renamefile(fpBak, filepath);
239 /* can't find .BAK, try .OLD */
240 code = renamefile(fpOld, filepath);
241 if (code && errno == ENOENT) /* If doesn't exist don't fail */
244 /* now rename .OLD to .BAK */
245 if (stat(fpOld, &tstat) == 0)
246 code = renamefile(fpOld, fpBak);
251 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
257 #define BOZO_OLDTIME (7*24*3600) /* 7 days old */
259 SaveOldFiles(char *aname)
261 register afs_int32 code;
262 char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX];
264 register afs_int32 now;
265 afs_int32 oldTime, bakTime;
267 strcpy(bbuffer, aname);
268 strcat(bbuffer, ".BAK");
269 strcpy(obuffer, aname);
270 strcat(obuffer, ".OLD");
271 now = FT_ApproxTime();
273 code = stat(aname, &tstat);
275 return; /* can't stat file */
277 code = stat(obuffer, &tstat); /* discover old file's time */
281 oldTime = tstat.st_mtime;
283 code = stat(bbuffer, &tstat); /* discover back file's time */
287 bakTime = tstat.st_mtime;
289 if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
290 /* no .OLD file, or .BAK is at least a week old */
291 code = renamefile(bbuffer, obuffer);
294 /* finally rename to .BAK extension */
295 renamefile(aname, bbuffer);
299 SBOZO_Install(acall, aname, asize, mode, amtime)
300 struct rx_call *acall;
311 struct _utimbuf utbuf;
313 struct timeval tvb[2];
315 char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
316 char caller[MAXKTCNAMELEN];
318 if (!afsconf_SuperUser(bozo_confdir, acall, caller))
320 #ifdef BOS_RESTRICTED_MODE
321 if (bozo_isrestricted)
325 /* construct local path from canonical (wire-format) path */
326 if (ConstructLocalBinPath(aname, &fpp)) {
329 strcpy(filepath, fpp);
333 bozo_Log("%s is executing Install '%s'\n", caller, filepath);
336 fpp = filepath + strlen(filepath);
337 strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */
338 fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
343 len = rx_Read(acall, tbuffer, sizeof(tbuffer));
350 break; /* no more input */
351 code = write(fd, tbuffer, len);
357 total += len; /* track total written for safety check at end */
360 if (asize != total) {
362 return 101; /* wrong size */
366 *fpp = '\0'; /* remove ".NEW" from end of filepath */
367 SaveOldFiles(filepath); /* don't care if it works, still install */
369 /* all done, rename to final name */
370 strcpy(tbuffer, filepath);
371 strcat(tbuffer, ".NEW");
372 code = (renamefile(tbuffer, filepath) ? errno : 0);
374 /* label file with same time for our sanity */
376 utbuf.actime = utbuf.modtime = amtime;
377 _utime(filepath, &utbuf);
379 tvb[0].tv_sec = tvb[1].tv_sec = amtime;
380 tvb[0].tv_usec = tvb[1].tv_usec = 0;
381 utimes(filepath, tvb);
382 #endif /* AFS_NT40_ENV */
385 chmod(filepath, mode);
388 osi_auditU(acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
395 SBOZO_SetCellName(acall, aname)
396 struct rx_call *acall;
399 struct afsconf_cell tcell;
400 register afs_int32 code;
401 char caller[MAXKTCNAMELEN];
402 char clones[MAXHOSTSPERCELL];
404 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
409 bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
412 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
417 /* Check that tcell has enough space for the new cellname. */
418 if (strlen(aname) > sizeof tcell.name - 1) {
420 ("ERROR: SetCellName: cell name '%s' exceeds %ld bytes (cell name not changed)\n",
421 aname, (long)(sizeof tcell.name - 1));
426 strcpy(tcell.name, aname);
428 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
432 osi_auditU(acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
437 SBOZO_GetCellName(acall, aname)
438 struct rx_call *acall;
441 register afs_int32 code;
442 char tname[MAXCELLCHARS];
444 code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
446 /* must set output parameters even if aborting */
447 *aname = (char *)malloc(1);
450 *aname = (char *)malloc(strlen(tname) + 1);
451 strcpy(*aname, tname);
458 SBOZO_GetCellHost(acall, awhich, aname)
459 struct rx_call *acall;
463 register afs_int32 code;
464 struct afsconf_cell tcell;
466 char clones[MAXHOSTSPERCELL];
469 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
474 if (awhich >= tcell.numServers) {
479 tp = tcell.hostName[awhich];
480 *aname = (char *)malloc(strlen(tp) + 3);
481 if (clones[awhich]) {
490 *aname = (char *)malloc(1); /* return fake string */
498 SBOZO_DeleteCellHost(acall, aname)
499 struct rx_call *acall;
502 register afs_int32 code;
503 struct afsconf_cell tcell;
506 char caller[MAXKTCNAMELEN];
507 char clones[MAXHOSTSPERCELL];
509 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
514 bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
517 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
523 for (i = 0; i < tcell.numServers; i++) {
524 if (strcmp(tcell.hostName[i], aname) == 0) {
535 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
536 memset(tcell.hostName[which], 0, MAXHOSTCHARS);
538 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
542 osi_auditU(acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
547 SBOZO_AddCellHost(acall, aname)
548 struct rx_call *acall;
551 register afs_int32 code;
552 struct afsconf_cell tcell;
555 char caller[MAXKTCNAMELEN];
556 char clones[MAXHOSTSPERCELL];
560 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
565 bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
568 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
575 *(n + strlen(n) - 1) = 0;
581 for (i = 0; i < tcell.numServers; i++) {
582 if (strcmp(tcell.hostName[i], n) == 0) {
588 which = tcell.numServers;
592 * Check that tcell has enough space for an additional host.
594 * We assume that tcell.hostAddr[] and tcell.hostName[] have the
595 * same number of entries.
597 if (tcell.numServers >
598 sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]) {
600 ("ERROR: AddCellHost: attempt to add more than %ld database servers (database server '%s' not added)\n",
601 (long)(sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]),
607 /* Check that tcell has enough space for the new hostname. */
608 if (strlen(aname) > sizeof tcell.hostName[0] - 1) {
610 ("ERROR: AddCellHost: host name '%s' exceeds %ld bytes (not added)\n",
611 aname, (long)(sizeof tcell.hostName[0] - 1));
617 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
618 strcpy(tcell.hostName[which], n);
619 clones[which] = isClone;
621 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
625 osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
630 SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
631 struct rx_call *acall;
634 struct bozo_keyInfo *akeyinfo;
635 struct bozo_key *akey;
637 struct afsconf_keys tkeys;
638 register afs_int32 code;
641 char caller[MAXKTCNAMELEN];
642 rxkad_level enc_level = rxkad_clear;
644 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
649 bozo_Log("%s is executing ListKeys\n", caller);
651 code = afsconf_GetKeys(bozo_confdir, &tkeys);
655 if (tkeys.nkeys <= an) {
659 *akvno = tkeys.key[an].kvno;
660 memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
662 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
663 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
665 * only return actual keys in noauth or if this is an encrypted connection
668 if ((noauth) || (enc_level == rxkad_crypt)) {
669 memcpy(akey, tkeys.key[an].key, 8);
673 code = stat(AFSDIR_SERVER_KEY_FILEPATH, &tstat);
675 akeyinfo->mod_sec = tstat.st_mtime;
677 ka_KeyCheckSum(tkeys.key[an].key, &akeyinfo->keyCheckSum);
678 /* only errors is bad key parity */
682 osi_auditU(acall, BOS_UnAuthListKeysEvent, code, AUD_END);
683 osi_auditU(acall, BOS_ListKeysEvent, code, AUD_END);
688 SBOZO_AddKey(acall, an, akey)
689 struct rx_call *acall;
691 struct bozo_key *akey;
693 register afs_int32 code;
694 char caller[MAXKTCNAMELEN];
695 rxkad_level enc_level = rxkad_clear;
698 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
702 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
703 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
704 if ((!noauth) && (enc_level != rxkad_crypt)) {
709 bozo_Log("%s is executing AddKey\n", caller);
711 code = afsconf_AddKey(bozo_confdir, an, akey, 0);
712 if (code == AFSCONF_KEYINUSE)
713 code = BZKEYINUSE; /* Unique code for afs rpc calls */
715 osi_auditU(acall, BOS_AddKeyEvent, code, AUD_END);
720 SBOZO_SetNoAuthFlag(acall, aflag)
721 register struct rx_call *acall;
724 register afs_int32 code = 0;
725 char caller[MAXKTCNAMELEN];
727 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
732 bozo_Log("%s is executing Set No Authentication\n", caller);
734 afsconf_SetNoAuthFlag(bozo_confdir, aflag);
737 osi_auditU(acall, BOS_SetNoAuthEvent, code, AUD_LONG, aflag, AUD_END);
742 SBOZO_DeleteKey(acall, an)
743 struct rx_call *acall;
746 register afs_int32 code;
747 char caller[MAXKTCNAMELEN];
749 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
754 bozo_Log("%s is executing DeleteKey\n", caller);
756 code = afsconf_DeleteKey(bozo_confdir, an);
759 osi_auditU(acall, BOS_DeleteKeyEvent, code, AUD_END);
765 SBOZO_ListSUsers(acall, an, aname)
766 struct rx_call *acall;
768 register char **aname;
770 register afs_int32 code;
773 tp = *aname = (char *)malloc(256);
774 *tp = 0; /* in case getnthuser doesn't null-terminate the string */
775 code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
778 osi_auditU(acall, BOS_ListSUserEvent, code, AUD_END);
783 SBOZO_AddSUser(acall, aname)
784 struct rx_call *acall;
787 register afs_int32 code;
788 char caller[MAXKTCNAMELEN];
790 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
795 bozo_Log("%s is executing Add SuperUser '%s'\n", caller, aname);
797 code = afsconf_AddUser(bozo_confdir, aname);
800 osi_auditU(acall, BOS_AddSUserEvent, code, AUD_END);
805 SBOZO_DeleteSUser(acall, aname)
806 struct rx_call *acall;
809 register afs_int32 code;
810 char caller[MAXKTCNAMELEN];
812 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
818 bozo_Log("%s is executing Delete SuperUser '%s'\n", caller, aname);
820 code = afsconf_DeleteUser(bozo_confdir, aname);
823 osi_auditU(acall, BOS_DeleteSUserEvent, code, AUD_END);
828 SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
829 struct rx_call *acall;
832 char *ap1, *ap2, *ap3, *ap4, *ap5;
837 char caller[MAXKTCNAMELEN];
839 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
843 #ifdef BOS_RESTRICTED_MODE
844 if (bozo_isrestricted) {
845 if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp")
846 || strcmp(ap2, "now")
847 || strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
848 strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
856 bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,
859 bnode_SetStat(tb, BSTAT_NORMAL);
862 osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END);
868 register struct rx_call *acall;
870 register afs_int32 code;
871 char caller[MAXKTCNAMELEN];
873 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
879 bozo_Log("%s is executing Wait for All\n", caller);
881 code = bnode_WaitAll();
884 osi_auditU(acall, BOS_WaitAllEvent, code, AUD_END);
889 SBOZO_DeleteBnode(acall, ainstance)
890 struct rx_call *acall;
893 register afs_int32 code;
894 char caller[MAXKTCNAMELEN];
896 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
900 #ifdef BOS_RESTRICTED_MODE
901 if (bozo_isrestricted) {
907 bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
909 code = bnode_DeleteName(ainstance);
912 osi_auditU(acall, BOS_DeleteBnodeEvent, code, AUD_STR, ainstance,
918 swproc(abnode, arock)
919 register struct bnode *abnode;
922 if (abnode->goal == BSTAT_NORMAL)
923 return 0; /* this one's not shutting down */
924 /* otherwise, we are shutting down */
926 bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
927 bnode_Release(abnode);
928 return 0; /* don't stop apply function early, no matter what */
932 stproc(abnode, arock)
933 struct bnode *abnode;
936 if (abnode->fileGoal == BSTAT_SHUTDOWN)
937 return 0; /* don't do these guys */
940 bnode_SetStat(abnode, BSTAT_NORMAL);
941 bnode_Release(abnode);
946 sdproc(abnode, arock)
947 struct bnode *abnode;
951 bnode_SetStat(abnode, BSTAT_SHUTDOWN);
952 bnode_Release(abnode);
956 /* shutdown and leave down */
958 SBOZO_ShutdownAll(acall)
959 struct rx_call *acall;
961 /* iterate over all bnodes, setting the status to temporarily disabled */
962 register afs_int32 code;
963 char caller[MAXKTCNAMELEN];
965 /* check for authorization */
966 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
971 bozo_Log("%s is executing ShutdownAll\n", caller);
973 code = bnode_ApplyInstance(sdproc, NULL);
976 osi_auditU(acall, BOS_ShutdownAllEvent, code, AUD_END);
980 /* shutdown and restart */
982 SBOZO_RestartAll(acall)
983 struct rx_call *acall;
985 register afs_int32 code;
986 char caller[MAXKTCNAMELEN];
988 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
993 bozo_Log("%s is executing RestartAll\n", caller);
995 /* start shutdown of all processes */
996 code = bnode_ApplyInstance(sdproc, NULL);
1000 /* wait for all done */
1001 code = bnode_ApplyInstance(swproc, NULL);
1005 /* start them up again */
1006 code = bnode_ApplyInstance(stproc, NULL);
1009 osi_auditU(acall, BOS_RestartAllEvent, code, AUD_END);
1015 register struct rx_call *acall;
1017 register afs_int32 code;
1018 char caller[MAXKTCNAMELEN];
1020 /* acall is null if called internally to restart bosserver */
1021 if (acall && !afsconf_SuperUser(bozo_confdir, acall, caller)) {
1026 bozo_Log("%s is executing ReBozo\n", caller);
1028 /* start shutdown of all processes */
1029 code = bnode_ApplyInstance(sdproc, NULL);
1033 /* wait for all done */
1034 code = bnode_ApplyInstance(swproc, NULL);
1039 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
1041 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
1044 rx_EndCall(acall, 0); /* try to get it done */
1046 bozo_ReBozo(); /* this reexecs us, and doesn't return, of course */
1049 /* Differentiate between external and internal ReBozo; prevents AFS_Aud_NoCall event */
1051 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
1053 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
1054 return code; /* should only get here in unusual circumstances */
1057 /* make sure all are running */
1059 SBOZO_StartupAll(acall)
1060 struct rx_call *acall;
1062 register afs_int32 code;
1063 char caller[MAXKTCNAMELEN];
1065 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1070 bozo_Log("%s is executing StartupAll\n", caller);
1071 code = bnode_ApplyInstance(stproc, NULL);
1074 osi_auditU(acall, BOS_StartupAllEvent, code, AUD_END);
1079 SBOZO_Restart(acall, ainstance)
1080 struct rx_call *acall;
1081 register char *ainstance;
1083 register struct bnode *tb;
1084 register afs_int32 code;
1085 char caller[MAXKTCNAMELEN];
1087 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1092 bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);
1094 tb = bnode_FindInstance(ainstance);
1100 /* setup return code */
1104 bnode_SetStat(tb, BSTAT_SHUTDOWN);
1105 code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN); /* this can fail */
1106 bnode_SetStat(tb, BSTAT_NORMAL);
1110 osi_auditU(acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
1114 /* set temp status */
1116 SBOZO_SetTStatus(acall, ainstance, astatus)
1117 struct rx_call *acall;
1121 register struct bnode *tb;
1122 register afs_int32 code;
1123 char caller[MAXKTCNAMELEN];
1125 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1130 bozo_Log("%s is executing SetTempStatus '%s'\n", caller, ainstance);
1132 tb = bnode_FindInstance(ainstance);
1138 code = bnode_SetStat(tb, astatus);
1142 osi_auditU(acall, BOS_SetTempStatusEvent, code, AUD_STR, ainstance,
1148 SBOZO_SetStatus(acall, ainstance, astatus)
1149 struct rx_call *acall;
1153 register struct bnode *tb;
1154 register afs_int32 code;
1155 char caller[MAXKTCNAMELEN];
1157 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1162 bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller,
1163 ainstance, astatus);
1165 tb = bnode_FindInstance(ainstance);
1171 bnode_SetFileGoal(tb, astatus);
1172 code = bnode_SetStat(tb, astatus);
1176 osi_auditU(acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
1181 SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
1182 struct rx_call *acall;
1187 register struct bnode *tb;
1188 register afs_int32 code;
1190 tb = bnode_FindInstance(ainstance);
1197 code = bnode_GetStat(tb, astat);
1203 *astatDescr = (char *)malloc(BOZO_BSSIZE);
1204 code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
1207 (*astatDescr)[0] = 0; /* null string means no further info */
1211 *astatDescr = (char *)malloc(1);
1222 eifunc(abnode, arock)
1223 struct bnode *abnode;
1224 struct eidata *arock;
1226 if (arock->counter-- == 0) {
1228 strcpy(arock->iname, abnode->name);
1237 ZapFile(adir, aname)
1238 register char *adir;
1239 register char *aname;
1242 strcpy(tbuffer, adir);
1243 strcat(tbuffer, "/");
1244 strcat(tbuffer, aname);
1245 return unlink(tbuffer);
1249 SBOZO_Prune(acall, aflags)
1250 struct rx_call *acall;
1253 register afs_int32 code;
1255 register struct dirent *tde;
1257 char caller[MAXKTCNAMELEN];
1259 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1263 #ifdef BOS_RESTRICTED_MODE
1264 if (bozo_isrestricted) {
1270 bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
1272 /* first scan AFS binary directory */
1273 dirp = opendir(AFSDIR_SERVER_BIN_DIRPATH);
1275 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1276 i = strlen(tde->d_name);
1277 if (aflags & BOZO_PRUNEOLD) {
1278 if (i >= 4 && strncmp(tde->d_name + i - 4, ".OLD", 4) == 0)
1279 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1281 if (aflags & BOZO_PRUNEBAK) {
1282 if (i >= 4 && strncmp(tde->d_name + i - 4, ".BAK", 4) == 0)
1283 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1289 /* then scan AFS log directory */
1290 dirp = opendir(AFSDIR_SERVER_LOGS_DIRPATH);
1292 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1293 if (aflags & BOZO_PRUNECORE) {
1294 if (strncmp(tde->d_name, AFSDIR_CORE_FILE, 4) == 0)
1295 ZapFile(AFSDIR_SERVER_LOGS_DIRPATH, tde->d_name);
1303 osi_auditU(acall, BOS_PruneLogs, code, AUD_END);
1308 SBOZO_EnumerateInstance(acall, anum, ainstance)
1309 struct rx_call *acall;
1313 struct eidata tdata;
1315 *ainstance = (char *)malloc(BOZO_BSSIZE);
1317 tdata.counter = anum;
1318 tdata.iname = *ainstance;
1319 bnode_ApplyInstance(eifunc, &tdata);
1320 if (tdata.counter >= 0)
1321 return BZDOM; /* anum > # of actual instances */
1326 struct bozo_bosEntryStats bozo_bosEntryStats[] = {
1327 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH */
1328 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH */
1329 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH */
1330 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH */
1331 {NULL, 1, 0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
1332 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_DB_DIRPATH */
1333 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_LOCAL_DIRPATH */
1334 {NULL, 0, 1, 0600, 07}, /* AFSDIR_SERVER_KEY_FILEPATH */
1335 {NULL, 0, 1, 0600, 03}
1336 }; /* AFSDIR_SERVER_ULIST_FILEPATH */
1337 int bozo_nbosEntryStats =
1338 sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
1340 /* This function performs initialization of the bozo_bosEntrystats[]
1341 * array. This array contains the list of dirs that the bosserver
1342 * is interested in along with their recommended permissions
1343 * NOTE: This initialization is a bit ugly. This was caused because
1344 * the path names require procedural as opposed to static initialization.
1345 * The other fields in the struct are however, statically initialized.
1350 bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
1351 bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
1352 bozo_bosEntryStats[2].path = AFSDIR_SERVER_BIN_DIRPATH;
1353 bozo_bosEntryStats[3].path = AFSDIR_SERVER_LOGS_DIRPATH;
1354 bozo_bosEntryStats[4].path = AFSDIR_SERVER_BACKUP_DIRPATH;
1355 bozo_bosEntryStats[5].path = AFSDIR_SERVER_DB_DIRPATH;
1356 bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
1357 bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
1358 bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
1363 /* StatEachEntry - If it's not there, it is okay. If anything else goes wrong
1364 * complain. Otherwise check permissions: shouldn't allow write or (usually)
1368 StatEachEntry(stats)
1369 IN struct bozo_bosEntryStats *stats;
1372 if (stat(stats->path, &info)) {
1373 if (errno == ENOENT)
1374 return 1; /* no such entry: just ignore it */
1375 return 0; /* something else went wrong */
1378 if (((info.st_mode & S_IFDIR) != 0) != stats->dir)
1379 return 0; /* not expected type */
1380 if (stats->rootOwner && (info.st_uid != 0))
1381 return 0; /* not owned by root */
1382 rights = (info.st_mode & 0000777);
1383 if ((rights & stats->reqPerm) != stats->reqPerm)
1384 return 0; /* required permissions not present */
1385 if ((rights & stats->proPerm) != 0)
1386 return 0; /* prohibited permissions present */
1391 /* DirAccessOK - checks the mode bits on the AFS dir and decendents and
1392 * returns 0 if some are not OK and 1 otherwise. For efficiency, it doesn't do
1393 * this check more often than every 5 seconds. */
1399 /* underlying filesystem may not support directory protection */
1402 static afs_uint32 lastTime = 0;
1403 afs_uint32 now = FT_ApproxTime();
1404 static int lastResult = -1;
1408 if ((now - lastTime) < 5)
1413 for (i = 0; i < bozo_nbosEntryStats; i++) {
1414 struct bozo_bosEntryStats *e = &bozo_bosEntryStats[i];
1415 if (!StatEachEntry(e)) {
1416 bozo_Log("unhappy with %s which is a %s that should "
1417 "have at least rights %o, at most rights %o %s\n",
1418 e->path, e->dir ? "dir" : "file", e->reqPerm,
1419 (~e->proPerm & 0777),
1420 e->rootOwner ? ", owned by root" : "");
1426 if (result != lastResult) { /* log changes */
1427 bozo_Log("Server directory access is %sokay\n",
1428 (result ? "" : "not "));
1430 lastResult = result;
1432 #endif /* AFS_NT40_ENV */
1436 GetRequiredDirPerm(path)
1440 for (i = 0; i < bozo_nbosEntryStats; i++)
1441 if (strcmp(path, bozo_bosEntryStats[i].path) == 0)
1442 return bozo_bosEntryStats[i].reqPerm;
1447 SBOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
1448 IN struct rx_call *acall;
1451 OUT struct bozo_status *astatus;
1453 register struct bnode *tb;
1455 tb = bnode_FindInstance(ainstance);
1456 *atype = (char *)malloc(BOZO_BSSIZE);
1461 strcpy(*atype, tb->type->name);
1463 (*atype)[0] = 0; /* null string */
1464 memset(astatus, 0, sizeof(struct bozo_status)); /* good defaults */
1465 astatus->goal = tb->goal;
1466 astatus->fileGoal = tb->fileGoal;
1467 astatus->procStartTime = tb->procStartTime;
1468 astatus->procStarts = tb->procStarts;
1469 astatus->lastAnyExit = tb->lastAnyExit;
1470 astatus->lastErrorExit = tb->lastErrorExit;
1471 astatus->errorCode = tb->errorCode;
1472 astatus->errorSignal = tb->errorSignal;
1473 if (tb->flags & BNODE_ERRORSTOP)
1474 astatus->flags |= BOZO_ERRORSTOP;
1475 if (bnode_HasCore(tb))
1476 astatus->flags |= BOZO_HASCORE;
1478 astatus->flags |= BOZO_BADDIRACCESS;
1483 SBOZO_GetInstanceParm(acall, ainstance, anum, aparm)
1484 struct rx_call *acall;
1489 register struct bnode *tb;
1491 register afs_int32 code;
1493 tp = (char *)malloc(BOZO_BSSIZE);
1495 *tp = 0; /* null-terminate string in error case */
1496 tb = bnode_FindInstance(ainstance);
1502 memcpy(tp, tb->notifier, strlen(tb->notifier) + 1);
1505 code = BZNOENT; /* XXXXX */
1507 code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
1510 /* Not Currently Audited */
1515 SBOZO_GetLog(acall, aname)
1516 register struct rx_call *acall;
1519 register afs_int32 code;
1524 char caller[MAXKTCNAMELEN];
1526 /* Check access since 'aname' could specify a file outside of the
1527 * AFS log directory (which is bosserver's working directory).
1529 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1533 #ifdef BOS_RESTRICTED_MODE
1534 if (bozo_isrestricted && strchr(aname, '/')
1535 && strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
1541 /* construct local path from canonical (wire-format) path */
1542 if (ConstructLocalLogPath(aname, &logpath)) {
1546 bozo_Log("%s is executing GetLog '%s'\n", caller, logpath);
1547 tfile = fopen(logpath, "r");
1557 continue; /* our termination condition on other end */
1561 if (rx_Write(acall, &buffer, 1) != 1) {
1568 /* all done, cleanup and return */
1571 /* write out the end delimeter */
1573 if (rx_Write(acall, &buffer, 1) != 1)
1578 osi_auditU(acall, BOS_GetLogsEvent, code, AUD_END);
1583 SBOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
1584 struct rx_call *acall;
1586 char **as1, **as2, **as3, **as4;
1588 register struct bnode *tb;
1590 *as2 = (char *)malloc(1);
1592 *as3 = (char *)malloc(1);
1594 *as4 = (char *)malloc(1);
1596 tb = bnode_FindInstance(abnodeName);
1600 /* now, return the appropriate error string, if any */
1601 if (tb->lastErrorName) {
1602 *as1 = (char *)malloc(strlen(tb->lastErrorName) + 1);
1603 strcpy(*as1, tb->lastErrorName);
1605 *as1 = (char *)malloc(1);
1611 *as1 = (char *)malloc(1);
1616 #ifdef BOS_RESTRICTED_MODE
1618 SBOZO_GetRestrictedMode(acall, arestmode)
1619 struct rx_call *acall;
1620 afs_int32 *arestmode;
1622 *arestmode = bozo_isrestricted;
1627 SBOZO_SetRestrictedMode(acall, arestmode)
1628 struct rx_call *acall;
1629 afs_int32 arestmode;
1632 char caller[MAXKTCNAMELEN];
1634 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1637 if (bozo_isrestricted) {
1640 if (arestmode != 0 && arestmode != 1) {
1643 bozo_isrestricted = arestmode;
1644 code = WriteBozoFile(0);
1650 SBOZO_GetRestrictedMode(acall, arestmode)
1651 struct rx_call *acall;
1652 afs_int32 *arestmode;
1654 return RXGEN_OPCODE;
1658 SBOZO_SetRestrictedMode(acall, arestmode)
1659 struct rx_call *acall;
1660 afs_int32 arestmode;
1662 return RXGEN_OPCODE;
1667 bozo_ShutdownAndExit(int asignal)
1672 ("Shutdown of BOS server and processes in response to signal %d\n",
1675 /* start shutdown of all processes */
1676 if ((code = bnode_ApplyInstance(sdproc, NULL)) == 0) {
1677 /* wait for shutdown to complete */
1678 code = bnode_ApplyInstance(swproc, NULL);
1682 bozo_Log("Shutdown incomplete (code = %d); manual cleanup required\n",