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>
15 #include <sys/types.h>
19 #include <sys/utime.h>
22 #include <netinet/in.h>
23 #endif /* AFS_NT40_ENV */
28 #include <afs/cellconfig.h>
34 #include <afs/afsutil.h>
35 #include <afs/fileutil.h>
36 #include <afs/ktime.h>
37 #include <afs/audit.h>
38 #include <afs/kautils.h>
43 #include "bosprototypes.h"
45 extern struct ktime bozo_nextRestartKT, bozo_nextDayKT;
47 extern struct afsconf_dir *bozo_confdir;
48 extern int bozo_newKTs;
50 #ifdef BOS_RESTRICTED_MODE
51 extern int bozo_isrestricted;
55 SBOZO_GetRestartTime(struct rx_call *acall, afs_int32 atype, struct bozo_netKTime *aktime)
57 register afs_int32 code;
59 code = 0; /* assume success */
62 memcpy(aktime, &bozo_nextRestartKT, sizeof(struct ktime));
66 memcpy(aktime, &bozo_nextDayKT, sizeof(struct ktime));
78 SBOZO_SetRestartTime(struct rx_call *acall, afs_int32 atype, struct bozo_netKTime *aktime)
80 register afs_int32 code;
81 char caller[MAXKTCNAMELEN];
83 /* check for proper permissions */
84 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
89 bozo_Log("%s is executing SetRestartTime\n", caller);
91 code = 0; /* assume success */
94 memcpy(&bozo_nextRestartKT, aktime, sizeof(struct ktime));
98 memcpy(&bozo_nextDayKT, aktime, sizeof(struct ktime));
107 /* try to update the bozo init file */
108 code = WriteBozoFile(0);
113 osi_auditU(acall, BOS_SetRestartEvent, code, AUD_END);
118 SBOZO_Exec(struct rx_call *acall, char *acmd)
121 char caller[MAXKTCNAMELEN];
124 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
128 #ifdef BOS_RESTRICTED_MODE
129 if (bozo_isrestricted) {
135 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);
147 SBOZO_GetDates(struct rx_call *acall, char *aname, afs_int32 *atime,
148 afs_int32 *abakTime, afs_int32 *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;
182 SBOZO_UnInstall(struct rx_call *acall, 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)) {
209 bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
211 strcpy(fpBak, filepath);
212 strcat(fpBak, ".BAK");
213 strcpy(fpOld, filepath);
214 strcat(fpOld, ".OLD");
216 code = renamefile(fpBak, filepath);
218 /* can't find .BAK, try .OLD */
219 code = renamefile(fpOld, filepath);
220 if (code && errno == ENOENT) /* If doesn't exist don't fail */
223 /* now rename .OLD to .BAK */
224 if (stat(fpOld, &tstat) == 0)
225 code = renamefile(fpOld, fpBak);
230 osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
236 #define BOZO_OLDTIME (7*24*3600) /* 7 days old */
238 SaveOldFiles(char *aname)
240 register afs_int32 code;
241 char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX];
243 register afs_int32 now;
244 afs_int32 oldTime, bakTime;
246 strcpy(bbuffer, aname);
247 strcat(bbuffer, ".BAK");
248 strcpy(obuffer, aname);
249 strcat(obuffer, ".OLD");
250 now = FT_ApproxTime();
252 code = stat(aname, &tstat);
254 return; /* can't stat file */
256 code = stat(obuffer, &tstat); /* discover old file's time */
260 oldTime = tstat.st_mtime;
262 code = stat(bbuffer, &tstat); /* discover back file's time */
266 bakTime = tstat.st_mtime;
268 if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
269 /* no .OLD file, or .BAK is at least a week old */
270 code = renamefile(bbuffer, obuffer);
273 /* finally rename to .BAK extension */
274 renamefile(aname, bbuffer);
278 SBOZO_Install(struct rx_call *acall, char *aname, afs_int32 asize, afs_int32 mode, afs_int32 amtime)
285 struct _utimbuf utbuf;
287 struct timeval tvb[2];
289 char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
290 char caller[MAXKTCNAMELEN];
292 if (!afsconf_SuperUser(bozo_confdir, acall, caller))
294 #ifdef BOS_RESTRICTED_MODE
295 if (bozo_isrestricted)
299 /* construct local path from canonical (wire-format) path */
300 if (ConstructLocalBinPath(aname, &fpp)) {
303 strcpy(filepath, fpp);
307 bozo_Log("%s is executing Install '%s'\n", caller, filepath);
310 fpp = filepath + strlen(filepath);
311 strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */
312 fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
317 len = rx_Read(acall, tbuffer, sizeof(tbuffer));
324 break; /* no more input */
325 code = write(fd, tbuffer, len);
331 total += len; /* track total written for safety check at end */
334 if (asize != total) {
336 return 101; /* wrong size */
340 *fpp = '\0'; /* remove ".NEW" from end of filepath */
341 SaveOldFiles(filepath); /* don't care if it works, still install */
343 /* all done, rename to final name */
344 strcpy(tbuffer, filepath);
345 strcat(tbuffer, ".NEW");
346 code = (renamefile(tbuffer, filepath) ? errno : 0);
348 /* label file with same time for our sanity */
350 utbuf.actime = utbuf.modtime = amtime;
351 _utime(filepath, &utbuf);
353 tvb[0].tv_sec = tvb[1].tv_sec = amtime;
354 tvb[0].tv_usec = tvb[1].tv_usec = 0;
355 utimes(filepath, tvb);
356 #endif /* AFS_NT40_ENV */
359 chmod(filepath, mode);
362 osi_auditU(acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
369 SBOZO_SetCellName(struct rx_call *acall, char *aname)
371 struct afsconf_cell tcell;
372 register afs_int32 code;
373 char caller[MAXKTCNAMELEN];
374 char clones[MAXHOSTSPERCELL];
376 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
381 bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
384 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
389 /* Check that tcell has enough space for the new cellname. */
390 if (strlen(aname) > sizeof tcell.name - 1) {
392 ("ERROR: SetCellName: cell name '%s' exceeds %ld bytes (cell name not changed)\n",
393 aname, (long)(sizeof tcell.name - 1));
398 strcpy(tcell.name, aname);
400 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
404 osi_auditU(acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
409 SBOZO_GetCellName(struct rx_call *acall, char **aname)
411 register afs_int32 code;
412 char tname[MAXCELLCHARS];
414 code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
416 /* must set output parameters even if aborting */
417 *aname = (char *)malloc(1);
420 *aname = (char *)malloc(strlen(tname) + 1);
421 strcpy(*aname, tname);
428 SBOZO_GetCellHost(struct rx_call *acall, afs_uint32 awhich, char **aname)
430 register afs_int32 code;
431 struct afsconf_cell tcell;
433 char clones[MAXHOSTSPERCELL];
436 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
441 if (awhich >= tcell.numServers) {
446 tp = tcell.hostName[awhich];
447 *aname = (char *)malloc(strlen(tp) + 3);
448 if (clones[awhich]) {
457 *aname = (char *)malloc(1); /* return fake string */
465 SBOZO_DeleteCellHost(struct rx_call *acall, char *aname)
467 register afs_int32 code;
468 struct afsconf_cell tcell;
471 char caller[MAXKTCNAMELEN];
472 char clones[MAXHOSTSPERCELL];
474 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
479 bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
482 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
488 for (i = 0; i < tcell.numServers; i++) {
489 if (strcmp(tcell.hostName[i], aname) == 0) {
500 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
501 memset(tcell.hostName[which], 0, MAXHOSTCHARS);
503 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
507 osi_auditU(acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
512 SBOZO_AddCellHost(struct rx_call *acall, char *aname)
514 register afs_int32 code;
515 struct afsconf_cell tcell;
518 char caller[MAXKTCNAMELEN];
519 char clones[MAXHOSTSPERCELL];
523 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
528 bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
531 afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
538 *(n + strlen(n) - 1) = 0;
544 for (i = 0; i < tcell.numServers; i++) {
545 if (strcmp(tcell.hostName[i], n) == 0) {
551 which = tcell.numServers;
555 * Check that tcell has enough space for an additional host.
557 * We assume that tcell.hostAddr[] and tcell.hostName[] have the
558 * same number of entries.
560 if (tcell.numServers >
561 sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]) {
563 ("ERROR: AddCellHost: attempt to add more than %ld database servers (database server '%s' not added)\n",
564 (long)(sizeof tcell.hostAddr / sizeof tcell.hostAddr[0]),
570 /* Check that tcell has enough space for the new hostname. */
571 if (strlen(aname) > sizeof tcell.hostName[0] - 1) {
573 ("ERROR: AddCellHost: host name '%s' exceeds %ld bytes (not added)\n",
574 aname, (long)(sizeof tcell.hostName[0] - 1));
580 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
581 strcpy(tcell.hostName[which], n);
582 clones[which] = isClone;
584 afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
588 osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
593 SBOZO_ListKeys(struct rx_call *acall, afs_int32 an, afs_int32 *akvno,
594 struct bozo_key *akey, struct bozo_keyInfo *akeyinfo)
596 struct afsconf_keys tkeys;
597 register afs_int32 code;
600 char caller[MAXKTCNAMELEN];
601 rxkad_level enc_level = rxkad_clear;
603 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
608 bozo_Log("%s is executing ListKeys\n", caller);
610 code = afsconf_GetKeys(bozo_confdir, &tkeys);
614 if (tkeys.nkeys <= an) {
618 *akvno = tkeys.key[an].kvno;
619 memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
621 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
622 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
624 * only return actual keys in noauth or if this is an encrypted connection
627 if ((noauth) || (enc_level == rxkad_crypt)) {
628 memcpy(akey, tkeys.key[an].key, 8);
632 code = stat(AFSDIR_SERVER_KEY_FILEPATH, &tstat);
634 akeyinfo->mod_sec = tstat.st_mtime;
636 ka_KeyCheckSum(tkeys.key[an].key, &akeyinfo->keyCheckSum);
637 /* only errors is bad key parity */
641 osi_auditU(acall, BOS_UnAuthListKeysEvent, code, AUD_END);
642 osi_auditU(acall, BOS_ListKeysEvent, code, AUD_END);
647 SBOZO_AddKey(struct rx_call *acall, afs_int32 an, struct bozo_key *akey)
649 register afs_int32 code;
650 char caller[MAXKTCNAMELEN];
651 rxkad_level enc_level = rxkad_clear;
654 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
658 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
659 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
660 if ((!noauth) && (enc_level != rxkad_crypt)) {
665 bozo_Log("%s is executing AddKey\n", caller);
667 code = afsconf_AddKey(bozo_confdir, an, akey, 0);
668 if (code == AFSCONF_KEYINUSE)
669 code = BZKEYINUSE; /* Unique code for afs rpc calls */
671 osi_auditU(acall, BOS_AddKeyEvent, code, AUD_END);
676 SBOZO_SetNoAuthFlag(register struct rx_call *acall, afs_int32 aflag)
678 register afs_int32 code = 0;
679 char caller[MAXKTCNAMELEN];
681 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
686 bozo_Log("%s is executing Set No Authentication\n", caller);
688 afsconf_SetNoAuthFlag(bozo_confdir, aflag);
691 osi_auditU(acall, BOS_SetNoAuthEvent, code, AUD_LONG, aflag, AUD_END);
696 SBOZO_DeleteKey(struct rx_call *acall, afs_int32 an)
698 register afs_int32 code;
699 char caller[MAXKTCNAMELEN];
701 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
706 bozo_Log("%s is executing DeleteKey\n", caller);
708 code = afsconf_DeleteKey(bozo_confdir, an);
711 osi_auditU(acall, BOS_DeleteKeyEvent, code, AUD_END);
717 SBOZO_ListSUsers(struct rx_call *acall, afs_int32 an, register char **aname)
719 register afs_int32 code;
722 tp = *aname = (char *)malloc(256);
723 *tp = 0; /* in case getnthuser doesn't null-terminate the string */
724 code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
727 osi_auditU(acall, BOS_ListSUserEvent, code, AUD_END);
732 SBOZO_AddSUser(struct rx_call *acall, char *aname)
734 register afs_int32 code;
735 char caller[MAXKTCNAMELEN];
737 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
742 bozo_Log("%s is executing Add SuperUser '%s'\n", caller, aname);
744 code = afsconf_AddUser(bozo_confdir, aname);
747 osi_auditU(acall, BOS_AddSUserEvent, code, AUD_END);
752 SBOZO_DeleteSUser(struct rx_call *acall, char *aname)
754 register afs_int32 code;
755 char caller[MAXKTCNAMELEN];
757 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
763 bozo_Log("%s is executing Delete SuperUser '%s'\n", caller, aname);
765 code = afsconf_DeleteUser(bozo_confdir, aname);
768 osi_auditU(acall, BOS_DeleteSUserEvent, code, AUD_END);
773 SBOZO_CreateBnode(struct rx_call *acall, char *atype, char *ainstance,
774 char *ap1, char *ap2, char *ap3, char *ap4, char *ap5,
779 char caller[MAXKTCNAMELEN];
781 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
785 #ifdef BOS_RESTRICTED_MODE
786 if (bozo_isrestricted) {
787 if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp")
788 || strcmp(ap2, "now")
789 || strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
790 strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
798 bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,
801 bnode_SetStat(tb, BSTAT_NORMAL);
804 osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END);
809 SBOZO_WaitAll(register struct rx_call *acall)
811 register afs_int32 code;
812 char caller[MAXKTCNAMELEN];
814 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
820 bozo_Log("%s is executing Wait for All\n", caller);
822 code = bnode_WaitAll();
825 osi_auditU(acall, BOS_WaitAllEvent, code, AUD_END);
830 SBOZO_DeleteBnode(struct rx_call *acall, char *ainstance)
832 register afs_int32 code;
833 char caller[MAXKTCNAMELEN];
835 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
839 #ifdef BOS_RESTRICTED_MODE
840 if (bozo_isrestricted) {
846 bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
848 code = bnode_DeleteName(ainstance);
851 osi_auditU(acall, BOS_DeleteBnodeEvent, code, AUD_STR, ainstance,
857 swproc(register struct bnode *abnode, void *arock)
859 if (abnode->goal == BSTAT_NORMAL)
860 return 0; /* this one's not shutting down */
861 /* otherwise, we are shutting down */
863 bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
864 bnode_Release(abnode);
865 return 0; /* don't stop apply function early, no matter what */
869 stproc(struct bnode *abnode, void *arock)
871 if (abnode->fileGoal == BSTAT_SHUTDOWN)
872 return 0; /* don't do these guys */
875 bnode_SetStat(abnode, BSTAT_NORMAL);
876 bnode_Release(abnode);
881 sdproc(struct bnode *abnode, void *arock)
884 bnode_SetStat(abnode, BSTAT_SHUTDOWN);
885 bnode_Release(abnode);
889 /* shutdown and leave down */
891 SBOZO_ShutdownAll(struct rx_call *acall)
893 /* iterate over all bnodes, setting the status to temporarily disabled */
894 register afs_int32 code;
895 char caller[MAXKTCNAMELEN];
897 /* check for authorization */
898 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
903 bozo_Log("%s is executing ShutdownAll\n", caller);
905 code = bnode_ApplyInstance(sdproc, NULL);
908 osi_auditU(acall, BOS_ShutdownAllEvent, code, AUD_END);
912 /* shutdown and restart */
914 SBOZO_RestartAll(struct rx_call *acall)
916 register afs_int32 code;
917 char caller[MAXKTCNAMELEN];
919 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
924 bozo_Log("%s is executing RestartAll\n", caller);
926 /* start shutdown of all processes */
927 code = bnode_ApplyInstance(sdproc, NULL);
931 /* wait for all done */
932 code = bnode_ApplyInstance(swproc, NULL);
936 /* start them up again */
937 code = bnode_ApplyInstance(stproc, NULL);
940 osi_auditU(acall, BOS_RestartAllEvent, code, AUD_END);
945 SBOZO_ReBozo(struct rx_call *acall)
947 register afs_int32 code;
948 char caller[MAXKTCNAMELEN];
950 /* acall is null if called internally to restart bosserver */
951 if (acall && !afsconf_SuperUser(bozo_confdir, acall, caller)) {
956 bozo_Log("%s is executing ReBozo\n", caller);
958 /* start shutdown of all processes */
959 code = bnode_ApplyInstance(sdproc, NULL);
963 /* wait for all done */
964 code = bnode_ApplyInstance(swproc, NULL);
969 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
971 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
974 rx_EndCall(acall, 0); /* try to get it done */
976 bozo_ReBozo(); /* this reexecs us, and doesn't return, of course */
979 /* Differentiate between external and internal ReBozo; prevents AFS_Aud_NoCall event */
981 osi_auditU(acall, BOS_RebozoEvent, code, AUD_END);
983 osi_audit(BOS_RebozoIntEvent, code, AUD_END);
984 return code; /* should only get here in unusual circumstances */
987 /* make sure all are running */
989 SBOZO_StartupAll(struct rx_call *acall)
991 register afs_int32 code;
992 char caller[MAXKTCNAMELEN];
994 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
999 bozo_Log("%s is executing StartupAll\n", caller);
1000 code = bnode_ApplyInstance(stproc, NULL);
1003 osi_auditU(acall, BOS_StartupAllEvent, code, AUD_END);
1008 SBOZO_Restart(struct rx_call *acall, register char *ainstance)
1010 register struct bnode *tb;
1011 register afs_int32 code;
1012 char caller[MAXKTCNAMELEN];
1014 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1019 bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);
1021 tb = bnode_FindInstance(ainstance);
1027 /* setup return code */
1031 bnode_SetStat(tb, BSTAT_SHUTDOWN);
1032 code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN); /* this can fail */
1033 bnode_SetStat(tb, BSTAT_NORMAL);
1037 osi_auditU(acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
1041 /* set temp status */
1043 SBOZO_SetTStatus(struct rx_call *acall, char *ainstance, afs_int32 astatus)
1045 register struct bnode *tb;
1046 register afs_int32 code;
1047 char caller[MAXKTCNAMELEN];
1049 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1054 bozo_Log("%s is executing SetTempStatus '%s'\n", caller, ainstance);
1056 tb = bnode_FindInstance(ainstance);
1062 code = bnode_SetStat(tb, astatus);
1066 osi_auditU(acall, BOS_SetTempStatusEvent, code, AUD_STR, ainstance,
1072 SBOZO_SetStatus(struct rx_call *acall, char *ainstance, afs_int32 astatus)
1074 register struct bnode *tb;
1075 register afs_int32 code;
1076 char caller[MAXKTCNAMELEN];
1078 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1083 bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller,
1084 ainstance, astatus);
1086 tb = bnode_FindInstance(ainstance);
1092 bnode_SetFileGoal(tb, astatus);
1093 code = bnode_SetStat(tb, astatus);
1097 osi_auditU(acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
1102 SBOZO_GetStatus(struct rx_call *acall, char *ainstance, afs_int32 *astat,
1105 register struct bnode *tb;
1106 register afs_int32 code;
1108 tb = bnode_FindInstance(ainstance);
1115 code = bnode_GetStat(tb, astat);
1121 *astatDescr = (char *)malloc(BOZO_BSSIZE);
1122 code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
1125 (*astatDescr)[0] = 0; /* null string means no further info */
1129 *astatDescr = (char *)malloc(1);
1140 eifunc(struct bnode *abnode, void *param)
1142 struct eidata *arock = (struct eidata *)param;
1144 if (arock->counter-- == 0) {
1146 strcpy(arock->iname, abnode->name);
1155 ZapFile(const char *adir, const char *aname)
1158 if (snprintf(tbuffer, 256, "%s/%s", adir, aname)<256)
1159 return unlink(tbuffer);
1165 SBOZO_Prune(struct rx_call *acall, afs_int32 aflags)
1167 register afs_int32 code;
1169 register struct dirent *tde;
1171 char caller[MAXKTCNAMELEN];
1173 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1177 #ifdef BOS_RESTRICTED_MODE
1178 if (bozo_isrestricted) {
1184 bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
1186 /* first scan AFS binary directory */
1187 dirp = opendir(AFSDIR_SERVER_BIN_DIRPATH);
1189 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1190 i = strlen(tde->d_name);
1191 if (aflags & BOZO_PRUNEOLD) {
1192 if (i >= 4 && strncmp(tde->d_name + i - 4, ".OLD", 4) == 0)
1193 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1195 if (aflags & BOZO_PRUNEBAK) {
1196 if (i >= 4 && strncmp(tde->d_name + i - 4, ".BAK", 4) == 0)
1197 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1203 /* then scan AFS log directory */
1204 dirp = opendir(AFSDIR_SERVER_LOGS_DIRPATH);
1206 for (tde = readdir(dirp); tde; tde = readdir(dirp)) {
1207 if (aflags & BOZO_PRUNECORE) {
1208 if (strncmp(tde->d_name, AFSDIR_CORE_FILE, 4) == 0)
1209 ZapFile(AFSDIR_SERVER_LOGS_DIRPATH, tde->d_name);
1217 osi_auditU(acall, BOS_PruneLogs, code, AUD_END);
1222 SBOZO_EnumerateInstance(struct rx_call *acall, afs_int32 anum,
1225 struct eidata tdata;
1227 *ainstance = (char *)malloc(BOZO_BSSIZE);
1229 tdata.counter = anum;
1230 tdata.iname = *ainstance;
1231 bnode_ApplyInstance(eifunc, &tdata);
1232 if (tdata.counter >= 0)
1233 return BZDOM; /* anum > # of actual instances */
1238 struct bozo_bosEntryStats bozo_bosEntryStats[] = {
1239 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH */
1240 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH */
1241 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH */
1242 {NULL, 1, 1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH */
1243 {NULL, 1, 0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
1244 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_DB_DIRPATH */
1245 {NULL, 1, 1, 0700, 07}, /* AFSDIR_SERVER_LOCAL_DIRPATH */
1246 {NULL, 0, 1, 0600, 07}, /* AFSDIR_SERVER_KEY_FILEPATH */
1247 {NULL, 0, 1, 0600, 03}
1248 }; /* AFSDIR_SERVER_ULIST_FILEPATH */
1249 int bozo_nbosEntryStats =
1250 sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
1252 /* This function performs initialization of the bozo_bosEntrystats[]
1253 * array. This array contains the list of dirs that the bosserver
1254 * is interested in along with their recommended permissions
1255 * NOTE: This initialization is a bit ugly. This was caused because
1256 * the path names require procedural as opposed to static initialization.
1257 * The other fields in the struct are however, statically initialized.
1260 initBosEntryStats(void)
1262 bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
1263 bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
1264 bozo_bosEntryStats[2].path = AFSDIR_SERVER_BIN_DIRPATH;
1265 bozo_bosEntryStats[3].path = AFSDIR_SERVER_LOGS_DIRPATH;
1266 bozo_bosEntryStats[4].path = AFSDIR_SERVER_BACKUP_DIRPATH;
1267 bozo_bosEntryStats[5].path = AFSDIR_SERVER_DB_DIRPATH;
1268 bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
1269 bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
1270 bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
1275 /* StatEachEntry - If it's not there, it is okay. If anything else goes wrong
1276 * complain. Otherwise check permissions: shouldn't allow write or (usually)
1280 StatEachEntry(IN struct bozo_bosEntryStats *stats)
1283 if (stat(stats->path, &info)) {
1284 if (errno == ENOENT)
1285 return 1; /* no such entry: just ignore it */
1286 return 0; /* something else went wrong */
1289 if (((info.st_mode & S_IFDIR) != 0) != stats->dir)
1290 return 0; /* not expected type */
1291 if (stats->rootOwner && (info.st_uid != 0))
1292 return 0; /* not owned by root */
1293 rights = (info.st_mode & 0000777);
1294 if ((rights & stats->reqPerm) != stats->reqPerm)
1295 return 0; /* required permissions not present */
1296 if ((rights & stats->proPerm) != 0)
1297 return 0; /* prohibited permissions present */
1302 /* DirAccessOK - checks the mode bits on the AFS dir and decendents and
1303 * returns 0 if some are not OK and 1 otherwise. For efficiency, it doesn't do
1304 * this check more often than every 5 seconds. */
1310 /* underlying filesystem may not support directory protection */
1313 static afs_uint32 lastTime = 0;
1314 afs_uint32 now = FT_ApproxTime();
1315 static int lastResult = -1;
1319 if ((now - lastTime) < 5)
1324 for (i = 0; i < bozo_nbosEntryStats; i++) {
1325 struct bozo_bosEntryStats *e = &bozo_bosEntryStats[i];
1326 if (!StatEachEntry(e)) {
1327 bozo_Log("unhappy with %s which is a %s that should "
1328 "have at least rights %o, at most rights %o %s\n",
1329 e->path, e->dir ? "dir" : "file", e->reqPerm,
1330 (~e->proPerm & 0777),
1331 e->rootOwner ? ", owned by root" : "");
1337 if (result != lastResult) { /* log changes */
1338 bozo_Log("Server directory access is %sokay\n",
1339 (result ? "" : "not "));
1341 lastResult = result;
1343 #endif /* AFS_NT40_ENV */
1347 GetRequiredDirPerm(const char *path)
1350 for (i = 0; i < bozo_nbosEntryStats; i++)
1351 if (strcmp(path, bozo_bosEntryStats[i].path) == 0)
1352 return bozo_bosEntryStats[i].reqPerm;
1357 SBOZO_GetInstanceInfo(IN struct rx_call *acall,
1360 OUT struct bozo_status *astatus)
1362 register struct bnode *tb;
1364 tb = bnode_FindInstance(ainstance);
1365 *atype = (char *)malloc(BOZO_BSSIZE);
1370 strcpy(*atype, tb->type->name);
1372 (*atype)[0] = 0; /* null string */
1373 memset(astatus, 0, sizeof(struct bozo_status)); /* good defaults */
1374 astatus->goal = tb->goal;
1375 astatus->fileGoal = tb->fileGoal;
1376 astatus->procStartTime = tb->procStartTime;
1377 astatus->procStarts = tb->procStarts;
1378 astatus->lastAnyExit = tb->lastAnyExit;
1379 astatus->lastErrorExit = tb->lastErrorExit;
1380 astatus->errorCode = tb->errorCode;
1381 astatus->errorSignal = tb->errorSignal;
1382 if (tb->flags & BNODE_ERRORSTOP)
1383 astatus->flags |= BOZO_ERRORSTOP;
1384 if (bnode_HasCore(tb))
1385 astatus->flags |= BOZO_HASCORE;
1387 astatus->flags |= BOZO_BADDIRACCESS;
1392 SBOZO_GetInstanceParm(struct rx_call *acall,
1397 register struct bnode *tb;
1399 register afs_int32 code;
1401 tp = (char *)malloc(BOZO_BSSIZE);
1403 *tp = 0; /* null-terminate string in error case */
1404 tb = bnode_FindInstance(ainstance);
1410 memcpy(tp, tb->notifier, strlen(tb->notifier) + 1);
1413 code = BZNOENT; /* XXXXX */
1415 code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
1418 /* Not Currently Audited */
1423 SBOZO_GetLog(register struct rx_call *acall, char *aname)
1425 register afs_int32 code;
1430 char caller[MAXKTCNAMELEN];
1432 /* Check access since 'aname' could specify a file outside of the
1433 * AFS log directory (which is bosserver's working directory).
1435 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1439 #ifdef BOS_RESTRICTED_MODE
1440 if (bozo_isrestricted && strchr(aname, '/')
1441 && strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
1447 /* construct local path from canonical (wire-format) path */
1448 if (ConstructLocalLogPath(aname, &logpath)) {
1452 bozo_Log("%s is executing GetLog '%s'\n", caller, logpath);
1453 tfile = fopen(logpath, "r");
1463 continue; /* our termination condition on other end */
1467 if (rx_Write(acall, &buffer, 1) != 1) {
1474 /* all done, cleanup and return */
1477 /* write out the end delimeter */
1479 if (rx_Write(acall, &buffer, 1) != 1)
1484 osi_auditU(acall, BOS_GetLogsEvent, code, AUD_END);
1489 SBOZO_GetInstanceStrings(struct rx_call *acall, char *abnodeName,
1490 char **as1, char **as2, char **as3, char **as4)
1492 register struct bnode *tb;
1494 *as2 = (char *)malloc(1);
1496 *as3 = (char *)malloc(1);
1498 *as4 = (char *)malloc(1);
1500 tb = bnode_FindInstance(abnodeName);
1504 /* now, return the appropriate error string, if any */
1505 if (tb->lastErrorName) {
1506 *as1 = (char *)malloc(strlen(tb->lastErrorName) + 1);
1507 strcpy(*as1, tb->lastErrorName);
1509 *as1 = (char *)malloc(1);
1515 *as1 = (char *)malloc(1);
1520 #ifdef BOS_RESTRICTED_MODE
1522 SBOZO_GetRestrictedMode(struct rx_call *acall, afs_int32 *arestmode)
1524 *arestmode = bozo_isrestricted;
1529 SBOZO_SetRestrictedMode(struct rx_call *acall, afs_int32 arestmode)
1532 char caller[MAXKTCNAMELEN];
1534 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1537 if (bozo_isrestricted) {
1540 if (arestmode != 0 && arestmode != 1) {
1543 bozo_isrestricted = arestmode;
1544 code = WriteBozoFile(0);
1550 SBOZO_GetRestrictedMode(struct rx_call *acall, afs_int32 *arestmode)
1552 return RXGEN_OPCODE;
1556 SBOZO_SetRestrictedMode(struct rx_call *acall, afs_int32 arestmode)
1558 return RXGEN_OPCODE;
1563 bozo_ShutdownAndExit(void *param)
1565 int asignal = (intptr_t)param;
1569 ("Shutdown of BOS server and processes in response to signal %d\n",
1572 /* start shutdown of all processes */
1573 if ((code = bnode_ApplyInstance(sdproc, NULL)) == 0) {
1574 /* wait for shutdown to complete */
1575 code = bnode_ApplyInstance(swproc, NULL);
1579 bozo_Log("Shutdown incomplete (code = %d); manual cleanup required\n",