From 77eb1728331e0825ecb6fbe29db334c61b5276d0 Mon Sep 17 00:00:00 2001 From: Michael Meffie Date: Wed, 31 Aug 2022 13:41:30 -0400 Subject: [PATCH] Add command fallback to server config Add an initialization retry in the bos, vos, and pts commands to fallback to the server configuration directory when initialization fails with the client configuration directory. This allows admins to run unauthenticated bos, vos, and pts commands on servers without a client configuration (including symlinks created by the bosserver) without any extra command line options. Perform the initialization retry only when the -localauth or -config options are not given. The bos, vos, and pts commands already use the server configuration path when the -localauth option is given, so there is no point in retrying the same path. The vos and pts -config option specifies the path to be used, so we do not fallback to a different directory when the user specifies the configuration path to be used. While here, change the scope of the confdir variable in vos.c from a global to a local variable, since it is only used within the MyBeforeProc() function. This change does not add a vsu_ClientInit() retry in the bos salvage command. That command always requires authorization, so when run without -localauth requires a token (and therefore a cache manager and client cell configuration). Update the bos, vos, and pts man pages to describe this new fallback method to lookup the configuration directory. (The AFSCONF environment variable and .AFSCONF files are currently undocumented in the man pages. They should be documented or removed from the code in a future change.) Change-Id: I55c3109494db744e7bc2defcb54eaee3b4e30018 Reviewed-on: https://gerrit.openafs.org/15351 Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Cheyenne Wills Reviewed-by: Benjamin Kaduk --- doc/man-pages/pod1/pts.pod | 22 ++++++++++++++++++++-- doc/man-pages/pod1/vos.pod.in | 18 ++++++++++++++++++ doc/man-pages/pod8/bos.pod | 4 ++++ src/bozo/bos.c | 12 ++++++++++-- src/ptserver/pts.c | 21 ++++++++++++++++----- src/volser/vos.c | 20 ++++++++++++++------ 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/doc/man-pages/pod1/pts.pod b/doc/man-pages/pod1/pts.pod index 1a3a009c8e..36eebc1176 100644 --- a/doc/man-pages/pod1/pts.pod +++ b/doc/man-pages/pod1/pts.pod @@ -111,18 +111,36 @@ The value of the AFSCELL environment variable. The local F file. +=item * + +The local F file. + +=back + Do not combine the B<-cell> and B<-localauth> options. A command on which the B<-localauth> flag is included always runs in the local cell (as defined in the server machine's local F file), whereas a command on which the B<-cell> argument is included runs in the specified foreign cell. -=back - =item B<-config> > The location of the directory to use to obtain configuration information, including the CellServDB. This is primarily provided for testing purposes. +If the B<-config> and B<-localauth> arguments are omitted, the command +interpreter searches for the configuration information in the following order: + +=over 4 + +=item * + +The F directory. + +=item * + +The F directory. + +=back =item B<-force> diff --git a/doc/man-pages/pod1/vos.pod.in b/doc/man-pages/pod1/vos.pod.in index 3dab98b741..1438376718 100644 --- a/doc/man-pages/pod1/vos.pod.in +++ b/doc/man-pages/pod1/vos.pod.in @@ -157,6 +157,10 @@ The value of the AFSCELL environment variable. The local F file. +=item * + +The local F file. + =back Do not combine the B<-cell> and B<-localauth> options. A command on which @@ -169,6 +173,20 @@ specified foreign cell. The location of the directory to use to obtain configuration information, including the CellServDB. This is primarily provided for testing purposes. +If the B<-config> and B<-localauth> arguments are omitted, the command +interpreter searches for the configuration information in the following order: + +=over 4 + +=item * + +The F directory. + +=item * + +The F directory. + +=back =item B<-help> diff --git a/doc/man-pages/pod8/bos.pod b/doc/man-pages/pod8/bos.pod index 70f912667f..59889ed60e 100644 --- a/doc/man-pages/pod8/bos.pod +++ b/doc/man-pages/pod8/bos.pod @@ -147,6 +147,10 @@ The value of the AFSCELL environment variable. The local F file. +=item * + +The local F file. + =back Do not combine the B<-cell> and B<-localauth> options. A command on which diff --git a/src/bozo/bos.c b/src/bozo/bos.c index 86090478f9..aafd10dd63 100644 --- a/src/bozo/bos.c +++ b/src/bozo/bos.c @@ -91,6 +91,7 @@ GetConn(struct cmd_syndesc *as, int aencrypt) char *hostname; char *cellname = NULL; const char *confdir; + const char *retry_confdir; afs_int32 code; struct rx_connection *tconn; afs_int32 addr; @@ -116,16 +117,23 @@ GetConn(struct cmd_syndesc *as, int aencrypt) if (as->parms[ADDPARMOFFSET + 2].items) { /* -localauth */ secFlags |= AFSCONF_SECOPTS_LOCALAUTH; confdir = AFSDIR_SERVER_ETC_DIRPATH; + retry_confdir = NULL; } else { confdir = AFSDIR_CLIENT_ETC_DIRPATH; + retry_confdir = AFSDIR_SERVER_ETC_DIRPATH; } if (as->parms[ADDPARMOFFSET + 1].items) { /* -noauth */ + /* If we're running with -noauth, we don't need a configuration + * directory. */ secFlags |= AFSCONF_SECOPTS_NOAUTH; } else { - /* If we're running with -noauth, we don't need a configuration - * directory */ tdir = afsconf_Open(confdir); + if (tdir == NULL && retry_confdir != NULL) { + fprintf(stderr, "bos: Retrying initialization with directory %s\n", + retry_confdir); + tdir = afsconf_Open(retry_confdir); + } if (tdir == NULL) { fprintf(stderr, "bos: can't open cell database (%s)\n", confdir); exit(1); diff --git a/src/ptserver/pts.c b/src/ptserver/pts.c index 90d6f16447..1a0b1e1ccf 100644 --- a/src/ptserver/pts.c +++ b/src/ptserver/pts.c @@ -46,7 +46,7 @@ struct sourcestack { struct authstate { int sec; - const char *confdir; + int initialized; char cell[MAXCELLCHARS]; }; @@ -186,6 +186,7 @@ GetGlobals(struct cmd_syndesc *as, void *arock) afs_int32 sec; int changed = 0; const char* confdir; + const char* retry_confdir; RXGK_Level rxgk_level = RXGK_LEVEL_BOGUS; whoami = as->a0name; @@ -198,7 +199,7 @@ GetGlobals(struct cmd_syndesc *as, void *arock) } sec = state->sec; - if (state->confdir == NULL) { + if (state->initialized == 0) { changed = 1; } @@ -229,16 +230,21 @@ GetGlobals(struct cmd_syndesc *as, void *arock) if (as->parms[OPT_test].items || as->parms[OPT_localauth].items) { changed = 1; confdir = AFSDIR_SERVER_ETC_DIRPATH; + retry_confdir = NULL; } else { - if (sec == 2) + if (sec == 2) { confdir = AFSDIR_SERVER_ETC_DIRPATH; - else + retry_confdir = NULL; + } else { confdir = AFSDIR_CLIENT_ETC_DIRPATH; + retry_confdir = AFSDIR_SERVER_ETC_DIRPATH; + } } if (as->parms[OPT_config].items) { /* -config */ changed = 1; confdir = as->parms[OPT_config].items->data; + retry_confdir = NULL; } if (as->parms[OPT_rxgk].items) { @@ -261,6 +267,11 @@ GetGlobals(struct cmd_syndesc *as, void *arock) if (changed) { CleanUp(as, arock); code = pr_Initialize2(sec, confdir, cell, rxgk_level); + if (code != 0 && retry_confdir != NULL) { + fprintf(stderr, "pts: Retrying initialization with directory %s\n", + retry_confdir); + code = pr_Initialize2(sec, retry_confdir, cell, rxgk_level); + } } else { code = 0; } @@ -269,7 +280,7 @@ GetGlobals(struct cmd_syndesc *as, void *arock) return code; } state->sec = sec; - state->confdir = confdir; + state->initialized = 1; if (cell && cell != state->cell) strncpy(state->cell, cell, MAXCELLCHARS-1); diff --git a/src/volser/vos.c b/src/volser/vos.c index 1a3b71217c..d552d91bca 100644 --- a/src/volser/vos.c +++ b/src/volser/vos.c @@ -109,7 +109,6 @@ cmd_AddParmAtOffset(ts, COMMONPARM_OFFSET_RXGK, \ int rxInitDone = 0; extern struct ubik_client *cstruct; -const char *confdir; static struct tqHead busyHead, notokHead; @@ -5847,6 +5846,8 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock) char *rxgk_seclevel_str = NULL; afs_int32 code; int secFlags; + const char *confdir = AFSDIR_CLIENT_ETC_DIRPATH; + const char *retry_confdir = AFSDIR_SERVER_ETC_DIRPATH; /* Initialize the ubik_client connection */ rx_SetRxDeadTime(90); @@ -5863,6 +5864,7 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock) if (as->parms[COMMONPARM_OFFSET_LOCALAUTH].items) { /* -localauth specified */ secFlags |= AFSCONF_SECOPTS_LOCALAUTH; confdir = AFSDIR_SERVER_ETC_DIRPATH; + retry_confdir = NULL; } if (as->parms[COMMONPARM_OFFSET_ENCRYPT].items /* -encrypt specified */ @@ -5872,8 +5874,10 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock) ) secFlags |= AFSCONF_SECOPTS_ALWAYSENCRYPT; - if (as->parms[COMMONPARM_OFFSET_CONFIG].items) /* -config flag set */ + if (as->parms[COMMONPARM_OFFSET_CONFIG].items) { /* -config flag set */ confdir = as->parms[COMMONPARM_OFFSET_CONFIG].items->data; + retry_confdir = NULL; + } if (cmd_OptionAsString(as, COMMONPARM_OFFSET_RXGK, &rxgk_seclevel_str) == 0) { if (strcmp(rxgk_seclevel_str, "clear") == 0) @@ -5892,8 +5896,14 @@ MyBeforeProc(struct cmd_syndesc *as, void *arock) rxgk_seclevel_str = NULL; } - if ((code = vsu_ClientInit(confdir, tcell, secFlags, UV_SetSecurity, - &cstruct))) { + code = vsu_ClientInit(confdir, tcell, secFlags, UV_SetSecurity, &cstruct); + if (code != 0 && retry_confdir != NULL) { + fprintf(STDERR, "vos: Retrying initialization with directory %s\n", + retry_confdir); + code = vsu_ClientInit(retry_confdir, tcell, secFlags, UV_SetSecurity, + &cstruct); + } + if (code != 0) { fprintf(STDERR, "could not initialize VLDB library (code=%lu) \n", (unsigned long)code); exit(1); @@ -5935,8 +5945,6 @@ main(int argc, char **argv) sigaction(SIGSEGV, &nsa, NULL); #endif - confdir = AFSDIR_CLIENT_ETC_DIRPATH; - cmd_SetBeforeProc(MyBeforeProc, NULL); ts = cmd_CreateSyntax("create", CreateVolume, NULL, 0, "create a new volume");