chk_ar.cpp 15.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* chk_ar.cpp */

/* Synchronet ARS checking routine */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
rswindell's avatar
rswindell committed
11
 * Copyright 2007 Rob Swindell - http://www.synchro.net/copyright.html		*
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "sbbs.h"

bool sbbs_t::ar_exp(uchar **ptrptr, user_t* user)
{
42
	bool	result,_not,_or,equal;
43
44
	uint	i,n,artype,age;
	ulong	l;
45
	struct tm tm;
46
47
48
49
50
51
52
53

	result = true;

	for(;(**ptrptr);(*ptrptr)++) {

		if((**ptrptr)==AR_ENDNEST)
			break;

54
		_not=_or=equal = false;
55
56

		if((**ptrptr)==AR_OR) {
57
			_or=true;
58
59
60
			(*ptrptr)++; }
		
		if((**ptrptr)==AR_NOT) {
61
			_not=true;
62
63
64
65
66
67
			(*ptrptr)++; }

		if((**ptrptr)==AR_EQUAL) {
			equal=true;
			(*ptrptr)++; }

68
		if((result && _or) || (!result && !_or))
69
70
71
72
73
			break;

		if((**ptrptr)==AR_BEGNEST) {
			(*ptrptr)++;
			if(ar_exp(ptrptr,user))
74
				result=!_not;
75
			else
76
				result=_not;
77
78
79
80
81
82
83
84
85
86
87
88
89
90
			while((**ptrptr)!=AR_ENDNEST && (**ptrptr)) /* in case of early exit */
				(*ptrptr)++;
			if(!(**ptrptr))
				break;
			continue; }

		artype=(**ptrptr);
		switch(artype) {
			case AR_ANSI:				/* No arguments */
			case AR_RIP:
			case AR_WIP:
			case AR_LOCAL:
			case AR_EXPERT:
			case AR_SYSOP:
91
92
			case AR_GUEST:
			case AR_QNODE:
93
94
95
			case AR_QUIET:
			case AR_OS2:
			case AR_DOS:
96
97
98
			case AR_WIN32:
			case AR_UNIX:
			case AR_LINUX:
99
100
101
102
103
104
105
106
107
108
				break;
			default:
				(*ptrptr)++;
				break; }

		n=(**ptrptr);
		i=(*(short *)*ptrptr);
		switch(artype) {
			case AR_LEVEL:
				if((equal && user->level!=n) || (!equal && user->level<n))
109
					result=_not;
110
				else
111
					result=!_not;
112
113
114
115
116
117
118
				if(!result) {
					noaccess_str=text[NoAccessLevel];
					noaccess_val=n; }
				break;
			case AR_AGE:
				age=getage(&cfg,user->birth);
				if((equal && age!=n) || (!equal && age<n))
119
					result=_not;
120
				else
121
					result=!_not;
122
123
124
125
126
127
				if(!result) {
					noaccess_str=text[NoAccessAge];
					noaccess_val=n; }
				break;
			case AR_BPS:
				if((equal && cur_rate!=i) || (!equal && cur_rate<i))
128
					result=_not;
129
				else
130
					result=!_not;
131
132
133
134
135
136
137
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessBPS];
					noaccess_val=i; }
				break;
			case AR_ANSI:
				if(!(user->misc&ANSI))
138
139
					result=_not;
				else result=!_not;
140
141
142
				break;
			case AR_RIP:
				if(!(user->misc&RIP))
143
144
					result=_not;
				else result=!_not;
145
146
147
				break;
			case AR_WIP:
				if(!(user->misc&WIP))
148
149
					result=_not;
				else result=!_not;
150
151
152
				break;
			case AR_OS2:
				#ifndef __OS2__
153
					result=_not;
154
				#else
155
					result=!_not;
156
157
158
				#endif
				break;
			case AR_DOS:
deuce's avatar
deuce committed
159
				result=_not;
160
161
162
				break;
			case AR_WIN32:
				#ifndef _WIN32
163
					result=_not;
164
				#else
165
					result=!_not;
166
167
168
169
				#endif
				break;
			case AR_UNIX:
				#ifndef __unix__
170
					result=_not;
171
				#else
172
					result=!_not;
173
174
175
176
				#endif
				break;
			case AR_LINUX:
				#ifndef __linux__
177
					result=_not;
178
				#else
179
					result=!_not;
180
181
				#endif
				break;
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
			case AR_ACTIVE:
				if(user->misc&(DELETED|INACTIVE))
					result=_not;
				else result=!_not;
				break;
			case AR_INACTIVE:
				if(!(user->misc&INACTIVE))
					result=_not;
				else result=!_not;
				break;
			case AR_DELETED:
				if(!(user->misc&DELETED))
					result=_not;
				else result=!_not;
				break;
197
198
			case AR_EXPERT:
				if(!(user->misc&EXPERT))
199
200
					result=_not;
				else result=!_not;
201
202
203
				break;
			case AR_SYSOP:
				if(!SYSOP)
204
205
					result=_not;
				else result=!_not;
206
				break;
207
208
209
210
211
212
213
214
215
216
			case AR_GUEST:
				if(!(user->rest&FLAG('G')))
					result=_not;
				else result=!_not;
				break;
			case AR_QNODE:
				if(!(user->rest&FLAG('Q')))
					result=_not;
				else result=!_not;
				break;
217
218
			case AR_QUIET:
				if(thisnode.status!=NODE_QUIET)
219
220
					result=_not;
				else result=!_not;
221
222
223
				break;
			case AR_LOCAL:
				if(online!=ON_LOCAL)
224
225
					result=_not;
				else result=!_not;
226
227
228
				break;
			case AR_DAY:
				now=time(NULL);
229
230
231
				localtime_r(&now,&tm);
				if((equal && tm.tm_wday!=(int)n) 
					|| (!equal && tm.tm_wday<(int)n))
232
					result=_not;
233
				else
234
					result=!_not;
235
236
237
238
239
240
241
242
				if(!result) {
					noaccess_str=text[NoAccessDay];
					noaccess_val=n; }
				break;
			case AR_CREDIT:
				l=(ulong)i*1024UL;
				if((equal && user->cdt+user->freecdt!=l)
					|| (!equal && user->cdt+user->freecdt<l))
243
					result=_not;
244
				else
245
					result=!_not;
246
247
248
249
250
251
252
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessCredit];
					noaccess_val=l; }
				break;
			case AR_NODE:
				if((equal && cfg.node_num!=n) || (!equal && cfg.node_num<n))
253
					result=_not;
254
				else
255
					result=!_not;
256
257
258
259
260
261
				if(!result) {
					noaccess_str=text[NoAccessNode];
					noaccess_val=n; }
				break;
			case AR_USER:
				if((equal && user->number!=i) || (!equal && user->number<i))
262
					result=_not;
263
				else
264
					result=!_not;
265
266
267
268
269
270
271
272
273
274
275
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessUser];
					noaccess_val=i; }
				break;
			case AR_GROUP:
				if((equal
					&& (cursubnum>=cfg.total_subs
						|| cfg.sub[cursubnum]->grp!=i))
					|| (!equal && cursubnum<cfg.total_subs
						&& cfg.sub[cursubnum]->grp<i))
276
					result=_not;
277
				else
278
					result=!_not;
279
280
281
282
283
284
285
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessGroup];
					noaccess_val=i+1; }
				break;
			case AR_SUB:
				if((equal && cursubnum!=i) || (!equal && cursubnum<i))
286
					result=_not;
287
				else
288
					result=!_not;
289
290
291
292
293
294
295
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessSub];
					noaccess_val=i+1; }
				break;
			case AR_SUBCODE:
				if(cursubnum>=cfg.total_subs
296
					|| stricmp(cfg.sub[cursubnum]->code,(char*)*ptrptr))
297
					result=_not;
298
				else
299
					result=!_not;
300
301
302
303
304
305
306
307
308
309
310
				while(*(*ptrptr))
					(*ptrptr)++;
				if(!result)
					noaccess_str=text[NoAccessSub];
				break;
			case AR_LIB:
				if((equal
					&& (curdirnum>=cfg.total_dirs
						|| cfg.dir[curdirnum]->lib!=i))
					|| (!equal && curdirnum<cfg.total_dirs
						&& cfg.dir[curdirnum]->lib<i))
311
					result=_not;
312
				else
313
					result=!_not;
314
315
316
317
318
319
320
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessLib];
					noaccess_val=i+1; }
				break;
			case AR_DIR:
				if((equal && curdirnum!=i) || (!equal && curdirnum<i))
321
					result=_not;
322
				else
323
					result=!_not;
324
325
326
327
328
329
330
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessDir];
					noaccess_val=i+1; }
				break;
			case AR_DIRCODE:
				if(curdirnum>=cfg.total_dirs
331
					|| stricmp(cfg.dir[curdirnum]->code,(char *)*ptrptr))
332
					result=_not;
333
				else
334
					result=!_not;
335
336
337
338
339
340
341
342
				while(*(*ptrptr))
					(*ptrptr)++;
				if(!result)
					noaccess_str=text[NoAccessSub];
				break;
			case AR_EXPIRE:
				now=time(NULL);
				if(!user->expire || now+((long)i*24L*60L*60L)>user->expire)
343
					result=_not;
344
				else
345
					result=!_not;
346
347
348
349
350
351
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessExpire];
					noaccess_val=i; }
				break;
			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
358
359
360
361
				(*ptrptr)++;
				break;
			case AR_LASTON:
				now=time(NULL);
				if((now-user->laston)/(24L*60L*60L)<(long)i)
362
					result=_not;
363
				else
364
					result=!_not;
365
366
367
368
				(*ptrptr)++;
				break;
			case AR_LOGONS:
				if((equal && user->logons!=i) || (!equal && user->logons<i))
369
					result=_not;
370
				else
371
					result=!_not;
372
373
374
375
				(*ptrptr)++;
				break;
			case AR_MAIN_CMDS:
				if((equal && main_cmds!=i) || (!equal && main_cmds<i))
376
					result=_not;
377
				else
378
					result=!_not;
379
380
381
382
				(*ptrptr)++;
				break;
			case AR_FILE_CMDS:
				if((equal && xfer_cmds!=i) || (!equal && xfer_cmds<i))
383
					result=_not;
384
				else
385
					result=!_not;
386
387
388
389
				(*ptrptr)++;
				break;
			case AR_TLEFT:
				if(timeleft/60<(ulong)n)
390
					result=_not;
391
				else
392
					result=!_not;
393
394
395
396
397
398
				if(!result) {
					noaccess_str=text[NoAccessTimeLeft];
					noaccess_val=n; }
				break;
			case AR_TUSED:
				if((time(NULL)-logontime)/60<(long)n)
399
					result=_not;
400
				else
401
					result=!_not;
402
403
404
405
406
407
				if(!result) {
					noaccess_str=text[NoAccessTimeUsed];
					noaccess_val=n; }
				break;
			case AR_TIME:
				now=time(NULL);
408
409
				localtime_r(&now,&tm);
				if((tm.tm_hour*60)+tm.tm_min<(int)i)
410
					result=_not;
411
				else
412
					result=!_not;
413
414
415
416
417
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessTime];
					noaccess_val=i; }
				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
425
426
427
				if(!result) {
					noaccess_str=text[NoAccessPCR];
					noaccess_val=n; }
				break;
428
			case AR_UDR:	/* up/download byte ratio (by percentage) */
429
430
431
				l=user->dlb;
				if(!l) l=1;
				if(user->dlb>user->ulb
432
					&& (!user->ulb || (100/((float)l/user->ulb))<n))
433
					result=_not;
434
				else
435
					result=!_not;
436
437
438
439
				if(!result) {
					noaccess_str=text[NoAccessUDR];
					noaccess_val=n; }
				break;
440
			case AR_UDFR:	/* up/download file ratio (in percentage) */
441
442
443
				i=user->dls;
				if(!i) i=1;
				if(user->dls>user->uls
444
					&& (!user->uls || (100/((float)i/user->uls))<n))
445
					result=_not;
446
				else
447
					result=!_not;
448
449
450
451
				if(!result) {
					noaccess_str=text[NoAccessUDFR];
					noaccess_val=n; }
				break;
rswindell's avatar
rswindell committed
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
			case AR_ULS:
				if((equal && user->uls!=i) || (!equal && user->uls<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
			case AR_ULB:
				if((equal && user->ulb!=i) || (!equal && user->ulb<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
			case AR_DLS:
				if((equal && user->dls!=i) || (!equal && user->dls<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
			case AR_DLB:
				if((equal && user->dlb!=i) || (!equal && user->dlb<i))
					result=_not;
				else
					result=!_not;
				(*ptrptr)++;
				break;
480
481
482
			case AR_FLAG1:
				if((!equal && !(user->flags1&FLAG(n)))
					|| (equal && user->flags1!=FLAG(n)))
483
					result=_not;
484
				else
485
					result=!_not;
486
487
488
489
490
491
492
				if(!result) {
					noaccess_str=text[NoAccessFlag1];
					noaccess_val=n; }
				break;
			case AR_FLAG2:
				if((!equal && !(user->flags2&FLAG(n)))
					|| (equal && user->flags2!=FLAG(n)))
493
					result=_not;
494
				else
495
					result=!_not;
496
497
498
499
500
501
502
				if(!result) {
					noaccess_str=text[NoAccessFlag2];
					noaccess_val=n; }
				break;
			case AR_FLAG3:
				if((!equal && !(user->flags3&FLAG(n)))
					|| (equal && user->flags3!=FLAG(n)))
503
					result=_not;
504
				else
505
					result=!_not;
506
507
508
509
510
511
512
				if(!result) {
					noaccess_str=text[NoAccessFlag3];
					noaccess_val=n; }
				break;
			case AR_FLAG4:
				if((!equal && !(user->flags4&FLAG(n)))
					|| (equal && user->flags4!=FLAG(n)))
513
					result=_not;
514
				else
515
					result=!_not;
516
517
518
519
520
521
522
				if(!result) {
					noaccess_str=text[NoAccessFlag4];
					noaccess_val=n; }
				break;
			case AR_REST:
				if((!equal && !(user->rest&FLAG(n)))
					|| (equal && user->rest!=FLAG(n)))
523
					result=_not;
524
				else
525
					result=!_not;
526
527
528
529
530
531
532
				if(!result) {
					noaccess_str=text[NoAccessRest];
					noaccess_val=n; }
				break;
			case AR_EXEMPT:
				if((!equal && !(user->exempt&FLAG(n)))
					|| (equal && user->exempt!=FLAG(n)))
533
					result=_not;
534
				else
535
					result=!_not;
536
537
538
539
540
541
				if(!result) {
					noaccess_str=text[NoAccessExempt];
					noaccess_val=n; }
				break;
			case AR_SEX:
				if(user->sex!=n)
542
					result=_not;
543
				else
544
					result=!_not;
545
546
547
				if(!result) {
					noaccess_str=text[NoAccessSex];
					noaccess_val=n; }
548
549
550
551
552
553
554
555
556
557
				break; 
			case AR_SHELL:
				if(user->shell>=cfg.total_shells
					|| stricmp(cfg.shell[user->shell]->code,(char*)*ptrptr))
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				break;
558
559
560
561
562
563
564
565
			case AR_PROT:
				if(stricmp(user->modem,(char*)*ptrptr))	/* should this be changed to client.prot? */
					result=_not;
				else
					result=!_not;
				while(*(*ptrptr))
					(*ptrptr)++;
				break;
566
567
		}
	}
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
	return(result);
}

bool sbbs_t::chk_ar(uchar *ar, user_t* user)
{
	uchar *p;

	if(ar==NULL)
		return(true);
	p=ar;
	return(ar_exp(&p,user));
}


/****************************************************************************/
/* This function fills the usrsub, usrsubs, usrgrps, curgrp, and cursub     */
/* variables based on the security clearance of the current user (useron)   */
/****************************************************************************/
void sbbs_t::getusrsubs()
{
    uint i,j,k,l;

	for(j=0,i=0;i<cfg.total_grps;i++) {
		if(!chk_ar(cfg.grp[i]->ar,&useron))
			continue;
		for(k=0,l=0;l<cfg.total_subs;l++) {
			if(cfg.sub[l]->grp!=i) continue;
			if(!chk_ar(cfg.sub[l]->ar,&useron))
				continue;
597
598
			usrsub[j][k++]=l; 
		}
599
600
601
		usrsubs[j]=k;
		if(!k)          /* No subs accessible in group */
			continue;
602
603
		usrgrp[j++]=i; 
	}
604
	usrgrps=j;
605
606
	if(usrgrps==0)
		return;
607
608
609
610
611
612
613
614
615
616
617
618
619
620
	while((curgrp>=usrgrps || !usrsubs[curgrp]) && curgrp) curgrp--;
	while(cursub[curgrp]>=usrsubs[curgrp] && cursub[curgrp]) cursub[curgrp]--;
}

/****************************************************************************/
/* This function fills the usrdir, usrdirs, usrlibs, curlib, and curdir     */
/* variables based on the security clearance of the current user (useron)   */
/****************************************************************************/
void sbbs_t::getusrdirs()
{
    uint i,j,k,l;

	if(useron.rest&FLAG('T')) {
		usrlibs=0;
621
622
		return; 
	}
623
624
625
626
627
628
629
630
631
632
633
	for(j=0,i=0;i<cfg.total_libs;i++) {
		if(!chk_ar(cfg.lib[i]->ar,&useron))
			continue;
		for(k=0,l=0;l<cfg.total_dirs;l++) {
			if(cfg.dir[l]->lib!=i) continue;
			if(!chk_ar(cfg.dir[l]->ar,&useron))
				continue;
			usrdir[j][k++]=l; }
		usrdirs[j]=k;
		if(!k)          /* No dirs accessible in lib */
			continue;
634
635
		usrlib[j++]=i; 
	}
636
	usrlibs=j;
637
638
	if(usrlibs==0)
		return;
639
640
641
642
	while((curlib>=usrlibs || !usrdirs[curlib]) && curlib) curlib--;
	while(curdir[curlib]>=usrdirs[curlib] && curdir[curlib]) curdir[curlib]--;
}

643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
uint sbbs_t::getusrgrp(uint subnum)
{
	uint	ugrp;

	if(subnum==INVALID_SUB)
		return(0);

	if(usrgrps<=0)
		return(0);

	for(ugrp=0;ugrp<usrgrps;ugrp++)
		if(usrgrp[ugrp]==cfg.sub[subnum]->grp)
			break;

	return(ugrp+1);
}

uint sbbs_t::getusrsub(uint subnum)
{
	uint	usub;
	uint	ugrp;

	ugrp = getusrgrp(subnum);
	if(ugrp<=0)
		return(0);
	
	for(usub=0;usub<usrsubs[ugrp];usub++)
		if(usrsub[ugrp][usub]==subnum)
			break;

	return(usub+1);
}

676
677
678
679
680
681
int sbbs_t::dir_op(uint dirnum)
{
	return(SYSOP || (cfg.dir[dirnum]->op_ar[0] && chk_ar(cfg.dir[dirnum]->op_ar,&useron)));
}