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