Esempio n. 1
0
/*
 *  This function prints 1 rule from the kernel reply
 */
static void print_rule(const struct audit_rule_data *r)
{
	unsigned int i, count = 0, sc = 0;
	size_t boffset = 0;
	int mach = -1, watch = is_watch(r);
	unsigned long long a0 = 0, a1 = 0;

	if (!watch) { /* This is syscall auditing */
		printf("-a %s,%s",
			audit_action_to_name((int)r->action),
				audit_flag_to_name(r->flags));

		// Now find the arch and print it
		for (i = 0; i < r->field_count; i++) {
			int field = r->fields[i] & ~AUDIT_OPERATORS;
			if (field == AUDIT_ARCH) {
				int op = r->fieldflags[i] & AUDIT_OPERATORS;
				mach = print_arch(r->values[i], op);
			}
		}
		// And last do the syscalls
		count = print_syscall(r, &sc);
	}

	// Now iterate over the fields
	for (i = 0; i < r->field_count; i++) {
		const char *name;
		int op = r->fieldflags[i] & AUDIT_OPERATORS;
		int field = r->fields[i] & ~AUDIT_OPERATORS;

		if (field == AUDIT_ARCH)
			continue;	// already printed

		name = audit_field_to_name(field);
		if (name) {
			// Special cases to print the different field types
			// in a meaningful way.
			if (field == AUDIT_MSGTYPE) {
				if (!audit_msg_type_to_name(r->values[i]))
					printf(" -F %s%s%d", name,
						audit_operator_to_symbol(op),
						r->values[i]);
				else
					printf(" -F %s%s%s", name,
						audit_operator_to_symbol(op),
						audit_msg_type_to_name(
						r->values[i]));
			} else if ((field >= AUDIT_SUBJ_USER &&
						field <= AUDIT_OBJ_LEV_HIGH)
						&& field != AUDIT_PPID) {
				printf(" -F %s%s%.*s", name,
						audit_operator_to_symbol(op),
						r->values[i], &r->buf[boffset]);
				boffset += r->values[i];
			} else if (field == AUDIT_WATCH) {
				if (watch)
					printf("-w %.*s", r->values[i],
						&r->buf[boffset]);
				else
					printf(" -F path=%.*s",	r->values[i],
						&r->buf[boffset]);
				boffset += r->values[i];
			} else if (field == AUDIT_DIR) {
				if (watch)
					printf("-w %.*s/", r->values[i],
						&r->buf[boffset]);
				else
					printf(" -F dir=%.*s", r->values[i],
						&r->buf[boffset]);

				boffset += r->values[i];
			} else if (field == AUDIT_FILTERKEY) {
				char *rkey, *ptr, *saved;
				if (asprintf(&rkey, "%.*s", r->values[i],
					      &r->buf[boffset]) < 0)
					rkey = NULL;
				boffset += r->values[i];
				ptr = strtok_r(rkey, key_sep, &saved);
				while (ptr) {
					if (watch)
						printf(" -k %s", ptr);
					else
						printf(" -F key=%s", ptr);
					ptr = strtok_r(NULL, key_sep, &saved);
				}
				free(rkey);
			} else if (field == AUDIT_PERM) {
				char perms[5];
				int val=r->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");
				if (watch)
					printf(" -p %s", perms);
				else
					printf(" -F perm=%s", perms);
			} else if (field == AUDIT_INODE) {
				// This is unsigned
				printf(" -F %s%s%u", name, 
						audit_operator_to_symbol(op),
						r->values[i]);
			} else if (field == AUDIT_FIELD_COMPARE) {
				print_field_cmp(r->values[i], op);
			} else if (field >= AUDIT_ARG0 && field <= AUDIT_ARG3){
				if (field == AUDIT_ARG0)
					a0 = r->values[i];
				else if (field == AUDIT_ARG1)
					a1 = r->values[i];

				// Show these as hex
				if (count > 1 || interpret == 0)
					printf(" -F %s%s0x%X", name, 
						audit_operator_to_symbol(op),
						r->values[i]);
				else {	// Use ignore to mean interpret
					const char *out;
					idata id;
					char val[32];
					int type;

					id.syscall = sc;
					id.machine = mach;
					id.a0 = a0;
					id.a1 = a1;
					id.name = name;
					snprintf(val, 32, "%x", r->values[i]);
					id.val = val;
					type = auparse_interp_adjust_type(
						AUDIT_SYSCALL, name, val);
					out = auparse_do_interpretation(type,
								 &id);
					printf(" -F %s%s%s", name,
						audit_operator_to_symbol(op),
								out);
					free((void *)out);
				}
			} else if (field == AUDIT_EXIT) {
				int e = abs((int)r->values[i]);
				const char *err = audit_errno_to_name(e);

				if (((int)r->values[i] < 0) && err)
					printf(" -F %s%s-%s", name,
						audit_operator_to_symbol(op),
						err);
				else
					printf(" -F %s%s%d", name,
						audit_operator_to_symbol(op),
						(int)r->values[i]);
			} else {
				// The default is signed decimal
				printf(" -F %s%s%d", name, 
						audit_operator_to_symbol(op),
						r->values[i]);
			}
		} else {
			 // The field name is unknown 
			printf(" f%d%s%d", r->fields[i],
						audit_operator_to_symbol(op),
						r->values[i]);
		}
	}
	printf("\n");
}
Esempio n. 2
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;
	}
}