1 /* $Id: prop.c,v 1.17 2015/06/18 03:42:48 manu Exp $ */
2 
3 /*
4  * Copyright (c) 2006-2012 Emmanuel Dreyfus
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *        This product includes software developed by Emmanuel Dreyfus
18  *
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "config.h"
33 
34 #ifdef HAVE_SYS_CDEFS_H
35 #include <sys/cdefs.h>
36 #ifdef __RCSID
37 __RCSID("$Id: prop.c,v 1.17 2015/06/18 03:42:48 manu Exp $");
38 #endif
39 #endif
40 
41 #include <stdio.h>
42 #include <unistd.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <syslog.h>
46 #include <errno.h>
47 #include <ctype.h>
48 #include <sysexits.h>
49 #include <signal.h>
50 #include <fnmatch.h>
51 
52 #if defined(HAVE_OLD_QUEUE_H) || !defined(HAVE_SYS_QUEUE_H)
53 #include "queue.h"
54 #else
55 #include <sys/queue.h>
56 #endif
57 #include <sys/types.h>
58 
59 #include "milter-greylist.h"
60 #include "pending.h"
61 #include "spf.h"
62 #include "acl.h"
63 #include "conf.h"
64 #include "sync.h"
65 #include "prop.h"
66 
67 #ifdef USE_DMALLOC
68 #include <dmalloc.h>
69 #endif
70 
71 #ifndef FNM_CASEFOLD
72 #define FNM_CASEFOLD 0	/* non portable extension */
73 #endif
74 
75 static void
_prop_push(linep,valp,clear,priv,dolower)76 _prop_push(linep, valp, clear, priv, dolower)
77 	char *linep;
78 	char *valp;
79 	int clear;
80 	struct mlfi_priv *priv;
81 	int dolower;
82 {
83 	char *cp;
84 	struct prop *up;
85 
86 	if ((up = malloc(sizeof(*up))) == NULL) {
87 		mg_log(LOG_ERR, "malloc failed: %s", strerror(errno));
88 		exit(EX_OSERR);
89 	}
90 
91 	if ((up->up_name = strdup(linep)) == NULL) {
92 		mg_log(LOG_ERR, "strup failed: %s", strerror(errno));
93 		exit(EX_OSERR);
94 	}
95 
96 	if ((up->up_value = strdup(valp)) == NULL) {
97 		mg_log(LOG_ERR, "strdup failed: %s", strerror(errno));
98 		exit(EX_OSERR);
99 	}
100 
101 	/*
102 	 * Convert everything to lower-case
103 	 */
104 	if (dolower) {
105 		for (cp = up->up_name; *cp; cp++)
106 			*cp = (char)tolower((int)*cp);
107 
108 		for (cp = up->up_value; *cp; cp++)
109 			*cp = (char)tolower((int)*cp);
110 	}
111 
112 	up->up_flags = UP_PLAINPROP|UP_TMPPROP;
113 	if (clear)
114 		up->up_flags |= UP_CLEARPROP;
115 
116 	/*
117 	 * If called at RCPT stage, record the recipient
118 	 */
119 	if (priv->priv_cur_rcpt[0] != '\0') {
120 		if ((up->up_rcpt = strdup(priv->priv_cur_rcpt)) == NULL) {
121 			mg_log(LOG_ERR, "strdup failed: %s", strerror(errno));
122 			exit(EX_OSERR);
123 		}
124 	} else {
125 		up->up_rcpt = NULL;
126 	}
127 
128 	LIST_INSERT_HEAD(&priv->priv_prop, up, up_list);
129 
130 	if (conf.c_debug)
131 		mg_log(LOG_DEBUG, "got prop $%s = \"%s\"", linep, valp);
132 
133 	return;
134 }
135 
136 void
prop_push(linep,valp,clear,priv)137 prop_push(linep, valp, clear, priv)
138 	char *linep;
139 	char *valp;
140 	int clear;
141 	struct mlfi_priv *priv;
142 {
143 	_prop_push(linep, valp, clear, priv, 1);
144 }
145 
146 
147 int
prop_string_validate(ad,stage,ap,priv)148 prop_string_validate(ad, stage, ap, priv)
149 	acl_data_t *ad;
150 	acl_stage_t stage;
151 	struct acl_param *ap;
152 	struct mlfi_priv *priv;
153 {
154 	struct prop *up;
155 	acl_data_t *upd;
156 	char *string;
157 	int retval = 0;
158 
159 	upd = ad->prop->upd_data;
160 	string = fstring_expand(priv, NULL, upd->string, NULL);
161 
162 	LIST_FOREACH(up, &priv->priv_prop, up_list) {
163 		if (strcasecmp(ad->prop->upd_name, up->up_name) != 0)
164 			continue;
165 
166 		if (conf.c_debug)
167 			mg_log(LOG_DEBUG, "test $%s = \"%s\" vs \"%s\"",
168 			    up->up_name, up->up_value, string);
169 
170 		if (strcasecmp(up->up_value, string) == 0) {
171 			priv->priv_prop_match = up;
172 			retval = 1;
173 			break;
174 		}
175 	}
176 
177 	free(string);
178 	return retval;
179 }
180 
181 int
prop_glob_validate(ad,stage,ap,priv)182 prop_glob_validate(ad, stage, ap, priv)
183 	acl_data_t *ad;
184 	acl_stage_t stage;
185 	struct acl_param *ap;
186 	struct mlfi_priv *priv;
187 {
188 	struct prop *up;
189 	acl_data_t *upd;
190 	char *string;
191 	int retval = 0;
192 
193 	upd = ad->prop->upd_data;
194 	string = fstring_expand(priv, NULL, upd->string, NULL);
195 
196 	LIST_FOREACH(up, &priv->priv_prop, up_list) {
197 		if (strcasecmp(ad->prop->upd_name, up->up_name) != 0)
198 			continue;
199 
200 		if (conf.c_debug)
201 			mg_log(LOG_DEBUG, "test $%s = \"%s\" vs \"%s\"",
202 			    up->up_name, up->up_value, string);
203 
204 		if (fnmatch(up->up_value, string, FNM_CASEFOLD) == 0) {
205 			priv->priv_prop_match = up;
206 			retval = 1;
207 			break;
208 		}
209 	}
210 
211 	free(string);
212 	return retval;
213 }
214 
215 void
prop_opnum_add(ad,data)216 prop_opnum_add(ad, data)
217 	acl_data_t *ad;
218 	void *data;
219 {
220 	struct acl_opnum_prop *aonp;
221 
222 	aonp = (struct acl_opnum_prop *)data;
223 
224 	if ((ad->aonp = malloc(sizeof(*ad->aonp))) == NULL) {
225 		mg_log(LOG_ERR, "malloc() failed");
226 		exit(EX_OSERR);
227 	}
228 
229 	ad->aonp->aonp_op = aonp->aonp_op;
230 	ad->aonp->aonp_type = aonp->aonp_type;
231 	if ((ad->aonp->aonp_name = strdup(aonp->aonp_name)) == NULL) {
232 		mg_log(LOG_ERR, "strdup() failed");
233 		exit(EX_OSERR);
234 	}
235 
236 	return;
237 }
238 
239 void
prop_opnum_free(ad)240 prop_opnum_free(ad)
241 	acl_data_t *ad;
242 {
243 	free(ad->aonp->aonp_name);
244 	free(ad->aonp);
245 	return;
246 }
247 
248 
249 char *
prop_opnum_print(ad,buf,len)250 prop_opnum_print(ad, buf, len)
251 	acl_data_t *ad;
252 	char *buf;
253 	size_t len;
254 {
255 	struct {
256 		enum operator op;
257 		char *str;
258 	} op_to_str[] = {
259 		{ OP_EQ, "==" },
260 		{ OP_NE, "!=" },
261 		{ OP_GT, ">" },
262 		{ OP_LT, "<" },
263 		{ OP_GE, ">=" },
264 		{ OP_LE, "<=" },
265 	};
266 	int i;
267 	char *str = NULL;
268 
269 	for (i = 0; i < sizeof(op_to_str) / sizeof(*op_to_str); i++) {
270 		if (op_to_str[i].op == ad->aonp->aonp_op) {
271 			str = op_to_str[i].str;
272 			break;
273 		}
274 	}
275 	if (str == NULL) {
276 		mg_log(LOG_ERR, "unexpected operator");
277 		exit(EX_SOFTWARE);
278 	}
279 
280 	snprintf(buf, len, "%s $%s", str, ad->aonp->aonp_name);
281 
282 	return buf;
283 }
284 
285 int
prop_rhsnum_validate(ad,stage,ap,priv)286 prop_rhsnum_validate(ad, stage, ap, priv)
287 	acl_data_t *ad;
288 	acl_stage_t stage;
289 	struct acl_param *ap;
290 	struct mlfi_priv *priv;
291 {
292 	struct prop *up;
293 	struct acl_opnum_prop *aonp;
294 	int val1, val2;
295 	int retval = 0;
296 
297 	aonp = ad->aonp;
298 	LIST_FOREACH(up, &priv->priv_prop, up_list) {
299 		if (strcasecmp(up->up_name, aonp->aonp_name) != 0)
300 			continue;
301 
302 		if (conf.c_debug)
303 			mg_log(LOG_DEBUG, "test $%s = \"%s\" vs \"%s\"",
304 			    up->up_name, up->up_value, aonp->aonp_name);
305 
306 		switch (aonp->aonp_type) {
307 		case AONP_MSGSIZE:
308 			val1 = priv->priv_msgcount;
309 			break;
310 		case AONP_RCPTCOUNT:
311 			val1 = priv->priv_rcptcount;
312 			break;
313 #ifdef USE_SPAMD
314 		case AONP_SPAMD:
315 			val1 = priv->priv_spamd_score10;
316 			break;
317 #endif /* USE_SPAMD */
318 		default:
319 			mg_log(LOG_ERR, "unexpected aonp_type");
320 			exit(EX_SOFTWARE);
321 		}
322 		val2 = atoi(up->up_value);
323 
324 		retval = acl_opnum_cmp(val1, aonp->aonp_op, val2);
325 		break;
326 	}
327 
328 	return retval;
329 }
330 
331 int
prop_lhsnum_validate(ad,stage,ap,priv)332 prop_lhsnum_validate(ad, stage, ap, priv)
333 	acl_data_t *ad;
334 	acl_stage_t stage;
335 	struct acl_param *ap;
336 	struct mlfi_priv *priv;
337 {
338 	struct acl_opnum_data *aond;
339 	char *current;
340 
341 	aond = ad->prop->upd_data;
342 
343 	current = prop_byname(priv, ad->prop->upd_name);
344 	if (current == NULL)
345 		return 0;
346 
347 	return acl_opnum_cmp(atoi(current), aond->op, aond->num);
348 }
349 
350 int
prop_pop_validate(ad,stage,ap,priv)351 prop_pop_validate(ad, stage, ap, priv)
352 	acl_data_t *ad;
353 	acl_stage_t stage;
354 	struct acl_param *ap;
355 	struct mlfi_priv *priv;
356 {
357 	struct acl_prop_pop *apop;
358 	char *lhs_str;
359 	char *rhs_str;
360 
361 	apop = ad->apop;
362 
363 	lhs_str = prop_byname(priv, apop->apop_lhs);
364 	if (lhs_str == NULL)
365 		lhs_str = "0";
366 
367 	rhs_str = prop_byname(priv, apop->apop_rhs);
368 	if (rhs_str == NULL)
369 		rhs_str = "0";
370 
371 	return acl_opnum_cmp(atoi(lhs_str), apop->apop_op, atoi(rhs_str));
372 }
373 
374 
375 void
prop_delete(up)376 prop_delete(up)
377 	struct prop *up;
378 {
379 	free(up->up_name);
380 	free(up->up_value);
381 	if (up->up_rcpt != NULL)
382 		free(up->up_rcpt);
383 	LIST_REMOVE(up, up_list);
384 	free(up);
385 }
386 
387 void
prop_delete_byname(priv,name)388 prop_delete_byname(priv, name)
389 	struct mlfi_priv *priv;
390 	char *name;
391 {
392 	struct prop *up;
393 	struct prop *nup;
394 
395 	up = LIST_FIRST(&priv->priv_prop);
396 
397 	while (up != NULL) {
398 		nup = LIST_NEXT(up, up_list);
399 		if (strcmp(up->up_name, name) == 0)
400 			prop_delete(up);
401 		up = nup;
402 	}
403 	return;
404 }
405 
406 void
prop_clear(priv,flags)407 prop_clear(priv, flags)
408 	struct mlfi_priv *priv;
409 	int flags;
410 {
411 	struct prop *up;
412 	struct prop *nup;
413 
414 	up = LIST_FIRST(&priv->priv_prop);
415 
416 	while (up != NULL) {
417 		nup = LIST_NEXT(up, up_list);
418 		if (up->up_flags & flags) {
419 			if (priv->priv_prop_match == up)
420 				priv->priv_prop_match = NULL;
421 			free(up->up_name);
422 			free(up->up_value);
423 			if (up->up_rcpt != NULL)
424 				free(up->up_rcpt);
425 			LIST_REMOVE(up, up_list);
426 			free(up);
427 		}
428 		up = nup;
429 	}
430 	return;
431 }
432 
433 void
prop_untmp(priv)434 prop_untmp(priv)
435 	struct mlfi_priv *priv;
436 {
437 	struct prop *up;
438 
439 	LIST_FOREACH(up, &priv->priv_prop, up_list)
440 		up->up_flags &= ~UP_TMPPROP;
441 	return;
442 }
443 
444 int
prop_regex_validate(ad,stage,ap,priv)445 prop_regex_validate(ad, stage, ap, priv)
446 	acl_data_t *ad;
447 	acl_stage_t stage;
448 	struct acl_param *ap;
449 	struct mlfi_priv *priv;
450 {
451 	struct prop *up;
452 	acl_data_t *upd;
453 	int retval = 0;
454 
455 	upd = ad->prop->upd_data;
456 
457 	LIST_FOREACH(up, &priv->priv_prop, up_list) {
458 		if (strcasecmp(ad->prop->upd_name, up->up_name) != 0)
459 			continue;
460 
461 		if (conf.c_debug)
462 			mg_log(LOG_DEBUG, "test $%s = \"%s\" vs %s",
463 			    up->up_name, up->up_value, upd->regex.re_copy);
464 
465 		if (myregexec(priv, upd, ap, up->up_value) == 0) {
466 			priv->priv_prop_match = up;
467 			retval = 1;
468 			break;
469 		}
470 	}
471 
472 	return retval;
473 }
474 
475 #define ERRLEN 1024
476 typedef enum { PBV_BODY, PBV_HEADER } pbv_t;
477 
478 static int
prop_data_validate(ad,stage,ap,priv,type)479 prop_data_validate(ad, stage, ap, priv, type)
480 	acl_data_t *ad;
481 	acl_stage_t stage;
482 	struct acl_param *ap;
483 	struct mlfi_priv *priv;
484 	pbv_t type;
485 {
486 	struct prop *up;
487 	struct line *l;
488 	int retval = 0;
489 	char *typestr;
490 	struct bh_line *data;
491 
492 	if (type == PBV_BODY) {
493 		typestr = "body";
494 		data = &priv->priv_body;
495 	} else {
496 		typestr = "header";
497 		data = &priv->priv_header;
498 	}
499 
500 	if (stage != AS_DATA) {
501 		mg_log(LOG_ERR, "%s filter called at non DATA stage", typestr);
502 		exit(EX_SOFTWARE);
503 	}
504 
505 	LIST_FOREACH(up, &priv->priv_prop, up_list) {
506 		size_t len;
507 		char *regexstr = NULL;
508 		regex_t regex;
509 		int is_regex;
510 
511 		if (strcasecmp(ad->string, up->up_name) != 0)
512 			continue;
513 
514 		if (conf.c_debug)
515 			mg_log(LOG_DEBUG, "test $%s = %s vs %s",
516 			    up->up_name, up->up_value, typestr);
517 
518 		len = strlen(up->up_value);
519 		is_regex = 0;
520 
521 		/*
522 		 * Regex case
523 		 */
524 		if (up->up_value[0] == '/' && up->up_value[len - 1] == '/') {
525 			char errstr[ERRLEN + 1];
526 			int fl;
527 			int error;
528 
529 			if ((regexstr = strdup(up->up_value)) == NULL) {
530 				mg_log(LOG_ERR, "strdup failed");
531 				exit(EX_OSERR);
532 			}
533 
534 			/* Strip trailing / */
535 			regexstr[len - 1] = '\0';
536 
537 			fl = (REG_ICASE | REG_NEWLINE | REG_NOSUB);
538 			if (conf.c_extendedregex)
539 				fl |= REG_EXTENDED;
540 
541 			/* +1 to strip leading / */
542 			if ((error = regcomp(&regex, regexstr + 1, fl)) != 0) {
543 				regerror(error, &regex, errstr, ERRLEN);
544 				mg_log(LOG_WARNING, "bad regular expression "
545 				       "\"%s\": %s", regexstr, errstr);
546 				free(regexstr);
547 				continue;
548         		}
549 
550 			is_regex = 1;
551 		}
552 
553 
554 		/*
555 		 * For each line
556 		 */
557 		TAILQ_FOREACH(l, data, l_list) {
558 			if (conf.c_debug)
559 				mg_log(LOG_DEBUG, "test $%s = %s vs \"%s\"",
560 				    up->up_name, up->up_value, l->l_line);
561 
562 			/*
563 			 * substring match
564 			 */
565 			if (!is_regex) {
566 				if (strstr(l->l_line, up->up_value) != NULL) {
567 					priv->priv_prop_match = up;
568 					return 1;
569 				}
570 				continue;
571 			}
572 
573 			/*
574 			 * regex match
575 			 */
576 			if (regexec(&regex, l->l_line, 0, NULL, 0) == 0) {
577 				priv->priv_prop_match = up;
578 				retval = 1;
579 				break;
580 			}
581 		}
582 
583 		if (is_regex) {
584 			regfree(&regex);
585 			free(regexstr);
586 		}
587 
588 		if (retval == 1)
589 			return 1;
590 	}
591 
592 	return 0;
593 }
594 
595 int
prop_body_validate(ad,stage,ap,priv)596 prop_body_validate(ad, stage, ap, priv)
597 	acl_data_t *ad;
598 	acl_stage_t stage;
599 	struct acl_param *ap;
600 	struct mlfi_priv *priv;
601 {
602 	return prop_data_validate(ad, stage, ap, priv, PBV_BODY);
603 }
604 
605 int
prop_header_validate(ad,stage,ap,priv)606 prop_header_validate(ad, stage, ap, priv)
607 	acl_data_t *ad;
608 	acl_stage_t stage;
609 	struct acl_param *ap;
610 	struct mlfi_priv *priv;
611 {
612 	return prop_data_validate(ad, stage, ap, priv, PBV_HEADER);
613 }
614 
615 /*
616  * This does not cope well with multivalued props
617  */
618 char *
prop_byname(priv,name)619 prop_byname(priv, name)
620 	struct mlfi_priv *priv;
621 	char *name;
622 {
623 	struct prop *up;
624 
625 	LIST_FOREACH(up, &priv->priv_prop, up_list) {
626 		if (strcasecmp(name, up->up_name) != 0)
627 			continue;
628 
629 		return up->up_value;
630 	}
631 
632 	return NULL;
633 }
634 
635 static int
_prop_eqset_string(ad,priv,clear)636 _prop_eqset_string(ad, priv, clear)
637 	acl_data_t *ad;
638 	struct mlfi_priv *priv;
639 	int clear;
640 {
641 	acl_data_t *upd;
642 	char *string;
643 
644 	upd = ad->prop->upd_data;
645 	string = fstring_expand(priv, NULL, upd->string, NULL);
646 
647 	/* Delete existing value, add new one */
648 	prop_delete_byname(priv, ad->prop->upd_name);
649 	_prop_push(ad->prop->upd_name, string, clear, priv, 0);
650 
651 	free(string);
652 
653 	/* always match */
654 	return 1;
655 }
656 
657 static int
_prop_incset_string(ad,priv,clear,coef)658 _prop_incset_string(ad, priv, clear, coef)
659 	acl_data_t *ad;
660 	struct mlfi_priv *priv;
661 	int clear;
662 	int coef;
663 {
664 	acl_data_t *upd;
665 	char *current;
666 	char *string;
667 	char newval[16]; /* 16 is enough for an int */
668 
669 	current = prop_byname(priv, ad->prop->upd_name);
670 	if (current == NULL)
671 		current = "0";
672 
673 	upd = ad->prop->upd_data;
674 	string = fstring_expand(priv, NULL, upd->string, NULL);
675 
676 	(void)sprintf(newval, "%d", atoi(current) + (coef * atoi(string)));
677 
678 	/* Delete existing value, add new one */
679 	prop_delete_byname(priv, ad->prop->upd_name);
680 	_prop_push(ad->prop->upd_name, newval, clear, priv, 0);
681 
682 	free(string);
683 
684 	/* always match */
685 	return 1;
686 }
687 
688 static int
_prop_eqset_prop(ad,priv,clear)689 _prop_eqset_prop(ad, priv, clear)
690 	acl_data_t *ad;
691 	struct mlfi_priv *priv;
692 	int clear;
693 {
694 	acl_data_t *upd;
695 	char *string;
696 
697 	upd = ad->prop->upd_data;
698 	string = prop_byname(priv, upd->string);
699 
700 	if (string == NULL)
701 		string = "";
702 
703 	/* Delete existing value, add new one */
704 	prop_delete_byname(priv, ad->prop->upd_name);
705 	_prop_push(ad->prop->upd_name, string, clear, priv, 0);
706 
707 	/* always match */
708 	return 1;
709 }
710 
711 static int
_prop_incset_prop(ad,priv,clear,coef)712 _prop_incset_prop(ad, priv, clear, coef)
713 	acl_data_t *ad;
714 	struct mlfi_priv *priv;
715 	int clear;
716 	int coef;
717 {
718 	acl_data_t *upd;
719 	char *current;
720 	char *string;
721 	char newval[16]; /* 16 is enough for an int */
722 
723 	current = prop_byname(priv, ad->prop->upd_name);
724 	if (current == NULL)
725 		current = "0";
726 
727 	upd = ad->prop->upd_data;
728 	string = prop_byname(priv, upd->string);
729 
730 	if (string == NULL)
731 		goto out;
732 
733 	(void)sprintf(newval, "%d", atoi(current) +(coef * atoi(string)));
734 
735 	/* Delete existing value, add new one */
736 	prop_delete_byname(priv, ad->prop->upd_name);
737 	_prop_push(ad->prop->upd_name, newval, clear, priv, 0);
738 
739 out:
740 	/* always match */
741 	return 1;
742 }
743 
744 int
prop_eqset_string(ad,stage,ap,priv)745 prop_eqset_string(ad, stage, ap, priv)
746 	acl_data_t *ad;
747 	acl_stage_t stage;
748 	struct acl_param *ap;
749 	struct mlfi_priv *priv;
750 {
751 	return _prop_eqset_string(ad, priv, 0);
752 }
753 
754 int
prop_eqrset_string(ad,stage,ap,priv)755 prop_eqrset_string(ad, stage, ap, priv)
756 	acl_data_t *ad;
757 	acl_stage_t stage;
758 	struct acl_param *ap;
759 	struct mlfi_priv *priv;
760 {
761 	return _prop_eqset_string(ad, priv, UP_CLEARPROP);
762 }
763 
764 int
prop_incset_string(ad,stage,ap,priv)765 prop_incset_string(ad, stage, ap, priv)
766 	acl_data_t *ad;
767 	acl_stage_t stage;
768 	struct acl_param *ap;
769 	struct mlfi_priv *priv;
770 {
771 	return _prop_incset_string(ad, priv, 0, 1);
772 }
773 
774 int
prop_incrset_string(ad,stage,ap,priv)775 prop_incrset_string(ad, stage, ap, priv)
776 	acl_data_t *ad;
777 	acl_stage_t stage;
778 	struct acl_param *ap;
779 	struct mlfi_priv *priv;
780 {
781 	return _prop_incset_string(ad, priv, UP_CLEARPROP, 1);
782 }
783 
784 int
prop_decset_string(ad,stage,ap,priv)785 prop_decset_string(ad, stage, ap, priv)
786 	acl_data_t *ad;
787 	acl_stage_t stage;
788 	struct acl_param *ap;
789 	struct mlfi_priv *priv;
790 {
791 	return _prop_incset_string(ad, priv, 0, -1);
792 }
793 
794 int
prop_decrset_string(ad,stage,ap,priv)795 prop_decrset_string(ad, stage, ap, priv)
796 	acl_data_t *ad;
797 	acl_stage_t stage;
798 	struct acl_param *ap;
799 	struct mlfi_priv *priv;
800 {
801 	return _prop_incset_string(ad, priv, UP_CLEARPROP, -1);
802 }
803 
804 int
prop_eqset_prop(ad,stage,ap,priv)805 prop_eqset_prop(ad, stage, ap, priv)
806 	acl_data_t *ad;
807 	acl_stage_t stage;
808 	struct acl_param *ap;
809 	struct mlfi_priv *priv;
810 {
811 	return _prop_eqset_prop(ad, priv, 0);
812 }
813 
814 int
prop_eqrset_prop(ad,stage,ap,priv)815 prop_eqrset_prop(ad, stage, ap, priv)
816 	acl_data_t *ad;
817 	acl_stage_t stage;
818 	struct acl_param *ap;
819 	struct mlfi_priv *priv;
820 {
821 	return _prop_eqset_prop(ad, priv, UP_CLEARPROP);
822 }
823 
824 int
prop_incset_prop(ad,stage,ap,priv)825 prop_incset_prop(ad, stage, ap, priv)
826 	acl_data_t *ad;
827 	acl_stage_t stage;
828 	struct acl_param *ap;
829 	struct mlfi_priv *priv;
830 {
831 	return _prop_incset_prop(ad, priv, 0, 1);
832 }
833 
834 int
prop_incrset_prop(ad,stage,ap,priv)835 prop_incrset_prop(ad, stage, ap, priv)
836 	acl_data_t *ad;
837 	acl_stage_t stage;
838 	struct acl_param *ap;
839 	struct mlfi_priv *priv;
840 {
841 	return _prop_incset_prop(ad, priv, UP_CLEARPROP, 1);
842 }
843 
844 int
prop_decset_prop(ad,stage,ap,priv)845 prop_decset_prop(ad, stage, ap, priv)
846 	acl_data_t *ad;
847 	acl_stage_t stage;
848 	struct acl_param *ap;
849 	struct mlfi_priv *priv;
850 {
851 	return _prop_incset_prop(ad, priv, 0, -1);
852 }
853 
854 int
prop_decrset_prop(ad,stage,ap,priv)855 prop_decrset_prop(ad, stage, ap, priv)
856 	acl_data_t *ad;
857 	acl_stage_t stage;
858 	struct acl_param *ap;
859 	struct mlfi_priv *priv;
860 {
861 	return _prop_incset_prop(ad, priv, UP_CLEARPROP, -1);
862 }
863