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

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
633
634
635
636
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);
}

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