chk_ar.cpp 14.5 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)		*
 *																			*
11
 * Copyright 2004 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
182
183
				#endif
				break;
			case AR_EXPERT:
				if(!(user->misc&EXPERT))
184
185
					result=_not;
				else result=!_not;
186
187
188
				break;
			case AR_SYSOP:
				if(!SYSOP)
189
190
					result=_not;
				else result=!_not;
191
				break;
192
193
194
195
196
197
198
199
200
201
			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;
202
203
			case AR_QUIET:
				if(thisnode.status!=NODE_QUIET)
204
205
					result=_not;
				else result=!_not;
206
207
208
				break;
			case AR_LOCAL:
				if(online!=ON_LOCAL)
209
210
					result=_not;
				else result=!_not;
211
212
213
				break;
			case AR_DAY:
				now=time(NULL);
214
215
216
				localtime_r(&now,&tm);
				if((equal && tm.tm_wday!=(int)n) 
					|| (!equal && tm.tm_wday<(int)n))
217
					result=_not;
218
				else
219
					result=!_not;
220
221
222
223
224
225
226
227
				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))
228
					result=_not;
229
				else
230
					result=!_not;
231
232
233
234
235
236
237
				(*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))
238
					result=_not;
239
				else
240
					result=!_not;
241
242
243
244
245
246
				if(!result) {
					noaccess_str=text[NoAccessNode];
					noaccess_val=n; }
				break;
			case AR_USER:
				if((equal && user->number!=i) || (!equal && user->number<i))
247
					result=_not;
248
				else
249
					result=!_not;
250
251
252
253
254
255
256
257
258
259
260
				(*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))
261
					result=_not;
262
				else
263
					result=!_not;
264
265
266
267
268
269
270
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessGroup];
					noaccess_val=i+1; }
				break;
			case AR_SUB:
				if((equal && cursubnum!=i) || (!equal && cursubnum<i))
271
					result=_not;
272
				else
273
					result=!_not;
274
275
276
277
278
279
280
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessSub];
					noaccess_val=i+1; }
				break;
			case AR_SUBCODE:
				if(cursubnum>=cfg.total_subs
281
					|| stricmp(cfg.sub[cursubnum]->code,(char*)*ptrptr))
282
					result=_not;
283
				else
284
					result=!_not;
285
286
287
288
289
290
291
292
293
294
295
				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))
296
					result=_not;
297
				else
298
					result=!_not;
299
300
301
302
303
304
305
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessLib];
					noaccess_val=i+1; }
				break;
			case AR_DIR:
				if((equal && curdirnum!=i) || (!equal && curdirnum<i))
306
					result=_not;
307
				else
308
					result=!_not;
309
310
311
312
313
314
315
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessDir];
					noaccess_val=i+1; }
				break;
			case AR_DIRCODE:
				if(curdirnum>=cfg.total_dirs
316
					|| stricmp(cfg.dir[curdirnum]->code,(char *)*ptrptr))
317
					result=_not;
318
				else
319
					result=!_not;
320
321
322
323
324
325
326
327
				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)
328
					result=_not;
329
				else
330
					result=!_not;
331
332
333
334
335
336
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessExpire];
					noaccess_val=i; }
				break;
			case AR_RANDOM:
337
				n=sbbs_random(i+1);
338
				if((equal && n!=i) || (!equal && n<i))
339
					result=_not;
340
				else
341
					result=!_not;
342
343
344
345
346
				(*ptrptr)++;
				break;
			case AR_LASTON:
				now=time(NULL);
				if((now-user->laston)/(24L*60L*60L)<(long)i)
347
					result=_not;
348
				else
349
					result=!_not;
350
351
352
353
				(*ptrptr)++;
				break;
			case AR_LOGONS:
				if((equal && user->logons!=i) || (!equal && user->logons<i))
354
					result=_not;
355
				else
356
					result=!_not;
357
358
359
360
				(*ptrptr)++;
				break;
			case AR_MAIN_CMDS:
				if((equal && main_cmds!=i) || (!equal && main_cmds<i))
361
					result=_not;
362
				else
363
					result=!_not;
364
365
366
367
				(*ptrptr)++;
				break;
			case AR_FILE_CMDS:
				if((equal && xfer_cmds!=i) || (!equal && xfer_cmds<i))
368
					result=_not;
369
				else
370
					result=!_not;
371
372
373
374
				(*ptrptr)++;
				break;
			case AR_TLEFT:
				if(timeleft/60<(ulong)n)
375
					result=_not;
376
				else
377
					result=!_not;
378
379
380
381
382
383
				if(!result) {
					noaccess_str=text[NoAccessTimeLeft];
					noaccess_val=n; }
				break;
			case AR_TUSED:
				if((time(NULL)-logontime)/60<(long)n)
384
					result=_not;
385
				else
386
					result=!_not;
387
388
389
390
391
392
				if(!result) {
					noaccess_str=text[NoAccessTimeUsed];
					noaccess_val=n; }
				break;
			case AR_TIME:
				now=time(NULL);
393
394
				localtime_r(&now,&tm);
				if((tm.tm_hour*60)+tm.tm_min<(int)i)
395
					result=_not;
396
				else
397
					result=!_not;
398
399
400
401
402
				(*ptrptr)++;
				if(!result) {
					noaccess_str=text[NoAccessTime];
					noaccess_val=i; }
				break;
403
			case AR_PCR:	/* post/call ratio (by percentage) */
404
				if(user->logons>user->posts
405
					&& (!user->posts || (100/((float)user->logons/user->posts))<(long)n))
406
					result=_not;
407
				else
408
					result=!_not;
409
410
411
412
				if(!result) {
					noaccess_str=text[NoAccessPCR];
					noaccess_val=n; }
				break;
413
			case AR_UDR:	/* up/download byte ratio (by percentage) */
414
415
416
				l=user->dlb;
				if(!l) l=1;
				if(user->dlb>user->ulb
417
					&& (!user->ulb || (100/((float)l/user->ulb))<n))
418
					result=_not;
419
				else
420
					result=!_not;
421
422
423
424
				if(!result) {
					noaccess_str=text[NoAccessUDR];
					noaccess_val=n; }
				break;
425
			case AR_UDFR:	/* up/download file ratio (in percentage) */
426
427
428
				i=user->dls;
				if(!i) i=1;
				if(user->dls>user->uls
429
					&& (!user->uls || (100/((float)i/user->uls))<n))
430
					result=_not;
431
				else
432
					result=!_not;
433
434
435
436
437
438
439
				if(!result) {
					noaccess_str=text[NoAccessUDFR];
					noaccess_val=n; }
				break;
			case AR_FLAG1:
				if((!equal && !(user->flags1&FLAG(n)))
					|| (equal && user->flags1!=FLAG(n)))
440
					result=_not;
441
				else
442
					result=!_not;
443
444
445
446
447
448
449
				if(!result) {
					noaccess_str=text[NoAccessFlag1];
					noaccess_val=n; }
				break;
			case AR_FLAG2:
				if((!equal && !(user->flags2&FLAG(n)))
					|| (equal && user->flags2!=FLAG(n)))
450
					result=_not;
451
				else
452
					result=!_not;
453
454
455
456
457
458
459
				if(!result) {
					noaccess_str=text[NoAccessFlag2];
					noaccess_val=n; }
				break;
			case AR_FLAG3:
				if((!equal && !(user->flags3&FLAG(n)))
					|| (equal && user->flags3!=FLAG(n)))
460
					result=_not;
461
				else
462
					result=!_not;
463
464
465
466
467
468
469
				if(!result) {
					noaccess_str=text[NoAccessFlag3];
					noaccess_val=n; }
				break;
			case AR_FLAG4:
				if((!equal && !(user->flags4&FLAG(n)))
					|| (equal && user->flags4!=FLAG(n)))
470
					result=_not;
471
				else
472
					result=!_not;
473
474
475
476
477
478
479
				if(!result) {
					noaccess_str=text[NoAccessFlag4];
					noaccess_val=n; }
				break;
			case AR_REST:
				if((!equal && !(user->rest&FLAG(n)))
					|| (equal && user->rest!=FLAG(n)))
480
					result=_not;
481
				else
482
					result=!_not;
483
484
485
486
487
488
489
				if(!result) {
					noaccess_str=text[NoAccessRest];
					noaccess_val=n; }
				break;
			case AR_EXEMPT:
				if((!equal && !(user->exempt&FLAG(n)))
					|| (equal && user->exempt!=FLAG(n)))
490
					result=_not;
491
				else
492
					result=!_not;
493
494
495
496
497
498
				if(!result) {
					noaccess_str=text[NoAccessExempt];
					noaccess_val=n; }
				break;
			case AR_SEX:
				if(user->sex!=n)
499
					result=_not;
500
				else
501
					result=!_not;
502
503
504
				if(!result) {
					noaccess_str=text[NoAccessSex];
					noaccess_val=n; }
505
506
507
508
509
510
511
512
513
514
				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;
515
516
517
518
519
520
521
522
			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;
523
524
		}
	}
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
	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;
554
555
			usrsub[j][k++]=l; 
		}
556
557
558
		usrsubs[j]=k;
		if(!k)          /* No subs accessible in group */
			continue;
559
560
		usrgrp[j++]=i; 
	}
561
	usrgrps=j;
562
563
	if(usrgrps==0)
		return;
564
565
566
567
568
569
570
571
572
573
574
575
576
577
	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;
578
579
		return; 
	}
580
581
582
583
584
585
586
587
588
589
590
	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;
591
592
		usrlib[j++]=i; 
	}
593
	usrlibs=j;
594
595
	if(usrlibs==0)
		return;
596
597
598
599
	while((curlib>=usrlibs || !usrdirs[curlib]) && curlib) curlib--;
	while(curdir[curlib]>=usrdirs[curlib] && curdir[curlib]) curdir[curlib]--;
}

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
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);
}

633
634
635
636
637
638
int sbbs_t::dir_op(uint dirnum)
{
	return(SYSOP || (cfg.dir[dirnum]->op_ar[0] && chk_ar(cfg.dir[dirnum]->op_ar,&useron)));
}