1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* plugins/audit/au_simple_main.c - Sample Audit plugin implementation */
3 /*
4 * Copyright (C) 2013 by the Massachusetts Institute of Technology.
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 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * This is a demo implementation of Audit JSON-based module.
35 * It utilizes MIT Kerberos <kdc_j_encode.h> routines for JSON processing and
36 * the Fedora/Debian libaudit library for audit logs.
37 */
38
39 #include <k5-int.h>
40 #include <krb5/audit_plugin.h>
41 #include <libaudit.h>
42 #include <kdc_j_encode.h>
43
44 krb5_error_code
45 audit_simple_initvt(krb5_context context, int maj_ver, int min_ver,
46 krb5_plugin_vtable vtable);
47
48 struct krb5_audit_moddata_st {
49 int fd;
50 };
51
52 /* Open connection to the audit system. Returns 0 on success. */
53 static krb5_error_code
open_au(krb5_audit_moddata * auctx_out)54 open_au(krb5_audit_moddata *auctx_out)
55 {
56 krb5_error_code ret;
57 int fd = 0;
58 krb5_audit_moddata auctx;
59
60 auctx = k5calloc(1, sizeof(*auctx), &ret);
61 if (ret)
62 return ENOMEM;
63 fd = audit_open();
64 if (fd < 0)
65 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
66
67 auctx->fd = fd;
68 *auctx_out = auctx;
69
70 return 0;
71 }
72
73 /* Close connection to the audit system. Returns 0 on success. */
74 static krb5_error_code
close_au(krb5_audit_moddata auctx)75 close_au(krb5_audit_moddata auctx)
76 {
77 int fd = auctx->fd;
78
79 audit_close(fd);
80 return 0;
81 }
82
83 /* Log KDC-start event. Returns 0 on success. */
84 static krb5_error_code
j_kdc_start(krb5_audit_moddata auctx,krb5_boolean ev_success)85 j_kdc_start(krb5_audit_moddata auctx, krb5_boolean ev_success)
86 {
87 krb5_error_code ret = 0;
88 int local_type = AUDIT_USER_START;
89 int fd = auctx->fd;
90 char *jout = NULL;
91
92 if (fd < 0)
93 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
94
95 ret = kau_j_kdc_start(ev_success, &jout);
96 if (ret)
97 return ret;
98 if (audit_log_user_message(fd, local_type, jout,
99 NULL, NULL, NULL, ev_success) <= 0)
100 ret = EIO;
101 free(jout);
102 return ret;
103 }
104
105 /* Log KDC-stop event. Returns 0 on success. */
106 static krb5_error_code
j_kdc_stop(krb5_audit_moddata auctx,krb5_boolean ev_success)107 j_kdc_stop(krb5_audit_moddata auctx, krb5_boolean ev_success)
108 {
109 krb5_error_code ret = 0;
110 int local_type = AUDIT_USER_END;
111 int fd = auctx->fd;
112 char *jout = NULL;
113
114 if (fd < 0)
115 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
116
117 ret = kau_j_kdc_stop(ev_success, &jout);
118 if (ret)
119 return ret;
120 if (audit_log_user_message(fd, local_type, jout,
121 NULL, NULL, NULL, ev_success) <= 0)
122 ret = EIO;
123 free(jout);
124 return ret;
125 }
126
127 /* Log AS_REQ event. Returns 0 on success */
128 static krb5_error_code
j_as_req(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)129 j_as_req(krb5_audit_moddata auctx, krb5_boolean ev_success,
130 krb5_audit_state *state)
131 {
132 krb5_error_code ret = 0;
133 int local_type = AUDIT_USER_AUTH;
134 int fd = auctx->fd;
135 char *jout = NULL;
136
137 if (fd < 0)
138 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
139
140 ret = kau_j_as_req(ev_success, state, &jout);
141 if (ret)
142 return ret;
143 if (audit_log_user_message(fd, local_type, jout,
144 NULL, NULL, NULL, ev_success) <= 0)
145 ret = EIO;
146 free(jout);
147 return ret;
148 }
149
150 /* Log TGS_REQ event. Returns 0 on success */
151 static krb5_error_code
j_tgs_req(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)152 j_tgs_req(krb5_audit_moddata auctx, krb5_boolean ev_success,
153 krb5_audit_state *state)
154 {
155 krb5_error_code ret = 0;
156 int local_type = AUDIT_USER_AUTH;
157 int fd = auctx->fd;
158 char *jout = NULL;
159
160 if (fd < 0)
161 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
162
163 ret = kau_j_tgs_req(ev_success, state, &jout);
164 if (ret)
165 return ret;
166 if (audit_log_user_message(fd, local_type, jout,
167 NULL, NULL, NULL, ev_success) <= 0)
168 ret = EIO;
169 free(jout);
170 return ret;
171 }
172
173 /* Log S4U2SELF event. Returns 0 on success */
174 static krb5_error_code
j_tgs_s4u2self(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)175 j_tgs_s4u2self(krb5_audit_moddata auctx, krb5_boolean ev_success,
176 krb5_audit_state *state)
177 {
178 krb5_error_code ret = 0;
179 int local_type = AUDIT_USER_AUTH;
180 int fd = auctx->fd;
181 char *jout = NULL;
182
183 if (fd < 0)
184 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
185
186 ret = kau_j_tgs_s4u2self(ev_success, state, &jout);
187 if (ret)
188 return ret;
189 if (audit_log_user_message(fd, local_type, jout,
190 NULL, NULL, NULL, ev_success) <= 0)
191 ret = EIO;
192 free(jout);
193 return ret;
194 }
195
196 /* Log S4U2PROXY event. Returns 0 on success */
197 static krb5_error_code
j_tgs_s4u2proxy(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)198 j_tgs_s4u2proxy(krb5_audit_moddata auctx, krb5_boolean ev_success,
199 krb5_audit_state *state)
200 {
201 krb5_error_code ret = 0;
202 int local_type = AUDIT_USER_AUTH;
203 int fd = auctx->fd;
204 char *jout = NULL;
205
206 if (fd < 0)
207 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
208
209 ret = kau_j_tgs_s4u2proxy(ev_success, state, &jout);
210 if (ret)
211 return ret;
212 if (audit_log_user_message(fd, local_type, jout,
213 NULL, NULL, NULL, ev_success) <= 0)
214 ret = EIO;
215 free(jout);
216 return ret;
217 }
218
219 /* Log user-to-user event. Returns 0 on success */
220 static krb5_error_code
j_tgs_u2u(krb5_audit_moddata auctx,krb5_boolean ev_success,krb5_audit_state * state)221 j_tgs_u2u(krb5_audit_moddata auctx, krb5_boolean ev_success,
222 krb5_audit_state *state)
223 {
224 krb5_error_code ret = 0;
225 int local_type = AUDIT_USER_AUTH;
226 int fd = auctx->fd;
227 char *jout = NULL;
228
229 if (fd < 0)
230 return KRB5_PLUGIN_NO_HANDLE; /* audit module is unavailable */
231
232 ret = kau_j_tgs_u2u(ev_success, state, &jout);
233 if (ret)
234 return ret;
235 if (audit_log_user_message(fd, local_type, jout,
236 NULL, NULL, NULL, ev_success) <= 0)
237 ret = EIO;
238 free(jout);
239 return ret;
240 }
241
242 krb5_error_code
audit_simple_initvt(krb5_context context,int maj_ver,int min_ver,krb5_plugin_vtable vtable)243 audit_simple_initvt(krb5_context context, int maj_ver,
244 int min_ver, krb5_plugin_vtable vtable)
245 {
246 krb5_audit_vtable vt;
247
248 if (maj_ver != 1)
249 return KRB5_PLUGIN_VER_NOTSUPP;
250
251 vt = (krb5_audit_vtable)vtable;
252 vt->name = "simple";
253 vt->open = open_au;
254 vt->close = close_au;
255 vt->kdc_start = j_kdc_start;
256 vt->kdc_stop = j_kdc_stop;
257 vt->as_req = j_as_req;
258 vt->tgs_req = j_tgs_req;
259 vt->tgs_s4u2self = j_tgs_s4u2self;
260 vt->tgs_s4u2proxy = j_tgs_s4u2proxy;
261 vt->tgs_u2u = j_tgs_u2u;
262 return 0;
263 }
264