Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

chk_ar.cpp 14.2 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
	while((curlib>=usrlibs || !usrdirs[curlib]) && curlib) curlib--;
	while(curdir[curlib]>=usrdirs[curlib] && curdir[curlib]) curdir[curlib]--;
}

584 585 586 587 588 589 590 591 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
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);
}

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