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