]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2003-2007 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
27 | */ | |
28 | /* | |
29 | * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce | |
30 | * support for mandatory and extensible security protections. This notice | |
31 | * is included in support of clause 2.2 (b) of the Apple Public License, | |
32 | * Version 2.0. | |
33 | */ | |
34 | #include <sys/types.h> | |
35 | #include <sys/vnode_internal.h> | |
36 | #include <sys/ipc.h> | |
37 | #include <sys/sem.h> | |
38 | #include <sys/socketvar.h> | |
39 | #include <sys/socket.h> | |
40 | #include <sys/queue.h> | |
41 | #include <sys/fcntl.h> | |
42 | #include <sys/user.h> | |
43 | ||
44 | #include <sys/ipc.h> | |
45 | #include <bsm/audit.h> | |
46 | #include <bsm/audit_record.h> | |
47 | #include <bsm/audit_kernel.h> | |
48 | #include <bsm/audit_kevents.h> | |
49 | #include <bsm/audit_klib.h> | |
50 | ||
51 | #include <netinet/in_systm.h> | |
52 | #include <netinet/in.h> | |
53 | #include <netinet/ip.h> | |
54 | ||
55 | #include <kern/lock.h> | |
56 | #include <kern/kalloc.h> | |
57 | ||
58 | #if CONFIG_MACF | |
59 | #include <security/mac_framework.h> | |
60 | #endif | |
61 | ||
62 | /* The number of BSM records allocated. */ | |
63 | static int bsm_rec_count = 0; | |
64 | ||
65 | /* | |
66 | * Records that can be recycled are maintained in the list given below | |
67 | * The maximum number of elements that can be present in this list is | |
68 | * bounded by MAX_AUDIT_RECORDS. Memory allocated for these records are never | |
69 | * freed | |
70 | */ | |
71 | LIST_HEAD(, au_record) bsm_free_q; | |
72 | ||
73 | /* | |
74 | * Lock for serializing access to the list of audit records. | |
75 | */ | |
76 | static lck_grp_t *bsm_audit_grp; | |
77 | static lck_attr_t *bsm_audit_attr; | |
78 | static lck_grp_attr_t *bsm_audit_grp_attr; | |
79 | static lck_mtx_t *bsm_audit_mutex; | |
80 | ||
81 | static void audit_sys_auditon(struct audit_record *ar, struct au_record *rec); | |
82 | ||
83 | /* | |
84 | * Initialize the BSM auditing subsystem. | |
85 | */ | |
86 | void | |
87 | kau_init(void) | |
88 | { | |
89 | printf("BSM auditing present\n"); | |
90 | LIST_INIT(&bsm_free_q); | |
91 | bsm_audit_grp_attr = lck_grp_attr_alloc_init(); | |
92 | bsm_audit_grp = lck_grp_alloc_init("BSM Audit", bsm_audit_grp_attr); | |
93 | bsm_audit_attr = lck_attr_alloc_init(); | |
94 | bsm_audit_mutex = lck_mtx_alloc_init(bsm_audit_grp, bsm_audit_attr); | |
95 | au_evclassmap_init(); | |
96 | } | |
97 | ||
98 | /* | |
99 | * This call reserves memory for the audit record. | |
100 | * Memory must be guaranteed before any auditable event can be | |
101 | * generated. | |
102 | * The au_record structure maintains a reference to the | |
103 | * memory allocated above and also the list of tokens associated | |
104 | * with this record | |
105 | */ | |
106 | struct au_record * | |
107 | kau_open(void) | |
108 | { | |
109 | struct au_record *rec = NULL; | |
110 | ||
111 | /* | |
112 | * Find an unused record, remove it from the free list, mark as used | |
113 | */ | |
114 | lck_mtx_lock(bsm_audit_mutex); | |
115 | if (!LIST_EMPTY(&bsm_free_q)) { | |
116 | rec = LIST_FIRST(&bsm_free_q); | |
117 | LIST_REMOVE(rec, au_rec_q); | |
118 | } | |
119 | lck_mtx_unlock(bsm_audit_mutex); | |
120 | ||
121 | if (rec == NULL) { | |
122 | lck_mtx_lock(bsm_audit_mutex); | |
123 | if (bsm_rec_count >= MAX_AUDIT_RECORDS) { | |
124 | /* XXX We need to increase size of MAX_AUDIT_RECORDS */ | |
125 | lck_mtx_unlock(bsm_audit_mutex); | |
126 | return NULL; | |
127 | } | |
128 | lck_mtx_unlock(bsm_audit_mutex); | |
129 | ||
130 | /* | |
131 | * Create a new BSM kernel record. | |
132 | */ | |
133 | rec = (struct au_record *)kalloc(sizeof(*rec)); | |
134 | if(rec == NULL) { | |
135 | return NULL; | |
136 | } | |
137 | rec->data = (u_char *)kalloc(MAX_AUDIT_RECORD_SIZE * sizeof(u_char)); | |
138 | if((rec->data) == NULL) { | |
139 | kfree(rec, sizeof(*rec)); | |
140 | return NULL; | |
141 | } | |
142 | lck_mtx_lock(bsm_audit_mutex); | |
143 | bsm_rec_count++; | |
144 | lck_mtx_unlock(bsm_audit_mutex); | |
145 | } | |
146 | memset(rec->data, 0, MAX_AUDIT_RECORD_SIZE); | |
147 | ||
148 | TAILQ_INIT(&rec->token_q); | |
149 | rec->len = 0; | |
150 | rec->used = 1; | |
151 | ||
152 | return rec; | |
153 | } | |
154 | ||
155 | /* | |
156 | * Store the token with the record descriptor | |
157 | * | |
158 | */ | |
159 | int kau_write(struct au_record *rec, struct au_token *tok) | |
160 | { | |
161 | if(tok == NULL) { | |
162 | return -1; /* Invalid Token */ | |
163 | } | |
164 | ||
165 | /* Add the token to the tail */ | |
166 | /* | |
167 | * XXX Not locking here -- we should not be writing to | |
168 | * XXX the same audit record from different threads | |
169 | */ | |
170 | TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens); | |
171 | ||
172 | rec->len += tok->len; /* grow record length by token size bytes */ | |
173 | ||
174 | return 0; | |
175 | } | |
176 | ||
177 | /* | |
178 | * Close out the audit record by adding the header token, identifying | |
179 | * any missing tokens. Write out the tokens to the record memory. | |
180 | */ | |
181 | int | |
182 | kau_close(struct au_record *rec, struct timespec *ctime, short event) | |
183 | { | |
184 | u_char *dptr; | |
185 | size_t tot_rec_size; | |
186 | token_t *cur, *hdr, *trail; | |
187 | int retval = 0; | |
188 | ||
189 | tot_rec_size = rec->len + HEADER_SIZE + TRAILER_SIZE; | |
190 | if(tot_rec_size <= MAX_AUDIT_RECORD_SIZE) { | |
191 | /* Create the header token */ | |
192 | hdr = kau_to_header32(ctime, tot_rec_size, event, 0); | |
193 | ||
194 | if(hdr != NULL) { | |
195 | /* Add to head of list */ | |
196 | TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens); | |
197 | ||
198 | trail = au_to_trailer(tot_rec_size); | |
199 | if(trail != NULL) { | |
200 | TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens); | |
201 | } | |
202 | } | |
203 | /* Serialize token data to the record */ | |
204 | ||
205 | rec->len = tot_rec_size; | |
206 | dptr = rec->data; | |
207 | TAILQ_FOREACH(cur, &rec->token_q, tokens) { | |
208 | memcpy(dptr, cur->t_data, cur->len); | |
209 | dptr += cur->len; | |
210 | } | |
211 | } | |
212 | ||
213 | return(retval); | |
214 | } | |
215 | ||
216 | /* | |
217 | * Free a BSM audit record by releasing all the tokens and clearing the | |
218 | * audit record information. | |
219 | */ | |
220 | void kau_free(struct au_record *rec) | |
221 | { | |
222 | struct au_token *tok; | |
223 | ||
224 | /* Free the token list */ | |
225 | while ((tok = TAILQ_FIRST(&rec->token_q))) { | |
226 | TAILQ_REMOVE(&rec->token_q, tok, tokens); | |
227 | kfree(tok, sizeof(*tok) + tok->len); | |
228 | } | |
229 | ||
230 | rec->used = 0; | |
231 | rec->len = 0; | |
232 | ||
233 | lck_mtx_lock(bsm_audit_mutex); | |
234 | ||
235 | /* Add the record to the freelist */ | |
236 | LIST_INSERT_HEAD(&bsm_free_q, rec, au_rec_q); | |
237 | ||
238 | lck_mtx_unlock(bsm_audit_mutex); | |
239 | ||
240 | } | |
241 | ||
242 | /* | |
243 | * XXX May want turn some (or all) of these macros into functions in order | |
244 | * to reduce the generated code size. | |
245 | */ | |
246 | #if CONFIG_MACF | |
247 | #define MAC_VNODE1_LABEL_TOKEN \ | |
248 | do { \ | |
249 | if (ar->ar_vnode1_mac_labels != NULL) { \ | |
250 | tok = au_to_text(ar->ar_vnode1_mac_labels); \ | |
251 | kau_write(rec, tok); \ | |
252 | } \ | |
253 | } while (0) | |
254 | ||
255 | #define MAC_VNODE2_LABEL_TOKEN \ | |
256 | do { \ | |
257 | if (ar->ar_vnode2_mac_labels != NULL) { \ | |
258 | tok = au_to_text(ar->ar_vnode2_mac_labels); \ | |
259 | kau_write(rec, tok); \ | |
260 | } \ | |
261 | } while (0) | |
262 | #else | |
263 | #define MAC_VNODE1_LABEL_TOKEN | |
264 | #define MAC_VNODE2_LABEL_TOKEN | |
265 | #endif | |
266 | #define UPATH1_TOKENS \ | |
267 | do { \ | |
268 | if (ar->ar_valid_arg & ARG_UPATH1) { \ | |
269 | tok = au_to_path(ar->ar_arg_upath1); \ | |
270 | kau_write(rec, tok); \ | |
271 | } \ | |
272 | } while (0) | |
273 | ||
274 | #define UPATH2_TOKENS \ | |
275 | do { \ | |
276 | if (ar->ar_valid_arg & ARG_UPATH2) { \ | |
277 | tok = au_to_path(ar->ar_arg_upath2); \ | |
278 | kau_write(rec, tok); \ | |
279 | } \ | |
280 | } while (0) | |
281 | ||
282 | #define UPATH1_KPATH1_VNODE1_TOKENS \ | |
283 | do { \ | |
284 | if (ar->ar_valid_arg & ARG_UPATH1) { \ | |
285 | tok = au_to_path(ar->ar_arg_upath1); \ | |
286 | kau_write(rec, tok); \ | |
287 | } \ | |
288 | if (ar->ar_valid_arg & ARG_KPATH1) { \ | |
289 | tok = au_to_path(ar->ar_arg_kpath1); \ | |
290 | kau_write(rec, tok); \ | |
291 | } \ | |
292 | if (ar->ar_valid_arg & ARG_VNODE1) { \ | |
293 | tok = kau_to_attr32(&ar->ar_arg_vnode1);\ | |
294 | kau_write(rec, tok); \ | |
295 | MAC_VNODE1_LABEL_TOKEN; \ | |
296 | } \ | |
297 | } while (0) | |
298 | ||
299 | #define KPATH1_VNODE1_TOKENS \ | |
300 | do { \ | |
301 | if (ar->ar_valid_arg & ARG_KPATH1) { \ | |
302 | tok = au_to_path(ar->ar_arg_kpath1); \ | |
303 | kau_write(rec, tok); \ | |
304 | } \ | |
305 | if (ar->ar_valid_arg & ARG_VNODE1) { \ | |
306 | tok = kau_to_attr32(&ar->ar_arg_vnode1);\ | |
307 | kau_write(rec, tok); \ | |
308 | MAC_VNODE1_LABEL_TOKEN; \ | |
309 | } \ | |
310 | } while (0) | |
311 | ||
312 | #define KPATH2_VNODE2_TOKENS \ | |
313 | do { \ | |
314 | if (ar->ar_valid_arg & ARG_KPATH2) { \ | |
315 | tok = au_to_path(ar->ar_arg_kpath2); \ | |
316 | kau_write(rec, tok); \ | |
317 | } \ | |
318 | if (ar->ar_valid_arg & ARG_VNODE2) { \ | |
319 | tok = kau_to_attr32(&ar->ar_arg_vnode2);\ | |
320 | kau_write(rec, tok); \ | |
321 | MAC_VNODE2_LABEL_TOKEN; \ | |
322 | } \ | |
323 | } while (0) | |
324 | ||
325 | #define FD_KPATH1_VNODE1_TOKENS \ | |
326 | do { \ | |
327 | if (ar->ar_valid_arg & ARG_KPATH1) { \ | |
328 | tok = au_to_path(ar->ar_arg_kpath1); \ | |
329 | kau_write(rec, tok); \ | |
330 | if (ar->ar_valid_arg & ARG_VNODE1) { \ | |
331 | tok = kau_to_attr32(&ar->ar_arg_vnode1);\ | |
332 | kau_write(rec, tok); \ | |
333 | MAC_VNODE1_LABEL_TOKEN; \ | |
334 | } \ | |
335 | } else { \ | |
336 | tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \ | |
337 | kau_write(rec, tok); \ | |
338 | } \ | |
339 | } while (0) | |
340 | ||
341 | #define PROCESS_PID_TOKENS(argn) \ | |
342 | do { \ | |
343 | if ((ar->ar_arg_pid > 0) /* Kill a single process */ \ | |
344 | && (ar->ar_valid_arg & ARG_PROCESS)) { \ | |
345 | tok = au_to_process(ar->ar_arg_auid, ar->ar_arg_euid, \ | |
346 | ar->ar_arg_egid, ar->ar_arg_ruid, \ | |
347 | ar->ar_arg_rgid, ar->ar_arg_pid, \ | |
348 | ar->ar_arg_asid, &ar->ar_arg_termid); \ | |
349 | kau_write(rec, tok); \ | |
350 | } else { \ | |
351 | tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\ | |
352 | kau_write(rec, tok); \ | |
353 | } \ | |
354 | } while (0) \ | |
355 | ||
356 | #define PROCESS_MAC_TOKENS \ | |
357 | do { \ | |
358 | if (ar->ar_valid_arg & ARG_MAC_STRING) { \ | |
359 | tok = au_to_text(ar->ar_arg_mac_string); \ | |
360 | kau_write(rec, tok); \ | |
361 | } \ | |
362 | } while (0) \ | |
363 | ||
364 | /* | |
365 | * Implement auditing for the auditon() system call. The audit tokens | |
366 | * that are generated depend on the command that was sent into the | |
367 | * auditon() system call. | |
368 | * | |
369 | */ | |
370 | static void | |
371 | audit_sys_auditon(struct audit_record *ar, struct au_record *rec) | |
372 | { | |
373 | struct au_token *tok; | |
374 | ||
375 | switch (ar->ar_arg_cmd) { | |
376 | case A_SETPOLICY: | |
377 | if (sizeof(ar->ar_arg_auditon.au_flags) > 4) | |
378 | tok = au_to_arg64(1, "policy", | |
379 | ar->ar_arg_auditon.au_flags); | |
380 | else | |
381 | tok = au_to_arg32(1, "policy", | |
382 | ar->ar_arg_auditon.au_flags); | |
383 | kau_write(rec, tok); | |
384 | break; | |
385 | case A_SETKMASK: | |
386 | tok = au_to_arg32(2, "setkmask:as_success", | |
387 | ar->ar_arg_auditon.au_mask.am_success); | |
388 | kau_write(rec, tok); | |
389 | tok = au_to_arg32(2, "setkmask:as_failure", | |
390 | ar->ar_arg_auditon.au_mask.am_failure); | |
391 | kau_write(rec, tok); | |
392 | break; | |
393 | case A_SETQCTRL: | |
394 | tok = au_to_arg32(3, "setqctrl:aq_hiwater", | |
395 | ar->ar_arg_auditon.au_qctrl.aq_hiwater); | |
396 | kau_write(rec, tok); | |
397 | tok = au_to_arg32(3, "setqctrl:aq_lowater", | |
398 | ar->ar_arg_auditon.au_qctrl.aq_lowater); | |
399 | kau_write(rec, tok); | |
400 | tok = au_to_arg32(3, "setqctrl:aq_bufsz", | |
401 | ar->ar_arg_auditon.au_qctrl.aq_bufsz); | |
402 | kau_write(rec, tok); | |
403 | tok = au_to_arg32(3, "setqctrl:aq_delay", | |
404 | ar->ar_arg_auditon.au_qctrl.aq_delay); | |
405 | kau_write(rec, tok); | |
406 | tok = au_to_arg32(3, "setqctrl:aq_minfree", | |
407 | ar->ar_arg_auditon.au_qctrl.aq_minfree); | |
408 | kau_write(rec, tok); | |
409 | break; | |
410 | case A_SETUMASK: | |
411 | tok = au_to_arg32(3, "setumask:as_success", | |
412 | ar->ar_arg_auditon.au_auinfo.ai_mask.am_success); | |
413 | kau_write(rec, tok); | |
414 | tok = au_to_arg32(3, "setumask:as_failure", | |
415 | ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure); | |
416 | kau_write(rec, tok); | |
417 | break; | |
418 | case A_SETSMASK: | |
419 | tok = au_to_arg32(3, "setsmask:as_success", | |
420 | ar->ar_arg_auditon.au_auinfo.ai_mask.am_success); | |
421 | kau_write(rec, tok); | |
422 | tok = au_to_arg32(3, "setsmask:as_failure", | |
423 | ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure); | |
424 | kau_write(rec, tok); | |
425 | break; | |
426 | case A_SETCOND: | |
427 | if (sizeof(ar->ar_arg_auditon.au_cond) > 4) | |
428 | tok = au_to_arg64(3, "setcond", | |
429 | ar->ar_arg_auditon.au_cond); | |
430 | else | |
431 | tok = au_to_arg32(3, "setcond", | |
432 | ar->ar_arg_auditon.au_cond); | |
433 | kau_write(rec, tok); | |
434 | break; | |
435 | case A_SETCLASS: | |
436 | tok = au_to_arg32(2, "setclass:ec_event", | |
437 | ar->ar_arg_auditon.au_evclass.ec_number); | |
438 | kau_write(rec, tok); | |
439 | tok = au_to_arg32(3, "setclass:ec_class", | |
440 | ar->ar_arg_auditon.au_evclass.ec_class); | |
441 | kau_write(rec, tok); | |
442 | break; | |
443 | case A_SETPMASK: | |
444 | tok = au_to_arg32(2, "setpmask:as_success", | |
445 | ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success); | |
446 | kau_write(rec, tok); | |
447 | tok = au_to_arg32(2, "setpmask:as_failure", | |
448 | ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure); | |
449 | kau_write(rec, tok); | |
450 | break; | |
451 | case A_SETFSIZE: | |
452 | tok = au_to_arg32(2, "setfsize:filesize", | |
453 | ar->ar_arg_auditon.au_fstat.af_filesz); | |
454 | kau_write(rec, tok); | |
455 | break; | |
456 | default: | |
457 | break; | |
458 | } | |
459 | } | |
460 | ||
461 | /* | |
462 | * Convert an internal kernel audit record to a BSM record and return | |
463 | * a success/failure indicator. The BSM record is passed as an out | |
464 | * parameter to this function. | |
465 | * Return conditions: | |
466 | * BSM_SUCCESS: The BSM record is valid | |
467 | * BSM_FAILURE: Failure; the BSM record is NULL. | |
468 | * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL. | |
469 | */ | |
470 | int | |
471 | kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau) | |
472 | { | |
473 | struct au_token *tok = NULL, *subj_tok; | |
474 | struct au_record *rec; | |
475 | au_tid_t tid; | |
476 | struct audit_record *ar; | |
477 | ||
478 | *pau = NULL; | |
479 | if (kar == NULL) | |
480 | return (BSM_FAILURE); | |
481 | ||
482 | ar = &kar->k_ar; | |
483 | ||
484 | rec = kau_open(); | |
485 | if (rec == NULL) | |
486 | return (BSM_FAILURE); | |
487 | ||
488 | /* Create the subject token */ | |
489 | tid.port = ar->ar_subj_term.port; | |
490 | tid.machine = ar->ar_subj_term.machine; | |
491 | subj_tok = au_to_subject32(ar->ar_subj_auid, /* audit ID */ | |
492 | ar->ar_subj_cred.cr_uid, /* eff uid */ | |
493 | ar->ar_subj_egid, /* eff group id */ | |
494 | ar->ar_subj_ruid, /* real uid */ | |
495 | ar->ar_subj_rgid, /* real group id */ | |
496 | ar->ar_subj_pid, /* process id */ | |
497 | ar->ar_subj_asid, /* session ID */ | |
498 | &tid); | |
499 | ||
500 | /* The logic inside each case fills in the tokens required for the | |
501 | * event, except for the header, trailer, and return tokens. The | |
502 | * header and trailer tokens are added by the kau_close() function. | |
503 | * The return token is added outside of the switch statement. | |
504 | */ | |
505 | switch(ar->ar_event) { | |
506 | ||
507 | /* | |
508 | * Socket-related events. | |
509 | */ | |
510 | case AUE_ACCEPT: | |
511 | case AUE_BIND: | |
512 | case AUE_CONNECT: | |
513 | case AUE_RECVFROM: | |
514 | case AUE_RECVMSG: | |
515 | case AUE_SENDMSG: | |
516 | case AUE_SENDTO: | |
517 | tok = au_to_arg32(1, "fd", ar->ar_arg_fd); | |
518 | kau_write(rec, tok); | |
519 | if (ar->ar_valid_arg & ARG_SADDRINET) { | |
520 | tok = au_to_sock_inet( | |
521 | (struct sockaddr_in *)&ar->ar_arg_sockaddr); | |
522 | kau_write(rec, tok); | |
523 | } | |
524 | if (ar->ar_valid_arg & ARG_SADDRUNIX) { | |
525 | tok = au_to_sock_unix( | |
526 | (struct sockaddr_un *)&ar->ar_arg_sockaddr); | |
527 | kau_write(rec, tok); | |
528 | UPATH1_TOKENS; | |
529 | } | |
530 | /* XXX Need to handle ARG_SADDRINET6 */ | |
531 | break; | |
532 | ||
533 | case AUE_SOCKET: | |
534 | case AUE_SOCKETPAIR: | |
535 | tok = au_to_arg32(1,"domain", ar->ar_arg_sockinfo.so_domain); | |
536 | kau_write(rec, tok); | |
537 | tok = au_to_arg32(2,"type", ar->ar_arg_sockinfo.so_type); | |
538 | kau_write(rec, tok); | |
539 | tok = au_to_arg32(3,"protocol",ar->ar_arg_sockinfo.so_protocol); | |
540 | kau_write(rec, tok); | |
541 | break; | |
542 | ||
543 | case AUE_SETSOCKOPT: | |
544 | case AUE_SHUTDOWN: | |
545 | tok = au_to_arg32(1, "fd", ar->ar_arg_fd); | |
546 | kau_write(rec, tok); | |
547 | break; | |
548 | ||
549 | case AUE_ACCT: | |
550 | if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) { | |
551 | UPATH1_KPATH1_VNODE1_TOKENS; | |
552 | } else { | |
553 | tok = au_to_arg32(1, "accounting off", 0); | |
554 | kau_write(rec, tok); | |
555 | } | |
556 | break; | |
557 | ||
558 | case AUE_SETAUID: | |
559 | tok = au_to_arg32(2, "setauid", ar->ar_arg_auid); | |
560 | kau_write(rec, tok); | |
561 | break; | |
562 | ||
563 | case AUE_SETAUDIT: | |
564 | if (ar->ar_valid_arg & ARG_AUID) { | |
565 | tok = au_to_arg32(1, "setaudit:auid", ar->ar_arg_auid); | |
566 | kau_write(rec, tok); | |
567 | tok = au_to_arg32(1, "setaudit:port", | |
568 | ar->ar_arg_termid.port); | |
569 | kau_write(rec, tok); | |
570 | tok = au_to_arg32(1, "setaudit:machine", | |
571 | ar->ar_arg_termid.machine); | |
572 | kau_write(rec, tok); | |
573 | tok = au_to_arg32(1, "setaudit:as_success", | |
574 | ar->ar_arg_amask.am_success); | |
575 | kau_write(rec, tok); | |
576 | tok = au_to_arg32(1, "setaudit:as_failure", | |
577 | ar->ar_arg_amask.am_failure); | |
578 | kau_write(rec, tok); | |
579 | tok = au_to_arg32(1, "setaudit:asid", ar->ar_arg_asid); | |
580 | kau_write(rec, tok); | |
581 | } | |
582 | break; | |
583 | ||
584 | case AUE_SETAUDIT_ADDR: | |
585 | break; /* XXX need to add arguments */ | |
586 | ||
587 | case AUE_AUDITON: | |
588 | /* For AUDITON commands without own event, audit the cmd */ | |
589 | tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd); | |
590 | kau_write(rec, tok); | |
591 | /* fall thru */ | |
592 | ||
593 | case AUE_AUDITON_GETCAR: | |
594 | case AUE_AUDITON_GETCLASS: | |
595 | case AUE_AUDITON_GETCOND: | |
596 | case AUE_AUDITON_GETCWD: | |
597 | case AUE_AUDITON_GETKMASK: | |
598 | case AUE_AUDITON_GETSTAT: | |
599 | case AUE_AUDITON_GPOLICY: | |
600 | case AUE_AUDITON_GQCTRL: | |
601 | case AUE_AUDITON_SETCLASS: | |
602 | case AUE_AUDITON_SETCOND: | |
603 | case AUE_AUDITON_SETKMASK: | |
604 | case AUE_AUDITON_SETSMASK: | |
605 | case AUE_AUDITON_SETSTAT: | |
606 | case AUE_AUDITON_SETUMASK: | |
607 | case AUE_AUDITON_SPOLICY: | |
608 | case AUE_AUDITON_SQCTRL: | |
609 | if (ar->ar_valid_arg & ARG_AUDITON) { | |
610 | audit_sys_auditon(ar, rec); | |
611 | } | |
612 | break; | |
613 | ||
614 | case AUE_AUDITCTL: | |
615 | UPATH1_KPATH1_VNODE1_TOKENS; | |
616 | break; | |
617 | ||
618 | case AUE_ADJTIME: | |
619 | case AUE_AUDIT: | |
620 | case AUE_EXIT: | |
621 | case AUE_GETAUDIT: | |
622 | case AUE_GETAUDIT_ADDR: | |
623 | case AUE_GETAUID: | |
624 | case AUE_GETFSSTAT: | |
625 | case AUE_MAC_GETFSSTAT: | |
626 | case AUE_PIPE: | |
627 | case AUE_SETPGRP: | |
628 | case AUE_SETRLIMIT: | |
629 | case AUE_SETSID: | |
630 | case AUE_SETTIMEOFDAY: | |
631 | /* Header, subject, and return tokens added at end */ | |
632 | break; | |
633 | ||
634 | case AUE_ACCESS: | |
635 | case AUE_CHDIR: | |
636 | case AUE_CHROOT: | |
637 | case AUE_EXECVE: | |
638 | case AUE_GETATTRLIST: | |
639 | case AUE_GETFH: | |
640 | case AUE_LSTAT: | |
641 | case AUE_MKFIFO: | |
642 | case AUE_PATHCONF: | |
643 | case AUE_READLINK: | |
644 | case AUE_REVOKE: | |
645 | case AUE_RMDIR: | |
646 | case AUE_SEARCHFS: | |
647 | case AUE_SETATTRLIST: | |
648 | case AUE_STAT: | |
649 | case AUE_STATFS: | |
650 | case AUE_TRUNCATE: | |
651 | case AUE_UNDELETE: | |
652 | case AUE_UNLINK: | |
653 | case AUE_UTIMES: | |
654 | UPATH1_KPATH1_VNODE1_TOKENS; | |
655 | break; | |
656 | ||
657 | case AUE_CHFLAGS: | |
658 | tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); | |
659 | kau_write(rec, tok); | |
660 | UPATH1_KPATH1_VNODE1_TOKENS; | |
661 | break; | |
662 | ||
663 | case AUE_CHMOD: | |
664 | tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode); | |
665 | kau_write(rec, tok); | |
666 | UPATH1_KPATH1_VNODE1_TOKENS; | |
667 | break; | |
668 | ||
669 | case AUE_CHOWN: | |
670 | case AUE_LCHOWN: | |
671 | tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid); | |
672 | kau_write(rec, tok); | |
673 | tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid); | |
674 | kau_write(rec, tok); | |
675 | UPATH1_KPATH1_VNODE1_TOKENS; | |
676 | break; | |
677 | ||
678 | case AUE_EXCHANGEDATA: | |
679 | UPATH1_KPATH1_VNODE1_TOKENS; | |
680 | KPATH2_VNODE2_TOKENS; | |
681 | break; | |
682 | ||
683 | case AUE_CLOSE: | |
684 | tok = au_to_arg32(2, "fd", ar->ar_arg_fd); | |
685 | kau_write(rec, tok); | |
686 | UPATH1_KPATH1_VNODE1_TOKENS; | |
687 | break; | |
688 | ||
689 | case AUE_FCHMOD: | |
690 | tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode); | |
691 | kau_write(rec, tok); | |
692 | FD_KPATH1_VNODE1_TOKENS; | |
693 | break; | |
694 | ||
695 | case AUE_NFSSVC: | |
696 | tok = au_to_arg32(1, "request", ar->ar_arg_cmd); | |
697 | kau_write(rec, tok); | |
698 | if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) { | |
699 | UPATH1_KPATH1_VNODE1_TOKENS; | |
700 | } | |
701 | break; | |
702 | ||
703 | case AUE_FCHDIR: | |
704 | case AUE_FPATHCONF: | |
705 | case AUE_FSTAT: /* XXX Need to handle sockets and shm */ | |
706 | case AUE_FSTATFS: | |
707 | case AUE_FTRUNCATE: | |
708 | case AUE_FUTIMES: | |
709 | case AUE_GETDIRENTRIES: | |
710 | case AUE_GETDIRENTRIESATTR: | |
711 | case AUE_EXTATTR_GET_FD: | |
712 | case AUE_EXTATTR_LIST_FD: | |
713 | case AUE_EXTATTR_SET_FD: | |
714 | case AUE_EXTATTR_DELETE_FD: | |
715 | FD_KPATH1_VNODE1_TOKENS; | |
716 | break; | |
717 | ||
718 | case AUE_FCHOWN: | |
719 | tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid); | |
720 | kau_write(rec, tok); | |
721 | tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid); | |
722 | kau_write(rec, tok); | |
723 | FD_KPATH1_VNODE1_TOKENS; | |
724 | break; | |
725 | ||
726 | case AUE_FCNTL: | |
727 | tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd); | |
728 | kau_write(rec, tok); | |
729 | if (ar->ar_valid_arg & ARG_VNODE1) { | |
730 | FD_KPATH1_VNODE1_TOKENS; | |
731 | } | |
732 | break; | |
733 | ||
734 | case AUE_FCHFLAGS: | |
735 | tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); | |
736 | kau_write(rec, tok); | |
737 | FD_KPATH1_VNODE1_TOKENS; | |
738 | break; | |
739 | ||
740 | case AUE_FLOCK: | |
741 | tok = au_to_arg32(2, "operation", ar->ar_arg_cmd); | |
742 | kau_write(rec, tok); | |
743 | FD_KPATH1_VNODE1_TOKENS; | |
744 | break; | |
745 | ||
746 | case AUE_FORK: | |
747 | case AUE_VFORK: | |
748 | tok = au_to_arg32(0, "child PID", ar->ar_arg_pid); | |
749 | kau_write(rec, tok); | |
750 | break; | |
751 | ||
752 | case AUE_GETLCID: | |
753 | tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid); | |
754 | kau_write(rec, tok); | |
755 | break; | |
756 | ||
757 | case AUE_SETLCID: | |
758 | tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid); | |
759 | kau_write(rec, tok); | |
760 | tok = au_to_arg32(2, "lcid", (u_int32_t)ar->ar_arg_value); | |
761 | kau_write(rec, tok); | |
762 | break; | |
763 | ||
764 | case AUE_IOCTL: | |
765 | tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd); | |
766 | kau_write(rec, tok); | |
767 | tok = au_to_arg32(1, "arg", (u_int32_t)ar->ar_arg_addr); | |
768 | kau_write(rec, tok); | |
769 | if (ar->ar_valid_arg & ARG_VNODE1) { | |
770 | FD_KPATH1_VNODE1_TOKENS; | |
771 | } else { | |
772 | if (ar->ar_valid_arg & ARG_SOCKINFO) { | |
773 | tok = kau_to_socket(&ar->ar_arg_sockinfo); | |
774 | kau_write(rec, tok); | |
775 | } else { | |
776 | tok = au_to_arg32(1, "fd", ar->ar_arg_fd); | |
777 | kau_write(rec, tok); | |
778 | } | |
779 | } | |
780 | break; | |
781 | ||
782 | case AUE_KILL: | |
783 | tok = au_to_arg32(2, "signal", ar->ar_arg_signum); | |
784 | kau_write(rec, tok); | |
785 | PROCESS_PID_TOKENS(1); | |
786 | break; | |
787 | ||
788 | case AUE_LINK: | |
789 | case AUE_RENAME: | |
790 | UPATH1_KPATH1_VNODE1_TOKENS; | |
791 | UPATH2_TOKENS; | |
792 | break; | |
793 | ||
794 | case AUE_MKDIR: | |
795 | tok = au_to_arg32(2, "mode", ar->ar_arg_mode); | |
796 | kau_write(rec, tok); | |
797 | UPATH1_KPATH1_VNODE1_TOKENS; | |
798 | break; | |
799 | ||
800 | case AUE_MKNOD: | |
801 | tok = au_to_arg32(2, "mode", ar->ar_arg_mode); | |
802 | kau_write(rec, tok); | |
803 | tok = au_to_arg32(3, "dev", ar->ar_arg_dev); | |
804 | kau_write(rec, tok); | |
805 | UPATH1_KPATH1_VNODE1_TOKENS; | |
806 | break; | |
807 | ||
808 | case AUE_MMAP: | |
809 | case AUE_MUNMAP: | |
810 | case AUE_MPROTECT: | |
811 | case AUE_MLOCK: | |
812 | case AUE_MUNLOCK: | |
813 | case AUE_MINHERIT: | |
814 | tok = au_to_arg32(1, "addr", (u_int32_t)ar->ar_arg_addr); /* LP64todo */ | |
815 | kau_write(rec, tok); | |
816 | tok = au_to_arg32(2, "len", ar->ar_arg_len); /* LP64todo */ | |
817 | kau_write(rec, tok); | |
818 | if (ar->ar_event == AUE_MMAP) | |
819 | FD_KPATH1_VNODE1_TOKENS; | |
820 | if (ar->ar_event == AUE_MPROTECT) { | |
821 | tok = au_to_arg32(3, "protection", ar->ar_arg_value); | |
822 | kau_write(rec, tok); | |
823 | } | |
824 | if (ar->ar_event == AUE_MINHERIT) { | |
825 | tok = au_to_arg32(3, "inherit", ar->ar_arg_value); | |
826 | kau_write(rec, tok); | |
827 | } | |
828 | break; | |
829 | ||
830 | #if CONFIG_MACF | |
831 | case AUE_MAC_MOUNT: | |
832 | PROCESS_MAC_TOKENS; | |
833 | /* fall through */ | |
834 | #endif | |
835 | case AUE_MOUNT: | |
836 | /* XXX Need to handle NFS mounts */ | |
837 | tok = au_to_arg32(3, "flags", ar->ar_arg_fflags); | |
838 | kau_write(rec, tok); | |
839 | if (ar->ar_valid_arg & ARG_TEXT) { | |
840 | tok = au_to_text(ar->ar_arg_text); | |
841 | kau_write(rec, tok); | |
842 | } | |
843 | /* fall through */ | |
844 | case AUE_UNMOUNT: | |
845 | UPATH1_KPATH1_VNODE1_TOKENS; | |
846 | break; | |
847 | ||
848 | case AUE_MSGCTL: | |
849 | ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd); | |
850 | /* Fall through */ | |
851 | case AUE_MSGRCV: | |
852 | case AUE_MSGSND: | |
853 | tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id); | |
854 | kau_write(rec, tok); | |
855 | if (ar->ar_errno != EINVAL) { | |
856 | tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id); | |
857 | kau_write(rec, tok); | |
858 | } | |
859 | break; | |
860 | ||
861 | case AUE_MSGGET: | |
862 | if (ar->ar_errno == 0) { | |
863 | tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id); | |
864 | kau_write(rec, tok); | |
865 | } | |
866 | break; | |
867 | ||
868 | case AUE_OPEN_RC: | |
869 | case AUE_OPEN_RTC: | |
870 | case AUE_OPEN_RWC: | |
871 | case AUE_OPEN_RWTC: | |
872 | case AUE_OPEN_WC: | |
873 | case AUE_OPEN_WTC: | |
874 | tok = au_to_arg32(3, "mode", ar->ar_arg_mode); | |
875 | kau_write(rec, tok); | |
876 | /* fall thru */ | |
877 | ||
878 | case AUE_OPEN: | |
879 | case AUE_OPEN_R: | |
880 | case AUE_OPEN_RT: | |
881 | case AUE_OPEN_RW: | |
882 | case AUE_OPEN_RWT: | |
883 | case AUE_OPEN_W: | |
884 | case AUE_OPEN_WT: | |
885 | tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); | |
886 | kau_write(rec, tok); | |
887 | UPATH1_KPATH1_VNODE1_TOKENS; | |
888 | break; | |
889 | ||
890 | case AUE_PTRACE: | |
891 | tok = au_to_arg32(1, "request", ar->ar_arg_cmd); | |
892 | kau_write(rec, tok); | |
893 | tok = au_to_arg32(3, "addr", (u_int32_t)ar->ar_arg_addr); /* LP64todo */ | |
894 | kau_write(rec, tok); | |
895 | tok = au_to_arg32(4, "data", ar->ar_arg_value); | |
896 | kau_write(rec, tok); | |
897 | PROCESS_PID_TOKENS(2); | |
898 | break; | |
899 | ||
900 | case AUE_QUOTACTL: | |
901 | tok = au_to_arg32(2, "command", ar->ar_arg_cmd); | |
902 | kau_write(rec, tok); | |
903 | tok = au_to_arg32(3, "uid", ar->ar_arg_uid); | |
904 | kau_write(rec, tok); | |
905 | UPATH1_KPATH1_VNODE1_TOKENS; | |
906 | break; | |
907 | ||
908 | case AUE_REBOOT: | |
909 | tok = au_to_arg32(1, "howto", ar->ar_arg_cmd); | |
910 | kau_write(rec, tok); | |
911 | break; | |
912 | ||
913 | case AUE_SEMCTL: | |
914 | ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd); | |
915 | /* Fall through */ | |
916 | case AUE_SEMOP: | |
917 | tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id); | |
918 | kau_write(rec, tok); | |
919 | if (ar->ar_errno != EINVAL) { | |
920 | tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id); | |
921 | kau_write(rec, tok); | |
922 | } | |
923 | break; | |
924 | case AUE_SEMGET: | |
925 | if (ar->ar_errno == 0) { | |
926 | tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id); | |
927 | kau_write(rec, tok); | |
928 | } | |
929 | break; | |
930 | case AUE_SETEGID: | |
931 | tok = au_to_arg32(1, "gid", ar->ar_arg_egid); | |
932 | kau_write(rec, tok); | |
933 | break; | |
934 | case AUE_SETEUID: | |
935 | tok = au_to_arg32(1, "uid", ar->ar_arg_euid); | |
936 | kau_write(rec, tok); | |
937 | break; | |
938 | case AUE_SETGID: | |
939 | tok = au_to_arg32(1, "gid", ar->ar_arg_gid); | |
940 | kau_write(rec, tok); | |
941 | break; | |
942 | case AUE_SETUID: | |
943 | tok = au_to_arg32(1, "uid", ar->ar_arg_uid); | |
944 | kau_write(rec, tok); | |
945 | break; | |
946 | case AUE_SETGROUPS: | |
947 | if (ar->ar_valid_arg & ARG_GROUPSET) { | |
948 | u_int ctr; | |
949 | ||
950 | for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++) | |
951 | { | |
952 | tok = au_to_arg32(1, "setgroups", ar->ar_arg_groups.gidset[ctr]); | |
953 | kau_write(rec, tok); | |
954 | } | |
955 | } | |
956 | break; | |
957 | ||
958 | case AUE_SETLOGIN: | |
959 | if (ar->ar_valid_arg & ARG_TEXT) { | |
960 | tok = au_to_text(ar->ar_arg_text); | |
961 | kau_write(rec, tok); | |
962 | } | |
963 | break; | |
964 | ||
965 | case AUE_SETPRIORITY: | |
966 | tok = au_to_arg32(1, "which", ar->ar_arg_cmd); | |
967 | kau_write(rec, tok); | |
968 | tok = au_to_arg32(2, "who", ar->ar_arg_uid); | |
969 | kau_write(rec, tok); | |
970 | tok = au_to_arg32(2, "priority", ar->ar_arg_value); | |
971 | kau_write(rec, tok); | |
972 | break; | |
973 | ||
974 | case AUE_SETPRIVEXEC: | |
975 | tok = au_to_arg32(1, "flag", ar->ar_arg_value); | |
976 | kau_write(rec, tok); | |
977 | break; | |
978 | ||
979 | /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */ | |
980 | case AUE_SHMAT: | |
981 | tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id); | |
982 | kau_write(rec, tok); | |
983 | tok = au_to_arg64(2, "shmaddr", ar->ar_arg_svipc_addr); | |
984 | kau_write(rec, tok); | |
985 | if (ar->ar_valid_arg & ARG_SVIPC_PERM) { | |
986 | tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id); | |
987 | kau_write(rec, tok); | |
988 | tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm); | |
989 | kau_write(rec, tok); | |
990 | } | |
991 | break; | |
992 | ||
993 | case AUE_SHMCTL: | |
994 | tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id); | |
995 | kau_write(rec, tok); | |
996 | switch (ar->ar_arg_svipc_cmd) { | |
997 | case IPC_STAT: | |
998 | ar->ar_event = AUE_SHMCTL_STAT; | |
999 | if (ar->ar_valid_arg & ARG_SVIPC_PERM) { | |
1000 | tok = au_to_ipc(AT_IPC_SHM, | |
1001 | ar->ar_arg_svipc_id); | |
1002 | kau_write(rec, tok); | |
1003 | } | |
1004 | break; | |
1005 | case IPC_RMID: | |
1006 | ar->ar_event = AUE_SHMCTL_RMID; | |
1007 | if (ar->ar_valid_arg & ARG_SVIPC_PERM) { | |
1008 | tok = au_to_ipc(AT_IPC_SHM, | |
1009 | ar->ar_arg_svipc_id); | |
1010 | kau_write(rec, tok); | |
1011 | } | |
1012 | break; | |
1013 | case IPC_SET: | |
1014 | ar->ar_event = AUE_SHMCTL_SET; | |
1015 | if (ar->ar_valid_arg & ARG_SVIPC_PERM) { | |
1016 | tok = au_to_ipc(AT_IPC_SHM, | |
1017 | ar->ar_arg_svipc_id); | |
1018 | kau_write(rec, tok); | |
1019 | tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm); | |
1020 | kau_write(rec, tok); | |
1021 | } | |
1022 | break; | |
1023 | default: | |
1024 | break; /* We will audit a bad command */ | |
1025 | } | |
1026 | break; | |
1027 | ||
1028 | case AUE_SHMDT: | |
1029 | tok = au_to_arg64(1, "shmaddr", ar->ar_arg_svipc_addr); | |
1030 | kau_write(rec, tok); | |
1031 | break; | |
1032 | ||
1033 | case AUE_SHMGET: | |
1034 | /* This is unusual; the return value is in an argument token */ | |
1035 | tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id); | |
1036 | kau_write(rec, tok); | |
1037 | if (ar->ar_valid_arg & ARG_SVIPC_PERM) { | |
1038 | tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id); | |
1039 | kau_write(rec, tok); | |
1040 | tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm); | |
1041 | kau_write(rec, tok); | |
1042 | } | |
1043 | break; | |
1044 | ||
1045 | /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE | |
1046 | * and AUE_SEMUNLINK are Posix IPC */ | |
1047 | case AUE_SHMOPEN: | |
1048 | tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); | |
1049 | kau_write(rec, tok); | |
1050 | tok = au_to_arg32(3, "mode", ar->ar_arg_mode); | |
1051 | kau_write(rec, tok); | |
1052 | case AUE_SHMUNLINK: | |
1053 | if (ar->ar_valid_arg & ARG_TEXT) { | |
1054 | tok = au_to_text(ar->ar_arg_text); | |
1055 | kau_write(rec, tok); | |
1056 | } | |
1057 | if (ar->ar_valid_arg & ARG_POSIX_IPC_PERM) { | |
1058 | /* Create an ipc_perm token */ | |
1059 | struct ipc_perm perm; | |
1060 | perm.uid = ar->ar_arg_pipc_perm.pipc_uid; | |
1061 | perm.gid = ar->ar_arg_pipc_perm.pipc_gid; | |
1062 | perm.cuid = ar->ar_arg_pipc_perm.pipc_uid; | |
1063 | perm.cgid = ar->ar_arg_pipc_perm.pipc_gid; | |
1064 | perm.mode = ar->ar_arg_pipc_perm.pipc_mode; | |
1065 | perm._seq = 0; | |
1066 | perm._key = 0; | |
1067 | tok = au_to_ipc_perm(&perm); | |
1068 | kau_write(rec, tok); | |
1069 | } | |
1070 | break; | |
1071 | ||
1072 | case AUE_SEMOPEN: | |
1073 | tok = au_to_arg32(2, "flags", ar->ar_arg_fflags); | |
1074 | kau_write(rec, tok); | |
1075 | tok = au_to_arg32(3, "mode", ar->ar_arg_mode); | |
1076 | kau_write(rec, tok); | |
1077 | tok = au_to_arg32(4, "value", ar->ar_arg_value); | |
1078 | kau_write(rec, tok); | |
1079 | /* fall through */ | |
1080 | case AUE_SEMUNLINK: | |
1081 | if (ar->ar_valid_arg & ARG_TEXT) { | |
1082 | tok = au_to_text(ar->ar_arg_text); | |
1083 | kau_write(rec, tok); | |
1084 | } | |
1085 | if (ar->ar_valid_arg & ARG_POSIX_IPC_PERM) { | |
1086 | /* Create an ipc_perm token */ | |
1087 | struct ipc_perm perm; | |
1088 | perm.uid = ar->ar_arg_pipc_perm.pipc_uid; | |
1089 | perm.gid = ar->ar_arg_pipc_perm.pipc_gid; | |
1090 | perm.cuid = ar->ar_arg_pipc_perm.pipc_uid; | |
1091 | perm.cgid = ar->ar_arg_pipc_perm.pipc_gid; | |
1092 | perm.mode = ar->ar_arg_pipc_perm.pipc_mode; | |
1093 | perm._seq = 0; | |
1094 | perm._key = 0; | |
1095 | tok = au_to_ipc_perm(&perm); | |
1096 | kau_write(rec, tok); | |
1097 | } | |
1098 | break; | |
1099 | ||
1100 | case AUE_SEMCLOSE: | |
1101 | tok = au_to_arg32(1, "sem", ar->ar_arg_fd); | |
1102 | kau_write(rec, tok); | |
1103 | break; | |
1104 | ||
1105 | case AUE_SYMLINK: | |
1106 | if (ar->ar_valid_arg & ARG_TEXT) { | |
1107 | tok = au_to_text(ar->ar_arg_text); | |
1108 | kau_write(rec, tok); | |
1109 | } | |
1110 | UPATH1_KPATH1_VNODE1_TOKENS; | |
1111 | break; | |
1112 | ||
1113 | case AUE_SYSCTL: | |
1114 | case AUE_SYSCTL_NONADMIN: | |
1115 | if (ar->ar_valid_arg & (ARG_CTLNAME | ARG_LEN)) { | |
1116 | int ctr; | |
1117 | ||
1118 | for (ctr = 0; ctr < ar->ar_arg_len; ctr++) { | |
1119 | tok = au_to_arg32(1, "name", ar->ar_arg_ctlname[ctr]); | |
1120 | kau_write(rec, tok); | |
1121 | } | |
1122 | } | |
1123 | if (ar->ar_valid_arg & ARG_VALUE) { | |
1124 | tok = au_to_arg32(5, "newval", ar->ar_arg_value); | |
1125 | kau_write(rec, tok); | |
1126 | } | |
1127 | if (ar->ar_valid_arg & ARG_TEXT) { | |
1128 | tok = au_to_text(ar->ar_arg_text); | |
1129 | kau_write(rec, tok); | |
1130 | } | |
1131 | break; | |
1132 | ||
1133 | case AUE_UMASK: | |
1134 | tok = au_to_arg32(1, "new mask", ar->ar_arg_mask); | |
1135 | kau_write(rec, tok); | |
1136 | tok = au_to_arg32(0, "prev mask", ar->ar_retval); | |
1137 | kau_write(rec, tok); | |
1138 | break; | |
1139 | ||
1140 | /************************ | |
1141 | * Mach system calls * | |
1142 | ************************/ | |
1143 | case AUE_INITPROCESS: | |
1144 | break; | |
1145 | ||
1146 | case AUE_PIDFORTASK: | |
1147 | tok = au_to_arg32(1, "port", (u_int32_t)ar->ar_arg_mach_port1); | |
1148 | kau_write(rec, tok); | |
1149 | if (ar->ar_valid_arg & ARG_PID) { | |
1150 | tok = au_to_arg32(2, "pid", (u_int32_t)ar->ar_arg_pid); | |
1151 | kau_write(rec, tok); | |
1152 | } | |
1153 | break; | |
1154 | ||
1155 | case AUE_TASKFORPID: | |
1156 | tok = au_to_arg32(1, "target port", | |
1157 | (u_int32_t)ar->ar_arg_mach_port1); | |
1158 | kau_write(rec, tok); | |
1159 | if (ar->ar_valid_arg & ARG_MACHPORT2) { | |
1160 | tok = au_to_arg32(3, "task port", | |
1161 | (u_int32_t)ar->ar_arg_mach_port2); | |
1162 | kau_write(rec, tok); | |
1163 | } | |
1164 | PROCESS_PID_TOKENS(2); | |
1165 | break; | |
1166 | ||
1167 | case AUE_SWAPON: | |
1168 | tok = au_to_arg32(4, "priority", | |
1169 | (u_int32_t)ar->ar_arg_value); | |
1170 | kau_write(rec, tok); | |
1171 | UPATH1_KPATH1_VNODE1_TOKENS; | |
1172 | break; | |
1173 | ||
1174 | case AUE_SWAPOFF: | |
1175 | UPATH1_KPATH1_VNODE1_TOKENS; | |
1176 | break; | |
1177 | ||
1178 | case AUE_MAPFD: | |
1179 | tok = au_to_arg32(3, "va", (u_int32_t)ar->ar_arg_addr); | |
1180 | kau_write(rec, tok); | |
1181 | FD_KPATH1_VNODE1_TOKENS; | |
1182 | break; | |
1183 | ||
1184 | case AUE_EXTATTR_GET_FILE: | |
1185 | case AUE_EXTATTR_SET_FILE: | |
1186 | case AUE_EXTATTR_LIST_FILE: | |
1187 | case AUE_EXTATTR_DELETE_FILE: | |
1188 | case AUE_EXTATTR_GET_LINK: | |
1189 | case AUE_EXTATTR_SET_LINK: | |
1190 | case AUE_EXTATTR_LIST_LINK: | |
1191 | case AUE_EXTATTR_DELETE_LINK: | |
1192 | UPATH1_KPATH1_VNODE1_TOKENS; | |
1193 | break; | |
1194 | ||
1195 | #if CONFIG_MACF | |
1196 | case AUE_MAC_GET_FILE: | |
1197 | case AUE_MAC_SET_FILE: | |
1198 | case AUE_MAC_GET_LINK: | |
1199 | case AUE_MAC_SET_LINK: | |
1200 | case AUE_MAC_GET_MOUNT: | |
1201 | UPATH1_KPATH1_VNODE1_TOKENS; | |
1202 | PROCESS_MAC_TOKENS; | |
1203 | break; | |
1204 | ||
1205 | case AUE_MAC_GET_FD: | |
1206 | case AUE_MAC_SET_FD: | |
1207 | FD_KPATH1_VNODE1_TOKENS; | |
1208 | PROCESS_MAC_TOKENS; | |
1209 | break; | |
1210 | ||
1211 | case AUE_MAC_SYSCALL: | |
1212 | PROCESS_MAC_TOKENS; | |
1213 | tok = au_to_arg32(3, "call", ar->ar_arg_value); | |
1214 | kau_write(rec, tok); | |
1215 | break; | |
1216 | ||
1217 | case AUE_MAC_EXECVE: | |
1218 | UPATH1_KPATH1_VNODE1_TOKENS; | |
1219 | PROCESS_MAC_TOKENS; | |
1220 | break; | |
1221 | ||
1222 | case AUE_MAC_GET_PID: | |
1223 | tok = au_to_arg32(1, "pid", (u_int32_t)ar->ar_arg_pid); | |
1224 | kau_write(rec, tok); | |
1225 | PROCESS_MAC_TOKENS; | |
1226 | break; | |
1227 | ||
1228 | case AUE_MAC_GET_LCID: | |
1229 | tok = au_to_arg32(1, "lcid", (u_int32_t)ar->ar_arg_value); | |
1230 | kau_write(rec, tok); | |
1231 | PROCESS_MAC_TOKENS; | |
1232 | break; | |
1233 | ||
1234 | case AUE_MAC_GET_PROC: | |
1235 | case AUE_MAC_SET_PROC: | |
1236 | case AUE_MAC_GET_LCTX: | |
1237 | case AUE_MAC_SET_LCTX: | |
1238 | PROCESS_MAC_TOKENS; | |
1239 | break; | |
1240 | #endif | |
1241 | ||
1242 | default: /* We shouldn't fall through to here. */ | |
1243 | printf("BSM conversion requested for unknown event %d\n", | |
1244 | ar->ar_event); | |
1245 | kau_free(rec); | |
1246 | return BSM_NOAUDIT; | |
1247 | } | |
1248 | ||
1249 | #if CONFIG_MACF | |
1250 | do { | |
1251 | /* Convert the audit data from the MAC policies */ | |
1252 | struct mac_audit_record *mar; | |
1253 | ||
1254 | LIST_FOREACH(mar, ar->ar_mac_records, records) { | |
1255 | switch (mar->type) { | |
1256 | case MAC_AUDIT_DATA_TYPE: | |
1257 | tok = au_to_data(AUP_BINARY, AUR_BYTE, | |
1258 | mar->length, mar->data); | |
1259 | break; | |
1260 | case MAC_AUDIT_TEXT_TYPE: | |
1261 | tok = au_to_text((char*) mar->data); | |
1262 | break; | |
1263 | default: | |
1264 | /* | |
1265 | * XXX: we can either continue, | |
1266 | * skipping this particular entry, | |
1267 | * or we can pre-verify the list and | |
1268 | * abort before writing any records | |
1269 | */ | |
1270 | printf("kaudit_to_bsm(): BSM conversion requested for unknown mac_audit data type %d\n", | |
1271 | mar->type); | |
1272 | } | |
1273 | ||
1274 | kau_write(rec, tok); | |
1275 | } | |
1276 | } while (0); | |
1277 | #endif | |
1278 | ||
1279 | kau_write(rec, subj_tok); | |
1280 | ||
1281 | #if CONFIG_MACF | |
1282 | if (ar->ar_cred_mac_labels != NULL) { | |
1283 | tok = au_to_text(ar->ar_cred_mac_labels); | |
1284 | kau_write(rec, tok); | |
1285 | } | |
1286 | #endif | |
1287 | ||
1288 | tok = au_to_return32((char)ar->ar_errno, ar->ar_retval); | |
1289 | kau_write(rec, tok); /* Every record gets a return token */ | |
1290 | ||
1291 | kau_close(rec, &ar->ar_endtime, ar->ar_event); | |
1292 | ||
1293 | *pau = rec; | |
1294 | return BSM_SUCCESS; | |
1295 | } | |
1296 | ||
1297 | /* | |
1298 | * Verify that a record is a valid BSM record. This verification is | |
1299 | * simple now, but may be expanded on sometime in the future. | |
1300 | * Return 1 if the record is good, 0 otherwise. | |
1301 | * | |
1302 | */ | |
1303 | int | |
1304 | bsm_rec_verify(void* rec) | |
1305 | { | |
1306 | char c = *(char *)rec; | |
1307 | /* | |
1308 | * Check the token ID of the first token; it has to be a header | |
1309 | * token. | |
1310 | */ | |
1311 | /* XXXAUDIT There needs to be a token structure to map a token. | |
1312 | * XXXAUDIT 'Shouldn't be simply looking at the first char. | |
1313 | */ | |
1314 | if ( (c != AU_HEADER_32_TOKEN) && | |
1315 | (c != AU_HEADER_EX_32_TOKEN) && | |
1316 | (c != AU_HEADER_64_TOKEN) && | |
1317 | (c != AU_HEADER_EX_64_TOKEN) ) { | |
1318 | return (0); | |
1319 | } | |
1320 | return (1); | |
1321 | } |