|
|
1.1 root 1: /* newuser.cpp */
2:
3: /* Synchronet new user routine */
4:
1.1.1.2 ! root 5: /* $Id: newuser.cpp,v 1.41 2004/10/21 09:03:11 rswindell Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
1.1.1.2 ! root 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39: #include "cmdshell.h"
40:
41: /****************************************************************************/
42: /* This function is invoked when a user enters "NEW" at the NN: prompt */
43: /* Prompts user for personal information and then sends feedback to sysop. */
44: /* Called from function waitforcall */
45: /****************************************************************************/
1.1.1.2 ! root 46: BOOL sbbs_t::newuser()
1.1 root 47: {
48: char c,str[512];
49: char tmp[512];
1.1.1.2 ! root 50: uint i;
! 51: long kmode;
1.1 root 52: bool usa;
53:
54: if(cur_rate<cfg.node_minbps) {
55: bprintf(text[MinimumModemSpeed],cfg.node_minbps);
56: sprintf(str,"%stooslow.msg",cfg.text_dir);
57: if(fexist(str))
58: printfile(str,0);
59: sprintf(str,"New user modem speed: %lu<%u"
60: ,cur_rate,cfg.node_minbps);
61: logline("N!",str);
62: hangup();
1.1.1.2 ! root 63: return(FALSE);
! 64: }
1.1 root 65:
66: getnodedat(cfg.node_num,&thisnode,0);
67: if(thisnode.misc&NODE_LOCK) {
68: bputs(text[NodeLocked]);
69: logline("N!","New user locked node logon attempt");
70: hangup();
1.1.1.2 ! root 71: return(FALSE);
! 72: }
1.1 root 73:
74: if(cfg.sys_misc&SM_CLOSED) {
75: bputs(text[NoNewUsers]);
76: hangup();
1.1.1.2 ! root 77: return(FALSE);
! 78: }
1.1 root 79: getnodedat(cfg.node_num,&thisnode,1);
80: thisnode.status=NODE_NEWUSER;
81: thisnode.connection=0xffff;
82: putnodedat(cfg.node_num,&thisnode);
83: memset(&useron,0,sizeof(user_t)); /* Initialize user info to null */
84: if(cfg.new_pass[0] && online==ON_REMOTE) {
85: c=0;
86: while(++c<4) {
87: bputs(text[NewUserPasswordPrompt]);
88: getstr(str,40,K_UPPER);
89: if(!strcmp(str,cfg.new_pass))
90: break;
91: sprintf(tmp,"NUP Attempted: '%s'",str);
1.1.1.2 ! root 92: logline("N!",tmp);
! 93: }
1.1 root 94: if(c==4) {
95: sprintf(str,"%snupguess.msg",cfg.text_dir);
96: if(fexist(str))
97: printfile(str,P_NOABORT);
98: hangup();
1.1.1.2 ! root 99: return(FALSE);
! 100: }
! 101: }
1.1 root 102:
103: /* Sets defaults per sysop config */
104: useron.misc|=(cfg.new_misc&~(DELETED|INACTIVE|QUIET|NETMAIL));
1.1.1.2 ! root 105: useron.qwk=QWK_DEFAULT;
1.1 root 106: useron.firston=useron.laston=useron.pwmod=time(NULL);
107: if(cfg.new_expire) {
108: now=time(NULL);
1.1.1.2 ! root 109: useron.expire=now+((long)cfg.new_expire*24L*60L*60L);
! 110: } else
1.1 root 111: useron.expire=0;
1.1.1.2 ! root 112: useron.sex=' ';
1.1 root 113: useron.prot=cfg.new_prot;
114: strcpy(useron.note,cid); /* Caller ID if supported, NULL otherwise */
115: if((i=userdatdupe(0,U_NOTE,LEN_NOTE,cid,true))!=0) { /* Duplicate IP address */
1.1.1.2 ! root 116: sprintf(useron.comment,"Warning: same IP address as user #%d %s"
! 117: ,i,username(&cfg,i,str));
1.1 root 118: logline("N!",useron.comment);
119: }
120:
121: strcpy(useron.alias,"New"); /* just for status line */
122: strcpy(useron.modem,connection);
123: if(!lastuser(&cfg)) { /* Automatic sysop access for first user */
1.1.1.2 ! root 124: bprintf("Creating sysop account... System password required.\r\n");
! 125: if(!chksyspass())
! 126: return(FALSE);
1.1 root 127: useron.level=99;
128: useron.exempt=useron.flags1=useron.flags2=0xffffffffUL;
129: useron.flags3=useron.flags4=0xffffffffUL;
1.1.1.2 ! root 130: useron.rest=0L;
! 131: } else {
1.1 root 132: useron.level=cfg.new_level;
133: useron.flags1=cfg.new_flags1;
134: useron.flags2=cfg.new_flags2;
135: useron.flags3=cfg.new_flags3;
136: useron.flags4=cfg.new_flags4;
137: useron.rest=cfg.new_rest;
1.1.1.2 ! root 138: useron.exempt=cfg.new_exempt;
! 139: }
1.1 root 140:
141: useron.cdt=cfg.new_cdt;
142: useron.min=cfg.new_min;
143: useron.freecdt=cfg.level_freecdtperday[useron.level];
144:
145: if(cfg.total_fcomps)
146: strcpy(useron.tmpext,cfg.fcomp[0]->ext);
147: else
148: strcpy(useron.tmpext,"ZIP");
149:
150: useron.shell=cfg.new_shell;
151:
152: useron.alias[0]=0;
1.1.1.2 ! root 153:
! 154: kmode=(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL;
! 155: if(!(cfg.uq&UQ_NOUPRLWR))
! 156: kmode|=K_UPRLWR;
! 157:
1.1 root 158: while(online) {
1.1.1.2 ! root 159:
! 160: if(autoterm || yesno(text[AutoTerminalQ])) {
! 161: useron.misc|=AUTOTERM;
! 162: useron.misc|=autoterm;
! 163: } else
! 164: useron.misc&=~AUTOTERM;
! 165:
! 166: if(!(useron.misc&AUTOTERM)) {
! 167: if(yesno(text[AnsiTerminalQ]))
! 168: useron.misc|=ANSI;
! 169: else
! 170: useron.misc&=~ANSI;
! 171: }
! 172:
! 173: if(useron.misc&ANSI) {
! 174: useron.rows=0; /* Auto-rows */
! 175: if(useron.misc&(RIP|WIP|HTML) || yesno(text[ColorTerminalQ]))
! 176: useron.misc|=COLOR;
! 177: else
! 178: useron.misc&=~COLOR;
! 179: }
! 180: else
! 181: useron.rows=24;
! 182: if(!yesno(text[ExAsciiTerminalQ]))
! 183: useron.misc|=NO_EXASCII;
! 184: else
! 185: useron.misc&=~NO_EXASCII;
! 186:
1.1 root 187: if(sys_status&SS_RLOGIN && rlogin_name[0])
188: strcpy(useron.alias,rlogin_name);
189: else {
190: while(online) {
191: if(cfg.uq&UQ_ALIASES)
192: bputs(text[EnterYourAlias]);
193: else
194: bputs(text[EnterYourRealName]);
1.1.1.2 ! root 195: getstr(useron.alias,LEN_ALIAS,kmode);
1.1 root 196: truncsp(useron.alias);
1.1.1.2 ! root 197: if(useron.alias[0]<=' ' || !isalpha(useron.alias[0])
! 198: || alias(&cfg,useron.alias,tmp)!=useron.alias
! 199: || !stricmp(useron.alias,cfg.sys_id)
1.1 root 200: || strchr(useron.alias,0xff)
1.1.1.2 ! root 201: || matchuser(&cfg,useron.alias,TRUE /* sysop_alias */)
! 202: || trashcan(useron.alias,"name")
! 203: || (!(cfg.uq&UQ_ALIASES) && !strchr(useron.alias,' '))) {
1.1 root 204: bputs(text[YouCantUseThatName]);
1.1.1.2 ! root 205: if(!yesno(text[ContinueQ]))
! 206: return(FALSE);
! 207: continue;
! 208: }
! 209: break;
! 210: }
1.1 root 211: }
1.1.1.2 ! root 212: if(!online) return(FALSE);
1.1 root 213: if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) {
214: while(online) {
215: bputs(text[EnterYourRealName]);
1.1.1.2 ! root 216: if(!getstr(useron.name,LEN_NAME,kmode)
1.1 root 217: || trashcan(useron.name,"name")
218: || strchr(useron.name,0xff)
1.1.1.2 ! root 219: || !strchr(useron.name,' ')
1.1 root 220: || (cfg.uq&UQ_DUPREAL
221: && userdatdupe(useron.number,U_NAME,LEN_NAME
222: ,useron.name,0)))
223: bputs(text[YouCantUseThatName]);
224: else
1.1.1.2 ! root 225: break;
! 226: if(!yesno(text[ContinueQ]))
! 227: return(FALSE);
! 228: }
! 229: }
1.1 root 230: else if(cfg.uq&UQ_COMPANY) {
231: bputs(text[EnterYourCompany]);
1.1.1.2 ! root 232: getstr(useron.name,LEN_NAME,(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL);
! 233: }
1.1 root 234: if(!useron.name[0])
235: strcpy(useron.name,useron.alias);
1.1.1.2 ! root 236: if(!online) return(FALSE);
1.1 root 237: if(!useron.handle[0])
238: sprintf(useron.handle,"%.*s",LEN_HANDLE,useron.alias);
239: while(cfg.uq&UQ_HANDLE && online) {
240: bputs(text[EnterYourHandle]);
241: if(!getstr(useron.handle,LEN_HANDLE
242: ,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC))
243: || strchr(useron.handle,0xff)
244: || (cfg.uq&UQ_DUPHAND
245: && userdatdupe(0,U_HANDLE,LEN_HANDLE,useron.handle,0))
246: || trashcan(useron.handle,"name"))
247: bputs(text[YouCantUseThatName]);
248: else
1.1.1.2 ! root 249: break;
! 250: if(!yesno(text[ContinueQ]))
! 251: return(FALSE);
1.1 root 252: }
1.1.1.2 ! root 253: if(!online) return(FALSE);
1.1 root 254: if(cfg.uq&UQ_ADDRESS)
255: while(online) { /* Get address and zip code */
256: bputs(text[EnterYourAddress]);
1.1.1.2 ! root 257: if(getstr(useron.address,LEN_ADDRESS,kmode))
! 258: break;
! 259: }
! 260: if(!online) return(FALSE);
1.1 root 261: while(cfg.uq&UQ_LOCATION && online) {
262: bputs(text[EnterYourCityState]);
1.1.1.2 ! root 263: if(getstr(useron.location,LEN_LOCATION,kmode)
1.1 root 264: && (cfg.uq&UQ_NOCOMMAS || strchr(useron.location,',')))
265: break;
266: bputs("\r\nYou must include a comma between the city and state.\r\n");
1.1.1.2 ! root 267: useron.location[0]=0;
! 268: }
1.1 root 269: if(cfg.uq&UQ_ADDRESS)
270: while(online) {
271: bputs(text[EnterYourZipCode]);
272: if(getstr(useron.zipcode,LEN_ZIPCODE
273: ,K_UPPER|(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL))
1.1.1.2 ! root 274: break;
! 275: }
! 276: if(!online) return(FALSE);
1.1 root 277: if(cfg.uq&UQ_PHONE) {
278: usa=yesno(text[CallingFromNorthAmericaQ]);
279: while(online) {
280: bputs(text[EnterYourPhoneNumber]);
281: if(!usa) {
282: if(getstr(useron.phone,LEN_PHONE
283: ,K_UPPER|K_LINE|(cfg.uq&UQ_NOEXASC)|K_EDIT|K_AUTODEL)<5)
1.1.1.2 ! root 284: continue;
! 285: }
1.1 root 286: else {
287: if(gettmplt(useron.phone,cfg.sys_phonefmt
288: ,K_LINE|(cfg.uq&UQ_NOEXASC)|K_EDIT)<strlen(cfg.sys_phonefmt))
1.1.1.2 ! root 289: continue;
! 290: }
1.1 root 291: if(!trashcan(useron.phone,"phone"))
1.1.1.2 ! root 292: break;
! 293: }
! 294: }
! 295: if(!online) return(FALSE);
1.1 root 296: if(cfg.uq&UQ_SEX) {
297: bputs(text[EnterYourSex]);
1.1.1.2 ! root 298: useron.sex=(char)getkeys("MF",0);
! 299: }
1.1 root 300: while(cfg.uq&UQ_BIRTH && online) {
1.1.1.2 ! root 301: bprintf(text[EnterYourBirthday]
! 302: ,cfg.sys_misc&SM_EURODATE ? "DD/MM/YY" : "MM/DD/YY");
1.1 root 303: if(gettmplt(useron.birth,"nn/nn/nn",K_EDIT)==8 && getage(&cfg,useron.birth))
1.1.1.2 ! root 304: break;
! 305: }
! 306: if(!online) return(FALSE);
! 307: while(!(sys_status&SS_RLOGIN) && !(cfg.uq&UQ_NONETMAIL) && online) {
! 308: bputs(text[EnterNetMailAddress]);
! 309: if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE)
! 310: && !trashcan(useron.netmail,"email"))
! 311: break;
! 312: }
! 313: if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && yesno(text[ForwardMailQ]))
! 314: useron.misc|=NETMAIL;
! 315: else
! 316: useron.misc&=~NETMAIL;
1.1 root 317: if(yesno(text[UserInfoCorrectQ]))
1.1.1.2 ! root 318: break;
! 319: }
! 320: if(!online) return(FALSE);
1.1 root 321: sprintf(str,"New user: %s",useron.alias);
322: logline("N",str);
1.1.1.2 ! root 323: if(!online) return(FALSE);
1.1 root 324: CLS;
325: sprintf(str,"%ssbbs.msg",cfg.text_dir);
326: printfile(str,P_NOABORT);
327: if(lncntr)
328: pause();
329: CLS;
330: sprintf(str,"%ssystem.msg",cfg.text_dir);
331: printfile(str,P_NOABORT);
332: if(lncntr)
333: pause();
334: CLS;
335: sprintf(str,"%snewuser.msg",cfg.text_dir);
336: printfile(str,P_NOABORT);
337: if(lncntr)
338: pause();
339: CLS;
340: answertime=time(NULL); /* could take 10 minutes to get this far */
341:
1.1.1.2 ! root 342: /* Default editor (moved here, after terminal type setup Jan-2003) */
! 343: for(i=0;i<cfg.total_xedits;i++)
! 344: if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit) && chk_ar(cfg.xedit[i]->ar,&useron))
! 345: break;
! 346: if(i<cfg.total_xedits)
! 347: useron.xedit=i+1;
! 348:
! 349: if(cfg.total_xedits && cfg.uq&UQ_XEDIT
! 350: && !noyes("Use an external text editor")) {
1.1 root 351: if(useron.xedit) useron.xedit--;
352: for(i=0;i<cfg.total_xedits;i++)
353: uselect(1,i,"External Editor",cfg.xedit[i]->name,cfg.xedit[i]->ar);
354: if((int)(i=uselect(0,useron.xedit,0,0,0))>=0)
1.1.1.2 ! root 355: useron.xedit=i+1;
! 356: }
1.1 root 357:
358: if(cfg.total_shells>1 && cfg.uq&UQ_CMDSHELL) {
359: for(i=0;i<cfg.total_shells;i++)
360: uselect(1,i,"Command Shell",cfg.shell[i]->name,cfg.shell[i]->ar);
361: if((int)(i=uselect(0,useron.shell,0,0,0))>=0)
1.1.1.2 ! root 362: useron.shell=i;
! 363: }
1.1 root 364:
365: c=0;
366: while(c<LEN_PASS) { /* Create random password */
367: useron.pass[c]=sbbs_random(43)+'0';
368: if(isalnum(useron.pass[c]))
1.1.1.2 ! root 369: c++;
! 370: }
1.1 root 371: useron.pass[c]=0;
372:
373: if(!(sys_status&SS_RLOGIN)) {
374: bprintf(text[YourPasswordIs],useron.pass);
375:
376: if(cfg.sys_misc&SM_PWEDIT && yesno(text[NewPasswordQ]))
377: while(online) {
378: bputs(text[NewPassword]);
379: getstr(str,LEN_PASS,K_UPPER|K_LINE);
380: truncsp(str);
381: if(chkpass(str,&useron,true)) {
382: strcpy(useron.pass,str);
383: CRLF;
384: bprintf(text[YourPasswordIs],useron.pass);
1.1.1.2 ! root 385: break;
! 386: }
! 387: CRLF;
! 388: }
1.1 root 389:
390: c=0;
391: while(online) {
392: bprintf(text[NewUserPasswordVerify]);
393: console|=CON_R_ECHOX;
394: if(!(cfg.sys_misc&SM_ECHO_PW))
395: console|=CON_L_ECHOX;
396: str[0]=0;
397: getstr(str,LEN_PASS,K_UPPER);
398: console&=~(CON_R_ECHOX|CON_L_ECHOX);
399: if(!strcmp(str,useron.pass)) break;
1.1.1.2 ! root 400: if(cfg.sys_misc&SM_ECHO_PW)
! 401: sprintf(tmp,"%s FAILED Password verification: '%s' instead of '%s'"
! 402: ,useron.alias
! 403: ,str
! 404: ,useron.pass);
! 405: else
! 406: sprintf(tmp,"%s FAILED Password verification"
! 407: ,useron.alias);
1.1 root 408: logline(nulstr,tmp);
409: if(++c==4) {
410: logline("N!","Couldn't figure out password.");
1.1.1.2 ! root 411: hangup();
! 412: }
1.1 root 413: bputs(text[IncorrectPassword]);
1.1.1.2 ! root 414: bprintf(text[YourPasswordIs],useron.pass);
! 415: }
1.1 root 416: }
417:
1.1.1.2 ! root 418: if(!online) return(FALSE);
1.1 root 419: if(cfg.new_magic[0]) {
420: bputs(text[MagicWordPrompt]);
421: str[0]=0;
422: getstr(str,50,K_UPPER);
423: if(strcmp(str,cfg.new_magic)) {
424: bputs(text[FailedMagicWord]);
1.1.1.2 ! root 425: sprintf(tmp,"%s failed magic word: '%s'",useron.alias,str);
1.1 root 426: logline("N!",tmp);
1.1.1.2 ! root 427: hangup();
! 428: }
! 429: if(!online) return(FALSE);
! 430: }
1.1 root 431:
432: bputs(text[CheckingSlots]);
1.1.1.2 ! root 433:
! 434: if((i=newuserdat(&cfg,&useron))!=0) {
! 435: sprintf(str,"user record #%u",useron.number);
! 436: errormsg(WHERE,ERR_CREATE,str,i);
! 437: hangup();
! 438: return(FALSE);
! 439: }
! 440: sprintf(str,"Created user record #%u: %s",useron.number,useron.alias);
! 441: logline(nulstr,str);
1.1 root 442: if(cfg.new_sif[0]) {
443: sprintf(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number);
1.1.1.2 ! root 444: create_sif_dat(cfg.new_sif,str);
! 445: }
1.1 root 446: if(!(cfg.uq&UQ_NODEF))
447: maindflts(&useron);
448:
449: delallmail(useron.number);
450:
451: if(useron.number!=1 && cfg.node_valuser) {
452: sprintf(str,"%sfeedback.msg",cfg.text_dir);
453: CLS;
454: printfile(str,P_NOABORT);
455: sprintf(str,text[NewUserFeedbackHdr]
456: ,nulstr,getage(&cfg,useron.birth),useron.sex,useron.birth
457: ,useron.name,useron.phone,useron.comp,useron.modem);
458: email(cfg.node_valuser,str,"New User Validation",WM_EMAIL);
459: if(!useron.fbacks && !useron.emails) {
460: if(online) { /* didn't hang up */
461: bprintf(text[NoFeedbackWarning],username(&cfg,cfg.node_valuser,tmp));
462: email(cfg.node_valuser,str,"New User Validation",WM_EMAIL);
463: } /* give 'em a 2nd try */
464: if(!useron.fbacks && !useron.emails) {
465: bprintf(text[NoFeedbackWarning],username(&cfg,cfg.node_valuser,tmp));
466: logline("N!","Aborted feedback");
467: hangup();
468: putuserrec(&cfg,useron.number,U_COMMENT,60,"Didn't leave feedback");
469: putuserrec(&cfg,useron.number,U_MISC,8
470: ,ultoa(useron.misc|DELETED,tmp,16));
1.1.1.2 ! root 471: putusername(&cfg,useron.number,nulstr);
! 472: return(FALSE);
! 473: }
! 474: }
! 475: }
1.1 root 476:
477: answertime=starttime=time(NULL); /* set answertime to now */
1.1.1.2 ! root 478:
! 479: #ifdef JAVASCRIPT
! 480: js_create_user_objects();
! 481: #endif
! 482:
1.1 root 483: if(cfg.newuser_mod[0])
484: exec_bin(cfg.newuser_mod,&main_csi);
485: user_event(EVENT_NEWUSER);
486: getuserdat(&cfg,&useron); // In case event(s) modified user data
487: logline("N+","Successful new user logon");
488: sys_status|=SS_NEWUSER;
1.1.1.2 ! root 489:
! 490: return(TRUE);
1.1 root 491: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.