Ejemplo n.º 1
0
int audit_rule_syscallbyname(struct audit_rule *rule,
                             const char *scall)
{
	int nr, i;
	int machine;

	if (!strcmp(scall, "all")) {
		for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++) 
			rule->mask[i] = ~0;
		return 0;
	}
	if (!audit_elf)
		machine = audit_detect_machine();
	else
		machine = audit_elf_to_machine(audit_elf);
	if (machine < 0)
		return -2;
	nr = audit_name_to_syscall(scall, machine);
	if (nr < 0) {
		if (isdigit(scall[0]))
			nr = strtol(scall, NULL, 0);
	}
	if (nr >= 0) 
		return audit_rule_syscall(rule, nr);
	return -1;
}
Ejemplo n.º 2
0
const char *aulookup_syscall(llist *l, char *buf, size_t size)
{
	const char *sys;

	if (report_format <= RPT_DEFAULT) {
		snprintf(buf, size, "%d", l->s.syscall);
		return buf;
	}
	machine = audit_elf_to_machine(l->s.arch);
	if (machine < 0)
		return Q;
	sys = audit_syscall_to_name(l->s.syscall, machine);
	if (sys) {
		const char *func = NULL;
		if (strcmp(sys, "socketcall") == 0) {
			if (list_find_item(l, AUDIT_SYSCALL))
				func = aulookup_socketcall((long)l->cur->a0);
		} else if (strcmp(sys, "ipc") == 0) {
			if(list_find_item(l, AUDIT_SYSCALL))
				func = aulookup_ipccall((long)l->cur->a0);
		}
		if (func) {
			snprintf(buf, size, "%s(%s)", sys, func);
			return buf;
		}
		return sys;
	}
	snprintf(buf, size, "%d", l->s.syscall);
	return buf;
}
Ejemplo n.º 3
0
static int print_syscall(const struct audit_rule_data *r, unsigned int *sc)
{
	int count = 0;
	int all = 1;
	unsigned int i;
	int machine = audit_detect_machine();

	/* Rules on the following filters do not take a syscall */
	if (((r->flags & AUDIT_FILTER_MASK) == AUDIT_FILTER_USER) ||
	    ((r->flags & AUDIT_FILTER_MASK) == AUDIT_FILTER_TASK) ||
	    ((r->flags &AUDIT_FILTER_MASK) == AUDIT_FILTER_EXCLUDE))
		return 0;

	/* See if its all or specific syscalls */
	for (i = 0; i < (AUDIT_BITMASK_SIZE-1); i++) {
		if (r->mask[i] != (uint32_t)~0) {
			all = 0;
			break;
		}
	}

	if (all) {
		printf(" -S all");
		count = i;
	} else for (i = 0; i < AUDIT_BITMASK_SIZE * 32; i++) {
		int word = AUDIT_WORD(i);
		int bit  = AUDIT_BIT(i);
		if (r->mask[word] & bit) {
			const char *ptr;
			if (_audit_elf)
				machine = audit_elf_to_machine(_audit_elf);
			if (machine < 0)
				ptr = NULL;
			else
				ptr = audit_syscall_to_name(i, machine);
			if (!count)
				printf(" -S ");
			if (ptr)
				printf("%s%s", !count ? "" : ",", ptr);
			else
				printf("%s%d", !count ? "" : ",", i);
			count++;
			*sc = i;
		}
	}
	return count;
}
Ejemplo n.º 4
0
static void print_arch(const char *val)
{
	unsigned int ival;
	const char *ptr;

	errno = 0;
	ival = strtoul(val, NULL, 16);
	if (errno) {
		printf("conversion error(%s) ", val);
		return;
	}
	machine = audit_elf_to_machine(ival);
	if (machine < 0) {
		printf("unknown elf type(%s) ", val);
		return;
	}
	ptr = audit_machine_to_name(machine);
	printf("%s ", ptr);
}
Ejemplo n.º 5
0
static int print_arch(unsigned int value, int op)
{
	int machine;
	_audit_elf = value;
	machine = audit_elf_to_machine(_audit_elf);
	if (machine < 0)
		printf(" -F arch%s0x%X", audit_operator_to_symbol(op),
				(unsigned)value);
	else {
		if (interpret == 0) {
			if (__AUDIT_ARCH_64BIT & _audit_elf)
				printf(" -F arch%sb64",
						audit_operator_to_symbol(op));
			else
				printf(" -F arch%sb32",
						audit_operator_to_symbol(op));
		} else {	
			const char *ptr = audit_machine_to_name(machine);
			printf(" -F arch%s%s", audit_operator_to_symbol(op),
						ptr);
		}
	}
	return machine;
}
Ejemplo n.º 6
0
static void interpret(char *name, char *val, int comma, int rtype)
{
	int type;
	idata id;

	while (*name == ' '||*name == '(')
		name++;

	if (*name == 'a' && strcmp(name, "acct") == 0) {
		// Remove trailing punctuation
		int len = strlen(val);
		if (val[len-1] == ':')
			val[len-1] = 0;
	}
	type = auparse_interp_adjust_type(rtype, name, val);

	if (rtype == AUDIT_SYSCALL) {
		if (machine == (unsigned long)-1) 
			machine = audit_detect_machine();
		if (*name == 'a' && strcmp(name, "arch") == 0) {
			unsigned long ival;
			errno = 0;
			ival = strtoul(val, NULL, 16);
			if (errno) {
				printf("arch conversion error(%s) ", val);
				return;
			}
			machine = audit_elf_to_machine(ival);
		}
		if (cur_syscall < 0 && *name == 's' &&
				strcmp(name, "syscall") == 0) {
			unsigned long ival;
			errno = 0;
			ival = strtoul(val, NULL, 10);
			if (errno) {
				printf("syscall conversion error(%s) ", val);
				return;
			}
			cur_syscall = ival;
		}
		id.syscall = cur_syscall;
	} else
		id.syscall = 0;
	id.machine = machine;
	id.a0 = a0;
	id.a1 = a1;
	id.name = name;
	id.val = val;

	char *out = auparse_do_interpretation(type, &id);
	if (type == AUPARSE_TYPE_UNCLASSIFIED)
		printf("%s%c", val, comma ? ',' : ' ');
	else if (name[0] == 'k' && strcmp(name, "key") == 0) {
		char *str, *ptr = out;
		int count = 0;
		while ((str = strchr(ptr, AUDIT_KEY_SEPARATOR))) {
			*str = 0;
			if (count == 0) {
				printf("%s", ptr);
				count++;
			} else
				printf(" key=%s", ptr);
			ptr = str+1;
		}
		if (count == 0)
			printf("%s ", out);
		else
			printf(" key=%s ", ptr);
	} else if (type == AUPARSE_TYPE_TTY_DATA)
		printf("%s", out);
	else
		printf("%s ", out);
	free(out);
}
Ejemplo n.º 7
0
/*
 * This function interprets the reply and prints it to stdout. It returns
 * 0 if no more should be read and 1 to indicate that more messages of this
 * type may need to be read. 
 */
static int audit_print_reply(struct audit_reply *rep)
{
	unsigned int i;
	int first;
	int sparse;
	int machine = audit_detect_machine();
	size_t boffset;
	int show_syscall;

	_audit_elf = 0; 
	switch (rep->type) {
		case NLMSG_NOOP:
			return 1;
		case NLMSG_DONE:
			if (printed == 0)
				printf("No rules\n");
			return 0;
		case NLMSG_ERROR: 
		        printf("NLMSG_ERROR %d (%s)\n",
				-rep->error->error, 
				strerror(-rep->error->error));
			printed = 1;
			return 0;
		case AUDIT_GET:
			printf("AUDIT_STATUS: enabled=%d flag=%d pid=%d"
			" rate_limit=%d backlog_limit=%d lost=%d backlog=%u\n",
			rep->status->enabled, rep->status->failure,
			rep->status->pid, rep->status->rate_limit,
			rep->status->backlog_limit, rep->status->lost,
			rep->status->backlog);
			printed = 1;
			return 0;
		case AUDIT_LIST_RULES:
			list_requested = 0;
			boffset = 0;
			show_syscall = 1;
			if (key_match(rep) == 0)
				return 1;
			printed = 1;
			printf("%s: %s,%s", audit_msg_type_to_name(rep->type),
				audit_flag_to_name((int)rep->ruledata->flags),
				audit_action_to_name(rep->ruledata->action));

			for (i = 0; i < rep->ruledata->field_count; i++) {
				const char *name;
				int op = rep->ruledata->fieldflags[i] &
						AUDIT_OPERATORS;
				int field = rep->ruledata->fields[i] &
						~AUDIT_OPERATORS;
                
				name = audit_field_to_name(field);
				if (name) {
					if (strcmp(name, "arch") == 0) { 
						_audit_elf =
						    rep->ruledata->values[i];
						printf(" %s%s%u", name, 
						  audit_operator_to_symbol(op),
					    (unsigned)rep->ruledata->values[i]);
					}
					else if (strcmp(name, "msgtype") == 0) {
						if (!audit_msg_type_to_name(
						      rep->ruledata->values[i]))
							printf(" %s%s%d", name,
								audit_operator_to_symbol(op),
								rep->ruledata->values[i]);
						else {
							printf(" %s%s%s", name,
								audit_operator_to_symbol(op),
								audit_msg_type_to_name(rep->ruledata->values[i]));
						}
					} else if ((field >= AUDIT_SUBJ_USER &&
						  field <= AUDIT_OBJ_LEV_HIGH)
						&& field != AUDIT_PPID &&
					       rep->type == AUDIT_LIST_RULES) {
						printf(" %s%s%.*s", name,
						  audit_operator_to_symbol(op),
						  rep->ruledata->values[i],
						  &rep->ruledata->buf[boffset]);
						boffset +=
						    rep->ruledata->values[i];
					} else if (field == AUDIT_WATCH) {
						printf(" watch=%.*s", 
						  rep->ruledata->values[i],
						  &rep->ruledata->buf[boffset]);
						boffset +=
						    rep->ruledata->values[i];
					} else if (field == AUDIT_DIR) {
						printf(" dir=%.*s", 
						  rep->ruledata->values[i],
						  &rep->ruledata->buf[boffset]);
						boffset +=
						    rep->ruledata->values[i];
					} else if (field == AUDIT_FILTERKEY) {
						char *rkey, *ptr;
						asprintf(&rkey, "%.*s",
						rep->ruledata->values[i],
						&rep->ruledata->buf[boffset]);
						boffset +=
						    rep->ruledata->values[i];
						ptr = strtok(rkey, key_sep);
						while (ptr) {
							printf(" key=%s", ptr);
							ptr = strtok(NULL,
								key_sep);
						}
						free(rkey);
					} else if (field == AUDIT_PERM) {
						char perms[5];
						int val=rep->ruledata->values[i];
						perms[0] = 0;
						if (val & AUDIT_PERM_READ)
							strcat(perms, "r");
						if (val & AUDIT_PERM_WRITE)
							strcat(perms, "w");
						if (val & AUDIT_PERM_EXEC)
							strcat(perms, "x");
						if (val & AUDIT_PERM_ATTR)
							strcat(perms, "a");
						printf(" perm=%s", perms);
						show_syscall = 0;
					} else if (field == AUDIT_INODE) {
						// Unsigned items
						printf(" %s%s%u", name, 
							audit_operator_to_symbol(op),
							rep->ruledata->values[i]);
					} else if (field == AUDIT_FIELD_COMPARE) {
						switch (rep->ruledata->values[i])
						{
						case AUDIT_COMPARE_UID_TO_OBJ_UID:
							printf(" uid%sobj_uid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_GID_TO_OBJ_GID:
							printf(" gid%sobj_gid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_EUID_TO_OBJ_UID:
							printf(" euid%sobj_uid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_EGID_TO_OBJ_GID:
							printf(" egid%sobj_gid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_AUID_TO_OBJ_UID:
							printf(" auid%sobj_uid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_SUID_TO_OBJ_UID:
							printf(" suid%sobj_uid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_SGID_TO_OBJ_GID:
							printf(" sgid%sobj_gid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
							printf(" fsuid%sobj_uid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
							printf(" fsgid%sobj_gid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_UID_TO_AUID:
							printf(" uid%sauid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_UID_TO_EUID:
							printf(" uid%seuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_UID_TO_FSUID:
							printf(" uid%sfsuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_UID_TO_SUID:
							printf(" uid%ssuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_AUID_TO_FSUID:
							printf(" auid%sfsuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_AUID_TO_SUID:
							printf(" auid%ssuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_AUID_TO_EUID:
							printf(" auid%seuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_EUID_TO_SUID:
							printf(" euid%ssuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_EUID_TO_FSUID:
							printf(" euid%sfsuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_SUID_TO_FSUID:
							printf(" suid%sfsuid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_GID_TO_EGID:
							printf(" gid%segid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_GID_TO_FSGID:
							printf(" gid%sfsgid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_GID_TO_SGID:
							printf(" gid%ssgid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_EGID_TO_FSGID:
							printf(" egid%sfsgid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_EGID_TO_SGID:
							printf(" egid%ssgid",audit_operator_to_symbol(op));
							break;
						case AUDIT_COMPARE_SGID_TO_FSGID:
							printf(" sgid%sfsgid",audit_operator_to_symbol(op));
							break;
						}
					} else {
						// Signed items
						printf(" %s%s%d", name, 
							audit_operator_to_symbol(op),
							rep->ruledata->values[i]);
					}
				} else { 
					printf(" f%d%s%d", rep->ruledata->fields[i],
						audit_operator_to_symbol(op),
						rep->ruledata->values[i]);
				}
				/* Avoid printing value if the field type is 
				 * known to return a string. */
				if (rep->ruledata->values[i] && 
						(field < AUDIT_SUBJ_USER ||
						 field > AUDIT_SUBJ_CLR) &&
						field != AUDIT_WATCH &&
						field != AUDIT_FILTERKEY &&
						field != AUDIT_PERM &&
						field != AUDIT_FIELD_COMPARE)
					printf(" (0x%x)", rep->ruledata->values[i]);
			}
			if (show_syscall &&
				((rep->ruledata->flags & AUDIT_FILTER_MASK) != 
						AUDIT_FILTER_USER) &&
				((rep->ruledata->flags & AUDIT_FILTER_MASK) !=
						AUDIT_FILTER_TASK) &&
				((rep->ruledata->flags & AUDIT_FILTER_MASK) !=
						AUDIT_FILTER_EXCLUDE)) {
				printf(" syscall=");
				for (sparse = 0, i = 0; 
					i < (AUDIT_BITMASK_SIZE-1); i++) {
					if (rep->ruledata->mask[i] != (uint32_t)~0)
						sparse = 1;
				}
				if (!sparse) {
					printf("all");
				} else for (first = 1, i = 0;
					i < AUDIT_BITMASK_SIZE * 32; i++) {
					int word = AUDIT_WORD(i);
					int bit  = AUDIT_BIT(i);
					if (rep->ruledata->mask[word] & bit) {
						const char *ptr;
						if (_audit_elf)
							machine = 
							audit_elf_to_machine(
								_audit_elf);
						if (machine < 0)
							ptr = NULL;
						else
							ptr = 
							audit_syscall_to_name(i, 
							machine);
						if (ptr)
							printf("%s%s", 
							first ? "" : ",", ptr);
						else
							printf("%s%d", 
							first ? "" : ",", i);
						first = 0;
					}
				}
			}
			printf("\n");
			return 1; /* get more messages until NLMSG_DONE */
		default:
			printf("Unknown: type=%d, len=%d\n", rep->type, 
				rep->nlh->nlmsg_len);
			printed = 1;
			return 0;
	}
}
Ejemplo n.º 8
0
int audit_rule_fieldpair(struct audit_rule *rule, const char *pair, int flags)
{
	const char *f = pair;
	char       *v;
	int        op;
	int        field;
	int        vlen;
    
	if (f == NULL)
		return -1;

	/* look for 2-char operators first
	   then look for 1-char operators afterwards
	   when found, null out the bytes under the operators to split
	   and set value pointer just past operator bytes
	*/
	if ( (v = strstr(pair, "!=")) ) {
		*v++ = '\0';
		*v++ = '\0';
		op = AUDIT_NEGATE; // legacy
		// op = AUDIT_NOT_EQUAL;
	} else if ( (v = strstr(pair, ">")) ) {
		return -10;
	} else if ( (v = strstr(pair, "<")) ) {
		return -10;
	} else if ( (v = strstr(pair, "&")) ) {
		return -10;
	} else if ( (v = strstr(pair, "=")) ) {
		*v++ = '\0';
		op = 0; // legacy 
		// op = AUDIT_EQUAL;
	}

	if (v == NULL)
		return -1;
	
	if (*f == 0)
		return -22;

	if (*v == 0)
		return -20;

	audit_msg(LOG_DEBUG,"pair=%s\n", f);
	if ((field = audit_name_to_field(f)) < 0) 
		return -2;

	/* Exclude filter can be used only with MSGTYPE field */
	if (flags == AUDIT_FILTER_EXCLUDE && field != AUDIT_MSGTYPE)
		return -12; 

	audit_msg(LOG_DEBUG,"f%d%s%s\n", field, audit_operator_to_symbol(op),v);
	rule->fields[rule->field_count] = field | op;
	switch (field)
	{
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
		case AUDIT_LOGINUID:
			// Do positive & negative separate for 32 bit systems
			vlen = strlen(v);
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtoul(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
						(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else {
				if (name_to_uid(v, 
					&rule->values[rule->field_count])) {
					audit_msg(LOG_ERR, "Unknown user: %s",
						v);
					return -2;
				}
			}
			break;
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtol(v, NULL, 0);
			else {
				if (name_to_gid(v, 
					&rule->values[rule->field_count])) {
					audit_msg(LOG_ERR, "Unknown group: %s",
						v);
					return -2;
				}
			}
			break;
		case AUDIT_EXIT:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			vlen = strlen(v);
			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
					(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else {
				rule->values[rule->field_count] =
						audit_name_to_errno(v);
				if (rule->values[rule->field_count] == 0) 
					return -15;
			}
			break;
		case AUDIT_MSGTYPE:
			if (flags != AUDIT_FILTER_EXCLUDE)
				return -9;

			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else
				if (audit_name_to_msg_type(v) > 0)
					rule->values[rule->field_count] =
						audit_name_to_msg_type(v);
				else
					return -8;
			break;
		case AUDIT_ARCH:
			if (audit_syscalladded) 
				return -3;
			if (!(op == AUDIT_NEGATE || op == 0))
				return -13;
			if (isdigit((char)*(v))) {
				int machine;

				errno = 0;
				audit_elf = strtoul(v, NULL, 0);
				if (errno) 
					return -5;

				// Make sure we have a valid mapping
				machine = audit_elf_to_machine(audit_elf);
				if (machine < 0)
					return -5;
			}
			else {
				// what do we want? i686, x86_64, ia64
				// or b64, b32
				int machine;
				unsigned int bits=0, elf;
				const char *arch=v;
				if (strcasecmp("b64", arch) == 0) {
					bits = __AUDIT_ARCH_64BIT;
					machine = audit_detect_machine();
				} else if (strcasecmp("b32", arch) == 0) {
					bits = ~__AUDIT_ARCH_64BIT;
					machine = audit_detect_machine();
				} 
				else 
					machine = audit_name_to_machine(arch);

				if (machine < 0) 
					return -4;

				/* Here's where we fixup the machine.
				 * for example, they give x86_64 & want 32 bits.
				 * we translate that to i686. */
				if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_86_64)
						machine = MACH_X86;
				else if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_PPC64)
						machine = MACH_PPC;
				else if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_S390X)
						machine = MACH_S390;

				/* Check for errors - return -6 
				 * We don't allow 32 bit machines to specify 
				 * 64 bit. */
				switch (machine)
				{
					case MACH_X86:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_IA64:
						if (bits == ~__AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_PPC:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_S390:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_86_64: /* fallthrough */
					case MACH_PPC64: /* fallthrough */
					case MACH_S390X: /* fallthrough */
						break;
					default:
						return -6;
				}

				/* OK, we have the machine type, now convert
				   to elf. */
				elf = audit_machine_to_elf(machine);
				if (elf == 0)
					return -5;

				audit_elf = elf;
			}
			rule->values[rule->field_count] = audit_elf;
			audit_archadded = 1;
			break;
		case AUDIT_FILETYPE:
			if (flags != AUDIT_FILTER_EXIT && flags != AUDIT_FILTER_ENTRY)
				return -17;
			rule->values[rule->field_count] =
				audit_name_to_ftype(v);
			if (rule->values[rule->field_count] < 0) {
				return -16;
			}
			break;
		/* These are strings */
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
		case AUDIT_WATCH:
		case AUDIT_PERM:
		case AUDIT_DIR:
		case AUDIT_FILTERKEY:
			return -10;
                case AUDIT_ARG0...AUDIT_ARG3:
			vlen = strlen(v);
			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtoul(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
						(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else
				return -21;
			break;
                case AUDIT_DEVMAJOR...AUDIT_INODE:
                case AUDIT_SUCCESS:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			/* fallthrough */
		default:
			if (field == AUDIT_INODE) {
				if (!(op == AUDIT_NEGATE || op == 0))
					return -13;
			}
			if (field == AUDIT_PPID && (flags != AUDIT_FILTER_EXIT
				&& flags != AUDIT_FILTER_ENTRY))
				return -17;
			
			if (flags == AUDIT_FILTER_EXCLUDE)
				return -18;
			
			if (!isdigit((char)*(v)))
				return -21;

			if (field == AUDIT_INODE) 
				rule->values[rule->field_count] =
						strtoul(v, NULL, 0);
			else
				rule->values[rule->field_count] =
						strtol(v, NULL, 0);
			break;
	}
	++rule->field_count;
	return 0;
}
Ejemplo n.º 9
0
int match(llist *l)
{
	// Are we within time range?
	if (start_time == 0 || l->e.sec >= start_time) {
		if (end_time == 0 || l->e.sec <= end_time) {
			if (event_id == -1 || event_id == l->e.serial) {
				// OK - do the heavier checking
				if (extract_search_items(l)) {
					return 0;
				}

				// perform additional tests for the field
				if (event_node_list) {
					const snode *sn;
					int found=0;
					slist *sptr = event_node_list;

					if (l->e.node == NULL)
				  		return 0;

					slist_first(sptr);
					sn=slist_get_cur(sptr);
					while (sn && !found) {
						if (sn->str &&  (!strcmp(sn->str, l->e.node)))
							found++;
						else
							sn=slist_next(sptr);
					}
					if (!found)
						return 0;
				}
				if (user_match(l) == 0)
					return 0;
				if (group_match(l) == 0)
					return 0;
				if ((event_ppid != -1) && 
						(event_ppid != l->s.ppid))
					return 0;
				if ((event_pid != -1) && 
						(event_pid != l->s.pid))
					return 0;
				if (event_machine != -1 && 
						(event_machine !=
					audit_elf_to_machine(l->s.arch)))
					return 0;
				if ((event_syscall != -1) && 
					(event_syscall != l->s.syscall))
						return 0;
				if ((event_session_id != -2) &&
					(event_session_id != l->s.session_id))
					return 0;
				if (event_exit_is_set) {
					if (l->s.exit_is_set == 0)
						return 0;
					if (event_exit != l->s.exit)
						return 0;
				}

				if ((event_success != S_UNSET) &&
						(event_success != l->s.success))
					return 0;
				// event_type requires looking at each item
				if (event_type != NULL) {
					int found = 0;
					const lnode *n;

					list_first(l);
					n = list_get_cur(l);
					do {
						int_node *in;
						ilist_first(event_type);
						in = ilist_get_cur(event_type);
						do {
							if (in->num == n->type){
								found = 1;
								break;
							}
						} while((in = 
						    ilist_next(event_type)));
						if (found)
							break;
					} while ((n = list_next(l)));
					if (!found)
						return 0;
				}

				// Done all the easy compares, now do the 
				// string searches.
				if (event_filename) {
					int found = 0;
					if (l->s.filename == NULL && l->s.cwd == NULL)
						return 0;
					if (l->s.filename) {
						const snode *sn;
						slist *sptr = l->s.filename;

						slist_first(sptr);
						sn=slist_get_cur(sptr);
						do {
							if (sn->str == NULL)
								return 0;
							if (strmatch(
								event_filename,
								sn->str)) {
								found = 1;
								break;
							}
						} while ((sn=slist_next(sptr)));

						if (!found && l->s.cwd == NULL)
							return 0;
					}
					if (l->s.cwd && !found) {
						/* Check cwd, too */
						if (strmatch(event_filename,
								l->s.cwd) == 0)
							return 0;
					}
				}
				if (event_hostname) {
					if (l->s.hostname == NULL)
						return 0;
					if (strmatch(event_hostname, 
						l->s.hostname) == 0)
						return 0; 
				}
				if (event_terminal) {
					if (l->s.terminal == NULL)
						return 0;
					if (strmatch(event_terminal, 
						l->s.terminal) == 0)
						return 0; 
				}
				if (event_exe) {
					if (l->s.exe == NULL)
						return 0;
					if (strmatch(event_exe, 
						l->s.exe) == 0)
						return 0; 
				}				
				if (event_comm) {
					if (l->s.comm == NULL)
						return 0;
					if (strmatch(event_comm, 
						l->s.comm) == 0)
						return 0; 
				}				
				if (event_key) {
					if (l->s.key == NULL)
						return 0;
					else {
						int found = 0;
						const snode *sn;
						slist *sptr = l->s.key;

						slist_first(sptr);
						sn=slist_get_cur(sptr);
						do {
							if (sn->str == NULL)
								return 0;
							if (strmatch(
								event_key,
								sn->str)) {
								found = 1;
								break;
							}
						} while ((sn=slist_next(sptr)));
						if (!found)
							return 0;
					}
				}				
				if (event_vmname) {
					if (l->s.vmname == NULL)
						return 0;
					if (strmatch(event_vmname,
							l->s.vmname) == 0)
						return 0;
				}
				if (event_uuid) {
					if (l->s.uuid == NULL)
						return 0;
					if (strmatch(event_uuid,
							l->s.uuid) == 0)
						return 0;
				}
				if (context_match(l) == 0)
					return 0;
				return 1;
			}
		}
	}
	return 0;
}
Ejemplo n.º 10
0
int audit_rule_fieldpair_data(struct audit_rule_data **rulep, const char *pair,
                              int flags)
{
	const char *f = pair;
	char       *v;
	int        op;
	int        field;
	int        vlen;
	int        offset;
	struct audit_rule_data *rule = *rulep;

	if (f == NULL)
		return -1;

	/* look for 2-char operators first
	   then look for 1-char operators afterwards
	   when found, null out the bytes under the operators to split
	   and set value pointer just past operator bytes
	*/
	if ( (v = strstr(pair, "!=")) ) {
		*v++ = '\0';
		*v++ = '\0';
		op = AUDIT_NOT_EQUAL;
	} else if ( (v = strstr(pair, ">=")) ) {
		*v++ = '\0';
		*v++ = '\0';
		op = AUDIT_GREATER_THAN_OR_EQUAL;
	} else if ( (v = strstr(pair, "<=")) ) {
		*v++ = '\0';
		*v++ = '\0';
		op = AUDIT_LESS_THAN_OR_EQUAL;
	} else if ( (v = strstr(pair, "&=")) ) {
		*v++ = '\0';
		*v++ = '\0';
		op = AUDIT_BIT_TEST;
	} else if ( (v = strstr(pair, "=")) ) {
		*v++ = '\0';
		op = AUDIT_EQUAL;
	} else if ( (v = strstr(pair, ">")) ) {
		*v++ = '\0';
		op = AUDIT_GREATER_THAN;
	} else if ( (v = strstr(pair, "<")) ) {
		*v++ = '\0';
		op = AUDIT_LESS_THAN;
	} else if ( (v = strstr(pair, "&")) ) {
		*v++ = '\0';
		op = AUDIT_BIT_MASK;
	}

	if (v == NULL)
		return -1;
	
	if (*f == 0)
		return -22;

	if (*v == 0)
		return -20;

	if ((field = audit_name_to_field(f)) < 0) 
		return -2;

	/* Exclude filter can be used only with MSGTYPE field */
	if (flags == AUDIT_FILTER_EXCLUDE && field != AUDIT_MSGTYPE)
		return -12; 

	rule->fields[rule->field_count] = field;
	rule->fieldflags[rule->field_count] = op;
	switch (field)
	{
		case AUDIT_UID:
		case AUDIT_EUID:
		case AUDIT_SUID:
		case AUDIT_FSUID:
		case AUDIT_LOGINUID:
		case AUDIT_OBJ_UID:
		case AUDIT_OBJ_GID:
			// Do positive & negative separate for 32 bit systems
			vlen = strlen(v);
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtoul(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
						(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else {
				if (strcmp(v, "unset") == 0)
					rule->values[rule->field_count] =
								4294967295;
				else if (audit_name_to_uid(v, 
					&rule->values[rule->field_count])) {
					audit_msg(LOG_ERR, "Unknown user: %s",
						v);
					return -2;
				}
			}
			break;
		case AUDIT_GID:
		case AUDIT_EGID:
		case AUDIT_SGID:
		case AUDIT_FSGID:
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtol(v, NULL, 0);
			else {
				if (audit_name_to_gid(v, 
					&rule->values[rule->field_count])) {
					audit_msg(LOG_ERR, "Unknown group: %s",
						v);
					return -2;
				}
			}
			break;
		case AUDIT_EXIT:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			vlen = strlen(v);
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtol(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' && 
						(isdigit((char)*(v+1)))) 
				rule->values[rule->field_count] = 
					strtol(v, NULL, 0);
			else {
				rule->values[rule->field_count] = 
						audit_name_to_errno(v);
				if (rule->values[rule->field_count] == 0) 
					return -15;
			}
			break;
		case AUDIT_MSGTYPE:
			if (flags != AUDIT_FILTER_EXCLUDE &&
					flags != AUDIT_FILTER_USER)
				return -9;

			if (isdigit((char)*(v)))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else
				if (audit_name_to_msg_type(v) > 0)
					rule->values[rule->field_count] =
						audit_name_to_msg_type(v);
				else
					return -8;
			break;
		/* These next few are strings */
		case AUDIT_OBJ_USER:
		case AUDIT_OBJ_ROLE:
		case AUDIT_OBJ_TYPE:
		case AUDIT_OBJ_LEV_LOW:
		case AUDIT_OBJ_LEV_HIGH:
		case AUDIT_WATCH:
		case AUDIT_DIR:
			/* Watch & object filtering is invalid on anything
			 * but exit */
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			if (field == AUDIT_WATCH || field == AUDIT_DIR)
				_audit_permadded = 1;

			/* fallthrough */
		case AUDIT_SUBJ_USER:
		case AUDIT_SUBJ_ROLE:
		case AUDIT_SUBJ_TYPE:
		case AUDIT_SUBJ_SEN:
		case AUDIT_SUBJ_CLR:
		case AUDIT_FILTERKEY:
			if (field == AUDIT_FILTERKEY && !(_audit_syscalladded || _audit_permadded))
                                return -19;
			vlen = strlen(v);
			if (field == AUDIT_FILTERKEY &&
					vlen > AUDIT_MAX_KEY_LEN)
				return -11;
			else if (vlen > PATH_MAX)
				return -11;
			rule->values[rule->field_count] = vlen;
			offset = rule->buflen;
			rule->buflen += vlen;
			*rulep = realloc(rule, sizeof(*rule) + rule->buflen);
			if (*rulep == NULL) {
				free(rule);
				audit_msg(LOG_ERR, "Cannot realloc memory!\n");
				return -3;
			} else {
				rule = *rulep;
			}
			strncpy(&rule->buf[offset], v, vlen);

			break;
		case AUDIT_ARCH:
			if (_audit_syscalladded) 
				return -3;
			if (!(op == AUDIT_NOT_EQUAL || op == AUDIT_EQUAL))
				return -13;
			if (isdigit((char)*(v))) {
				int machine;

				errno = 0;
				_audit_elf = strtoul(v, NULL, 0);
				if (errno) 
					return -5;

				// Make sure we have a valid mapping
				machine = audit_elf_to_machine(_audit_elf);
				if (machine < 0)
					return -5;
			}
			else {
				// what do we want? i686, x86_64, ia64
				// or b64, b32
				int machine;
				unsigned int bits=0, elf;
				const char *arch=v;
				if (strcasecmp("b64", arch) == 0) {
					bits = __AUDIT_ARCH_64BIT;
					machine = audit_detect_machine();
				} else if (strcasecmp("b32", arch) == 0) {
					bits = ~__AUDIT_ARCH_64BIT;
					machine = audit_detect_machine();
				} 
				else 
					machine = audit_name_to_machine(arch);

				if (machine < 0) 
					return -4;

				/* Here's where we fixup the machine.
				 * for example, they give x86_64 & want 32 bits.
				 * we translate that to i686. */
				if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_86_64)
						machine = MACH_X86;
				else if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_PPC64)
						machine = MACH_PPC;
				else if (bits == ~__AUDIT_ARCH_64BIT &&
					machine == MACH_S390X)
						machine = MACH_S390;

				/* Check for errors - return -6 
				 * We don't allow 32 bit machines to specify 
				 * 64 bit. */
				switch (machine)
				{
					case MACH_X86:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_IA64:
						if (bits == ~__AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_PPC:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
					case MACH_S390:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
#ifdef WITH_ARMEB
					case MACH_ARMEB:
						if (bits == __AUDIT_ARCH_64BIT)
							return -6;
						break;
#endif
#ifdef WITH_AARCH64
					case MACH_AARCH64:
						if (bits != __AUDIT_ARCH_64BIT)
							return -6;
						break;
#endif
					case MACH_86_64: /* fallthrough */
					case MACH_PPC64: /* fallthrough */
					case MACH_S390X: /* fallthrough */
						break;
					default:
						return -6;
				}

				/* OK, we have the machine type, now convert
				   to elf. */
				elf = audit_machine_to_elf(machine);
				if (elf == 0)
					return -5;

				_audit_elf = elf;
			}
			rule->values[rule->field_count] = _audit_elf; 
			_audit_archadded = 1;
			break;
		case AUDIT_PERM:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			else if (op != AUDIT_EQUAL)
				return -13;
			else {
				unsigned int i, len, val = 0;

				len = strlen(v);
				if (len > 4)
					return -11;

				for (i = 0; i < len; i++) {
					switch (tolower(v[i])) {
						case 'r':
							val |= AUDIT_PERM_READ;
							break;
						case 'w':
							val |= AUDIT_PERM_WRITE;
							break;
						case 'x':
							val |= AUDIT_PERM_EXEC;
							break;
						case 'a':
							val |= AUDIT_PERM_ATTR;
							break;
						default:
							return -14;
					}
				}
				rule->values[rule->field_count] = val;
			}
			break;
		case AUDIT_FILETYPE:
			if (!(flags == AUDIT_FILTER_EXIT || flags == AUDIT_FILTER_ENTRY))
				return -17;
			rule->values[rule->field_count] = 
				audit_name_to_ftype(v);
			if ((int)rule->values[rule->field_count] < 0) {
				return -16;
			}
			break;
		case AUDIT_ARG0...AUDIT_ARG3:
			vlen = strlen(v);
			if (isdigit((char)*(v))) 
				rule->values[rule->field_count] = 
					strtoul(v, NULL, 0);
			else if (vlen >= 2 && *(v)=='-' &&
						(isdigit((char)*(v+1))))
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			else 
				return -21;
			break;
		case AUDIT_DEVMAJOR...AUDIT_INODE:
		case AUDIT_SUCCESS:
			if (flags != AUDIT_FILTER_EXIT)
				return -7;
			/* fallthrough */
		default:
			if (field == AUDIT_INODE) {
				if (!(op == AUDIT_NOT_EQUAL ||
							op == AUDIT_EQUAL))
					return -13;
			}

			if (field == AUDIT_PPID && !(flags == AUDIT_FILTER_EXIT
				|| flags == AUDIT_FILTER_ENTRY))
				return -17;
			
			if (!isdigit((char)*(v)))
				return -21;

			if (field == AUDIT_INODE)
				rule->values[rule->field_count] =
					strtoul(v, NULL, 0);
			else
				rule->values[rule->field_count] =
					strtol(v, NULL, 0);
			break;
	}
	rule->field_count++;
	return 0;
}