2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
16 #include <sys/types.h>
20 #include <sys/utime.h>
23 #include <netinet/in.h>
24 #endif /* AFS_NT40_ENV */
29 #include <afs/cellconfig.h>
35 #include <afs/afsutil.h>
36 #include <afs/fileutil.h>
37 #include <afs/ktime.h>
38 #include <afs/audit.h>
44 extern struct ktime bozo_nextRestartKT, bozo_nextDayKT;
46 extern struct afsconf_dir *bozo_confdir;
47 extern struct rx_securityClass *bozo_rxsc[2];
48 extern int bozo_newKTs;
50 #ifdef BOS_RESTRICTED_MODE
51 extern int bozo_isrestricted;
54 SBOZO_GetRestartTime(acall, atype, aktime)
55 struct rx_call *acall;
57 struct bozo_netKTime *aktime;
59 register afs_int32 code;
61 code = 0; /* assume success */
64 memcpy(aktime, &bozo_nextRestartKT, sizeof(struct ktime));
68 memcpy(aktime, &bozo_nextDayKT, sizeof(struct ktime));
79 SBOZO_SetRestartTime(acall, atype, aktime)
80 struct rx_call *acall;
82 struct bozo_netKTime *aktime;
84 register afs_int32 code;
85 char caller[MAXKTCNAMELEN];
87 /* check for proper permissions */
88 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
92 if (DoLogging) bozo_Log("%s is executing SetRestartTime\n", caller);
94 code = 0; /* assume success */
97 memcpy(&bozo_nextRestartKT, aktime, sizeof(struct ktime));
101 memcpy(&bozo_nextDayKT, aktime, sizeof(struct ktime));
110 /* try to update the bozo init file */
111 code = WriteBozoFile(0);
116 osi_auditU (acall, BOS_SetRestartEvent, code, AUD_END);
120 SBOZO_Exec(acall, acmd)
121 struct rx_call *acall;
124 char caller[MAXKTCNAMELEN];
127 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
131 #ifdef BOS_RESTRICTED_MODE
132 if (bozo_isrestricted) {
137 if (DoLogging) bozo_Log("%s is executing the shell command '%s'\n", caller, acmd);
139 /* should copy output to acall, but don't yet cause its hard */
140 /* hard... NOT! Nnow _at least_ return the exit status */
142 osi_auditU (acall, BOS_ExecEvent, code, AUD_STR, acmd, AUD_END);
148 SBOZO_GetDates(acall, aname, atime, abakTime, aoldTime)
149 struct rx_call *acall;
151 afs_int32 *atime, *abakTime, *aoldTime; {
154 char tbuffer[AFSDIR_PATH_MAX];
156 *atime = *abakTime = *aoldTime = 0;
158 /* construct local path from canonical (wire-format) path */
159 if (ConstructLocalBinPath(aname, &strp)) {
162 strcpy(tbuffer, strp);
165 strp = tbuffer + strlen(tbuffer);
167 if (!stat(tbuffer, &tstat)) {
168 *atime = tstat.st_mtime;
171 strcpy(strp, ".BAK");
172 if (!stat(tbuffer, &tstat)) {
173 *abakTime = tstat.st_mtime;
176 strcpy(strp, ".OLD");
177 if (!stat(tbuffer, &tstat)) {
178 *aoldTime = tstat.st_mtime;
183 SBOZO_UnInstall(acall, aname)
184 struct rx_call *acall;
185 register char *aname; {
187 char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX];
189 char caller[MAXKTCNAMELEN];
192 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
194 osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
197 #ifdef BOS_RESTRICTED_MODE
198 if (bozo_isrestricted) {
200 osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
205 /* construct local path from canonical (wire-format) path */
206 if (ConstructLocalBinPath(aname, &filepath)) {
210 if (DoLogging) bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
212 strcpy(fpBak, filepath);
213 strcat(fpBak, ".BAK");
214 strcpy(fpOld, filepath);
215 strcat(fpOld, ".OLD");
217 code = renamefile(fpBak, filepath);
219 /* can't find .BAK, try .OLD */
220 code = renamefile(fpOld, filepath);
221 if (code && errno == ENOENT) /* If doesn't exist don't fail */
224 /* now rename .OLD to .BAK */
225 if (stat(fpOld, &tstat) == 0)
226 code = renamefile(fpOld, fpBak);
231 osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
237 #define BOZO_OLDTIME (7*24*3600) /* 7 days old */
238 static void 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);
253 if (code < 0) return; /* can't stat file */
255 code = stat(obuffer, &tstat); /* discover old file's time */
256 if (code) oldTime = 0;
257 else oldTime = tstat.st_mtime;
259 code = stat(bbuffer, &tstat); /* discover back file's time */
260 if (code) bakTime = 0;
261 else bakTime = tstat.st_mtime;
263 if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
264 /* no .OLD file, or .BAK is at least a week old */
265 code = renamefile(bbuffer, obuffer);
268 /* finally rename to .BAK extension */
269 renamefile(aname, bbuffer);
272 SBOZO_Install(acall, aname, asize, mode, amtime)
273 struct rx_call *acall;
283 struct _utimbuf utbuf;
285 struct timeval tvb[2];
287 char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
288 char caller[MAXKTCNAMELEN];
290 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) return BZACCESS;
291 #ifdef BOS_RESTRICTED_MODE
292 if (bozo_isrestricted) return BZACCESS;
295 /* construct local path from canonical (wire-format) path */
296 if (ConstructLocalBinPath(aname, &fpp)) {
299 strcpy(filepath, fpp);
302 if (DoLogging) bozo_Log("%s is executing Install '%s'\n", caller, filepath);
305 fpp = filepath + strlen(filepath);
306 strcpy(fpp, ".NEW"); /* append ".NEW" to end of filepath */
307 fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
308 if (fd < 0) return errno;
311 len = rx_Read(acall, tbuffer, sizeof(tbuffer));
317 if (len == 0) break; /* no more input */
318 code = write(fd, tbuffer, len);
324 total += len; /* track total written for safety check at end */
327 if (asize != total) {
329 return 101; /* wrong size */
333 *fpp = '\0'; /* remove ".NEW" from end of filepath */
334 SaveOldFiles(filepath); /* don't care if it works, still install */
336 /* all done, rename to final name */
337 strcpy(tbuffer, filepath);
338 strcat(tbuffer, ".NEW");
339 code = (renamefile(tbuffer, filepath) ? errno : 0);
341 /* label file with same time for our sanity */
343 utbuf.actime = utbuf.modtime = amtime;
344 _utime(filepath, &utbuf);
346 tvb[0].tv_sec = tvb[1].tv_sec = amtime;
347 tvb[0].tv_usec = tvb[1].tv_usec = 0;
348 utimes(filepath, tvb);
349 #endif /* AFS_NT40_ENV */
352 chmod(filepath, mode);
355 osi_auditU (acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
361 SBOZO_SetCellName(acall, aname)
362 struct rx_call *acall;
364 struct afsconf_cell tcell;
365 register afs_int32 code;
366 char caller[MAXKTCNAMELEN];
367 char clones[MAXHOSTSPERCELL];
369 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
373 if (DoLogging) bozo_Log("%s is executing SetCellName '%s'\n", caller, aname);
375 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
379 /* Check that tcell has enough space for the new cellname. */
380 if (strlen(aname) > sizeof tcell.name - 1) {
381 bozo_Log("ERROR: SetCellName: cell name '%s' exceeds %ld bytes (cell name not changed)\n",
382 aname, (long)(sizeof tcell.name - 1));
387 strcpy(tcell.name, aname);
388 code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
391 osi_auditU (acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
395 SBOZO_GetCellName(acall, aname)
396 struct rx_call *acall;
398 register afs_int32 code;
399 char tname[MAXCELLCHARS];
401 code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
403 /* must set output parameters even if aborting */
404 *aname = (char *) malloc(1);
408 *aname = (char *) malloc(strlen(tname)+1);
409 strcpy(*aname, tname);
415 SBOZO_GetCellHost(acall, awhich, aname)
416 struct rx_call *acall;
419 register afs_int32 code;
420 struct afsconf_cell tcell;
422 char clones[MAXHOSTSPERCELL];
424 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
427 if (awhich >= tcell.numServers) {
432 tp = tcell.hostName[awhich];
433 *aname = (char *) malloc(strlen(tp)+3);
434 if (clones[awhich]) {
443 *aname = (char *) malloc(1); /* return fake string */
450 SBOZO_DeleteCellHost(acall, aname)
451 struct rx_call *acall;
453 register afs_int32 code;
454 struct afsconf_cell tcell;
457 char caller[MAXKTCNAMELEN];
458 char clones[MAXHOSTSPERCELL];
460 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
465 bozo_Log("%s is executing DeleteCellHost '%s'\n", caller, aname);
467 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
472 for(i=0;i<tcell.numServers;i++) {
473 if (strcmp(tcell.hostName[i], aname) == 0) {
484 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
485 memset(tcell.hostName[which], 0, MAXHOSTCHARS);
486 code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
489 osi_auditU( acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
493 SBOZO_AddCellHost(acall, aname)
494 struct rx_call *acall;
496 register afs_int32 code;
497 struct afsconf_cell tcell;
500 char caller[MAXKTCNAMELEN];
501 char clones[MAXHOSTSPERCELL];
505 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
510 bozo_Log("%s is executing AddCellHost '%s'\n", caller, aname);
512 code = afsconf_GetExtendedCellInfo(bozo_confdir, (char *) 0, (char *) 0, &tcell, &clones);
518 *(n + strlen(n) -1) = 0;
524 for(i=0;i<tcell.numServers;i++) {
525 if (strcmp(tcell.hostName[i], n) == 0) {
531 which = tcell.numServers;
535 * Check that tcell has enough space for an additional host.
537 * We assume that tcell.hostAddr[] and tcell.hostName[] have the
538 * same number of entries.
540 if (tcell.numServers > sizeof tcell.hostAddr/sizeof tcell.hostAddr[0]) {
541 bozo_Log("ERROR: AddCellHost: attempt to add more than %ld database servers (database server '%s' not added)\n",
542 (long)(sizeof tcell.hostAddr/sizeof tcell.hostAddr[0]), aname);
547 /* Check that tcell has enough space for the new hostname. */
548 if (strlen(aname) > sizeof tcell.hostName[0] - 1) {
549 bozo_Log("ERROR: AddCellHost: host name '%s' exceeds %ld bytes (not added)\n",
550 aname, (long)(sizeof tcell.hostName[0] - 1));
556 memset(&tcell.hostAddr[which], 0, sizeof(struct sockaddr_in));
557 strcpy(tcell.hostName[which], n);
558 clones[which] = isClone;
559 code = afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH, &tcell, &clones);
562 osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
566 SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
567 struct rx_call *acall;
570 struct bozo_keyInfo *akeyinfo;
571 struct bozo_key *akey;
573 struct afsconf_keys tkeys;
574 register afs_int32 code;
577 char caller[MAXKTCNAMELEN];
578 rxkad_level enc_level = rxkad_clear;
580 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
584 if (DoLogging) bozo_Log("%s is executing ListKeys\n", caller);
586 code = afsconf_GetKeys(bozo_confdir, &tkeys);
590 if (tkeys.nkeys <= an) {
594 *akvno = tkeys.key[an].kvno;
595 memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
597 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
598 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
600 * only return actual keys in noauth or if this is an encrypted connection
603 if ((noauth) || (enc_level == rxkad_crypt)) {
604 memcpy(akey, tkeys.key[an].key, 8);
606 else memset(akey, 0, 8);
608 code = stat(AFSDIR_SERVER_KEY_FILEPATH, &tstat);
610 akeyinfo->mod_sec = tstat.st_mtime;
612 ka_KeyCheckSum (tkeys.key[an].key, &akeyinfo->keyCheckSum);
613 /* only errors is bad key parity */
617 osi_auditU(acall, BOS_UnAuthListKeysEvent, code, AUD_END);
618 osi_auditU(acall, BOS_ListKeysEvent, code, AUD_END);
622 SBOZO_AddKey(acall, an, akey)
623 struct rx_call *acall;
625 struct bozo_key *akey; {
626 register afs_int32 code;
627 char caller[MAXKTCNAMELEN];
628 rxkad_level enc_level = rxkad_clear;
631 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
635 noauth = afsconf_GetNoAuthFlag(bozo_confdir);
636 rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
637 if ((!noauth) && (enc_level != rxkad_crypt)) {
641 if (DoLogging) bozo_Log("%s is executing AddKey\n", caller);
643 code = afsconf_AddKey(bozo_confdir, an, akey, 0);
644 if (code == AFSCONF_KEYINUSE)
645 code = BZKEYINUSE; /* Unique code for afs rpc calls */
647 osi_auditU(acall, BOS_AddKeyEvent, code, AUD_END);
651 SBOZO_SetNoAuthFlag(acall, aflag)
652 register struct rx_call *acall;
654 register afs_int32 code = 0;
655 char caller[MAXKTCNAMELEN];
657 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
661 if (DoLogging) bozo_Log("%s is executing Set No Authentication\n", caller);
663 afsconf_SetNoAuthFlag(bozo_confdir, aflag);
666 osi_auditU(acall, BOS_SetNoAuthEvent, code, AUD_LONG, aflag, AUD_END);
670 SBOZO_DeleteKey(acall, an)
671 struct rx_call *acall;
673 register afs_int32 code;
674 char caller[MAXKTCNAMELEN];
676 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
680 if (DoLogging) bozo_Log("%s is executing DeleteKey\n", caller);
682 code = afsconf_DeleteKey(bozo_confdir, an);
685 osi_auditU(acall, BOS_DeleteKeyEvent, code, AUD_END);
690 SBOZO_ListSUsers(acall, an, aname)
691 struct rx_call *acall;
693 register char **aname; {
694 register afs_int32 code;
697 tp = *aname = (char *) malloc(256);
698 *tp = 0; /* in case getnthuser doesn't null-terminate the string */
699 code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
702 osi_auditU(acall, BOS_ListSUserEvent, code, AUD_END);
706 SBOZO_AddSUser(acall, aname)
707 struct rx_call *acall;
709 register afs_int32 code;
710 char caller[MAXKTCNAMELEN];
712 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
717 bozo_Log("%s is executing Add SuperUser '%s'\n", caller, aname);
719 code = afsconf_AddUser(bozo_confdir, aname);
722 osi_auditU(acall, BOS_AddSUserEvent, code, AUD_END);
726 SBOZO_DeleteSUser(acall, aname)
727 struct rx_call *acall;
729 register afs_int32 code;
730 char caller[MAXKTCNAMELEN];
732 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
738 bozo_Log("%s is executing Delete SuperUser '%s'\n", caller, aname);
740 code = afsconf_DeleteUser(bozo_confdir, aname);
743 osi_auditU(acall, BOS_DeleteSUserEvent, code, AUD_END);
747 SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
748 struct rx_call *acall;
751 char *ap1, *ap2, *ap3, *ap4, *ap5;
755 char caller[MAXKTCNAMELEN];
757 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
761 #ifdef BOS_RESTRICTED_MODE
762 if (bozo_isrestricted) {
763 if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp") ||
764 strcmp(ap2, "now") ||
765 strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
766 strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
773 code = bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,BSTAT_NORMAL);
775 bnode_SetStat(tb, BSTAT_NORMAL);
778 osi_auditU(acall, BOS_CreateBnodeEvent, code, AUD_END);
783 register struct rx_call *acall; {
784 register afs_int32 code;
785 char caller[MAXKTCNAMELEN];
787 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
792 if (DoLogging) bozo_Log("%s is executing Wait for All\n", caller);
794 code = bnode_WaitAll();
797 osi_auditU(acall, BOS_WaitAllEvent, code, AUD_END);
801 SBOZO_DeleteBnode(acall, ainstance)
802 struct rx_call *acall;
804 register afs_int32 code;
805 char caller[MAXKTCNAMELEN];
807 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
811 #ifdef BOS_RESTRICTED_MODE
812 if (bozo_isrestricted) {
817 if (DoLogging) bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
819 code = bnode_DeleteName(ainstance);
822 osi_auditU(acall, BOS_DeleteBnodeEvent, code, AUD_STR, ainstance, AUD_END);
826 static swproc(abnode, arock)
827 register struct bnode *abnode;
829 if (abnode->goal == BSTAT_NORMAL) return 0; /* this one's not shutting down */
830 /* otherwise, we are shutting down */
832 bnode_WaitStatus(abnode, BSTAT_SHUTDOWN);
833 bnode_Release(abnode);
834 return 0; /* don't stop apply function early, no matter what */
837 static stproc(abnode, arock)
838 struct bnode *abnode;
840 if (abnode->fileGoal == BSTAT_SHUTDOWN) return 0; /* don't do these guys */
843 bnode_SetStat(abnode, BSTAT_NORMAL);
844 bnode_Release(abnode);
848 static sdproc(abnode, arock)
849 struct bnode *abnode;
852 bnode_SetStat(abnode, BSTAT_SHUTDOWN);
853 bnode_Release(abnode);
857 /* shutdown and leave down */
858 SBOZO_ShutdownAll(acall)
859 struct rx_call *acall; {
860 /* iterate over all bnodes, setting the status to temporarily disabled */
861 register afs_int32 code;
862 char caller[MAXKTCNAMELEN];
864 /* check for authorization */
865 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
869 if (DoLogging) bozo_Log("%s is executing ShutdownAll\n", caller);
871 code = bnode_ApplyInstance(sdproc, (char *) 0);
874 osi_auditU (acall, BOS_ShutdownAllEvent, code, AUD_END);
878 /* shutdown and restart */
879 SBOZO_RestartAll(acall)
880 struct rx_call *acall; {
881 register afs_int32 code;
882 char caller[MAXKTCNAMELEN];
884 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
888 if (DoLogging) bozo_Log("%s is executing RestartAll\n", caller);
890 /* start shutdown of all processes */
891 code = bnode_ApplyInstance(sdproc, (char *) 0);
894 /* wait for all done */
895 code = bnode_ApplyInstance(swproc, (char *) 0);
898 /* start them up again */
899 code = bnode_ApplyInstance(stproc, (char *) 0);
902 osi_auditU (acall, BOS_RestartAllEvent, code, AUD_END);
907 register struct rx_call *acall; {
908 register afs_int32 code;
909 char caller[MAXKTCNAMELEN];
911 /* acall is null if called internally to restart bosserver */
912 if (acall && !afsconf_SuperUser(bozo_confdir, acall, caller)) {
916 if (DoLogging) bozo_Log("%s is executing ReBozo\n", caller);
918 /* start shutdown of all processes */
919 code = bnode_ApplyInstance(sdproc, (char *) 0);
922 /* wait for all done */
923 code = bnode_ApplyInstance(swproc, (char *) 0);
926 if (acall) osi_auditU (acall, BOS_RebozoEvent, code, AUD_END);
927 else osi_audit (BOS_RebozoIntEvent, code, AUD_END);
929 if (acall) rx_EndCall(acall, 0); /* try to get it done */
931 bozo_ReBozo(); /* this reexecs us, and doesn't return, of course */
934 /* Differentiate between external and internal ReBozo; prevents AFS_Aud_NoCall event */
935 if (acall) osi_auditU (acall, BOS_RebozoEvent, code, AUD_END);
936 else osi_audit (BOS_RebozoIntEvent, code, AUD_END);
937 return code; /* should only get here in unusual circumstances */
940 /* make sure all are running */
941 SBOZO_StartupAll(acall)
942 struct rx_call *acall; {
943 register afs_int32 code;
944 char caller[MAXKTCNAMELEN];
946 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
950 if (DoLogging) bozo_Log("%s is executing StartupAll\n", caller);
951 code = bnode_ApplyInstance(stproc, (char *) 0);
954 osi_auditU (acall, BOS_StartupAllEvent, code, AUD_END);
958 SBOZO_Restart(acall, ainstance)
959 struct rx_call *acall;
960 register char *ainstance; {
961 register struct bnode *tb;
962 register afs_int32 code;
963 char caller[MAXKTCNAMELEN];
965 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
969 if (DoLogging) bozo_Log("%s is executing Restart '%s'\n", caller, ainstance);
971 tb = bnode_FindInstance(ainstance);
977 /* setup return code */
981 bnode_SetStat(tb, BSTAT_SHUTDOWN);
982 code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN); /* this can fail */
983 bnode_SetStat(tb, BSTAT_NORMAL);
987 osi_auditU (acall, BOS_RestartEvent, code, AUD_STR, ainstance, AUD_END);
991 /* set temp status */
992 SBOZO_SetTStatus(acall, ainstance, astatus)
993 struct rx_call *acall;
996 register struct bnode *tb;
997 register afs_int32 code;
998 char caller[MAXKTCNAMELEN];
1000 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1004 if (DoLogging) bozo_Log("%s is executing SetTempStatus '%s'\n", caller, ainstance);
1006 tb = bnode_FindInstance(ainstance);
1012 code = bnode_SetStat(tb, astatus);
1016 osi_auditU (acall, BOS_SetTempStatusEvent, code, AUD_STR, ainstance, AUD_END);
1020 SBOZO_SetStatus(acall, ainstance, astatus)
1021 struct rx_call *acall;
1023 afs_int32 astatus; {
1024 register struct bnode *tb;
1025 register afs_int32 code;
1026 char caller[MAXKTCNAMELEN];
1028 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1032 if (DoLogging) bozo_Log("%s is executing SetStatus '%s' (status = %d)\n", caller, ainstance, astatus);
1034 tb = bnode_FindInstance(ainstance);
1040 bnode_SetFileGoal(tb, astatus);
1041 code = bnode_SetStat(tb, astatus);
1045 osi_auditU (acall, BOS_SetStatusEvent, code, AUD_STR, ainstance, AUD_END);
1049 SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
1050 struct rx_call *acall;
1053 char **astatDescr; {
1054 register struct bnode *tb;
1055 register afs_int32 code;
1057 tb = bnode_FindInstance(ainstance);
1064 code = bnode_GetStat(tb, astat);
1070 *astatDescr = (char *) malloc(BOZO_BSSIZE);
1071 code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
1073 if (code) (*astatDescr)[0] = 0; /* null string means no further info */
1077 *astatDescr = (char *) malloc(1);
1087 static eifunc(abnode, arock)
1088 struct bnode *abnode;
1089 struct eidata *arock; {
1090 if (arock->counter-- == 0) {
1092 strcpy(arock->iname, abnode->name);
1101 static ZapFile(adir, aname)
1102 register char *adir;
1103 register char *aname; {
1105 strcpy(tbuffer, adir);
1106 strcat(tbuffer, "/");
1107 strcat(tbuffer, aname);
1108 return unlink(tbuffer);
1111 SBOZO_Prune(acall, aflags)
1112 struct rx_call *acall;
1114 register afs_int32 code;
1116 register struct dirent *tde;
1118 char caller[MAXKTCNAMELEN];
1120 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1124 #ifdef BOS_RESTRICTED_MODE
1125 if (bozo_isrestricted) {
1130 if (DoLogging) bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
1132 /* first scan AFS binary directory */
1133 dirp = opendir(AFSDIR_SERVER_BIN_DIRPATH);
1135 for(tde=readdir(dirp);tde;tde=readdir(dirp)) {
1136 i = strlen(tde->d_name);
1137 if (aflags & BOZO_PRUNEOLD) {
1138 if(i >= 4 && strncmp(tde->d_name+i-4, ".OLD", 4)==0)
1139 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1141 if (aflags & BOZO_PRUNEBAK) {
1142 if(i >= 4 && strncmp(tde->d_name+i-4, ".BAK", 4)==0)
1143 ZapFile(AFSDIR_SERVER_BIN_DIRPATH, tde->d_name);
1149 /* then scan AFS log directory */
1150 dirp = opendir(AFSDIR_SERVER_LOGS_DIRPATH);
1152 for(tde=readdir(dirp);tde;tde=readdir(dirp)) {
1153 if (aflags & BOZO_PRUNECORE) {
1154 if(strncmp(tde->d_name, AFSDIR_CORE_FILE, 4)==0)
1155 ZapFile(AFSDIR_SERVER_LOGS_DIRPATH, tde->d_name);
1163 osi_auditU ( acall, BOS_PruneLogs, code, AUD_END);
1167 SBOZO_EnumerateInstance(acall, anum, ainstance)
1168 struct rx_call *acall;
1171 struct eidata tdata;
1173 *ainstance = (char *) malloc(BOZO_BSSIZE);
1175 tdata.counter = anum;
1176 tdata.iname = *ainstance;
1177 bnode_ApplyInstance(eifunc, &tdata);
1178 if (tdata.counter >= 0) return BZDOM; /* anum > # of actual instances */
1182 struct bozo_bosEntryStats bozo_bosEntryStats[] = {
1183 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_AFS_DIRPATH */
1184 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_ETC_DIRPATH */
1185 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_BIN_DIRPATH */
1186 {NULL, 1,1, 0755, 02}, /* AFSDIR_SERVER_LOGS_DIRPATH */
1187 {NULL, 1,0, 0700, 07}, /* AFSDIR_SERVER_BACKUP_DIRPATH */
1188 {NULL, 1,1, 0700, 07}, /* AFSDIR_SERVER_DB_DIRPATH */
1189 {NULL, 1,1, 0700, 07}, /* AFSDIR_SERVER_LOCAL_DIRPATH */
1190 {NULL, 0,1, 0600, 07}, /* AFSDIR_SERVER_KEY_FILEPATH */
1191 {NULL, 0,1, 0600, 03}};/* AFSDIR_SERVER_ULIST_FILEPATH */
1192 int bozo_nbosEntryStats =
1193 sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
1195 /* This function performs initialization of the bozo_bosEntrystats[]
1196 * array. This array contains the list of dirs that the bosserver
1197 * is interested in along with their recommended permissions
1198 * NOTE: This initialization is a bit ugly. This was caused because
1199 * the path names require procedural as opposed to static initialization.
1200 * The other fields in the struct are however, statically initialized.
1202 int initBosEntryStats()
1204 bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
1205 bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
1206 bozo_bosEntryStats[2].path = AFSDIR_SERVER_BIN_DIRPATH;
1207 bozo_bosEntryStats[3].path = AFSDIR_SERVER_LOGS_DIRPATH;
1208 bozo_bosEntryStats[4].path = AFSDIR_SERVER_BACKUP_DIRPATH;
1209 bozo_bosEntryStats[5].path = AFSDIR_SERVER_DB_DIRPATH;
1210 bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
1211 bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
1212 bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
1216 /* StatEachEntry - If it's not there, it is okay. If anything else goes wrong
1217 * complain. Otherwise check permissions: shouldn't allow write or (usually)
1220 static int StatEachEntry (stats)
1221 IN struct bozo_bosEntryStats *stats;
1224 if (stat (stats->path, &info)) {
1225 if (errno == ENOENT) return 1; /* no such entry: just ignore it */
1226 return 0; /* something else went wrong */
1229 if (((info.st_mode & S_IFDIR) != 0) != stats->dir)
1230 return 0; /* not expected type */
1231 if (stats->rootOwner && (info.st_uid != 0))
1232 return 0; /* not owned by root */
1233 rights = (info.st_mode & 0000777);
1234 if ((rights & stats->reqPerm) != stats->reqPerm)
1235 return 0; /* required permissions not present */
1236 if ((rights & stats->proPerm) != 0)
1237 return 0; /* prohibited permissions present */
1242 /* DirAccessOK - checks the mode bits on the AFS dir and decendents and
1243 * returns 0 if some are not OK and 1 otherwise. For efficiency, it doesn't do
1244 * this check more often than every 5 seconds. */
1249 /* underlying filesystem may not support directory protection */
1252 static afs_uint32 lastTime = 0;
1253 afs_uint32 now = FT_ApproxTime();
1254 static int lastResult = -1;
1258 if ((now-lastTime) < 5) return lastResult;
1262 for (i=0; i<bozo_nbosEntryStats; i++) {
1263 struct bozo_bosEntryStats *e = &bozo_bosEntryStats[i];
1264 if (!StatEachEntry (e)) {
1270 if (result != lastResult) { /* log changes */
1271 bozo_Log ("Server directory access is %sokay\n",
1272 (result ? "" : "not "));
1274 lastResult = result;
1276 #endif /* AFS_NT40_ENV */
1279 int GetRequiredDirPerm (path)
1283 for (i=0; i<bozo_nbosEntryStats; i++)
1284 if (strcmp (path, bozo_bosEntryStats[i].path) == 0)
1285 return bozo_bosEntryStats[i].reqPerm;
1289 SBOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
1290 IN struct rx_call *acall;
1293 OUT struct bozo_status *astatus;
1295 register struct bnode *tb;
1297 tb = bnode_FindInstance(ainstance);
1298 *atype = (char *) malloc(BOZO_BSSIZE);
1300 if (!tb) return BZNOENT;
1302 strcpy(*atype, tb->type->name);
1304 (*atype)[0] = 0; /* null string */
1305 memset(astatus, 0, sizeof(struct bozo_status)); /* good defaults */
1306 astatus->goal = tb->goal;
1307 astatus->fileGoal = tb->fileGoal;
1308 astatus->procStartTime = tb->procStartTime;
1309 astatus->procStarts = tb->procStarts;
1310 astatus->lastAnyExit = tb->lastAnyExit;
1311 astatus->lastErrorExit = tb->lastErrorExit;
1312 astatus->errorCode = tb->errorCode;
1313 astatus->errorSignal = tb->errorSignal;
1314 if (tb->flags & BNODE_ERRORSTOP)
1315 astatus->flags |= BOZO_ERRORSTOP;
1316 if (bnode_HasCore(tb))
1317 astatus->flags |= BOZO_HASCORE;
1319 astatus->flags |= BOZO_BADDIRACCESS;
1323 SBOZO_GetInstanceParm(acall, ainstance, anum, aparm)
1324 struct rx_call *acall;
1328 register struct bnode *tb;
1330 register afs_int32 code;
1332 tp = (char *) malloc(BOZO_BSSIZE);
1334 *tp = 0; /* null-terminate string in error case */
1335 tb = bnode_FindInstance(ainstance);
1336 if (!tb) return BZNOENT;
1340 memcpy(tp, tb->notifier, strlen(tb->notifier)+1);
1343 code = BZNOENT; /* XXXXX */
1345 code = bnode_GetParm(tb, anum, tp, BOZO_BSSIZE);
1348 /* Not Currently Audited */
1352 SBOZO_GetLog(acall, aname)
1353 register struct rx_call *acall;
1355 register afs_int32 code;
1360 char caller[MAXKTCNAMELEN];
1362 /* Check access since 'aname' could specify a file outside of the
1363 * AFS log directory (which is bosserver's working directory).
1365 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1369 #ifdef BOS_RESTRICTED_MODE
1370 if (bozo_isrestricted && strchr(aname, '/') &&
1371 strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
1377 /* construct local path from canonical (wire-format) path */
1378 if (ConstructLocalLogPath(aname, &logpath)) {
1381 if (DoLogging) bozo_Log("%s is executing GetLog '%s'\n", caller, logpath);
1382 tfile = fopen(logpath, "r");
1391 if (tc == 0) continue; /* our termination condition on other end */
1392 if (tc == EOF) break;
1394 if (rx_Write(acall, &buffer, 1) != 1) {
1401 /* all done, cleanup and return */
1404 /* write out the end delimeter */
1406 if (rx_Write(acall, &buffer, 1) != 1) return BZNET;
1410 osi_auditU( acall, BOS_GetLogsEvent, code, AUD_END);
1414 SBOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
1415 struct rx_call *acall;
1417 char **as1, **as2, **as3, **as4; {
1418 register struct bnode *tb;
1420 *as2 = (char *) malloc(1);
1422 *as3 = (char *) malloc(1);
1424 *as4 = (char *) malloc(1);
1426 tb = bnode_FindInstance(abnodeName);
1429 /* now, return the appropriate error string, if any */
1430 if (tb->lastErrorName) {
1431 *as1 = (char *) malloc(strlen(tb->lastErrorName)+1);
1432 strcpy(*as1, tb->lastErrorName);
1435 *as1 = (char *) malloc(1);
1441 *as1 = (char *) malloc(1);
1446 #ifdef BOS_RESTRICTED_MODE
1447 SBOZO_GetRestrictedMode(acall, arestmode)
1448 struct rx_call *acall;
1449 afs_int32 *arestmode;
1451 *arestmode=bozo_isrestricted;
1455 SBOZO_SetRestrictedMode(acall, arestmode)
1456 struct rx_call *acall;
1457 afs_int32 arestmode;
1460 char caller[MAXKTCNAMELEN];
1462 if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
1465 if (bozo_isrestricted) {
1468 if (arestmode !=0 && arestmode !=1) {
1471 bozo_isrestricted=arestmode;
1472 code = WriteBozoFile(0);
1477 SBOZO_GetRestrictedMode(acall, arestmode)
1478 struct rx_call *acall;
1479 afs_int32 *arestmode;
1481 return RXGEN_OPCODE;
1484 SBOZO_SetRestrictedMode(acall, arestmode)
1485 struct rx_call *acall;
1486 afs_int32 arestmode;
1488 return RXGEN_OPCODE;
1492 void bozo_ShutdownAndExit(int asignal)
1496 bozo_Log("Shutdown of BOS server and processes in response to signal %d\n",
1499 /* start shutdown of all processes */
1500 if ((code = bnode_ApplyInstance(sdproc, (char *) 0)) == 0) {
1501 /* wait for shutdown to complete */
1502 code = bnode_ApplyInstance(swproc, (char *) 0);
1506 bozo_Log("Shutdown incomplete (code = %d); manual cleanup required\n",