From f2d37bac2e0811f0ea1b667c9cd64fcf9bdfd855 Mon Sep 17 00:00:00 2001 From: keni Date: Wed, 9 Jan 2008 01:57:41 +0000 Subject: [PATCH] system-wide configuration file Add options SYSCF (to add a system-wide configuration file) and SYSCF_FILE (for a file-based implementation of SYSCF) - this allows a binary distribution to be configured at install time. The only option supported at this time is WIZARDS - a list of usernames which can use -D; currently only for unix-likes but should be extendable to anything that has a concept of multiple users. Add mac tty multiuser config using sgid. --- include/config.h | 10 ++++++ include/decl.h | 3 ++ include/extern.h | 4 ++- include/hack.h | 11 ++++--- src/decl.c | 3 ++ src/files.c | 21 +++++++++--- src/options.c | 67 ++++++++++++++++++++++++++++++++------- sys/unix/Install.unx | 10 ++++++ sys/unix/Makefile.top | 15 ++++++--- sys/unix/hints/linux | 2 ++ sys/unix/hints/linux-x11 | 1 + sys/unix/hints/macosx | 1 + sys/unix/hints/macosx-mu | 55 ++++++++++++++++++++++++++++++++ sys/unix/hints/macosx-x11 | 1 + sys/unix/hints/macosx.sh | 57 +++++++++++++++++++++++++++++++++ sys/unix/hints/unix | 7 ++++ sys/unix/unixmain.c | 27 +++++++++++++++- 17 files changed, 269 insertions(+), 26 deletions(-) create mode 100644 sys/unix/hints/macosx-mu create mode 100755 sys/unix/hints/macosx.sh diff --git a/include/config.h b/include/config.h index 82c272d6e..9cc1baa10 100644 --- a/include/config.h +++ b/include/config.h @@ -144,11 +144,21 @@ * feature from the game; otherwise set the appropriate wizard * name. LOGFILE, NEWS and PANICLOG refer to files in the * playground. + * + * If SYSCF is defined, the following configuration info is + * available in a global config space, with the compiled-in + * entries as defaults: + * WIZARD ( a value of * allows anyone to be wizard) + * + * The following options select how the config space is stored: + * SYSCF_FILE in the named file */ #ifndef WIZARD /* allow for compile-time or Makefile changes */ # ifndef KR1ED # define WIZARD "wizard" /* the person allowed to use the -D option */ +/* #define SYSCF */ /* use a global configuration */ +/* #define SYSCF_FILE "sysconf" */ /* global configuration is in a file */ # else # define WIZARD # define WIZARD_NAME "wizard" diff --git a/include/decl.h b/include/decl.h index 08a70015f..96e5ffdc6 100644 --- a/include/decl.h +++ b/include/decl.h @@ -199,6 +199,9 @@ E const char *occtxt; /* defined when occupation != NULL */ E const char *nomovemsg; E const char nul[]; E char lock[]; +#ifdef SYSCF +E char wizards[]; +#endif E const schar xdir[], ydir[], zdir[]; diff --git a/include/extern.h b/include/extern.h index b83e45fb2..8e201d5ac 100644 --- a/include/extern.h +++ b/include/extern.h @@ -730,7 +730,7 @@ E void FDECL(unlock_file, (const char *)); #ifdef USER_SOUNDS E boolean FDECL(can_read_file, (const char *)); #endif -E void FDECL(read_config_file, (const char *)); +E void FDECL(read_config_file, (const char *, int)); E void FDECL(check_recordfile, (const char *)); #if defined(WIZARD) E void NDECL(read_wizkit); @@ -1580,6 +1580,8 @@ E char *FDECL(safe_qbuf, (char *,const char *,const char *,struct obj *, E boolean FDECL(match_optname, (const char *,const char *,int,BOOLEAN_P)); E void NDECL(initoptions); +E void NDECL(initoptions_init); +E void NDECL(initoptions_finish); E void FDECL(parseoptions, (char *,BOOLEAN_P,BOOLEAN_P)); E int NDECL(doset); E int NDECL(dotogglepickup); diff --git a/include/hack.h b/include/hack.h index ae3ec1a80..9e5e9e41d 100644 --- a/include/hack.h +++ b/include/hack.h @@ -340,10 +340,13 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ * Each higher number includes the characteristics of the numbers * below it. */ -#define SET_IN_FILE 0 /* config file option only */ -#define SET_VIA_PROG 1 /* may be set via extern program, not seen in game */ -#define DISP_IN_GAME 2 /* may be set via extern program, displayed in game */ -#define SET_IN_GAME 3 /* may be set via extern program or set in the game */ +/* XXX This should be replaced with a bitmap. */ +#define SET_IN_SYS 0 /* system config file option only */ +#define SET_IN_FILE 1 /* config file option only */ +#define SET_VIA_PROG 2 /* may be set via extern program, not seen in game */ +#define DISP_IN_GAME 3 /* may be set via extern program, displayed in game */ +#define SET_IN_GAME 4 /* may be set via extern program or set in the game */ +#define SET__IS_VALUE_VALID(s) ( (s < SET_IN_SYS) || (s > SET_IN_GAME) ) #define FEATURE_NOTICE_VER(major,minor,patch) (((unsigned long)major << 24) | \ ((unsigned long)minor << 16) | \ diff --git a/src/decl.c b/src/decl.c index 859804f0e..70e8c0120 100644 --- a/src/decl.c +++ b/src/decl.c @@ -70,6 +70,9 @@ const char ynNaqchars[] = "yn#aq"; NEARDATA long yn_number = 0L; const char disclosure_options[] = "iavgc"; +#ifdef SYSCF +char wizards[PL_PSIZ] = DUMMY; +#endif #if defined(MICRO) || defined(WIN32) char hackdir[PATHLEN]; /* where rumors, help, record are */ diff --git a/src/files.c b/src/files.c index 274370f32..7170001fb 100644 --- a/src/files.c +++ b/src/files.c @@ -185,7 +185,7 @@ STATIC_DCL boolean FDECL(make_compressed_name, (const char *, char *)); STATIC_DCL char *FDECL(make_lockname, (const char *,char *)); STATIC_DCL FILE *FDECL(fopen_config_file, (const char *)); STATIC_DCL int FDECL(get_uchars, (FILE *,char *,char *,uchar *,BOOLEAN_P,int,const char *)); -int FDECL(parse_config_line, (FILE *,char *,char *,char *)); +int FDECL(parse_config_line, (FILE *,char *,char *,char *,int)); #ifdef LOADSYMSETS STATIC_DCL FILE *NDECL(fopen_sym_file); STATIC_DCL void FDECL(set_symhandling, (char *,int)); @@ -1947,11 +1947,12 @@ int prefixid; /*ARGSUSED*/ int -parse_config_line(fp, buf, tmp_ramdisk, tmp_levels) +parse_config_line(fp, buf, tmp_ramdisk, tmp_levels, src) FILE *fp; char *buf; char *tmp_ramdisk; char *tmp_levels; +int src; { #if (defined(macintosh) && (defined(__SC__) || defined(__MRC__))) || defined(__MWERKS__) # pragma unused(tmp_ramdisk,tmp_levels) @@ -2064,6 +2065,10 @@ char *tmp_levels; (void) strncpy(dogname, bufp, PL_PSIZ-1); } else if (match_varname(buf, "CATNAME", 3)) { (void) strncpy(catname, bufp, PL_PSIZ-1); +#ifdef SYSCF + } else if ( (src==SET_IN_SYS) && match_varname(buf, "WIZARDS", 6)) { + (void) strncpy(wizards, bufp, PL_PSIZ-1); +#endif } else if (match_varname(buf, "BOULDER", 3)) { (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE, @@ -2267,8 +2272,9 @@ const char *filename; #endif /* USER_SOUNDS */ void -read_config_file(filename) +read_config_file(filename, src) const char *filename; +int src; { #define tmp_levels (char *)0 #define tmp_ramdisk (char *)0 @@ -2300,7 +2306,14 @@ const char *filename; set_duplicate_opt_detection(1); while (fgets(buf, 4*BUFSZ, fp)) { - if (!parse_config_line(fp, buf, tmp_ramdisk, tmp_levels)) { +#ifdef notyet +/* +XXX Don't call read() in parse_config_line, read as callback or reassemble line +at this level. +OR: Forbid multiline stuff for alternate config sources. +*/ +#endif + if (!parse_config_line(fp, buf, tmp_ramdisk, tmp_levels, src)) { raw_printf("Bad option line: \"%.50s\"", buf); wait_synch(); } diff --git a/src/options.c b/src/options.c index a42b5d089..f77e5503d 100644 --- a/src/options.c +++ b/src/options.c @@ -386,6 +386,9 @@ static struct Comp_Opt { "windowcolors", "the foreground/background colors of windows", /*WC*/ 80, DISP_IN_GAME }, { "windowtype", "windowing system to use", WINTYPELEN, DISP_IN_GAME }, +#ifdef SYSCF + { "wizards", "users with access to wizard mode (etc)", PL_PSIZ, SET_IN_SYS}, +#endif #ifdef BACKWARD_COMPAT {"DECgraphics", "load DECGraphics display symbols", 70, SET_IN_FILE}, {"IBMgraphics", "load IBMGraphics display symbols", 70, SET_IN_FILE}, @@ -547,8 +550,16 @@ const char *ev; return (char *)0; } +/* Split initoptions into 2 parts for SYSCF but don't break anything not + * using SYSCF. */ +void +initoptions(){ + initoptions_init(); + initoptions_finish(); +} + void -initoptions() +initoptions_init() { #ifndef MAC char *opts; @@ -671,17 +682,20 @@ initoptions() /* since this is done before init_objects(), do partial init here */ objects[SLIME_MOLD].oc_name_idx = SLIME_MOLD; nmcpy(pl_fruit, OBJ_NAME(objects[SLIME_MOLD]), PL_FSIZ); +} +void +initoptions_finish(){ #ifndef MAC - opts = getenv("NETHACKOPTIONS"); + char *opts = getenv("NETHACKOPTIONS"); if (!opts) opts = getenv("HACKOPTIONS"); if (opts) { if (*opts == '/' || *opts == '\\' || *opts == '@') { if (*opts == '@') opts++; /* @filename */ /* looks like a filename */ if (strlen(opts) < BUFSZ/2) - read_config_file(opts); + read_config_file(opts, SET_IN_FILE); } else { - read_config_file((char *)0); + read_config_file((char *)0, SET_IN_FILE); /* let the total length of options be long; * parseoptions() will check each individually */ @@ -689,7 +703,7 @@ initoptions() } } else #endif - read_config_file((char *)0); + read_config_file((char *)0, SET_IN_FILE); (void)fruitadd(pl_fruit); /* Remove "slime mold" from list of object names; this will */ @@ -2249,6 +2263,23 @@ goodfruit: return; } +#ifdef SYSCF + fullname = "wizards"; + if (wizard && match_optname(opts, fullname, 6, TRUE)) { + if (duplicate) { + complain_about_duplicate(opts,1); + return; + } + if (negated) { + bad_negation(fullname, FALSE); + return; + } else if ((op = string_for_env_opt(fullname, opts, FALSE)) != 0) { + nmcpy(wizards, op, PL_PSIZ); + } + return; + } +#endif + /* menustyle:traditional or combo or full or partial */ if (match_optname(opts, "menustyle", 4, TRUE)) { int tmp; @@ -2718,6 +2749,13 @@ doset() "Compounds (selecting will prompt for new value):", MENU_UNSELECTED); +#ifdef notyet /* SYSCF */ +/* XXX I think this is still fragile. Fixing initial/from_file and/or changing + the SET_* etc to bitmaps will let me make this better. */ + if(wizard) + startpass = SET_IN_SYS; + else +#endif startpass = DISP_IN_GAME; endpass = SET_IN_GAME; @@ -3451,6 +3489,14 @@ char *buf; #endif else if (!strcmp(optname, "catname")) Sprintf(buf, "%s", catname[0] ? catname : none ); +#ifdef SYSCF + else if (!strcmp(optname, "wizards")) +# ifdef KR1ED + Sprintf(buf, "%s", wizards[0] ? wizards : WIZARD_NAME); +# else + Sprintf(buf, "%s", wizards[0] ? wizards : WIZARD); +# endif +#endif else if (!strcmp(optname, "disclose")) { for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) { char topt[2]; @@ -4254,13 +4300,12 @@ struct wc_Opt wc2_options[] = { {(char *)0, 0L} }; - /* - * If a port wants to change or ensure that the + * If a port wants to change or ensure that the SET_IN_SYS, * SET_IN_FILE, DISP_IN_GAME, or SET_IN_GAME status of an option is * correct (for controlling its display in the option menu) call * set_option_mod_status() - * with the second argument of 0,2, or 3 respectively. + * with the appropriate second argument. */ void set_option_mod_status(optnam, status) @@ -4268,7 +4313,7 @@ const char *optnam; int status; { int k; - if (status < SET_IN_FILE || status > SET_IN_GAME) { + if ( SET__IS_VALUE_VALID(status) ) { impossible("set_option_mod_status: status out of range %d.", status); return; @@ -4301,7 +4346,7 @@ unsigned long optmask; int status; { int k = 0; - if (status < SET_IN_FILE || status > SET_IN_GAME) { + if ( SET__IS_VALUE_VALID(status) ) { impossible("set_wc_option_mod_status: status out of range %d.", status); return; @@ -4357,7 +4402,7 @@ unsigned long optmask; int status; { int k = 0; - if (status < SET_IN_FILE || status > SET_IN_GAME) { + if ( SET__IS_VALUE_VALID(status) ) { impossible("set_wc2_option_mod_status: status out of range %d.", status); return; diff --git a/sys/unix/Install.unx b/sys/unix/Install.unx index 8f5897a64..3a45a5f87 100644 --- a/sys/unix/Install.unx +++ b/sys/unix/Install.unx @@ -82,6 +82,16 @@ a game that was in progress. The recover command is installed in the HACKDIR by default. +9. If you specified SYSCF (and SYSCF_FILE) in config.h, create the file + defined as SYSCF_FILE and fill in any of the following values if you + wish to override the compiled-in defaults: + WIZARDS= a space-separated list of usernames who can use -D + If the first character is '*' then any user can use -D. + This is a standards config file, so blank lines and lines starting with + pound signs are ignored; while other, standard options (such as catname) + can be specified in this file, this is considered a bug and may be changed + in the future. + Notes: 1. Save files and bones files from previous versions will not work with diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 0f2b35e99..4c2ab435b 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -17,15 +17,17 @@ #PREFIX = /usr GAME = nethack # GAME = nethack.prg -GAMEUID = games -GAMEGRP = bin +#GAMEUID = games +#GAMEGRP = bin # Permissions - some places use setgid instead of setuid, for instance # See also the option "SECURE" in include/config.h -GAMEPERM = 04755 +#GAMEPERM = 04755 FILEPERM = 0644 +# VARFILEPERM = 0644 EXEPERM = 0755 DIRPERM = 0755 +# VARDIRPERM = 0755 # VARDIR may also appear in unixconf.h as "VAR_PLAYGROUND" else HACKDIR # @@ -234,6 +236,7 @@ update: $(GAME) recover $(VARDAT) dungeon spec_levs @echo You may also want to install the man pages via the doc Makefile. install: $(GAME) recover $(VARDAT) dungeon spec_levs + true; $(PREINSTALL) # set up the directories # not all mkdirs have -p; those that don't will create a -p directory -mkdir -p $(SHELLDIR) @@ -242,14 +245,16 @@ install: $(GAME) recover $(VARDAT) dungeon spec_levs -rmdir ./-p -$(CHOWN) $(GAMEUID) $(HACKDIR) $(VARDIR) $(VARDIR)/save $(CHGRP) $(GAMEGRP) $(HACKDIR) $(VARDIR) $(VARDIR)/save - chmod $(DIRPERM) $(HACKDIR) $(VARDIR) $(VARDIR)/save +# order counts here: + chmod $(DIRPERM) $(HACKDIR) + chmod $(VARDIRPERM) $(VARDIR) $(VARDIR)/save # set up the game files ( $(MAKE) dofiles ) # set up some additional files touch $(VARDIR)/perm $(VARDIR)/record $(VARDIR)/logfile -( cd $(VARDIR) ; $(CHOWN) $(GAMEUID) perm record logfile ; \ $(CHGRP) $(GAMEGRP) perm record logfile ; \ - chmod $(FILEPERM) perm record logfile ) + chmod $(VARFILEPERM) perm record logfile ) true; $(POSTINSTALL) # and a reminder @echo You may also want to reinstall the man pages via the doc Makefile. diff --git a/sys/unix/hints/linux b/sys/unix/hints/linux index b3f424e83..30ece238a 100644 --- a/sys/unix/hints/linux +++ b/sys/unix/hints/linux @@ -24,3 +24,5 @@ WINTTYLIB=-lcurses CHOWN=true CHGRP=true + +VARDIRPERM = 0755 diff --git a/sys/unix/hints/linux-x11 b/sys/unix/hints/linux-x11 index 62c377822..ff3f42a87 100644 --- a/sys/unix/hints/linux-x11 +++ b/sys/unix/hints/linux-x11 @@ -26,6 +26,7 @@ VARDATND = x11tiles NetHack.ad pet_mark.xbm CHOWN=true CHGRP=true +VARDIRPERM = 0755 POSTINSTALL= bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; (cd $(HACKDIR); mkfontdir) diff --git a/sys/unix/hints/macosx b/sys/unix/hints/macosx index 84eebceeb..2b93c341f 100644 --- a/sys/unix/hints/macosx +++ b/sys/unix/hints/macosx @@ -29,3 +29,4 @@ WINTTYLIB=-lncurses CHOWN=true CHGRP=true +VARDIRPERM = 0755 diff --git a/sys/unix/hints/macosx-mu b/sys/unix/hints/macosx-mu new file mode 100644 index 000000000..779dfda87 --- /dev/null +++ b/sys/unix/hints/macosx-mu @@ -0,0 +1,55 @@ +# +# SCCS Id: @(#)macosx-mu 3.5 2007/12/12 +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. +# NetHack may be freely redistributed. See license for details. +# +# Mac OS X (Darwin) hints file +# This is for Mac OS X 10.4.10 (Darwin 8.10). If this doesn't work for some +# other version of either Darwin or Mac OS X, make a new file for that OS, +# don't change this one. +# Useful info: http://www.opensource.apple.com/darwinsource/index.html + +# This is a tty build for a system with multiple users (since it is a tty +# build it does not try to look like a .app application). +# NetHack will be owned by user "games" and group "bin" - change the next 2 +# lines if this is a problem: +GAMEUID = games +GAMEGRP = bin +# NB: "make install" should be run as an admin user: +# sudo make install + +# NB: do NOT use $(wildcard ~$(GAMEUID)) since the user may not exist yet. +PREFIX:=/Users/$(GAMEUID) +SHELLDIR=$(PREFIX)/bin +HACKDIR=$(PREFIX)/nethackdir + +CC=gcc -W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN + +# XXX -g vs -O should go here, -I../include goes in the makefile +CFLAGS=-g -I../include $(CFLAGS2) $(CFLAGS3) +CFLAGS2=-DNOCLIPPING -DNOMAIL -DNOTPARMDECL -DHACKDIR=\"$(HACKDIR)\" +CFLAGS3=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE + +WINSRC = $(WINTTYSRC) +WINOBJ = $(WINTTYOBJ) +WINLIB = $(WINTTYLIB) + +WINTTYLIB=-lncurses + +CHOWN=chown +CHGRP=chgrp + +# We run sgid so the game has access to both HACKDIR and user preferences. +GAMEPERM = 02755 +VARFILEPERM = 0664 +VARDIRPERM = 0775 + +# make sure we have group GAMEUID and group GAMEGRP +PREINSTALL= . sys/unix/hints/macosx.sh user $(GAMEUID); . sys/unix/hints/macosx.sh group $(GAMEGRP); mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL= touch $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf + + +# notes: +#1) ~games/games is owned by root. +#2) group games exists because user games was created via Accounts pane. +#3) who should own/be able to run recover? diff --git a/sys/unix/hints/macosx-x11 b/sys/unix/hints/macosx-x11 index 04e7b7ba7..6a8a05290 100644 --- a/sys/unix/hints/macosx-x11 +++ b/sys/unix/hints/macosx-x11 @@ -32,6 +32,7 @@ CHGRP=true WINSRC = $(WINX11SRC) WINOBJ = $(WINX11OBJ) WINLIB = $(WINX11LIB) +VARDIRPERM = 0755 VARDATND = x11tiles NetHack.ad pet_mark.xbm diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh new file mode 100755 index 000000000..a40f9d99e --- /dev/null +++ b/sys/unix/hints/macosx.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# SCCS Id: @(#)macosx-mu.sh 3.5 2007/12/12 +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. +# NetHack may be freely redistributed. See license for details. +# +# hints helper script for macosx +# DO NOT invoke directly + +cmd=$1 + +case "x$cmd" in +xuser) + user=$2 + gotuser=`niutil -readval . /users/$user name 0 2>/dev/null` + [ -z $gotuser ] && (echo "User $user does not exist." + exit 1; + ) + exit 0 + ;; +#name: dummy1 +#_writers_passwd: dummy1 +#_writers_tim_password: dummy1 +#_writers_picture: dummy1 +#home: /Users/dummy1 +#gid: 504 +#picture: /Library/User Pictures/Animals/Dragonfly.tif +#uid: 504 +#hint: dummy1 +#_writers_hint: dummy1 +#sharedDir: +#_shadow_passwd: +#_writers_realname: dummy1 +#shell: /bin/bash +#passwd: ******** +#authentication_authority: ;ShadowHash; +#realname: dummyname1 +#generateduid: F6D4991C-BDF5-481F-A407-D84C6A2D0E2A +xgroup) + group=$2 + gotgrp=`niutil -readval . /groups/$group name 0 2>/dev/null` + [ -z $gotgrp ] && ( echo "Group $group does not exist." + exit 1 + ) + exit 0 + ;; +#niutil -read . /groups/bin name 0 +#name: bin +#gid: 7 +#passwd: * +#generateduid: ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000007 +#smb_sid: S-1-5-21-107 +#realname: Binary + +*) echo "Unknown command $cmd" + exit 1 + ;; +esac diff --git a/sys/unix/hints/unix b/sys/unix/hints/unix index 39018c548..4f51d2b59 100644 --- a/sys/unix/hints/unix +++ b/sys/unix/hints/unix @@ -23,3 +23,10 @@ WINTTYLIB=-ltermlib CHOWN=chown CHGRP=chgrp + +GAMEUID = games +GAMEGRP = bin + +GAMEPERM = 04755 +VARFILEPERM = 0644 +VARDIRPERM = 0755 diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 5d40e5f02..51ab1a674 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -128,6 +128,11 @@ char *argv[]; if (!strncmp(argv[1], "-s", 2) && strncmp(argv[1], "-style", 6)) { #ifdef CHDIR chdirx(dir,0); +#endif +#ifdef SYSCF + initoptions_init(); + read_config_file(SYSCF_FILE, SET_IN_SYS); + initoptions_finish(); #endif prscore(argc, argv); exit(EXIT_SUCCESS); @@ -148,7 +153,11 @@ char *argv[]; #ifdef __linux__ check_linux_console(); #endif - initoptions(); + initoptions_init(); +#ifdef SYSCF + read_config_file(SYSCF_FILE, SET_IN_SYS); +#endif + initoptions_finish(); exact_username = whoami(); /* @@ -530,6 +539,22 @@ authorize_wizard_mode() pw = getpwuid(uid); } } +#ifdef SYSCF + if (pw && wizards[0]) { + if(wizards[0] == '*') return TRUE; /*allow any user to be wizard*/ + int pwlen = strlen(pw->pw_name); + char *eop = eos(wizards); + char *w = wizards; + while( w+pwlen <= eop ){ + if( ! *w ) break; + if( isspace(*w) ){ w++; continue;} + if( !strncmp(w, pw->pw_name, pwlen) ){ + if( !w[pwlen] || isspace(w[pwlen]) ) return TRUE; + } + while( *w && !isspace(*w) ) w++; + } + } else +#endif if (pw && !strcmp(pw->pw_name, WIZARD_NAME)) return TRUE; #endif /* WIZARD */ return FALSE; -- 2.40.0