chk_ar.cpp 13.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
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
/* 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)		*
 *																			*
 * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html		*
 *																			*
 * 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
45
46
47
48
49
50
51
52
53
	uint	i,n,artype,age;
	ulong	l;
	struct tm * tm;

	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
91
92
93
			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:
			case AR_QUIET:
			case AR_OS2:
			case AR_DOS:
94
95
96
			case AR_WIN32:
			case AR_UNIX:
			case AR_LINUX:
97
98
99
100
101
102
103
104
105
106
				break;
			default:
				(*ptrptr)++;
				break; }

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

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