From ca7935d1c6bfa76ff99e1999c34b0329360aaa2e Mon Sep 17 00:00:00 2001 From: Chaskiel M Grundman Date: Mon, 29 Jan 2001 17:38:30 +0000 Subject: [PATCH] implement-bos-restricted-mode-20010129 This patch enables the bosserver to be placed in a restricted mode in which AFS superusers are only granted limited access to the server host. The following functionality is disabled when restricted mode is in use: bos exec bos getlog (except for files with no '/'s in their name)* bos create * bos delete bos install bos uninstall * specific exceptions are made for functionality that "bos salvage" uses: a cron bnode who's name is "salvage-tmp", time is now, and command begins with "/usr/afs/bin/salvager" may be created. This bnode deletes itself when complete, so no special "delete" support is needed. This functionality may be removed in the future if a "Salvage" RPC is implimented. The file with the exact path /usr/afs/logs/SalvageLog may be fetched, since that is how bos salvage [...] -showlog is implimented. Restricted mode is enabled using a new bos command (bos setrestricted) or bossever command line switch (bosserver -restricted). Restricted mode can be disabled by a) sending the bosserver process a SIGFPE (which will then allow restricted operations until the next restart or setrestricted command) or b) editing /usr/afs/local/BosConfig (or BosConfig.new), and restarting the bosserver. --- src/bozo/bos.c | 37 +++++++++++++++++ src/bozo/bosint.xg | 9 +++++ src/bozo/bosoprocs.c | 94 ++++++++++++++++++++++++++++++++++++++++++++ src/bozo/bosserver.c | 48 ++++++++++++++++++++++ 4 files changed, 188 insertions(+) diff --git a/src/bozo/bos.c b/src/bozo/bos.c index 69c2bc40f..1d3c1ede3 100644 --- a/src/bozo/bos.c +++ b/src/bozo/bos.c @@ -1518,6 +1518,33 @@ static DoStat (aname, aconn, aint32p, firstTime) return 0; } +#ifdef BOS_RESTRICTED_MODE +static GetRestrict(as) +struct cmd_syndesc *as; { + register struct rx_connection *tconn; + afs_int32 code, val; + + tconn = GetConn(as, 0); + code = BOZO_GetRestrictedMode(tconn, &val); + if (code) printf("bos: failed to get restricted mode (%s)\n", em(code)); + else printf("Restricted mode is %s\n", val ? "on" : "off"); + + return 0; +} + +static SetRestrict(as) +struct cmd_syndesc *as; { + register struct rx_connection *tconn; + afs_int32 code, val; + + tconn = GetConn(as, 0); + util_GetInt32(as->parms[1].items->data, &val); + code = BOZO_SetRestrictedMode(tconn, val); + if (code) printf("bos: failed to set restricted mode (%s)\n", em(code)); + return 0; +} +#endif + static void add_std_args (ts) register struct cmd_syndesc *ts; { @@ -1765,6 +1792,16 @@ main(argc, argv) "ignore | remove | attach"); add_std_args (ts); +#ifdef BOS_RESTRICTED_MODE + ts = cmd_CreateSyntax("getrestricted", GetRestrict, 0, "get restrict mode"); + cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); + add_std_args (ts); + + ts = cmd_CreateSyntax("setrestricted", SetRestrict, 0, "set restrict mode"); + cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name"); + cmd_AddParm(ts, "-mode", CMD_SINGLE, 0, "mode to set"); + add_std_args (ts); +#endif #endif code = cmd_Dispatch(argc, argv); diff --git a/src/bozo/bosint.xg b/src/bozo/bosint.xg index 21ae7432c..98c5fc1ff 100644 --- a/src/bozo/bosint.xg +++ b/src/bozo/bosint.xg @@ -222,3 +222,12 @@ GetInstanceStrings( OUT string spare2, OUT string spare3 ) = 114; + +GetRestrictedMode( + OUT afs_int32 *restmode +) = 115; + +SetRestrictedMode( + IN afs_int32 restmode +) = 116; +/* RPC #117 will be Salvage, if I get around to it */ diff --git a/src/bozo/bosoprocs.c b/src/bozo/bosoprocs.c index a2ff6d144..336d9269e 100644 --- a/src/bozo/bosoprocs.c +++ b/src/bozo/bosoprocs.c @@ -43,6 +43,9 @@ extern struct afsconf_dir *bozo_confdir; extern struct rx_securityClass *bozo_rxsc[2]; extern int bozo_newKTs; extern int DoLogging; +#ifdef BOS_RESTRICTED_MODE +extern int bozo_isrestricted; +#endif BOZO_GetRestartTime(acall, atype, aktime) struct rx_call *acall; @@ -119,6 +122,12 @@ char *acmd; { code = BZACCESS; goto fail; } +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted) { + code = BZACCESS; + goto fail; + } +#endif if (DoLogging) bozo_Log("%s is executing the shell command '%s'\n", caller, acmd); /* should copy output to acall, but don't yet cause its hard */ @@ -180,6 +189,13 @@ register char *aname; { osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END); return code; } +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted) { + code = BZACCESS; + osi_auditU (acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END); + return code; + } +#endif /* construct local path from canonical (wire-format) path */ if (ConstructLocalBinPath(aname, &filepath)) { @@ -267,6 +283,9 @@ afs_int32 mode; { char caller[MAXKTCNAMELEN]; if (!afsconf_SuperUser(bozo_confdir, acall, caller)) return BZACCESS; +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted) return BZACCESS; +#endif /* construct local path from canonical (wire-format) path */ if (ConstructLocalBinPath(aname, &fpp)) { @@ -715,6 +734,17 @@ char *notifier; { code = BZACCESS; goto fail; } +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted) { + if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp") || + strcmp(ap2, "now") || + strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH, + strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) { + code = BZACCESS; + goto fail; + } + } +#endif code = bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,BSTAT_NORMAL); if (!code) @@ -754,6 +784,12 @@ char *ainstance; { code = BZACCESS; goto fail; } +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted) { + code = BZACCESS; + goto fail; + } +#endif if (DoLogging) bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance); code = bnode_DeleteName(ainstance); @@ -1061,6 +1097,12 @@ afs_int32 aflags; { code = BZACCESS; goto fail; } +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted) { + code = BZACCESS; + goto fail; + } +#endif if (DoLogging) bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags); /* first scan AFS binary directory */ @@ -1299,6 +1341,13 @@ char *aname; { code = BZACCESS; goto fail; } +#ifdef BOS_RESTRICTED_MODE + if (bozo_isrestricted && strchr(aname, '/') && + strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) { + code = BZACCESS; + goto fail; + } +#endif /* construct local path from canonical (wire-format) path */ if (ConstructLocalLogPath(aname, &logpath)) { @@ -1369,6 +1418,51 @@ char **as1, **as2, **as3, **as4; { return BZNOENT; } +#ifdef BOS_RESTRICTED_MODE +BOZO_GetRestrictedMode(acall, arestmode) +struct rx_call *acall; +afs_int32 *arestmode; +{ + *arestmode=bozo_isrestricted; + return 0; +} + +BOZO_SetRestrictedMode(acall, arestmode) +struct rx_call *acall; +afs_int32 arestmode; +{ + afs_int32 code; + char caller[MAXKTCNAMELEN]; + + if (!afsconf_SuperUser(bozo_confdir, acall, caller)) { + return BZACCESS; + } + if (bozo_isrestricted) { + return BZACCESS; + } + if (arestmode !=0 && arestmode !=1) { + return BZDOM; + } + bozo_isrestricted=arestmode; + code = WriteBozoFile(0); + fail: + return code; +} +#else +BOZO_GetRestrictedMode(acall, arestmode) +struct rx_call *acall; +afs_int32 *arestmode; +{ + return RXGEN_OPCODE; +} + +BOZO_SetRestrictedMode(acall, arestmode) +struct rx_call *acall; +afs_int32 arestmode; +{ + return RXGEN_OPCODE; +} +#endif void bozo_ShutdownAndExit(int asignal) { diff --git a/src/bozo/bosserver.c b/src/bozo/bosserver.c index 409d72a00..cd00c2bc2 100644 --- a/src/bozo/bosserver.c +++ b/src/bozo/bosserver.c @@ -60,6 +60,17 @@ static afs_int32 nextDay; struct ktime bozo_nextRestartKT, bozo_nextDayKT; int bozo_newKTs; +#ifdef BOS_RESTRICTED_MODE +int bozo_isrestricted=0; +int bozo_restdisable=0; + +void bozo_insecureme(int sig) +{ + signal(SIGFPE, bozo_insecureme); + bozo_isrestricted=0; + bozo_restdisable=1; +} +#endif struct bztemp { FILE *file; @@ -209,6 +220,9 @@ char *aname; { afs_int32 i, goal; struct bnode *tb; char *parms[MAXPARMS]; +#ifdef BOS_RESTRICTED_MODE + int rmode; +#endif /* rename BozoInit to BosServer for the user */ if (!aname) { @@ -280,6 +294,23 @@ char *aname; { continue; } +#ifdef BOS_RESTRICTED_MODE + if (strncmp(tbuffer, "restrictmode", 12) == 0) { + code = sscanf(tbuffer, "restrictmode %d", + &rmode); + if (code != 1) { + code = -1; + goto fail; + } + if (rmode !=0 && rmode != 1) { + code = -1; + goto fail; + } + bozo_isrestricted=rmode; + continue; + } +#endif + if (strncmp("bnode", tbuffer, 5) != 0) { code = -1; goto fail; @@ -351,6 +382,9 @@ char *aname; { tfile = fopen(tbuffer, "w"); if (!tfile) return -1; btemp.file = tfile; +#ifdef BOS_RESTRICTED_MODE + fprintf(tfile, "restrictmode %d\n", bozo_isrestricted); +#endif fprintf(tfile, "restarttime %d %d %d %d %d\n", bozo_nextRestartKT.mask, bozo_nextRestartKT.day, bozo_nextRestartKT.hour, bozo_nextRestartKT.min, bozo_nextRestartKT.sec); @@ -406,6 +440,12 @@ static BozoDaemon() { IOMGR_Sleep(60); now = FT_ApproxTime(); +#ifdef BOS_RESTRICTED_MODE + if (bozo_restdisable) { + bozo_Log("Restricted mode disabled by signal\n"); + bozo_restdisable=0; + } +#endif if (bozo_newKTs) { /* need to recompute restart times */ bozo_newKTs = 0; /* done for a while */ nextRestart = ktime_next(&bozo_nextRestartKT, BOZO_MINSKIP); @@ -619,6 +659,9 @@ char **envp; sigaction(SIGSEGV, &nsa, NULL); sigaction(SIGABRT, &nsa, NULL); #endif +#ifdef BOS_RESTRICTED_MODE + signal(SIGFPE, bozo_insecureme); +#endif #ifdef AFS_NT40_ENV /* Initialize winsock */ @@ -669,6 +712,11 @@ char **envp; else if (strcmp(argv[code], "-enable_process_stats")==0) { rx_enableProcessRPCStats(); } +#ifdef BOS_RESTRICTED_MODE + else if (strcmp(argv[code], "-restricted")==0) { + bozo_isrestricted=1; + } +#endif else { /* hack to support help flag */ -- 2.39.5