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
94
95
96
97
98
99
100
101
102
103
			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:
				break;
			default:
				(*ptrptr)++;
				break; }

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