chk_ar.cpp 14.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)		*
 *																			*
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
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
				break;
			case AR_DAY:
				now=time(NULL);
206
207
208
				localtime_r(&now,&tm);
				if((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
386
				localtime_r(&now,&tm);
				if((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/((float)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/((float)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/((float)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
				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;
507
508
509
510
511
512
513
514
			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;
515
516
		}
	}
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
	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;
546
547
			usrsub[j][k++]=l; 
		}
548
549
550
		usrsubs[j]=k;
		if(!k)          /* No subs accessible in group */
			continue;
551
552
		usrgrp[j++]=i; 
	}
553
	usrgrps=j;
554
555
	if(usrgrps==0)
		return;
556
557
558
559
560
561
562
563
564
565
566
567
568
569
	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;
570
571
		return; 
	}
572
573
574
575
576
577
578
579
580
581
582
	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;
583
584
		usrlib[j++]=i; 
	}
585
	usrlibs=j;
586
587
	if(usrlibs==0)
		return;
588
589
590
591
	while((curlib>=usrlibs || !usrdirs[curlib]) && curlib) curlib--;
	while(curdir[curlib]>=usrdirs[curlib] && curdir[curlib]) curdir[curlib]--;
}

592
593
594
595
596
597
598
599
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
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);
}

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