1/*
2 * User-supplied callbacks and default implementations.
3 * Class and permission mappings.
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdarg.h>
9#include <errno.h>
10#include <selinux/selinux.h>
11#include "callbacks.h"
12
13pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
14
15/* default implementations */
16static int __attribute__ ((format(printf, 2, 3)))
17default_selinux_log(int type __attribute__((unused)), const char *fmt, ...)
18{
19	int rc;
20	va_list ap;
21	va_start(ap, fmt);
22	rc = vfprintf(stderr, fmt, ap);
23	va_end(ap);
24	return rc;
25}
26
27static int
28default_selinux_audit(void *ptr __attribute__((unused)),
29		      security_class_t cls __attribute__((unused)),
30		      char *buf __attribute__((unused)),
31		      size_t len __attribute__((unused)))
32{
33	return 0;
34}
35
36static int
37default_selinux_validate(char **ctx)
38{
39#ifndef BUILD_HOST
40	return security_check_context(*ctx);
41#else
42	(void) ctx;
43	return 0;
44#endif
45}
46
47static int
48default_selinux_setenforce(int enforcing __attribute__((unused)))
49{
50	return 0;
51}
52
53static int
54default_selinux_policyload(int seqno __attribute__((unused)))
55{
56	return 0;
57}
58
59/* callback pointers */
60int __attribute__ ((format(printf, 2, 3)))
61(*selinux_log_direct)(int, const char *, ...) =
62	default_selinux_log;
63
64int
65(*selinux_audit) (void *, security_class_t, char *, size_t) =
66	default_selinux_audit;
67
68int
69(*selinux_validate)(char **ctx) =
70	default_selinux_validate;
71
72int
73(*selinux_netlink_setenforce) (int enforcing) =
74	default_selinux_setenforce;
75
76int
77(*selinux_netlink_policyload) (int seqno) =
78	default_selinux_policyload;
79
80/* callback setting function */
81void
82selinux_set_callback(int type, union selinux_callback cb)
83{
84	switch (type) {
85	case SELINUX_CB_LOG:
86		selinux_log_direct = cb.func_log;
87		break;
88	case SELINUX_CB_AUDIT:
89		selinux_audit = cb.func_audit;
90		break;
91	case SELINUX_CB_VALIDATE:
92		selinux_validate = cb.func_validate;
93		break;
94	case SELINUX_CB_SETENFORCE:
95		selinux_netlink_setenforce = cb.func_setenforce;
96		break;
97	case SELINUX_CB_POLICYLOAD:
98		selinux_netlink_policyload = cb.func_policyload;
99		break;
100	}
101}
102
103/* callback getting function */
104union selinux_callback
105selinux_get_callback(int type)
106{
107	union selinux_callback cb;
108
109	switch (type) {
110	case SELINUX_CB_LOG:
111		cb.func_log = selinux_log_direct;
112		break;
113	case SELINUX_CB_AUDIT:
114		cb.func_audit = selinux_audit;
115		break;
116	case SELINUX_CB_VALIDATE:
117		cb.func_validate = selinux_validate;
118		break;
119	case SELINUX_CB_SETENFORCE:
120		cb.func_setenforce = selinux_netlink_setenforce;
121		break;
122	case SELINUX_CB_POLICYLOAD:
123		cb.func_policyload = selinux_netlink_policyload;
124		break;
125	default:
126		memset(&cb, 0, sizeof(cb));
127		errno = EINVAL;
128		break;
129	}
130	return cb;
131}
132