|
|
1.1 root 1: /* chk_ar.cpp */
2:
3: /* Synchronet ARS checking routine */
4:
5: /* $Id: chk_ar.cpp,v 1.16 2006/12/29 09:00: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:
40: bool sbbs_t::ar_exp(uchar **ptrptr, user_t* user)
41: {
42: bool result,_not,_or,equal;
43: uint i,n,artype,age;
44: ulong l;
45: struct tm tm;
46:
47: result = true;
48:
49: for(;(**ptrptr);(*ptrptr)++) {
50:
51: if((**ptrptr)==AR_ENDNEST)
52: break;
53:
54: _not=_or=equal = false;
55:
56: if((**ptrptr)==AR_OR) {
57: _or=true;
58: (*ptrptr)++; }
59:
60: if((**ptrptr)==AR_NOT) {
61: _not=true;
62: (*ptrptr)++; }
63:
64: if((**ptrptr)==AR_EQUAL) {
65: equal=true;
66: (*ptrptr)++; }
67:
68: if((result && _or) || (!result && !_or))
69: break;
70:
71: if((**ptrptr)==AR_BEGNEST) {
72: (*ptrptr)++;
73: if(ar_exp(ptrptr,user))
74: result=!_not;
75: else
76: result=_not;
77: while((**ptrptr)!=AR_ENDNEST && (**ptrptr)) /* in case of early exit */
78: (*ptrptr)++;
79: if(!(**ptrptr))
80: break;
81: continue; }
82:
83: artype=(**ptrptr);
84: switch(artype) {
85: case AR_ANSI: /* No arguments */
86: case AR_RIP:
87: case AR_WIP:
88: case AR_LOCAL:
89: case AR_EXPERT:
90: case AR_SYSOP:
91: case AR_GUEST:
92: case AR_QNODE:
93: case AR_QUIET:
94: case AR_OS2:
95: case AR_DOS:
96: case AR_WIN32:
97: case AR_UNIX:
98: case AR_LINUX:
99: break;
100: default:
101: (*ptrptr)++;
102: break; }
103:
104: n=(**ptrptr);
105: i=(*(short *)*ptrptr);
106: switch(artype) {
107: case AR_LEVEL:
108: if((equal && user->level!=n) || (!equal && user->level<n))
109: result=_not;
110: else
111: result=!_not;
112: if(!result) {
113: noaccess_str=text[NoAccessLevel];
114: noaccess_val=n; }
115: break;
116: case AR_AGE:
117: age=getage(&cfg,user->birth);
118: if((equal && age!=n) || (!equal && age<n))
119: result=_not;
120: else
121: result=!_not;
122: if(!result) {
123: noaccess_str=text[NoAccessAge];
124: noaccess_val=n; }
125: break;
126: case AR_BPS:
127: if((equal && cur_rate!=i) || (!equal && cur_rate<i))
128: result=_not;
129: else
130: result=!_not;
131: (*ptrptr)++;
132: if(!result) {
133: noaccess_str=text[NoAccessBPS];
134: noaccess_val=i; }
135: break;
136: case AR_ANSI:
137: if(!(user->misc&ANSI))
138: result=_not;
139: else result=!_not;
140: break;
141: case AR_RIP:
142: if(!(user->misc&RIP))
143: result=_not;
144: else result=!_not;
145: break;
146: case AR_WIP:
147: if(!(user->misc&WIP))
148: result=_not;
149: else result=!_not;
150: break;
151: case AR_OS2:
152: #ifndef __OS2__
153: result=_not;
154: #else
155: result=!_not;
156: #endif
157: break;
158: case AR_DOS:
159: result=_not;
160: break;
161: case AR_WIN32:
162: #ifndef _WIN32
163: result=_not;
164: #else
165: result=!_not;
166: #endif
167: break;
168: case AR_UNIX:
169: #ifndef __unix__
170: result=_not;
171: #else
172: result=!_not;
173: #endif
174: break;
175: case AR_LINUX:
176: #ifndef __linux__
177: result=_not;
178: #else
179: result=!_not;
180: #endif
181: break;
182: case AR_ACTIVE:
183: if(user->misc&(DELETED|INACTIVE))
184: result=_not;
185: else result=!_not;
186: break;
187: case AR_INACTIVE:
188: if(!(user->misc&INACTIVE))
189: result=_not;
190: else result=!_not;
191: break;
192: case AR_DELETED:
193: if(!(user->misc&DELETED))
194: result=_not;
195: else result=!_not;
196: break;
197: case AR_EXPERT:
198: if(!(user->misc&EXPERT))
199: result=_not;
200: else result=!_not;
201: break;
202: case AR_SYSOP:
203: if(!SYSOP)
204: result=_not;
205: else result=!_not;
206: break;
207: case AR_GUEST:
208: if(!(user->rest&FLAG('G')))
209: result=_not;
210: else result=!_not;
211: break;
212: case AR_QNODE:
213: if(!(user->rest&FLAG('Q')))
214: result=_not;
215: else result=!_not;
216: break;
217: case AR_QUIET:
218: if(thisnode.status!=NODE_QUIET)
219: result=_not;
220: else result=!_not;
221: break;
222: case AR_LOCAL:
223: if(online!=ON_LOCAL)
224: result=_not;
225: else result=!_not;
226: break;
227: case AR_DAY:
228: now=time(NULL);
229: localtime_r(&now,&tm);
230: if((equal && tm.tm_wday!=(int)n)
231: || (!equal && tm.tm_wday<(int)n))
232: result=_not;
233: else
234: result=!_not;
235: if(!result) {
236: noaccess_str=text[NoAccessDay];
237: noaccess_val=n; }
238: break;
239: case AR_CREDIT:
240: l=(ulong)i*1024UL;
241: if((equal && user->cdt+user->freecdt!=l)
242: || (!equal && user->cdt+user->freecdt<l))
243: result=_not;
244: else
245: result=!_not;
246: (*ptrptr)++;
247: if(!result) {
248: noaccess_str=text[NoAccessCredit];
249: noaccess_val=l; }
250: break;
251: case AR_NODE:
252: if((equal && cfg.node_num!=n) || (!equal && cfg.node_num<n))
253: result=_not;
254: else
255: result=!_not;
256: if(!result) {
257: noaccess_str=text[NoAccessNode];
258: noaccess_val=n; }
259: break;
260: case AR_USER:
261: if((equal && user->number!=i) || (!equal && user->number<i))
262: result=_not;
263: else
264: result=!_not;
265: (*ptrptr)++;
266: if(!result) {
267: noaccess_str=text[NoAccessUser];
268: noaccess_val=i; }
269: break;
270: case AR_GROUP:
271: if((equal
272: && (cursubnum>=cfg.total_subs
273: || cfg.sub[cursubnum]->grp!=i))
274: || (!equal && cursubnum<cfg.total_subs
275: && cfg.sub[cursubnum]->grp<i))
276: result=_not;
277: else
278: result=!_not;
279: (*ptrptr)++;
280: if(!result) {
281: noaccess_str=text[NoAccessGroup];
282: noaccess_val=i+1; }
283: break;
284: case AR_SUB:
285: if((equal && cursubnum!=i) || (!equal && cursubnum<i))
286: result=_not;
287: else
288: result=!_not;
289: (*ptrptr)++;
290: if(!result) {
291: noaccess_str=text[NoAccessSub];
292: noaccess_val=i+1; }
293: break;
294: case AR_SUBCODE:
295: if(cursubnum>=cfg.total_subs
296: || stricmp(cfg.sub[cursubnum]->code,(char*)*ptrptr))
297: result=_not;
298: else
299: result=!_not;
300: while(*(*ptrptr))
301: (*ptrptr)++;
302: if(!result)
303: noaccess_str=text[NoAccessSub];
304: break;
305: case AR_LIB:
306: if((equal
307: && (curdirnum>=cfg.total_dirs
308: || cfg.dir[curdirnum]->lib!=i))
309: || (!equal && curdirnum<cfg.total_dirs
310: && cfg.dir[curdirnum]->lib<i))
311: result=_not;
312: else
313: result=!_not;
314: (*ptrptr)++;
315: if(!result) {
316: noaccess_str=text[NoAccessLib];
317: noaccess_val=i+1; }
318: break;
319: case AR_DIR:
320: if((equal && curdirnum!=i) || (!equal && curdirnum<i))
321: result=_not;
322: else
323: result=!_not;
324: (*ptrptr)++;
325: if(!result) {
326: noaccess_str=text[NoAccessDir];
327: noaccess_val=i+1; }
328: break;
329: case AR_DIRCODE:
330: if(curdirnum>=cfg.total_dirs
331: || stricmp(cfg.dir[curdirnum]->code,(char *)*ptrptr))
332: result=_not;
333: else
334: result=!_not;
335: while(*(*ptrptr))
336: (*ptrptr)++;
337: if(!result)
338: noaccess_str=text[NoAccessSub];
339: break;
340: case AR_EXPIRE:
341: now=time(NULL);
342: if(!user->expire || now+((long)i*24L*60L*60L)>user->expire)
343: result=_not;
344: else
345: result=!_not;
346: (*ptrptr)++;
347: if(!result) {
348: noaccess_str=text[NoAccessExpire];
349: noaccess_val=i; }
350: break;
351: case AR_RANDOM:
352: n=sbbs_random(i+1);
353: if((equal && n!=i) || (!equal && n<i))
354: result=_not;
355: else
356: result=!_not;
357: (*ptrptr)++;
358: break;
359: case AR_LASTON:
360: now=time(NULL);
361: if((now-user->laston)/(24L*60L*60L)<(long)i)
362: result=_not;
363: else
364: result=!_not;
365: (*ptrptr)++;
366: break;
367: case AR_LOGONS:
368: if((equal && user->logons!=i) || (!equal && user->logons<i))
369: result=_not;
370: else
371: result=!_not;
372: (*ptrptr)++;
373: break;
374: case AR_MAIN_CMDS:
375: if((equal && main_cmds!=i) || (!equal && main_cmds<i))
376: result=_not;
377: else
378: result=!_not;
379: (*ptrptr)++;
380: break;
381: case AR_FILE_CMDS:
382: if((equal && xfer_cmds!=i) || (!equal && xfer_cmds<i))
383: result=_not;
384: else
385: result=!_not;
386: (*ptrptr)++;
387: break;
388: case AR_TLEFT:
389: if(timeleft/60<(ulong)n)
390: result=_not;
391: else
392: result=!_not;
393: if(!result) {
394: noaccess_str=text[NoAccessTimeLeft];
395: noaccess_val=n; }
396: break;
397: case AR_TUSED:
398: if((time(NULL)-logontime)/60<(long)n)
399: result=_not;
400: else
401: result=!_not;
402: if(!result) {
403: noaccess_str=text[NoAccessTimeUsed];
404: noaccess_val=n; }
405: break;
406: case AR_TIME:
407: now=time(NULL);
408: localtime_r(&now,&tm);
409: if((tm.tm_hour*60)+tm.tm_min<(int)i)
410: result=_not;
411: else
412: result=!_not;
413: (*ptrptr)++;
414: if(!result) {
415: noaccess_str=text[NoAccessTime];
416: noaccess_val=i; }
417: break;
418: case AR_PCR: /* post/call ratio (by percentage) */
419: if(user->logons>user->posts
420: && (!user->posts || (100/((float)user->logons/user->posts))<(long)n))
421: result=_not;
422: else
423: result=!_not;
424: if(!result) {
425: noaccess_str=text[NoAccessPCR];
426: noaccess_val=n; }
427: break;
428: case AR_UDR: /* up/download byte ratio (by percentage) */
429: l=user->dlb;
430: if(!l) l=1;
431: if(user->dlb>user->ulb
432: && (!user->ulb || (100/((float)l/user->ulb))<n))
433: result=_not;
434: else
435: result=!_not;
436: if(!result) {
437: noaccess_str=text[NoAccessUDR];
438: noaccess_val=n; }
439: break;
440: case AR_UDFR: /* up/download file ratio (in percentage) */
441: i=user->dls;
442: if(!i) i=1;
443: if(user->dls>user->uls
444: && (!user->uls || (100/((float)i/user->uls))<n))
445: result=_not;
446: else
447: result=!_not;
448: if(!result) {
449: noaccess_str=text[NoAccessUDFR];
450: noaccess_val=n; }
451: break;
452: case AR_FLAG1:
453: if((!equal && !(user->flags1&FLAG(n)))
454: || (equal && user->flags1!=FLAG(n)))
455: result=_not;
456: else
457: result=!_not;
458: if(!result) {
459: noaccess_str=text[NoAccessFlag1];
460: noaccess_val=n; }
461: break;
462: case AR_FLAG2:
463: if((!equal && !(user->flags2&FLAG(n)))
464: || (equal && user->flags2!=FLAG(n)))
465: result=_not;
466: else
467: result=!_not;
468: if(!result) {
469: noaccess_str=text[NoAccessFlag2];
470: noaccess_val=n; }
471: break;
472: case AR_FLAG3:
473: if((!equal && !(user->flags3&FLAG(n)))
474: || (equal && user->flags3!=FLAG(n)))
475: result=_not;
476: else
477: result=!_not;
478: if(!result) {
479: noaccess_str=text[NoAccessFlag3];
480: noaccess_val=n; }
481: break;
482: case AR_FLAG4:
483: if((!equal && !(user->flags4&FLAG(n)))
484: || (equal && user->flags4!=FLAG(n)))
485: result=_not;
486: else
487: result=!_not;
488: if(!result) {
489: noaccess_str=text[NoAccessFlag4];
490: noaccess_val=n; }
491: break;
492: case AR_REST:
493: if((!equal && !(user->rest&FLAG(n)))
494: || (equal && user->rest!=FLAG(n)))
495: result=_not;
496: else
497: result=!_not;
498: if(!result) {
499: noaccess_str=text[NoAccessRest];
500: noaccess_val=n; }
501: break;
502: case AR_EXEMPT:
503: if((!equal && !(user->exempt&FLAG(n)))
504: || (equal && user->exempt!=FLAG(n)))
505: result=_not;
506: else
507: result=!_not;
508: if(!result) {
509: noaccess_str=text[NoAccessExempt];
510: noaccess_val=n; }
511: break;
512: case AR_SEX:
513: if(user->sex!=n)
514: result=_not;
515: else
516: result=!_not;
517: if(!result) {
518: noaccess_str=text[NoAccessSex];
519: noaccess_val=n; }
520: break;
521: case AR_SHELL:
522: if(user->shell>=cfg.total_shells
523: || stricmp(cfg.shell[user->shell]->code,(char*)*ptrptr))
524: result=_not;
525: else
526: result=!_not;
527: while(*(*ptrptr))
528: (*ptrptr)++;
529: break;
530: case AR_PROT:
531: if(stricmp(user->modem,(char*)*ptrptr)) /* should this be changed to client.prot? */
532: result=_not;
533: else
534: result=!_not;
535: while(*(*ptrptr))
536: (*ptrptr)++;
537: break;
538: }
539: }
540: return(result);
541: }
542:
543: bool sbbs_t::chk_ar(uchar *ar, user_t* user)
544: {
545: uchar *p;
546:
547: if(ar==NULL)
548: return(true);
549: p=ar;
550: return(ar_exp(&p,user));
551: }
552:
553:
554: /****************************************************************************/
555: /* This function fills the usrsub, usrsubs, usrgrps, curgrp, and cursub */
556: /* variables based on the security clearance of the current user (useron) */
557: /****************************************************************************/
558: void sbbs_t::getusrsubs()
559: {
560: uint i,j,k,l;
561:
562: for(j=0,i=0;i<cfg.total_grps;i++) {
563: if(!chk_ar(cfg.grp[i]->ar,&useron))
564: continue;
565: for(k=0,l=0;l<cfg.total_subs;l++) {
566: if(cfg.sub[l]->grp!=i) continue;
567: if(!chk_ar(cfg.sub[l]->ar,&useron))
568: continue;
569: usrsub[j][k++]=l;
570: }
571: usrsubs[j]=k;
572: if(!k) /* No subs accessible in group */
573: continue;
574: usrgrp[j++]=i;
575: }
576: usrgrps=j;
577: if(usrgrps==0)
578: return;
579: while((curgrp>=usrgrps || !usrsubs[curgrp]) && curgrp) curgrp--;
580: while(cursub[curgrp]>=usrsubs[curgrp] && cursub[curgrp]) cursub[curgrp]--;
581: }
582:
583: /****************************************************************************/
584: /* This function fills the usrdir, usrdirs, usrlibs, curlib, and curdir */
585: /* variables based on the security clearance of the current user (useron) */
586: /****************************************************************************/
587: void sbbs_t::getusrdirs()
588: {
589: uint i,j,k,l;
590:
591: if(useron.rest&FLAG('T')) {
592: usrlibs=0;
593: return;
594: }
595: for(j=0,i=0;i<cfg.total_libs;i++) {
596: if(!chk_ar(cfg.lib[i]->ar,&useron))
597: continue;
598: for(k=0,l=0;l<cfg.total_dirs;l++) {
599: if(cfg.dir[l]->lib!=i) continue;
600: if(!chk_ar(cfg.dir[l]->ar,&useron))
601: continue;
602: usrdir[j][k++]=l; }
603: usrdirs[j]=k;
604: if(!k) /* No dirs accessible in lib */
605: continue;
606: usrlib[j++]=i;
607: }
608: usrlibs=j;
609: if(usrlibs==0)
610: return;
611: while((curlib>=usrlibs || !usrdirs[curlib]) && curlib) curlib--;
612: while(curdir[curlib]>=usrdirs[curlib] && curdir[curlib]) curdir[curlib]--;
613: }
614:
615: uint sbbs_t::getusrgrp(uint subnum)
616: {
617: uint ugrp;
618:
619: if(subnum==INVALID_SUB)
620: return(0);
621:
622: if(usrgrps<=0)
623: return(0);
624:
625: for(ugrp=0;ugrp<usrgrps;ugrp++)
626: if(usrgrp[ugrp]==cfg.sub[subnum]->grp)
627: break;
628:
629: return(ugrp+1);
630: }
631:
632: uint sbbs_t::getusrsub(uint subnum)
633: {
634: uint usub;
635: uint ugrp;
636:
637: ugrp = getusrgrp(subnum);
638: if(ugrp<=0)
639: return(0);
640:
641: for(usub=0;usub<usrsubs[ugrp];usub++)
642: if(usrsub[ugrp][usub]==subnum)
643: break;
644:
645: return(usub+1);
646: }
647:
648: int sbbs_t::dir_op(uint dirnum)
649: {
650: return(SYSOP || (cfg.dir[dirnum]->op_ar[0] && chk_ar(cfg.dir[dirnum]->op_ar,&useron)));
651: }
652:
653:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.