pull request #1110 - explore mode access

Pull request from entrez:  sysconf's EXPLORES=user-list is checked by
the #exploremode command but was no checked by -X on the command line
or 'playmode=explore' in the RC file.  Also a save file from wizard mode
that wasn't allowed to be restored in wizard mode (different user or
change in sysconf's WIZARDS=user-list) would 'downgrad' to explore mode
with checking whether the current user is allowed to use that.

Closes #1110
This commit is contained in:
PatR
2023-11-07 15:49:17 -08:00
10 changed files with 100 additions and 27 deletions

View File

@@ -2123,6 +2123,7 @@ extern int dohistory(void);
extern void chdirx(char *, boolean);
#endif /* CHDIR */
extern boolean authorize_wizard_mode(void);
extern boolean authorize_explore_mode(void);
#endif
#if defined(WIN32)
extern int getlock(void);
@@ -3100,6 +3101,7 @@ extern void port_help(void);
#endif
extern void sethanguphandler(void(*)(int));
extern boolean authorize_wizard_mode(void);
extern boolean authorize_explore_mode(void);
extern void append_slash(char *);
extern boolean check_user_string(const char *);
extern char *get_login_name(void);
@@ -3264,6 +3266,7 @@ extern void chdirx(const char *, boolean);
#endif /* CHDIR */
extern void sethanguphandler(void(*)(int));
extern boolean authorize_wizard_mode(void);
extern boolean authorize_explore_mode(void);
/* ### vmsmisc.c ### */

View File

@@ -412,6 +412,8 @@ struct instance_flags {
chosen_windowport[], but do not switch to
it in the midst of options processing */
genericptr_t returning_missile; /* 'struct obj *'; Mjollnir or aklys */
boolean wiz_error_flag; /* flag for tracking failed wizmode auth */
boolean explore_error_flag; /* ditto for explore mode */
boolean obsolete; /* obsolete options can point at this, it isn't used */
};

View File

@@ -965,10 +965,7 @@ enter_explore_mode(void)
} else {
const char *oldmode = !wizard ? "normal game" : "debug mode";
#ifdef SYSCF
#if defined(UNIX)
if (!sysopt.explorers || !sysopt.explorers[0]
|| !check_user_string(sysopt.explorers)) {
if (!authorize_explore_mode()) {
if (!wizard) {
You("cannot access explore mode.");
return ECMD_OK;
@@ -978,8 +975,6 @@ enter_explore_mode(void)
/* keep going */
}
}
#endif
#endif
pline("Beware! From explore mode there will be no return to %s,",
oldmode);
if (paranoid_query(ParanoidQuit,

View File

@@ -10257,11 +10257,17 @@ set_playmode(void)
gp.plnamelen = (int) strlen(strcpy(gp.plname, "wizard"));
else
wizard = FALSE; /* not allowed or not available */
/* force explore mode if we didn't make it into wizard mode */
/* try explore mode if we didn't make it into wizard mode */
/* if requesting wizard mode when restoring a normal game, this will
set iflags.deferred_X and prompt to activate explore mode after the
save file has already been deleted */
discover = !wizard;
iflags.deferred_X = FALSE;
}
/* don't need to do anything special for explore mode or normal play */
if (discover && !authorize_explore_mode()) {
discover = iflags.deferred_X = FALSE;
}
/* don't need to do anything special for normal play */
}
static void

View File

@@ -512,7 +512,7 @@ restgamestate(NHFILE *nhfp)
struct obj *bc_obj;
char timebuf[15];
unsigned long uid = 0;
boolean defer_perm_invent;
boolean defer_perm_invent, restoring_special;
if (nhfp->structlevel)
Mread(nhfp->fd, &uid, sizeof uid);
@@ -557,11 +557,12 @@ restgamestate(NHFILE *nhfp)
in the discover case, we don't want to set that for a normal
game until after the save file has been removed */
iflags.deferred_X = (newgameflags.explore && !discover);
restoring_special = (wizard || discover);
if (newgameflags.debug) {
/* authorized by startup code; wizard mode exists and is allowed */
wizard = TRUE, discover = iflags.deferred_X = FALSE;
} else if (wizard) {
/* specified by save file; check authorization now */
} else if (restoring_special) {
/* specified by save file; check authorization now. */
set_playmode();
}
role_init(); /* Reset the initial role, race, gender, and alignment */
@@ -572,6 +573,13 @@ restgamestate(NHFILE *nhfp)
Mread(nhfp->fd, &u, sizeof u);
gy.youmonst.cham = u.mcham;
if (restoring_special && iflags.explore_error_flag) {
/* savefile has wizard or explore mode, but player is no longer
authorized to access either; can't downgrade mode any further, so
fail restoration. */
u.uhp = 0;
}
if (nhfp->structlevel)
Mread(nhfp->fd, timebuf, 14);
timebuf[14] = '\0';

View File

@@ -50,7 +50,6 @@ extern void init_linux_cons(void);
#endif
static void wd_message(void);
static boolean wiz_error_flag = FALSE;
static struct passwd *get_unix_pw(void);
#ifdef __EMSCRIPTEN__
@@ -597,28 +596,48 @@ port_help(void)
boolean
authorize_wizard_mode(void)
{
struct passwd *pw = get_unix_pw();
if (pw && sysopt.wizards && sysopt.wizards[0]) {
if (sysopt.wizards && sysopt.wizards[0]) {
if (check_user_string(sysopt.wizards))
return TRUE;
}
wiz_error_flag = TRUE; /* not being allowed into wizard mode */
iflags.wiz_error_flag = TRUE; /* not being allowed into wizard mode */
return FALSE;
}
/* similar to above, validate explore mode access */
boolean
authorize_explore_mode(void)
{
#ifdef SYSCF
if (sysopt.explorers && sysopt.explorers[0]) {
if (check_user_string(sysopt.explorers))
return TRUE;
}
iflags.explore_error_flag = TRUE; /* not allowed into explore mode */
return FALSE;
#else
return TRUE; /* if sysconf disabled, no restrictions on explore mode */
#endif
}
static void
wd_message(void)
{
if (wiz_error_flag) {
if (iflags.wiz_error_flag) {
if (sysopt.wizards && sysopt.wizards[0]) {
char *tmp = build_english_list(sysopt.wizards);
pline("Only user%s %s may access debug (wizard) mode.",
strchr(sysopt.wizards, ' ') ? "s" : "", tmp);
free(tmp);
} else
} else {
You("cannot access debug (wizard) mode.");
}
wizard = FALSE; /* (paranoia) */
if (!iflags.explore_error_flag)
pline("Entering explore/discovery mode instead.");
wizard = 0, discover = 1; /* (paranoia) */
} else if (iflags.explore_error_flag) {
You("cannot access explore mode."); /* same as enter_explore_mode */
discover = iflags.deferred_X = FALSE; /* (more paranoia) */
} else if (discover)
You("are in non-scoring explore/discovery mode.");
}

View File

@@ -720,6 +720,13 @@ authorize_wizard_mode(void)
return FALSE;
}
/* similar to above, validate explore mode access */
boolean
authorize_explore_mode(void)
{
return TRUE; /* no restrictions on explore mode */
}
#ifdef EXEPATH
#ifdef __DJGPP__
#define PATH_SEPARATOR '/'

View File

@@ -53,7 +53,6 @@ extern void init_linux_cons(void);
#endif
static void wd_message(void);
static boolean wiz_error_flag = FALSE;
static struct passwd *get_unix_pw(void);
int
@@ -956,28 +955,48 @@ port_help(void)
boolean
authorize_wizard_mode(void)
{
struct passwd *pw = get_unix_pw();
if (pw && sysopt.wizards && sysopt.wizards[0]) {
if (sysopt.wizards && sysopt.wizards[0]) {
if (check_user_string(sysopt.wizards))
return TRUE;
}
wiz_error_flag = TRUE; /* not being allowed into wizard mode */
iflags.wiz_error_flag = TRUE; /* not being allowed into wizard mode */
return FALSE;
}
/* similar to above, validate explore mode access */
boolean
authorize_explore_mode(void)
{
#ifdef SYSCF
if (sysopt.explorers && sysopt.explorers[0]) {
if (check_user_string(sysopt.explorers))
return TRUE;
}
iflags.explore_error_flag = TRUE; /* not allowed into explore mode */
return FALSE;
#else
return TRUE; /* if sysconf disabled, no restrictions on explore mode */
#endif
}
static void
wd_message(void)
{
if (wiz_error_flag) {
if (iflags.wiz_error_flag) {
if (sysopt.wizards && sysopt.wizards[0]) {
char *tmp = build_english_list(sysopt.wizards);
pline("Only user%s %s may access debug (wizard) mode.",
strchr(sysopt.wizards, ' ') ? "s" : "", tmp);
free(tmp);
} else
} else {
You("cannot access debug (wizard) mode.");
}
wizard = FALSE; /* (paranoia) */
if (!iflags.explore_error_flag)
pline("Entering explore/discovery mode instead.");
wizard = 0, discover = 1; /* (paranoia) */
} else if (iflags.explore_error_flag) {
You("cannot access explore mode."); /* same as enter_explore_mode */
discover = iflags.deferred_X = FALSE; /* (more paranoia) */
} else if (discover)
You("are in non-scoring explore/discovery mode.");
}

View File

@@ -484,6 +484,13 @@ authorize_wizard_mode(void)
return FALSE;
}
/* similar to above, validate explore mode access */
boolean
authorize_explore_mode(void)
{
return TRUE; /* no restrictions on explore mode */
}
static void
wd_message(void)
{

View File

@@ -1021,6 +1021,13 @@ authorize_wizard_mode(void)
return FALSE;
}
/* similar to above, validate explore mode access */
boolean
authorize_explore_mode(void)
{
return TRUE; /* no restrictions on explore mode */
}
#define PATH_SEPARATOR '\\'
#if defined(WIN32) && !defined(WIN32CON)