From 7679dcf8616e87cbdc587a15b9f7a0eded167313 Mon Sep 17 00:00:00 2001 From: Rob Swindell <rob@synchro.net> Date: Fri, 30 Dec 2022 02:40:13 -0800 Subject: [PATCH] Common login control (e.g. via real name) using new find_login_id() function Previously, many servers and services didn't support login by real name (e.g. issue #469) even if the sysop had that option enabled in SCFG. Move login control settings from node.ini to system (main.ini -> login) The 3 node toggle options: - Allow Login by User Number - Allow Login by Real Name - Always Prompt for Password ... have been now moved from SCFG->Nodes->Node x->Toggle Options to SCFG-System->Toggle Options. If you upgraded to v3.20a before now, you'll want to double-check these settings to make sure they're how you want them set. New upgraders that run upgrade_to_v320.js (e.g. via 'jsexec update') will get these settings migrated automatically. Added some error detection/logging to upgrade_to_v320.js when failing to open .cnf files. Constified some more user/login related function args and return types. --- exec/load/sbbsdefs.js | 5 +++ exec/upgrade_to_v320.js | 19 +++++++++ src/sbbs3/answer.cpp | 8 ++-- src/sbbs3/ftpsrvr.c | 4 +- src/sbbs3/js_system.c | 8 ++++ src/sbbs3/login.cpp | 26 +++-------- src/sbbs3/mailsrvr.c | 6 +-- src/sbbs3/sbbs.h | 6 +-- src/sbbs3/sbbsdefs.h | 89 ++++++++++++++++++++------------------ src/sbbs3/scfg/scfgnode.c | 67 +---------------------------- src/sbbs3/scfg/scfgsys.c | 90 ++++++++++++++++++++++++++++++++------- src/sbbs3/scfgdefs.h | 3 +- src/sbbs3/scfglib1.c | 1 + src/sbbs3/scfgsave.c | 1 + src/sbbs3/services.c | 6 +-- src/sbbs3/userdat.c | 15 +++++++ src/sbbs3/userdat.h | 2 + src/sbbs3/websrvr.c | 7 +-- 18 files changed, 198 insertions(+), 165 deletions(-) diff --git a/exec/load/sbbsdefs.js b/exec/load/sbbsdefs.js index 647de21927..66b42e767b 100644 --- a/exec/load/sbbsdefs.js +++ b/exec/load/sbbsdefs.js @@ -60,6 +60,11 @@ var SYS_USRVDELM =(1<<30); /* Users can see deleted msgs */ var SYS_SYSVDELM =(1<<31); /* Sysops can see deleted msgs */ /********************************************/ + // system.login_settings +var LOGIN_USERNUM =(1<<0); // Allow logins by user number +var LOGIN_REALNAME =(1<<1); // Allow logins by user's real name +var LOGIN_PWPROMPT =(1<<2); // Always display password prompt, even for bad login-id + /********************************************/ /* bbs.sys_status */ /********************************************/ diff --git a/exec/upgrade_to_v320.js b/exec/upgrade_to_v320.js index b20f001773..69d3bd509e 100755 --- a/exec/upgrade_to_v320.js +++ b/exec/upgrade_to_v320.js @@ -1,13 +1,19 @@ // Convert SBBS v3.1x ctrl/*.cnf to SBBS v3.2 ctrl/*.ini print("Upgrading Synchronet v3.1x config files to v3.20"); +load('sbbsdefs.js'); var cnflib = load({}, 'cnflib.js'); +var node_settings; function upgrade_node(dir) { var path = dir + "node.cnf"; print(path + " -> node.ini"); var cnf = cnflib.read(path); + if(!cnf) { + alert("Error reading " + path); + exit(1); + } var ini = new File(dir + "node.ini"); ini.ini_section_separator = ""; if(!ini.open("w+")) { @@ -16,11 +22,16 @@ function upgrade_node(dir) } ini.iniSetObject(null, cnf); ini.close(); + node_settings = cnf.settings; } //--------------------------------------------------------------------------- print("main.cnf -> main.ini"); var cnf = cnflib.read("main.cnf"); +if(!cnf) { + alert("Error reading main.cnf"); + exit(1); +} var ini = new File("main.ini"); ini.ini_section_separator = ""; if(!ini.open("w+")) { @@ -89,6 +100,14 @@ for(var i in cnf.node_dir) { upgrade_node(path); } delete cnf.node_dir; +cnf.login = 0; +if(node_settings & NM_LOGON_R) + cnf.login |= LOGIN_REALNAME; +if(node_settings & NM_LOGON_P) + cnf.login |= LOGIN_PWPROMPT; +if(!(node_settings & NM_NO_NUM)) + cnf.login |= LOGIN_USERNUM; + for(var i in cnf.validation_set) ini.iniSetObject("valset:" + i, cnf.validation_set[i]); delete cnf.validation_set; diff --git a/src/sbbs3/answer.cpp b/src/sbbs3/answer.cpp index 62486e3147..f6883e5edf 100644 --- a/src/sbbs3/answer.cpp +++ b/src/sbbs3/answer.cpp @@ -91,7 +91,7 @@ bool sbbs_t::answer() truncstr(terminal,"/"); useron.number = 0; if(rlogin_name[0]) - useron.number=matchuser(&cfg, rlogin_name, /* sysop_alias: */FALSE); + useron.number = find_login_id(&cfg, rlogin_name); if(useron.number) { getuserdat(&cfg,&useron); SAFEPRINTF(path,"%srlogin.cfg",cfg.ctrl_dir); @@ -194,9 +194,7 @@ bool sbbs_t::answer() rlogin_name[0] = 0; pthread_mutex_unlock(&ssh_mutex); } - useron.number=matchuser(&cfg, rlogin_name, /* sysop_alias: */FALSE); - if(!useron.number && check_realname(&cfg, rlogin_name) && cfg.node_misc & NM_LOGON_R) - useron.number = finduserstr(0, USER_NAME, rlogin_name); + useron.number = find_login_id(&cfg, rlogin_name); if(useron.number) { getuserdat(&cfg,&useron); for(i=0;i<3 && online;i++) { @@ -464,7 +462,7 @@ bool sbbs_t::answer() if(!useron.number && rlogin_name[0]!=0 && !(cfg.sys_misc&SM_CLOSED) - && !matchuser(&cfg, rlogin_name, /* Sysop alias: */FALSE) + && !find_login_id(&cfg, rlogin_name) && !::trashcan(&cfg, rlogin_name, "name")) { lprintf(LOG_INFO, "%s !UNKNOWN specified username: '%s', starting new user signup", client.protocol,rlogin_name); bprintf("%s: %s\r\n", text[UNKNOWN_USER], rlogin_name); diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c index dfce5608ec..11716d9a8c 100644 --- a/src/sbbs3/ftpsrvr.c +++ b/src/sbbs3/ftpsrvr.c @@ -2423,7 +2423,7 @@ static void ctrl_thread(void* arg) SKIP_WHITESPACE(p); truncsp(p); SAFECOPY(user.alias,p); - user.number=matchuser(&scfg,user.alias,FALSE /*sysop_alias*/); + user.number = find_login_id(&scfg, user.alias); if(!user.number && (stricmp(user.alias,"anonymous") == 0 || stricmp(user.alias, "ftp") == 0)) user.number=matchuser(&scfg,"guest",FALSE); if(user.number && getuserdat(&scfg, &user)==0 && user.pass[0]==0) @@ -2439,7 +2439,7 @@ static void ctrl_thread(void* arg) SKIP_WHITESPACE(p); SAFECOPY(password,p); - user.number=matchuser(&scfg,user.alias,FALSE /*sysop_alias*/); + user.number = find_login_id(&scfg, user.alias); if(!user.number) { if(scfg.sys_misc&SM_ECHO_PW) lprintf(LOG_WARNING,"%04d !UNKNOWN USER: '%s' (password: %s)",sock,user.alias,p); diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c index 7a61ccc7f9..19488ef4ab 100644 --- a/src/sbbs3/js_system.c +++ b/src/sbbs3/js_system.c @@ -41,6 +41,7 @@ enum { ,SYS_PROP_OP_AVAIL ,SYS_PROP_ID ,SYS_PROP_MISC + ,SYS_PROP_LOGIN ,SYS_PROP_INETADDR ,SYS_PROP_LOCATION ,SYS_PROP_TIMEZONE @@ -148,6 +149,9 @@ static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) case SYS_PROP_MISC: *vp=UINT_TO_JSVAL(cfg->sys_misc); break; + case SYS_PROP_LOGIN: + *vp=UINT_TO_JSVAL(cfg->sys_login); + break; case SYS_PROP_INETADDR: p=cfg->sys_inetaddr; break; @@ -372,6 +376,9 @@ static JSBool js_system_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict case SYS_PROP_MISC: JS_ValueToECMAUint32(cx, *vp, (uint32_t*)&sys->cfg->sys_misc); break; + case SYS_PROP_LOGIN: + JS_ValueToECMAUint32(cx, *vp, (uint32_t*)&sys->cfg->sys_login); + break; case SYS_PROP_OP_AVAIL: if(!set_sysop_availability(sys->cfg, JSVAL_TO_BOOLEAN(*vp))) { JS_ReportError(cx, "%s: Failed to set sysop availability", __FUNCTION__); @@ -396,6 +403,7 @@ static jsSyncPropertySpec js_system_properties[] = { { "operator_available", SYS_PROP_OP_AVAIL, JSPROP_ENUMERATE, 31801 }, { "qwk_id", SYS_PROP_ID, SYSOBJ_FLAGS, 310 }, { "settings", SYS_PROP_MISC, JSPROP_ENUMERATE, 310 }, + { "login_settings", SYS_PROP_LOGIN, JSPROP_ENUMERATE, 32000 }, { "inetaddr", SYS_PROP_INETADDR, JSPROP_READONLY, 310 }, /* alias */ { "inet_addr", SYS_PROP_INETADDR, SYSOBJ_FLAGS, 311 }, { "location", SYS_PROP_LOCATION, SYSOBJ_FLAGS, 310 }, diff --git a/src/sbbs3/login.cpp b/src/sbbs3/login.cpp index 9d3c7d4777..e2c7bd5d1e 100644 --- a/src/sbbs3/login.cpp +++ b/src/sbbs3/login.cpp @@ -22,7 +22,7 @@ #include "sbbs.h" #include "cmdshell.h" -char* sbbs_t::parse_login(char* str) +const char* sbbs_t::parse_login(const char* str) { sys_status &= ~(SS_QWKLOGON|SS_FASTLOGON); @@ -38,35 +38,23 @@ char* sbbs_t::parse_login(char* str) return str; } -int sbbs_t::login(char *username, char *pw_prompt, const char* user_pw, const char* sys_pw) +int sbbs_t::login(const char *username, char *pw_prompt, const char* user_pw, const char* sys_pw) { char str[128]; char tmp[512]; long useron_misc=useron.misc; - useron.number=0; username = parse_login(username); - if(!(cfg.node_misc&NM_NO_NUM) && IS_DIGIT(username[0])) { - useron.number=atoi(username); + useron.number = find_login_id(&cfg, username); + if(useron.number) { getuserdat(&cfg,&useron); if(useron.number && useron.misc&(DELETED|INACTIVE)) - useron.number=0; - } - - if(!useron.number) { - useron.number=matchuser(&cfg,username,FALSE); - if(!useron.number && check_realname(&cfg, username) && cfg.node_misc & NM_LOGON_R) - useron.number = finduserstr(0, USER_NAME, username); - if(useron.number) { - getuserdat(&cfg,&useron); - if(useron.number && useron.misc&(DELETED|INACTIVE)) - useron.number=0; - } + useron.number=0; } if(!useron.number) { - if((cfg.node_misc&NM_LOGON_P) && pw_prompt != NULL) { + if((cfg.sys_login & LOGIN_PWPROMPT) && pw_prompt != NULL) { SAFECOPY(useron.alias,username); bputs(pw_prompt); console|=CON_R_ECHOX; @@ -140,7 +128,7 @@ int sbbs_t::login(char *username, char *pw_prompt, const char* user_pw, const ch return(LOGIC_TRUE); } -void sbbs_t::badlogin(char* user, char* passwd, const char* protocol, xp_sockaddr* addr, bool delay) +void sbbs_t::badlogin(const char* user, const char* passwd, const char* protocol, xp_sockaddr* addr, bool delay) { char reason[128]; char host_name[128]; diff --git a/src/sbbs3/mailsrvr.c b/src/sbbs3/mailsrvr.c index deea7c25c3..6330bc92ac 100644 --- a/src/sbbs3/mailsrvr.c +++ b/src/sbbs3/mailsrvr.c @@ -1295,7 +1295,7 @@ static void pop3_thread(void* arg) SKIP_WHITESPACE(p); SAFECOPY(password,p); } - user.number=matchuser(&scfg,username,FALSE /*sysop_alias*/); + user.number = find_login_id(&scfg, username); if(!user.number) { if(scfg.sys_misc&SM_ECHO_PW) lprintf(LOG_NOTICE,"%04d %s [%s] !UNKNOWN USER: '%s' (password: %s)" @@ -4190,7 +4190,7 @@ static void smtp_thread(void* arg) SAFECOPY(user_pass,p); } - if((relay_user.number=matchuser(&scfg,user_name,FALSE))==0) { + if((relay_user.number = find_login_id(&scfg, user_name))==0) { if(scfg.sys_misc&SM_ECHO_PW) lprintf(LOG_WARNING,"%04d %s %s !UNKNOWN USER: '%s' (password: %s)" ,socket, client.protocol, client_id, user_name, user_pass); @@ -4277,7 +4277,7 @@ static void smtp_thread(void* arg) else p=response; SAFECOPY(user_name,response); - if((relay_user.number=matchuser(&scfg,user_name,FALSE))==0) { + if((relay_user.number = find_login_id(&scfg, user_name))==0) { lprintf(LOG_WARNING,"%04d %s %s !UNKNOWN USER: '%s'" ,socket, client.protocol, client_id, user_name); badlogin(socket, session, client.protocol, badauth_rsp, user_name, NULL, host_name, &smtp.client_addr); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index 554e11cafb..875501cdff 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -965,9 +965,9 @@ public: int putnodeext(uint number, char * str); /* login.ccp */ - int login(char *user_name, char *pw_prompt, const char* user_pw = NULL, const char* sys_pw = NULL); - void badlogin(char* user, char* passwd, const char* protocol=NULL, xp_sockaddr* addr=NULL, bool delay=true); - char* parse_login(char*); + int login(const char *user_name, char *pw_prompt, const char* user_pw = NULL, const char* sys_pw = NULL); + void badlogin(const char* user, const char* passwd, const char* protocol=NULL, xp_sockaddr* addr=NULL, bool delay=true); + const char* parse_login(const char*); /* answer.cpp */ bool answer(void); diff --git a/src/sbbs3/sbbsdefs.h b/src/sbbs3/sbbsdefs.h index 9375801d72..abefc131f9 100644 --- a/src/sbbs3/sbbsdefs.h +++ b/src/sbbs3/sbbsdefs.h @@ -130,48 +130,53 @@ #define UQ_COLORTERM (1L<<20) /* Ask if new user has color terminal */ #define UQ_DUPNETMAIL (1L<<21) /* Don't allow duplicate e-mail address */ - /* Different bits in sys_misc */ -#define SM_CLOSED (1L<<0) /* System is clsoed to New Users */ -#define SM_SYSSTAT (1L<<1) /* Sysops activity included in statistics */ -#define SM_NOSYSINFO (1L<<2) /* Suppress system info display at logon */ -#define SM_PWEDIT (1L<<3) /* Allow users to change their passwords */ -#define SM_RA_EMU (1L<<4) /* Reverse R/A commands at msg read prompt */ -#define SM_ANON_EM (1L<<5) /* Allow anonymous e-mail */ -#define SM_LISTLOC (1L<<6) /* Use location of caller in user lists */ -#define SM_WILDCAT (1L<<7) /* Expand Wildcat color codes in messages */ -#define SM_PCBOARD (1L<<8) /* Expand PCBoard color codes in messages */ -#define SM_WWIV (1L<<9) /* Expand WWIV color codes in messages */ -#define SM_CELERITY (1L<<10) /* Expand Celerity color codes in messages */ -#define SM_RENEGADE (1L<<11) /* Expand Renegade color codes in messages */ -#define SM_ECHO_PW (1L<<12) /* Echo passwords locally */ -#define SM_SYSPASSLOGIN (1L<<13) /* Require system password for sysop login */ -#define SM_AUTO_DST (1L<<14) /* Automatic Daylight Savings Toggle (US) */ -#define SM_R_SYSOP (1L<<15) /* Allow remote sysop logon/commands */ -#define SM_QUOTE_EM (1L<<16) /* Allow quoting of e-mail */ -#define SM_EURODATE (1L<<17) /* Europian date format (DD/MM/YY) */ -#define SM_MILITARY (1L<<18) /* Military time format */ -#define SM_TIMEBANK (1L<<19) /* Allow time bank functions */ -#define SM_FILE_EM (1L<<20) /* Allow file attachments in E-mail */ -#define SM_SHRTPAGE (1L<<21) /* Short sysop page */ -#define SM_TIME_EXP (1L<<22) /* Set to expired values if out-of-time */ -#define SM_FASTMAIL (1L<<23) /* Fast e-mail storage mode */ -#define SM_NONODELIST (1L<<24) /* Suppress active node list during logon */ -#define SM_UNUSED2 (1L<<25) /* */ -#define SM_FWDTONET (1L<<26) /* Allow forwarding of e-mail to netmail */ -#define SM_DELREADM (1L<<27) /* Delete read mail automatically */ -#define SM_NOCDTCVT (1L<<28) /* No credit to minute conversions allowed */ -#define SM_DELEMAIL (1L<<29) /* Physically remove deleted e-mail immed. */ -#define SM_USRVDELM (1L<<30) /* Users can see deleted msgs */ -#define SM_SYSVDELM (1L<<31) /* Sysops can see deleted msgs */ - - /* Different bits in node_misc */ -#define NM_NO_NUM (1<<8) /* Don't allow logons by user number */ -#define NM_LOGON_R (1<<9) /* Allow logons by user real name */ -#define NM_LOGON_P (1<<10) /* Secure logons (always ask for password) */ -#define NM_LOWPRIO (1<<15) /* Always use low priority input */ -#define NM_7BITONLY (1L<<16) /* Except 7-bit input only (E71 terminals) */ -#define NM_NOPAUSESPIN (1L<<18) /* No spinning cursor at pause prompt */ -#define NM_CLOSENODEDAB (1L<<19) /* Keep node.dab file closed (for Samba) */ + // Different bits in sys_misc +#define SM_CLOSED (1<<0) // System is clsoed to New Users +#define SM_SYSSTAT (1<<1) // Sysops activity included in statistics +#define SM_NOSYSINFO (1<<2) // Suppress system info display at logon +#define SM_PWEDIT (1<<3) // Allow users to change their passwords +#define SM_RA_EMU (1<<4) // Reverse R/A commands at msg read prompt +#define SM_ANON_EM (1<<5) // Allow anonymous e-mail +#define SM_LISTLOC (1<<6) // Use location of caller in user lists +#define SM_WILDCAT (1<<7) // Expand Wildcat color codes in messages +#define SM_PCBOARD (1<<8) // Expand PCBoard color codes in messages +#define SM_WWIV (1<<9) // Expand WWIV color codes in messages +#define SM_CELERITY (1<<10) // Expand Celerity color codes in messages +#define SM_RENEGADE (1<<11) // Expand Renegade color codes in messages +#define SM_ECHO_PW (1<<12) // Echo passwords locally +#define SM_SYSPASSLOGIN (1<<13) // Require system password for sysop login +#define SM_AUTO_DST (1<<14) // Automatic Daylight Savings Toggle (US) +#define SM_R_SYSOP (1<<15) // Allow remote sysop login/commands +#define SM_QUOTE_EM (1<<16) // Allow quoting of e-mail +#define SM_EURODATE (1<<17) // European date format (DD/MM/YY) +#define SM_MILITARY (1<<18) // Military (24hr) time format +#define SM_TIMEBANK (1<<19) // Allow time bank functions +#define SM_FILE_EM (1<<20) // Allow file attachments in E-mail +#define SM_SHRTPAGE (1<<21) // Short sysop page +#define SM_TIME_EXP (1<<22) // Set to expired values if out-of-time +#define SM_FASTMAIL (1<<23) // Fast e-mail storage mode +#define SM_NONODELIST (1<<24) // Suppress active node list during logon +#define SM_UNUSED2 (1<<25) +#define SM_FWDTONET (1<<26) // Allow forwarding of e-mail to netmail +#define SM_DELREADM (1<<27) // Delete read mail automatically +#define SM_NOCDTCVT (1<<28) // No credit to minute conversions allowed +#define SM_DELEMAIL (1<<29) // Physically remove deleted e-mail immed. +#define SM_USRVDELM (1<<30) // Users can see deleted msgs +#define SM_SYSVDELM (1<<31) // Sysops can see deleted msgs + + // Bit flags for scfg_t.login +#define LOGIN_USERNUM (1<<0) // Allow logins by user number +#define LOGIN_REALNAME (1<<1) // Allow logins by user's real name +#define LOGIN_PWPROMPT (1<<2) // Always display password prompt, even for bad login-id + + // Different bits in node_misc +#define NM_NO_NUM (1<<8) // Don't allow logins by user number (deprecated) +#define NM_LOGON_R (1<<9) // Allow logins by user real name (deprecated) +#define NM_LOGON_P (1<<10) // Secure logins (always ask for password) (deprecated) +#define NM_LOWPRIO (1<<15) // Always use low priority input +#define NM_7BITONLY (1<<16) // Except 7-bit input only (E71 terminals) +#define NM_NOPAUSESPIN (1<<18) // No spinning cursor at pause prompt +#define NM_CLOSENODEDAB (1<<19) // Keep node.dab file closed (for Samba) /* Bit values for level_misc[x] */ #define LEVEL_EXPTOLVL (1<<0) /* Expire to level_expireto[x] */ diff --git a/src/sbbs3/scfg/scfgnode.c b/src/sbbs3/scfg/scfgnode.c index 526d8a0ccf..d7a5ea6cce 100644 --- a/src/sbbs3/scfg/scfgnode.c +++ b/src/sbbs3/scfg/scfgnode.c @@ -215,12 +215,6 @@ void node_cfg() done=0; while(!done) { i=0; - sprintf(opt[i++],"%-27.27s%s","Allow Login by User Number" - ,cfg.node_misc&NM_NO_NUM ? "No":"Yes"); - sprintf(opt[i++],"%-27.27s%s","Allow Login by Real Name" - ,cfg.node_misc&NM_LOGON_R ? "Yes":"No"); - sprintf(opt[i++],"%-27.27s%s","Always Prompt for Password" - ,cfg.node_misc&NM_LOGON_P ? "Yes":"No"); sprintf(opt[i++],"%-27.27s%s","Allow 8-bit Remote Logins" ,cfg.node_misc&NM_7BITONLY ? "No":"Yes"); sprintf(opt[i++],"%-27.27s%s","Spinning Pause Prompt" @@ -243,63 +237,6 @@ void node_cfg() done=1; break; case 0: - i=cfg.node_misc&NM_NO_NUM ? 1:0; - uifc.helpbuf= - "`Allow Login by User Number:`\n" - "\n" - "If you want users to be able login using their user number at the\n" - "login prompt, set this option to `Yes`.\n" - ; - i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 - ,"Allow Login by User Number",uifcYesNoOpts); - if(i==0 && cfg.node_misc&NM_NO_NUM) { - cfg.node_misc&=~NM_NO_NUM; - uifc.changes=1; - } - else if(i==1 && !(cfg.node_misc&NM_NO_NUM)) { - cfg.node_misc|=NM_NO_NUM; - uifc.changes=1; - } - break; - case 1: - i=cfg.node_misc&NM_LOGON_R ? 0:1; - uifc.helpbuf= - "`Allow Login by Real Name:`\n" - "\n" - "If you want users to be able login using their real name as well as\n" - "their alias, set this option to `Yes`.\n" - ; - i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 - ,"Allow Login by Real Name",uifcYesNoOpts); - if(i==0 && !(cfg.node_misc&NM_LOGON_R)) { - cfg.node_misc|=NM_LOGON_R; - uifc.changes=1; - } - else if(i==1 && (cfg.node_misc&NM_LOGON_R)) { - cfg.node_misc&=~NM_LOGON_R; - uifc.changes=1; - } - break; - case 2: - i=cfg.node_misc&NM_LOGON_P ? 0:1; - uifc.helpbuf= - "`Always Prompt for Password:`\n" - "\n" - "If you want to have attempted logins using an unknown user name still\n" - "prompt for a password (i.e. for enhanced security), set this option to `Yes`.\n" - ; - i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 - ,"Always Prompt for Password",uifcYesNoOpts); - if(i==0 && !(cfg.node_misc&NM_LOGON_P)) { - cfg.node_misc|=NM_LOGON_P; - uifc.changes=1; - } - else if(i==1 && (cfg.node_misc&NM_LOGON_P)) { - cfg.node_misc&=~NM_LOGON_P; - uifc.changes=1; - } - break; - case 3: i=cfg.node_misc&NM_7BITONLY ? 0:1; uifc.helpbuf= "`Allow 8-bit Remote Input During Login:`\n" @@ -319,7 +256,7 @@ void node_cfg() uifc.changes=1; } break; - case 4: + case 1: i=cfg.node_misc&NM_NOPAUSESPIN ? 1:0; uifc.helpbuf= "`Spinning Pause Prompt:`\n" @@ -338,7 +275,7 @@ void node_cfg() uifc.changes=1; } break; - case 5: + case 2: i=cfg.node_misc&NM_CLOSENODEDAB ? 1:0; uifc.helpbuf= "`Keep Node File Open:`\n" diff --git a/src/sbbs3/scfg/scfgsys.c b/src/sbbs3/scfg/scfgsys.c index 5cbd32a266..10f8482d4c 100644 --- a/src/sbbs3/scfg/scfgsys.c +++ b/src/sbbs3/scfg/scfgsys.c @@ -63,6 +63,7 @@ static void configure_dst(void) void sys_cfg(void) { static int sys_dflt,adv_dflt,tog_dflt,new_dflt; + static int tog_bar; static int adv_bar; char str[81],done=0; int i,j,k,dflt,bar; @@ -532,6 +533,10 @@ void sys_cfg(void) i=0; sprintf(opt[i++],"%-33.33s%s","Allow User Aliases" ,cfg.uq&UQ_ALIASES ? "Yes" : "No"); + sprintf(opt[i++],"%-33.33s%s","Allow Login by Real Name" + ,(!(cfg.uq&UQ_ALIASES) || cfg.sys_login & LOGIN_REALNAME) ? "Yes" : "No"); + sprintf(opt[i++],"%-33.33s%s","Allow Login by User Number" + ,(cfg.sys_login & LOGIN_USERNUM) ? "Yes" : "No"); sprintf(opt[i++],"%-33.33s%s","Allow Time Banking" ,cfg.sys_misc&SM_TIMEBANK ? "Yes" : "No"); sprintf(opt[i++],"%-33.33s%s","Allow Credit Conversions" @@ -540,6 +545,8 @@ void sys_cfg(void) ,cfg.sys_misc&SM_R_SYSOP ? "Yes" : "No"); sprintf(opt[i++],"%-33.33s%s","Display/Log Passwords Locally" ,cfg.sys_misc&SM_ECHO_PW ? "Yes" : "No"); + sprintf(opt[i++],"%-33.33s%s","Always Prompt for Password" + ,cfg.sys_login & LOGIN_PWPROMPT ? "Yes":"No"); sprintf(opt[i++],"%-33.33s%s","Short Sysop Page" ,cfg.sys_misc&SM_SHRTPAGE ? "Yes" : "No"); sprintf(opt[i++],"%-33.33s%s","Include Sysop in Statistics" @@ -567,12 +574,12 @@ void sys_cfg(void) "This is a menu of system related options that can be toggled between\n" "two or more states, such as `Yes` and `No`.\n" ; - switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,41,&tog_dflt,0 + switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,41,&tog_dflt,&tog_bar ,"Toggle Options",opt)) { case -1: done=1; break; - case 0: + case __COUNTER__: i=cfg.uq&UQ_ALIASES ? 0:1; uifc.helpbuf= "`Allow Users to Use Aliases:`\n" @@ -592,7 +599,41 @@ void sys_cfg(void) uifc.changes=1; } break; - case 1: + case __COUNTER__: + if(!(cfg.uq&UQ_ALIASES)) + break; + i = (cfg.sys_login & LOGIN_REALNAME) ? 0:1; + uifc.helpbuf= + "`Allow Login by Real Name:`\n" + "\n" + "If you want users to be able login using their real name as well as\n" + "their alias, set this option to `Yes`.\n" + ; + i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 + ,"Allow Login by Real Name",uifcYesNoOpts); + if((i==0 && !(cfg.sys_login & LOGIN_REALNAME)) + || (i==1 && (cfg.sys_login & LOGIN_REALNAME))) { + cfg.sys_login ^= LOGIN_REALNAME; + uifc.changes=1; + } + break; + case __COUNTER__: + i = (cfg.sys_login & LOGIN_USERNUM) ? 0:1; + uifc.helpbuf= + "`Allow Login by User Number:`\n" + "\n" + "If you want users to be able login using their user number at the\n" + "login prompt, set this option to `Yes`.\n" + ; + i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 + ,"Allow Login by User Number",uifcYesNoOpts); + if((i==0 && !(cfg.sys_login & LOGIN_USERNUM)) + || (i==1 && (cfg.sys_login & LOGIN_USERNUM))) { + cfg.sys_login ^= LOGIN_USERNUM; + uifc.changes=1; + } + break; + case __COUNTER__: i=cfg.sys_misc&SM_TIMEBANK ? 0:1; uifc.helpbuf= "`Allow Time Banking:`\n" @@ -614,7 +655,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 2: + case __COUNTER__: i=cfg.sys_misc&SM_NOCDTCVT ? 1:0; uifc.helpbuf= "`Allow Credits to be Converted into Minutes:`\n" @@ -635,7 +676,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 3: + case __COUNTER__: i=cfg.sys_misc&SM_R_SYSOP ? 0:1; uifc.helpbuf= "`Allow Sysop Access:`\n" @@ -654,7 +695,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 4: + case __COUNTER__: i=cfg.sys_misc&SM_ECHO_PW ? 0:1; uifc.helpbuf= "`Display/Log Passwords Locally:`\n" @@ -675,7 +716,24 @@ void sys_cfg(void) uifc.changes=1; } break; - case 5: + case __COUNTER__: + i=cfg.sys_login & LOGIN_PWPROMPT ? 0:1; + uifc.helpbuf= + "`Always Prompt for Password:`\n" + "\n" + "If you want to have attempted logins using an unknown user name still\n" + "prompt for a password (i.e. for enhanced security), set this option to\n" + "`Yes`.\n" + ; + i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 + ,"Always Prompt for Password",uifcYesNoOpts); + if((i==0 && !(cfg.sys_login & LOGIN_PWPROMPT)) + || (i==1 && (cfg.sys_login & LOGIN_PWPROMPT))) { + cfg.sys_login ^= LOGIN_PWPROMPT; + uifc.changes=1; + } + break; + case __COUNTER__: i=cfg.sys_misc&SM_SHRTPAGE ? 0:1; uifc.helpbuf= "`Short Sysop Page:`\n" @@ -694,7 +752,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 6: + case __COUNTER__: i=cfg.sys_misc&SM_SYSSTAT ? 0:1; uifc.helpbuf= "`Include Sysop Activity in System Statistics:`\n" @@ -716,7 +774,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 7: + case __COUNTER__: i=cfg.sys_misc&SM_CLOSED ? 0:1; uifc.helpbuf= "`Closed to New Users:`\n" @@ -734,7 +792,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 8: + case __COUNTER__: i=cfg.sys_misc&SM_LISTLOC ? 0:1; uifc.helpbuf= "`User Location in User Lists:`\n" @@ -755,7 +813,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 9: + case __COUNTER__: i=cfg.sys_misc&SM_MILITARY ? 0:1; uifc.helpbuf= "`Military:`\n" @@ -774,7 +832,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 10: + case __COUNTER__: i=cfg.sys_misc&SM_EURODATE ? 0:1; uifc.helpbuf= "`European Date Format:`\n" @@ -793,7 +851,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 11: + case __COUNTER__: i=cfg.sys_misc&SM_TIME_EXP ? 0:1; uifc.helpbuf= "`User Expires When Out-of-time:`\n" @@ -812,7 +870,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 12: + case __COUNTER__: i=cfg.sys_misc&SM_SYSPASSLOGIN ? 0:1; uifc.helpbuf= "`Require System Password for Sysop Login:`\n" @@ -832,7 +890,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 13: + case __COUNTER__: i=cfg.sys_misc&SM_NOSYSINFO ? 1:0; uifc.helpbuf= "`Display System Information During Logon:`\n" @@ -851,7 +909,7 @@ void sys_cfg(void) uifc.changes=1; } break; - case 14: + case __COUNTER__: i=cfg.sys_misc&SM_NONODELIST ? 1:0; uifc.helpbuf= "`Display Active Node List During Logon:`\n" diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index 5893b94d32..dbc37f5802 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -470,7 +470,8 @@ typedef struct uint16_t mdm_ansdelay; /* Modem seconds to delay after answer */ uchar mdm_rings; /* Rings to wait till answer */ - int32_t sys_misc; /* System Misc Settings */ + uint32_t sys_login; // Login Settings (Bit-flags) + uint32_t sys_misc; /* System Misc Settings */ char sys_pass[41]; /* System Pass Word */ char sys_name[41]; /* System Name */ char sys_id[LEN_QWKID+1];/* System ID for QWK Packets */ diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c index 6cfc349f50..4884d0ec03 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -110,6 +110,7 @@ BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) cfg->sys_timezone = iniGetShortInt(ini, ROOT_SECTION, "timezone", 0); cfg->sys_misc = iniGetUInteger(ini, ROOT_SECTION, "settings", 0); + cfg->sys_login = iniGetUInteger(ini, ROOT_SECTION, "login", 0); cfg->sys_pwdays = iniGetInteger(ini, ROOT_SECTION, "pwdays", 0); cfg->sys_deldays = iniGetInteger(ini, ROOT_SECTION, "deldays", 0); cfg->sys_exp_warn = iniGetInteger(ini, ROOT_SECTION, "exp_warn", 0); diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c index ae5d28656c..a7cc2b79db 100644 --- a/src/sbbs3/scfgsave.c +++ b/src/sbbs3/scfgsave.c @@ -128,6 +128,7 @@ BOOL write_main_cfg(scfg_t* cfg, int backup_level) iniSetString(&ini, ROOT_SECTION, "password", cfg->sys_pass, NULL); iniSetShortInt(&ini, ROOT_SECTION, "timezone", cfg->sys_timezone, NULL); iniSetHexInt(&ini, ROOT_SECTION, "settings", cfg->sys_misc, NULL); + iniSetHexInt(&ini, ROOT_SECTION, "login", cfg->sys_login, NULL); iniSetShortInt(&ini, ROOT_SECTION, "lastnode", cfg->sys_lastnode, NULL); iniSetShortInt(&ini, ROOT_SECTION, "pwdays", cfg->sys_pwdays, NULL); iniSetShortInt(&ini, ROOT_SECTION, "deldays", cfg->sys_deldays, NULL); diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index f70d035001..817077a148 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -385,10 +385,8 @@ js_login(JSContext *cx, uintN argc, jsval *arglist) putmsgptrs(&scfg, &client->user, client->subscan); } - if(IS_DIGIT(*user)) - client->user.number=atoi(user); - else if(*user) - client->user.number=matchuser(&scfg,user,FALSE); + if(*user) + client->user.number = find_login_id(&scfg, user); if(getuserdat(&scfg,&client->user)!=0) { lprintf(LOG_NOTICE,"%04d %s !USER NOT FOUND: '%s'" diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index afb7a974ea..6d09c0a39c 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -146,6 +146,21 @@ BOOL matchusername(scfg_t* cfg, const char* name, const char* comp) return *np == '\0' && (*cp == '\0' || *cp == '@'); } +uint find_login_id(scfg_t* cfg, const char* user_id) +{ + int usernum; + + if((cfg->sys_login & LOGIN_USERNUM) && IS_DIGIT(user_id[0])) + return atoi(user_id); + + usernum = matchuser(cfg, user_id, /* sysop_alias: */FALSE); + if(usernum < 1 && check_realname(cfg, user_id) && (cfg->sys_login & LOGIN_REALNAME)) + usernum = finduserstr(cfg, 0, USER_NAME, user_id + ,/* del: */FALSE, /* next: */FALSE + ,/* Progress_cb: */NULL, /* cbdata: */NULL); + return usernum; +} + /****************************************************************************/ uint total_users(scfg_t* cfg) { diff --git a/src/sbbs3/userdat.h b/src/sbbs3/userdat.h index 5894890fde..d41980ad78 100644 --- a/src/sbbs3/userdat.h +++ b/src/sbbs3/userdat.h @@ -89,6 +89,8 @@ DLLEXPORT int getnodeclient(scfg_t*, uint number, client_t*, time_t*); DLLEXPORT uint finduserstr(scfg_t*, uint usernumber, enum user_field, const char *str ,BOOL del, BOOL next, void (*progress)(void*, int, int), void* cbdata); +DLLEXPORT uint find_login_id(scfg_t*, const char* user_id); + DLLEXPORT BOOL chk_ar(scfg_t*, uchar* str, user_t*, client_t*); /* checks access requirements */ DLLEXPORT uint32_t getusermisc(scfg_t*, int usernumber); diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index c2e066e713..5b943ba099 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -1932,7 +1932,7 @@ static BOOL check_ars(http_session_t * session) } /* Require a password */ - i=matchuser(&scfg, session->req.auth.username, FALSE); + i = find_login_id(&scfg, session->req.auth.username); if(i==0) { if(session->last_user_num!=0) { if(session->last_user_num>0) @@ -5510,10 +5510,7 @@ js_login(JSContext *cx, uintN argc, jsval *arglist) memset(&user,0,sizeof(user)); - if(IS_DIGIT(*username)) - user.number=atoi(username); - else if(*username) - user.number=matchuser(&scfg,username,FALSE); + user.number = find_login_id(&scfg, username); if(getuserdat(&scfg,&user)!=0) { lprintf(LOG_NOTICE,"%04d !USER NOT FOUND: '%s'" -- GitLab