/*
 * policy.h - Header file for policy.c
 * Copyright (c) 2016,2020,2023 Red Hat
 * All Rights Reserved.
 *
 * This software may be freely redistributed and/or modified under the
 * terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING. If not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
 * Boston, MA 02110-1335, USA.
 *
 * Authors:
 *   Steve Grubb <sgrubb@redhat.com>
 */

#ifndef POLICY_HEADER
#define POLICY_HEADER

#include <stdatomic.h>
#include <stdio.h>
#include <time.h>
#include <sys/fanotify.h>
#include "decision-event.h"
#include "event.h"

#ifdef USE_AUDIT
#if HAVE_DECL_FAN_AUDIT
#define AUDIT FAN_AUDIT
#else
#define AUDIT 0x0010
#define FAN_ENABLE_AUDIT 0x00000040
#endif
#else
#define AUDIT 0x0
#endif

#define SYSLOG 0x0020
#define FAN_RESPONSE_MASK (FAN_ALLOW|FAN_DENY|FAN_AUDIT)

typedef enum {
	NO_OPINION = 0,
	ALLOW = FAN_ALLOW,
	DENY = FAN_DENY,
	#ifdef USE_AUDIT
	ALLOW_AUDIT = FAN_ALLOW | AUDIT,
	DENY_AUDIT = FAN_DENY | AUDIT,
	#endif
	ALLOW_SYSLOG = FAN_ALLOW | SYSLOG,
	DENY_SYSLOG = FAN_DENY | SYSLOG,
	ALLOW_LOG = FAN_ALLOW | AUDIT | SYSLOG,
	DENY_LOG = FAN_DENY | AUDIT | SYSLOG
} decision_t;

typedef enum {
	DECISION_SOURCE_RULE,
	DECISION_SOURCE_FALLTHROUGH
} decision_source_t;

struct decision_timing_span;

typedef struct {
	unsigned long allowed_by_rule;
	unsigned long allowed_by_fallthrough;
	unsigned long fallthrough_open;
	unsigned long fallthrough_execute;
	unsigned long fallthrough_trusted;
	unsigned long fallthrough_untrusted;
	unsigned long fallthrough_trust_unknown;
	unsigned long fallthrough_executable;
	unsigned long fallthrough_programmatic;
	unsigned long fallthrough_sharedlib;
	unsigned long fallthrough_unknown_ftype;
	unsigned long fallthrough_other_ftype;
	unsigned int ruleset_generation;
	time_t ruleset_effective_since;
} decision_metrics_t;

int dec_name_to_val(const char *name);
int load_rules(const conf_t *config);
int load_rules_from_stream(const conf_t *config, FILE *f);
int validate_rules_from_stream(FILE *f);
int load_rule_file(void);
int do_reload_rules(const conf_t *config);
void set_reload_rules(void);
decision_t process_event(event_t *e);
decision_t process_event_with_source(event_t *e, decision_source_t *source,
		struct decision_timing_span *response_timing);
int reply_event_init(int fd);
void reply_event_close_group(atomic_int *group_fd);
void reply_event(int fd, const struct fanotify_event_metadata *metadata,
		unsigned reply, event_t *e);
void make_policy_decision(decision_event_t *decision_event, int fd,
		uint64_t mask);
unsigned long getAllowed(void);
unsigned long getDenied(void);
unsigned long getAllowedReset(int reset);
unsigned long getDeniedReset(int reset);
unsigned long getReplyErrors(void);
void getDecisionMetrics(decision_metrics_t *metrics);
void getDecisionMetricsReset(decision_metrics_t *metrics, int reset);
void policy_rule_hits_report(FILE *f);
void policy_rule_hits_report_reset(FILE *f, int reset);
void policy_no_audit(void);
void destroy_rules(void);
unsigned int policy_get_rules_proc_status_mask(void);
unsigned int policy_get_syslog_proc_status_mask(void);
unsigned int policy_get_proc_status_mask(void);

#endif
