Deleted Added
full compact
bsm_token.c (191270) bsm_token.c (195740)
1/*-
2 * Copyright (c) 2004-2009 Apple Inc.
3 * Copyright (c) 2005 SPARTA, Inc.
4 * All rights reserved.
5 *
6 * This code was developed in part by Robert N. M. Watson, Senior Principal
7 * Scientist, SPARTA, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
1/*-
2 * Copyright (c) 2004-2009 Apple Inc.
3 * Copyright (c) 2005 SPARTA, Inc.
4 * All rights reserved.
5 *
6 * This code was developed in part by Robert N. M. Watson, Senior Principal
7 * Scientist, SPARTA, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#91
33 * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#93
34 */
35
36#include <sys/cdefs.h>
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: head/sys/security/audit/audit_bsm_token.c 191270 2009-04-19 14:53:17Z rwatson $");
37__FBSDID("$FreeBSD: head/sys/security/audit/audit_bsm_token.c 195740 2009-07-17 14:02:20Z rwatson $");
38
39#include <sys/types.h>
40#include <sys/endian.h>
41#include <sys/queue.h>
42#include <sys/socket.h>
43#include <sys/time.h>
44
45#include <sys/ipc.h>
46#include <sys/libkern.h>
47#include <sys/malloc.h>
48#include <sys/un.h>
49
50#include <netinet/in.h>
51#include <netinet/in_systm.h>
52#include <netinet/ip.h>
53
54
55#include <bsm/audit.h>
56#include <bsm/audit_internal.h>
57#include <bsm/audit_record.h>
58#include <security/audit/audit.h>
59#include <security/audit/audit_private.h>
60
61#define GET_TOKEN_AREA(t, dptr, length) do { \
62 t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK); \
63 t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO); \
64 t->len = length; \
65 dptr = t->t_data; \
66} while (0)
67
68/*
69 * token ID 1 byte
70 * argument # 1 byte
71 * argument value 4 bytes/8 bytes (32-bit/64-bit value)
72 * text length 2 bytes
73 * text N bytes + 1 terminating NULL byte
74 */
75token_t *
76au_to_arg32(char n, const char *text, u_int32_t v)
77{
78 token_t *t;
79 u_char *dptr = NULL;
80 u_int16_t textlen;
81
82 textlen = strlen(text);
83 textlen += 1;
84
85 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
86 sizeof(u_int16_t) + textlen);
87
88 ADD_U_CHAR(dptr, AUT_ARG32);
89 ADD_U_CHAR(dptr, n);
90 ADD_U_INT32(dptr, v);
91 ADD_U_INT16(dptr, textlen);
92 ADD_STRING(dptr, text, textlen);
93
94 return (t);
95}
96
97token_t *
98au_to_arg64(char n, const char *text, u_int64_t v)
99{
100 token_t *t;
101 u_char *dptr = NULL;
102 u_int16_t textlen;
103
104 textlen = strlen(text);
105 textlen += 1;
106
107 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
108 sizeof(u_int16_t) + textlen);
109
110 ADD_U_CHAR(dptr, AUT_ARG64);
111 ADD_U_CHAR(dptr, n);
112 ADD_U_INT64(dptr, v);
113 ADD_U_INT16(dptr, textlen);
114 ADD_STRING(dptr, text, textlen);
115
116 return (t);
117}
118
119token_t *
120au_to_arg(char n, const char *text, u_int32_t v)
121{
122
123 return (au_to_arg32(n, text, v));
124}
125
126#if defined(_KERNEL) || defined(KERNEL)
127/*
128 * token ID 1 byte
129 * file access mode 4 bytes
130 * owner user ID 4 bytes
131 * owner group ID 4 bytes
132 * file system ID 4 bytes
133 * node ID 8 bytes
134 * device 4 bytes/8 bytes (32-bit/64-bit)
135 */
136token_t *
137au_to_attr32(struct vnode_au_info *vni)
138{
139 token_t *t;
140 u_char *dptr = NULL;
141 u_int16_t pad0_16 = 0;
142 u_int32_t pad0_32 = 0;
143
144 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
145 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
146
147 ADD_U_CHAR(dptr, AUT_ATTR32);
148
149 /*
150 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
151 * so pad with 0.
152 *
153 * XXXRW: Possibly should be conditionally compiled.
154 *
155 * XXXRW: Should any conversions take place on the mode?
156 */
157 ADD_U_INT16(dptr, pad0_16);
158 ADD_U_INT16(dptr, vni->vn_mode);
159
160 ADD_U_INT32(dptr, vni->vn_uid);
161 ADD_U_INT32(dptr, vni->vn_gid);
162 ADD_U_INT32(dptr, vni->vn_fsid);
163
164 /*
165 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
166 * Attempt to handle both, and let the compiler sort it out. If we
167 * could pick this out at compile-time, it would be better, so as to
168 * avoid the else case below.
169 */
170 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
171 ADD_U_INT32(dptr, pad0_32);
172 ADD_U_INT32(dptr, vni->vn_fileid);
173 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
174 ADD_U_INT64(dptr, vni->vn_fileid);
175 else
176 ADD_U_INT64(dptr, 0LL);
177
178 ADD_U_INT32(dptr, vni->vn_dev);
179
180 return (t);
181}
182
183token_t *
184au_to_attr64(struct vnode_au_info *vni)
185{
186 token_t *t;
187 u_char *dptr = NULL;
188 u_int16_t pad0_16 = 0;
189 u_int32_t pad0_32 = 0;
190
191 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
192 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
193
194 ADD_U_CHAR(dptr, AUT_ATTR64);
195
196 /*
197 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
198 * so pad with 0.
199 *
200 * XXXRW: Possibly should be conditionally compiled.
201 *
202 * XXXRW: Should any conversions take place on the mode?
203 */
204 ADD_U_INT16(dptr, pad0_16);
205 ADD_U_INT16(dptr, vni->vn_mode);
206
207 ADD_U_INT32(dptr, vni->vn_uid);
208 ADD_U_INT32(dptr, vni->vn_gid);
209 ADD_U_INT32(dptr, vni->vn_fsid);
210
211 /*
212 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
213 * Attempt to handle both, and let the compiler sort it out. If we
214 * could pick this out at compile-time, it would be better, so as to
215 * avoid the else case below.
216 */
217 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
218 ADD_U_INT32(dptr, pad0_32);
219 ADD_U_INT32(dptr, vni->vn_fileid);
220 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
221 ADD_U_INT64(dptr, vni->vn_fileid);
222 else
223 ADD_U_INT64(dptr, 0LL);
224
225 ADD_U_INT64(dptr, vni->vn_dev);
226
227 return (t);
228}
229
230token_t *
231au_to_attr(struct vnode_au_info *vni)
232{
233
234 return (au_to_attr32(vni));
235}
236#endif /* !(defined(_KERNEL) || defined(KERNEL) */
237
238/*
239 * token ID 1 byte
240 * how to print 1 byte
241 * basic unit 1 byte
242 * unit count 1 byte
243 * data items (depends on basic unit)
244 */
245token_t *
246au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
247{
248 token_t *t;
249 u_char *dptr = NULL;
250 size_t datasize, totdata;
251
252 /* Determine the size of the basic unit. */
253 switch (unit_type) {
254 case AUR_BYTE:
255 /* case AUR_CHAR: */
256 datasize = AUR_BYTE_SIZE;
257 break;
258
259 case AUR_SHORT:
260 datasize = AUR_SHORT_SIZE;
261 break;
262
263 case AUR_INT32:
264 /* case AUR_INT: */
265 datasize = AUR_INT32_SIZE;
266 break;
267
268 case AUR_INT64:
269 datasize = AUR_INT64_SIZE;
270 break;
271
272 default:
273 return (NULL);
274 }
275
276 totdata = datasize * unit_count;
277
278 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
279
280 /*
281 * XXXRW: We should be byte-swapping each data item for multi-byte
282 * types.
283 */
284 ADD_U_CHAR(dptr, AUT_DATA);
285 ADD_U_CHAR(dptr, unit_print);
286 ADD_U_CHAR(dptr, unit_type);
287 ADD_U_CHAR(dptr, unit_count);
288 ADD_MEM(dptr, p, totdata);
289
290 return (t);
291}
292
293
294/*
295 * token ID 1 byte
296 * status 4 bytes
297 * return value 4 bytes
298 */
299token_t *
300au_to_exit(int retval, int err)
301{
302 token_t *t;
303 u_char *dptr = NULL;
304
305 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
306
307 ADD_U_CHAR(dptr, AUT_EXIT);
308 ADD_U_INT32(dptr, err);
309 ADD_U_INT32(dptr, retval);
310
311 return (t);
312}
313
314/*
315 */
316token_t *
317au_to_groups(int *groups)
318{
319
320 return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
321}
322
323/*
324 * token ID 1 byte
325 * number groups 2 bytes
326 * group list count * 4 bytes
327 */
328token_t *
329au_to_newgroups(u_int16_t n, gid_t *groups)
330{
331 token_t *t;
332 u_char *dptr = NULL;
333 int i;
334
335 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
336 n * sizeof(u_int32_t));
337
338 ADD_U_CHAR(dptr, AUT_NEWGROUPS);
339 ADD_U_INT16(dptr, n);
340 for (i = 0; i < n; i++)
341 ADD_U_INT32(dptr, groups[i]);
342
343 return (t);
344}
345
346/*
347 * token ID 1 byte
348 * internet address 4 bytes
349 */
350token_t *
351au_to_in_addr(struct in_addr *internet_addr)
352{
353 token_t *t;
354 u_char *dptr = NULL;
355
356 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
357
358 ADD_U_CHAR(dptr, AUT_IN_ADDR);
359 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
360
361 return (t);
362}
363
364/*
365 * token ID 1 byte
366 * address type/length 4 bytes
367 * address 16 bytes
368 */
369token_t *
370au_to_in_addr_ex(struct in6_addr *internet_addr)
371{
372 token_t *t;
373 u_char *dptr = NULL;
374 u_int32_t type = AU_IPv6;
375
376 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
377
378 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
379 ADD_U_INT32(dptr, type);
380 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
381
382 return (t);
383}
384
385/*
386 * token ID 1 byte
387 * ip header 20 bytes
388 *
389 * The IP header should be submitted in network byte order.
390 */
391token_t *
392au_to_ip(struct ip *ip)
393{
394 token_t *t;
395 u_char *dptr = NULL;
396
397 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
398
399 ADD_U_CHAR(dptr, AUT_IP);
400 ADD_MEM(dptr, ip, sizeof(struct ip));
401
402 return (t);
403}
404
405/*
406 * token ID 1 byte
407 * object ID type 1 byte
408 * object ID 4 bytes
409 */
410token_t *
411au_to_ipc(char type, int id)
412{
413 token_t *t;
414 u_char *dptr = NULL;
415
416 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
417
418 ADD_U_CHAR(dptr, AUT_IPC);
419 ADD_U_CHAR(dptr, type);
420 ADD_U_INT32(dptr, id);
421
422 return (t);
423}
424
425/*
426 * token ID 1 byte
427 * owner user ID 4 bytes
428 * owner group ID 4 bytes
429 * creator user ID 4 bytes
430 * creator group ID 4 bytes
431 * access mode 4 bytes
432 * slot sequence # 4 bytes
433 * key 4 bytes
434 */
435token_t *
436au_to_ipc_perm(struct ipc_perm *perm)
437{
438 token_t *t;
439 u_char *dptr = NULL;
440 u_int16_t pad0 = 0;
441
442 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
443 sizeof(u_int32_t));
444
445 ADD_U_CHAR(dptr, AUT_IPC_PERM);
446
447 /*
448 * Systems vary significantly in what types they use in struct
449 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
450 * allow for that, as BSM define 32-bit values here.
451 * Some systems define the sizes for ipc_perm members as 2 bytes;
452 * BSM defines 4 so pad with 0.
453 *
454 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
455 * need to be handled.
456 */
457 if (sizeof(perm->uid) != sizeof(u_int32_t)) {
458 ADD_U_INT16(dptr, pad0);
459 ADD_U_INT16(dptr, perm->uid);
460 ADD_U_INT16(dptr, pad0);
461 ADD_U_INT16(dptr, perm->gid);
462 ADD_U_INT16(dptr, pad0);
463 ADD_U_INT16(dptr, perm->cuid);
464 ADD_U_INT16(dptr, pad0);
465 ADD_U_INT16(dptr, perm->cgid);
466 } else {
467 ADD_U_INT32(dptr, perm->uid);
468 ADD_U_INT32(dptr, perm->gid);
469 ADD_U_INT32(dptr, perm->cuid);
470 ADD_U_INT32(dptr, perm->cgid);
471 }
472
473 ADD_U_INT16(dptr, pad0);
474 ADD_U_INT16(dptr, perm->mode);
475
476 ADD_U_INT16(dptr, pad0);
477
478 ADD_U_INT16(dptr, perm->seq);
479
480 ADD_U_INT32(dptr, perm->key);
481
482 return (t);
483}
484
485/*
486 * token ID 1 byte
487 * port IP address 2 bytes
488 */
489token_t *
490au_to_iport(u_int16_t iport)
491{
492 token_t *t;
493 u_char *dptr = NULL;
494
495 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
496
497 ADD_U_CHAR(dptr, AUT_IPORT);
498 ADD_U_INT16(dptr, iport);
499
500 return (t);
501}
502
503/*
504 * token ID 1 byte
505 * size 2 bytes
506 * data size bytes
507 */
508token_t *
509au_to_opaque(const char *data, u_int16_t bytes)
510{
511 token_t *t;
512 u_char *dptr = NULL;
513
514 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
515
516 ADD_U_CHAR(dptr, AUT_OPAQUE);
517 ADD_U_INT16(dptr, bytes);
518 ADD_MEM(dptr, data, bytes);
519
520 return (t);
521}
522
523/*
524 * token ID 1 byte
525 * seconds of time 4 bytes
526 * milliseconds of time 4 bytes
527 * file name len 2 bytes
528 * file pathname N bytes + 1 terminating NULL byte
529 */
530token_t *
531au_to_file(const char *file, struct timeval tm)
532{
533 token_t *t;
534 u_char *dptr = NULL;
535 u_int16_t filelen;
536 u_int32_t timems;
537
538 filelen = strlen(file);
539 filelen += 1;
540
541 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
542 sizeof(u_int16_t) + filelen);
543
544 timems = tm.tv_usec/1000;
545
546 ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
547 ADD_U_INT32(dptr, tm.tv_sec);
548 ADD_U_INT32(dptr, timems); /* We need time in ms. */
549 ADD_U_INT16(dptr, filelen);
550 ADD_STRING(dptr, file, filelen);
551
552 return (t);
553}
554
555/*
556 * token ID 1 byte
557 * text length 2 bytes
558 * text N bytes + 1 terminating NULL byte
559 */
560token_t *
561au_to_text(const char *text)
562{
563 token_t *t;
564 u_char *dptr = NULL;
565 u_int16_t textlen;
566
567 textlen = strlen(text);
568 textlen += 1;
569
570 /* XXXRW: Should validate length against token size limit. */
571
572 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
573
574 ADD_U_CHAR(dptr, AUT_TEXT);
575 ADD_U_INT16(dptr, textlen);
576 ADD_STRING(dptr, text, textlen);
577
578 return (t);
579}
580
581/*
582 * token ID 1 byte
583 * path length 2 bytes
584 * path N bytes + 1 terminating NULL byte
585 */
586token_t *
587au_to_path(const char *text)
588{
589 token_t *t;
590 u_char *dptr = NULL;
591 u_int16_t textlen;
592
593 textlen = strlen(text);
594 textlen += 1;
595
596 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
597
598 ADD_U_CHAR(dptr, AUT_PATH);
599 ADD_U_INT16(dptr, textlen);
600 ADD_STRING(dptr, text, textlen);
601
602 return (t);
603}
604
605/*
606 * token ID 1 byte
607 * audit ID 4 bytes
608 * effective user ID 4 bytes
609 * effective group ID 4 bytes
610 * real user ID 4 bytes
611 * real group ID 4 bytes
612 * process ID 4 bytes
613 * session ID 4 bytes
614 * terminal ID
615 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
616 * machine address 4 bytes
617 */
618token_t *
619au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
620 pid_t pid, au_asid_t sid, au_tid_t *tid)
621{
622 token_t *t;
623 u_char *dptr = NULL;
624
625 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
626
627 ADD_U_CHAR(dptr, AUT_PROCESS32);
628 ADD_U_INT32(dptr, auid);
629 ADD_U_INT32(dptr, euid);
630 ADD_U_INT32(dptr, egid);
631 ADD_U_INT32(dptr, ruid);
632 ADD_U_INT32(dptr, rgid);
633 ADD_U_INT32(dptr, pid);
634 ADD_U_INT32(dptr, sid);
635 ADD_U_INT32(dptr, tid->port);
636
637 /*
638 * Note: Solaris will write out IPv6 addresses here as a 32-bit
639 * address type and 16 bytes of address, but for IPv4 addresses it
640 * simply writes the 4-byte address directly. We support only IPv4
641 * addresses for process32 tokens.
642 */
643 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
644
645 return (t);
646}
647
648token_t *
649au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
650 pid_t pid, au_asid_t sid, au_tid_t *tid)
651{
652 token_t *t;
653 u_char *dptr = NULL;
654
655 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
656 sizeof(u_int64_t));
657
658 ADD_U_CHAR(dptr, AUT_PROCESS64);
659 ADD_U_INT32(dptr, auid);
660 ADD_U_INT32(dptr, euid);
661 ADD_U_INT32(dptr, egid);
662 ADD_U_INT32(dptr, ruid);
663 ADD_U_INT32(dptr, rgid);
664 ADD_U_INT32(dptr, pid);
665 ADD_U_INT32(dptr, sid);
666 ADD_U_INT64(dptr, tid->port);
667
668 /*
669 * Note: Solaris will write out IPv6 addresses here as a 32-bit
670 * address type and 16 bytes of address, but for IPv4 addresses it
671 * simply writes the 4-byte address directly. We support only IPv4
672 * addresses for process64 tokens.
673 */
674 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
675
676 return (t);
677}
678
679token_t *
680au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
681 pid_t pid, au_asid_t sid, au_tid_t *tid)
682{
683
684 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
685 tid));
686}
687
688/*
689 * token ID 1 byte
690 * audit ID 4 bytes
691 * effective user ID 4 bytes
692 * effective group ID 4 bytes
693 * real user ID 4 bytes
694 * real group ID 4 bytes
695 * process ID 4 bytes
696 * session ID 4 bytes
697 * terminal ID
698 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
699 * address type-len 4 bytes
700 * machine address 16 bytes
701 */
702token_t *
703au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
704 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
705{
706 token_t *t;
707 u_char *dptr = NULL;
708
709 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
710 ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
711 if (tid->at_type == AU_IPv4)
712 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
713 10 * sizeof(u_int32_t));
714 else
715 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
716 13 * sizeof(u_int32_t));
717
718 ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
719 ADD_U_INT32(dptr, auid);
720 ADD_U_INT32(dptr, euid);
721 ADD_U_INT32(dptr, egid);
722 ADD_U_INT32(dptr, ruid);
723 ADD_U_INT32(dptr, rgid);
724 ADD_U_INT32(dptr, pid);
725 ADD_U_INT32(dptr, sid);
726 ADD_U_INT32(dptr, tid->at_port);
727 ADD_U_INT32(dptr, tid->at_type);
728 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
729 if (tid->at_type == AU_IPv6) {
730 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
731 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
732 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
733 }
734
735 return (t);
736}
737
738token_t *
739au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
740 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
741{
742 token_t *t;
743 u_char *dptr = NULL;
744
745 if (tid->at_type == AU_IPv4)
746 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
747 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
748 2 * sizeof(u_int32_t));
749 else if (tid->at_type == AU_IPv6)
750 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
751 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
752 5 * sizeof(u_int32_t));
753 else
754 panic("au_to_process64_ex: invalidate at_type (%d)",
755 tid->at_type);
756
757 ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
758 ADD_U_INT32(dptr, auid);
759 ADD_U_INT32(dptr, euid);
760 ADD_U_INT32(dptr, egid);
761 ADD_U_INT32(dptr, ruid);
762 ADD_U_INT32(dptr, rgid);
763 ADD_U_INT32(dptr, pid);
764 ADD_U_INT32(dptr, sid);
765 ADD_U_INT64(dptr, tid->at_port);
766 ADD_U_INT32(dptr, tid->at_type);
767 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
768 if (tid->at_type == AU_IPv6) {
769 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
770 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
771 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
772 }
773
774 return (t);
775}
776
777token_t *
778au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
779 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
780{
781
782 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
783 tid));
784}
785
786/*
787 * token ID 1 byte
788 * error status 1 byte
789 * return value 4 bytes/8 bytes (32-bit/64-bit value)
790 */
791token_t *
792au_to_return32(char status, u_int32_t ret)
793{
794 token_t *t;
795 u_char *dptr = NULL;
796
797 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
798
799 ADD_U_CHAR(dptr, AUT_RETURN32);
800 ADD_U_CHAR(dptr, status);
801 ADD_U_INT32(dptr, ret);
802
803 return (t);
804}
805
806token_t *
807au_to_return64(char status, u_int64_t ret)
808{
809 token_t *t;
810 u_char *dptr = NULL;
811
812 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
813
814 ADD_U_CHAR(dptr, AUT_RETURN64);
815 ADD_U_CHAR(dptr, status);
816 ADD_U_INT64(dptr, ret);
817
818 return (t);
819}
820
821token_t *
822au_to_return(char status, u_int32_t ret)
823{
824
825 return (au_to_return32(status, ret));
826}
827
828/*
829 * token ID 1 byte
830 * sequence number 4 bytes
831 */
832token_t *
833au_to_seq(long audit_count)
834{
835 token_t *t;
836 u_char *dptr = NULL;
837
838 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
839
840 ADD_U_CHAR(dptr, AUT_SEQ);
841 ADD_U_INT32(dptr, audit_count);
842
843 return (t);
844}
845
846/*
847 * token ID 1 byte
848 * socket domain 2 bytes
849 * socket type 2 bytes
850 * address type 2 byte
851 * local port 2 bytes
852 * local address 4 bytes/16 bytes (IPv4/IPv6 address)
853 * remote port 2 bytes
854 * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
855 *
856 * Domain and type arguments to this routine are assumed to already have been
857 * converted to the BSM constant space, so we don't do that here.
858 */
859token_t *
860au_to_socket_ex(u_short so_domain, u_short so_type,
861 struct sockaddr *sa_local, struct sockaddr *sa_remote)
862{
863 token_t *t;
864 u_char *dptr = NULL;
865 struct sockaddr_in *sin;
866 struct sockaddr_in6 *sin6;
867
868 if (so_domain == AF_INET)
869 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
870 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
871 else if (so_domain == AF_INET6)
872 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
873 5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
874 else
875 return (NULL);
876
877 ADD_U_CHAR(dptr, AUT_SOCKET_EX);
878 ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
879 ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
880 if (so_domain == AF_INET) {
881 ADD_U_INT16(dptr, AU_IPv4);
882 sin = (struct sockaddr_in *)sa_local;
883 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
884 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
885 sin = (struct sockaddr_in *)sa_remote;
886 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
887 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
888 } else {
889 ADD_U_INT16(dptr, AU_IPv6);
890 sin6 = (struct sockaddr_in6 *)sa_local;
891 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
892 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
893 sin6 = (struct sockaddr_in6 *)sa_remote;
894 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
895 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
896 }
897
898 return (t);
899}
900
901/*
902 * Kernel-specific version of the above function.
903 *
904 * XXXRW: Should now use au_to_socket_ex() here.
905 */
906#ifdef _KERNEL
907token_t *
908kau_to_socket(struct socket_au_info *soi)
909{
910 token_t *t;
911 u_char *dptr;
912 u_int16_t so_type;
913
914 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
915 sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
916
917 ADD_U_CHAR(dptr, AUT_SOCKET);
918 /* Coerce the socket type into a short value */
919 so_type = soi->so_type;
920 ADD_U_INT16(dptr, so_type);
921 ADD_U_INT16(dptr, soi->so_lport);
922 ADD_U_INT32(dptr, soi->so_laddr);
923 ADD_U_INT16(dptr, soi->so_rport);
924 ADD_U_INT32(dptr, soi->so_raddr);
925
926 return (t);
927}
928#endif
929
930/*
931 * token ID 1 byte
932 * socket family 2 bytes
38
39#include <sys/types.h>
40#include <sys/endian.h>
41#include <sys/queue.h>
42#include <sys/socket.h>
43#include <sys/time.h>
44
45#include <sys/ipc.h>
46#include <sys/libkern.h>
47#include <sys/malloc.h>
48#include <sys/un.h>
49
50#include <netinet/in.h>
51#include <netinet/in_systm.h>
52#include <netinet/ip.h>
53
54
55#include <bsm/audit.h>
56#include <bsm/audit_internal.h>
57#include <bsm/audit_record.h>
58#include <security/audit/audit.h>
59#include <security/audit/audit_private.h>
60
61#define GET_TOKEN_AREA(t, dptr, length) do { \
62 t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK); \
63 t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO); \
64 t->len = length; \
65 dptr = t->t_data; \
66} while (0)
67
68/*
69 * token ID 1 byte
70 * argument # 1 byte
71 * argument value 4 bytes/8 bytes (32-bit/64-bit value)
72 * text length 2 bytes
73 * text N bytes + 1 terminating NULL byte
74 */
75token_t *
76au_to_arg32(char n, const char *text, u_int32_t v)
77{
78 token_t *t;
79 u_char *dptr = NULL;
80 u_int16_t textlen;
81
82 textlen = strlen(text);
83 textlen += 1;
84
85 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
86 sizeof(u_int16_t) + textlen);
87
88 ADD_U_CHAR(dptr, AUT_ARG32);
89 ADD_U_CHAR(dptr, n);
90 ADD_U_INT32(dptr, v);
91 ADD_U_INT16(dptr, textlen);
92 ADD_STRING(dptr, text, textlen);
93
94 return (t);
95}
96
97token_t *
98au_to_arg64(char n, const char *text, u_int64_t v)
99{
100 token_t *t;
101 u_char *dptr = NULL;
102 u_int16_t textlen;
103
104 textlen = strlen(text);
105 textlen += 1;
106
107 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
108 sizeof(u_int16_t) + textlen);
109
110 ADD_U_CHAR(dptr, AUT_ARG64);
111 ADD_U_CHAR(dptr, n);
112 ADD_U_INT64(dptr, v);
113 ADD_U_INT16(dptr, textlen);
114 ADD_STRING(dptr, text, textlen);
115
116 return (t);
117}
118
119token_t *
120au_to_arg(char n, const char *text, u_int32_t v)
121{
122
123 return (au_to_arg32(n, text, v));
124}
125
126#if defined(_KERNEL) || defined(KERNEL)
127/*
128 * token ID 1 byte
129 * file access mode 4 bytes
130 * owner user ID 4 bytes
131 * owner group ID 4 bytes
132 * file system ID 4 bytes
133 * node ID 8 bytes
134 * device 4 bytes/8 bytes (32-bit/64-bit)
135 */
136token_t *
137au_to_attr32(struct vnode_au_info *vni)
138{
139 token_t *t;
140 u_char *dptr = NULL;
141 u_int16_t pad0_16 = 0;
142 u_int32_t pad0_32 = 0;
143
144 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
145 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
146
147 ADD_U_CHAR(dptr, AUT_ATTR32);
148
149 /*
150 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
151 * so pad with 0.
152 *
153 * XXXRW: Possibly should be conditionally compiled.
154 *
155 * XXXRW: Should any conversions take place on the mode?
156 */
157 ADD_U_INT16(dptr, pad0_16);
158 ADD_U_INT16(dptr, vni->vn_mode);
159
160 ADD_U_INT32(dptr, vni->vn_uid);
161 ADD_U_INT32(dptr, vni->vn_gid);
162 ADD_U_INT32(dptr, vni->vn_fsid);
163
164 /*
165 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
166 * Attempt to handle both, and let the compiler sort it out. If we
167 * could pick this out at compile-time, it would be better, so as to
168 * avoid the else case below.
169 */
170 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
171 ADD_U_INT32(dptr, pad0_32);
172 ADD_U_INT32(dptr, vni->vn_fileid);
173 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
174 ADD_U_INT64(dptr, vni->vn_fileid);
175 else
176 ADD_U_INT64(dptr, 0LL);
177
178 ADD_U_INT32(dptr, vni->vn_dev);
179
180 return (t);
181}
182
183token_t *
184au_to_attr64(struct vnode_au_info *vni)
185{
186 token_t *t;
187 u_char *dptr = NULL;
188 u_int16_t pad0_16 = 0;
189 u_int32_t pad0_32 = 0;
190
191 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
192 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
193
194 ADD_U_CHAR(dptr, AUT_ATTR64);
195
196 /*
197 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
198 * so pad with 0.
199 *
200 * XXXRW: Possibly should be conditionally compiled.
201 *
202 * XXXRW: Should any conversions take place on the mode?
203 */
204 ADD_U_INT16(dptr, pad0_16);
205 ADD_U_INT16(dptr, vni->vn_mode);
206
207 ADD_U_INT32(dptr, vni->vn_uid);
208 ADD_U_INT32(dptr, vni->vn_gid);
209 ADD_U_INT32(dptr, vni->vn_fsid);
210
211 /*
212 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
213 * Attempt to handle both, and let the compiler sort it out. If we
214 * could pick this out at compile-time, it would be better, so as to
215 * avoid the else case below.
216 */
217 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
218 ADD_U_INT32(dptr, pad0_32);
219 ADD_U_INT32(dptr, vni->vn_fileid);
220 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
221 ADD_U_INT64(dptr, vni->vn_fileid);
222 else
223 ADD_U_INT64(dptr, 0LL);
224
225 ADD_U_INT64(dptr, vni->vn_dev);
226
227 return (t);
228}
229
230token_t *
231au_to_attr(struct vnode_au_info *vni)
232{
233
234 return (au_to_attr32(vni));
235}
236#endif /* !(defined(_KERNEL) || defined(KERNEL) */
237
238/*
239 * token ID 1 byte
240 * how to print 1 byte
241 * basic unit 1 byte
242 * unit count 1 byte
243 * data items (depends on basic unit)
244 */
245token_t *
246au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
247{
248 token_t *t;
249 u_char *dptr = NULL;
250 size_t datasize, totdata;
251
252 /* Determine the size of the basic unit. */
253 switch (unit_type) {
254 case AUR_BYTE:
255 /* case AUR_CHAR: */
256 datasize = AUR_BYTE_SIZE;
257 break;
258
259 case AUR_SHORT:
260 datasize = AUR_SHORT_SIZE;
261 break;
262
263 case AUR_INT32:
264 /* case AUR_INT: */
265 datasize = AUR_INT32_SIZE;
266 break;
267
268 case AUR_INT64:
269 datasize = AUR_INT64_SIZE;
270 break;
271
272 default:
273 return (NULL);
274 }
275
276 totdata = datasize * unit_count;
277
278 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
279
280 /*
281 * XXXRW: We should be byte-swapping each data item for multi-byte
282 * types.
283 */
284 ADD_U_CHAR(dptr, AUT_DATA);
285 ADD_U_CHAR(dptr, unit_print);
286 ADD_U_CHAR(dptr, unit_type);
287 ADD_U_CHAR(dptr, unit_count);
288 ADD_MEM(dptr, p, totdata);
289
290 return (t);
291}
292
293
294/*
295 * token ID 1 byte
296 * status 4 bytes
297 * return value 4 bytes
298 */
299token_t *
300au_to_exit(int retval, int err)
301{
302 token_t *t;
303 u_char *dptr = NULL;
304
305 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
306
307 ADD_U_CHAR(dptr, AUT_EXIT);
308 ADD_U_INT32(dptr, err);
309 ADD_U_INT32(dptr, retval);
310
311 return (t);
312}
313
314/*
315 */
316token_t *
317au_to_groups(int *groups)
318{
319
320 return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
321}
322
323/*
324 * token ID 1 byte
325 * number groups 2 bytes
326 * group list count * 4 bytes
327 */
328token_t *
329au_to_newgroups(u_int16_t n, gid_t *groups)
330{
331 token_t *t;
332 u_char *dptr = NULL;
333 int i;
334
335 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
336 n * sizeof(u_int32_t));
337
338 ADD_U_CHAR(dptr, AUT_NEWGROUPS);
339 ADD_U_INT16(dptr, n);
340 for (i = 0; i < n; i++)
341 ADD_U_INT32(dptr, groups[i]);
342
343 return (t);
344}
345
346/*
347 * token ID 1 byte
348 * internet address 4 bytes
349 */
350token_t *
351au_to_in_addr(struct in_addr *internet_addr)
352{
353 token_t *t;
354 u_char *dptr = NULL;
355
356 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
357
358 ADD_U_CHAR(dptr, AUT_IN_ADDR);
359 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
360
361 return (t);
362}
363
364/*
365 * token ID 1 byte
366 * address type/length 4 bytes
367 * address 16 bytes
368 */
369token_t *
370au_to_in_addr_ex(struct in6_addr *internet_addr)
371{
372 token_t *t;
373 u_char *dptr = NULL;
374 u_int32_t type = AU_IPv6;
375
376 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
377
378 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
379 ADD_U_INT32(dptr, type);
380 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
381
382 return (t);
383}
384
385/*
386 * token ID 1 byte
387 * ip header 20 bytes
388 *
389 * The IP header should be submitted in network byte order.
390 */
391token_t *
392au_to_ip(struct ip *ip)
393{
394 token_t *t;
395 u_char *dptr = NULL;
396
397 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
398
399 ADD_U_CHAR(dptr, AUT_IP);
400 ADD_MEM(dptr, ip, sizeof(struct ip));
401
402 return (t);
403}
404
405/*
406 * token ID 1 byte
407 * object ID type 1 byte
408 * object ID 4 bytes
409 */
410token_t *
411au_to_ipc(char type, int id)
412{
413 token_t *t;
414 u_char *dptr = NULL;
415
416 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
417
418 ADD_U_CHAR(dptr, AUT_IPC);
419 ADD_U_CHAR(dptr, type);
420 ADD_U_INT32(dptr, id);
421
422 return (t);
423}
424
425/*
426 * token ID 1 byte
427 * owner user ID 4 bytes
428 * owner group ID 4 bytes
429 * creator user ID 4 bytes
430 * creator group ID 4 bytes
431 * access mode 4 bytes
432 * slot sequence # 4 bytes
433 * key 4 bytes
434 */
435token_t *
436au_to_ipc_perm(struct ipc_perm *perm)
437{
438 token_t *t;
439 u_char *dptr = NULL;
440 u_int16_t pad0 = 0;
441
442 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
443 sizeof(u_int32_t));
444
445 ADD_U_CHAR(dptr, AUT_IPC_PERM);
446
447 /*
448 * Systems vary significantly in what types they use in struct
449 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
450 * allow for that, as BSM define 32-bit values here.
451 * Some systems define the sizes for ipc_perm members as 2 bytes;
452 * BSM defines 4 so pad with 0.
453 *
454 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
455 * need to be handled.
456 */
457 if (sizeof(perm->uid) != sizeof(u_int32_t)) {
458 ADD_U_INT16(dptr, pad0);
459 ADD_U_INT16(dptr, perm->uid);
460 ADD_U_INT16(dptr, pad0);
461 ADD_U_INT16(dptr, perm->gid);
462 ADD_U_INT16(dptr, pad0);
463 ADD_U_INT16(dptr, perm->cuid);
464 ADD_U_INT16(dptr, pad0);
465 ADD_U_INT16(dptr, perm->cgid);
466 } else {
467 ADD_U_INT32(dptr, perm->uid);
468 ADD_U_INT32(dptr, perm->gid);
469 ADD_U_INT32(dptr, perm->cuid);
470 ADD_U_INT32(dptr, perm->cgid);
471 }
472
473 ADD_U_INT16(dptr, pad0);
474 ADD_U_INT16(dptr, perm->mode);
475
476 ADD_U_INT16(dptr, pad0);
477
478 ADD_U_INT16(dptr, perm->seq);
479
480 ADD_U_INT32(dptr, perm->key);
481
482 return (t);
483}
484
485/*
486 * token ID 1 byte
487 * port IP address 2 bytes
488 */
489token_t *
490au_to_iport(u_int16_t iport)
491{
492 token_t *t;
493 u_char *dptr = NULL;
494
495 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
496
497 ADD_U_CHAR(dptr, AUT_IPORT);
498 ADD_U_INT16(dptr, iport);
499
500 return (t);
501}
502
503/*
504 * token ID 1 byte
505 * size 2 bytes
506 * data size bytes
507 */
508token_t *
509au_to_opaque(const char *data, u_int16_t bytes)
510{
511 token_t *t;
512 u_char *dptr = NULL;
513
514 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
515
516 ADD_U_CHAR(dptr, AUT_OPAQUE);
517 ADD_U_INT16(dptr, bytes);
518 ADD_MEM(dptr, data, bytes);
519
520 return (t);
521}
522
523/*
524 * token ID 1 byte
525 * seconds of time 4 bytes
526 * milliseconds of time 4 bytes
527 * file name len 2 bytes
528 * file pathname N bytes + 1 terminating NULL byte
529 */
530token_t *
531au_to_file(const char *file, struct timeval tm)
532{
533 token_t *t;
534 u_char *dptr = NULL;
535 u_int16_t filelen;
536 u_int32_t timems;
537
538 filelen = strlen(file);
539 filelen += 1;
540
541 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
542 sizeof(u_int16_t) + filelen);
543
544 timems = tm.tv_usec/1000;
545
546 ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
547 ADD_U_INT32(dptr, tm.tv_sec);
548 ADD_U_INT32(dptr, timems); /* We need time in ms. */
549 ADD_U_INT16(dptr, filelen);
550 ADD_STRING(dptr, file, filelen);
551
552 return (t);
553}
554
555/*
556 * token ID 1 byte
557 * text length 2 bytes
558 * text N bytes + 1 terminating NULL byte
559 */
560token_t *
561au_to_text(const char *text)
562{
563 token_t *t;
564 u_char *dptr = NULL;
565 u_int16_t textlen;
566
567 textlen = strlen(text);
568 textlen += 1;
569
570 /* XXXRW: Should validate length against token size limit. */
571
572 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
573
574 ADD_U_CHAR(dptr, AUT_TEXT);
575 ADD_U_INT16(dptr, textlen);
576 ADD_STRING(dptr, text, textlen);
577
578 return (t);
579}
580
581/*
582 * token ID 1 byte
583 * path length 2 bytes
584 * path N bytes + 1 terminating NULL byte
585 */
586token_t *
587au_to_path(const char *text)
588{
589 token_t *t;
590 u_char *dptr = NULL;
591 u_int16_t textlen;
592
593 textlen = strlen(text);
594 textlen += 1;
595
596 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
597
598 ADD_U_CHAR(dptr, AUT_PATH);
599 ADD_U_INT16(dptr, textlen);
600 ADD_STRING(dptr, text, textlen);
601
602 return (t);
603}
604
605/*
606 * token ID 1 byte
607 * audit ID 4 bytes
608 * effective user ID 4 bytes
609 * effective group ID 4 bytes
610 * real user ID 4 bytes
611 * real group ID 4 bytes
612 * process ID 4 bytes
613 * session ID 4 bytes
614 * terminal ID
615 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
616 * machine address 4 bytes
617 */
618token_t *
619au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
620 pid_t pid, au_asid_t sid, au_tid_t *tid)
621{
622 token_t *t;
623 u_char *dptr = NULL;
624
625 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
626
627 ADD_U_CHAR(dptr, AUT_PROCESS32);
628 ADD_U_INT32(dptr, auid);
629 ADD_U_INT32(dptr, euid);
630 ADD_U_INT32(dptr, egid);
631 ADD_U_INT32(dptr, ruid);
632 ADD_U_INT32(dptr, rgid);
633 ADD_U_INT32(dptr, pid);
634 ADD_U_INT32(dptr, sid);
635 ADD_U_INT32(dptr, tid->port);
636
637 /*
638 * Note: Solaris will write out IPv6 addresses here as a 32-bit
639 * address type and 16 bytes of address, but for IPv4 addresses it
640 * simply writes the 4-byte address directly. We support only IPv4
641 * addresses for process32 tokens.
642 */
643 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
644
645 return (t);
646}
647
648token_t *
649au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
650 pid_t pid, au_asid_t sid, au_tid_t *tid)
651{
652 token_t *t;
653 u_char *dptr = NULL;
654
655 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
656 sizeof(u_int64_t));
657
658 ADD_U_CHAR(dptr, AUT_PROCESS64);
659 ADD_U_INT32(dptr, auid);
660 ADD_U_INT32(dptr, euid);
661 ADD_U_INT32(dptr, egid);
662 ADD_U_INT32(dptr, ruid);
663 ADD_U_INT32(dptr, rgid);
664 ADD_U_INT32(dptr, pid);
665 ADD_U_INT32(dptr, sid);
666 ADD_U_INT64(dptr, tid->port);
667
668 /*
669 * Note: Solaris will write out IPv6 addresses here as a 32-bit
670 * address type and 16 bytes of address, but for IPv4 addresses it
671 * simply writes the 4-byte address directly. We support only IPv4
672 * addresses for process64 tokens.
673 */
674 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
675
676 return (t);
677}
678
679token_t *
680au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
681 pid_t pid, au_asid_t sid, au_tid_t *tid)
682{
683
684 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
685 tid));
686}
687
688/*
689 * token ID 1 byte
690 * audit ID 4 bytes
691 * effective user ID 4 bytes
692 * effective group ID 4 bytes
693 * real user ID 4 bytes
694 * real group ID 4 bytes
695 * process ID 4 bytes
696 * session ID 4 bytes
697 * terminal ID
698 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
699 * address type-len 4 bytes
700 * machine address 16 bytes
701 */
702token_t *
703au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
704 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
705{
706 token_t *t;
707 u_char *dptr = NULL;
708
709 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
710 ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
711 if (tid->at_type == AU_IPv4)
712 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
713 10 * sizeof(u_int32_t));
714 else
715 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
716 13 * sizeof(u_int32_t));
717
718 ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
719 ADD_U_INT32(dptr, auid);
720 ADD_U_INT32(dptr, euid);
721 ADD_U_INT32(dptr, egid);
722 ADD_U_INT32(dptr, ruid);
723 ADD_U_INT32(dptr, rgid);
724 ADD_U_INT32(dptr, pid);
725 ADD_U_INT32(dptr, sid);
726 ADD_U_INT32(dptr, tid->at_port);
727 ADD_U_INT32(dptr, tid->at_type);
728 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
729 if (tid->at_type == AU_IPv6) {
730 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
731 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
732 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
733 }
734
735 return (t);
736}
737
738token_t *
739au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
740 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
741{
742 token_t *t;
743 u_char *dptr = NULL;
744
745 if (tid->at_type == AU_IPv4)
746 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
747 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
748 2 * sizeof(u_int32_t));
749 else if (tid->at_type == AU_IPv6)
750 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
751 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
752 5 * sizeof(u_int32_t));
753 else
754 panic("au_to_process64_ex: invalidate at_type (%d)",
755 tid->at_type);
756
757 ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
758 ADD_U_INT32(dptr, auid);
759 ADD_U_INT32(dptr, euid);
760 ADD_U_INT32(dptr, egid);
761 ADD_U_INT32(dptr, ruid);
762 ADD_U_INT32(dptr, rgid);
763 ADD_U_INT32(dptr, pid);
764 ADD_U_INT32(dptr, sid);
765 ADD_U_INT64(dptr, tid->at_port);
766 ADD_U_INT32(dptr, tid->at_type);
767 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
768 if (tid->at_type == AU_IPv6) {
769 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
770 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
771 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
772 }
773
774 return (t);
775}
776
777token_t *
778au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
779 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
780{
781
782 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
783 tid));
784}
785
786/*
787 * token ID 1 byte
788 * error status 1 byte
789 * return value 4 bytes/8 bytes (32-bit/64-bit value)
790 */
791token_t *
792au_to_return32(char status, u_int32_t ret)
793{
794 token_t *t;
795 u_char *dptr = NULL;
796
797 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
798
799 ADD_U_CHAR(dptr, AUT_RETURN32);
800 ADD_U_CHAR(dptr, status);
801 ADD_U_INT32(dptr, ret);
802
803 return (t);
804}
805
806token_t *
807au_to_return64(char status, u_int64_t ret)
808{
809 token_t *t;
810 u_char *dptr = NULL;
811
812 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
813
814 ADD_U_CHAR(dptr, AUT_RETURN64);
815 ADD_U_CHAR(dptr, status);
816 ADD_U_INT64(dptr, ret);
817
818 return (t);
819}
820
821token_t *
822au_to_return(char status, u_int32_t ret)
823{
824
825 return (au_to_return32(status, ret));
826}
827
828/*
829 * token ID 1 byte
830 * sequence number 4 bytes
831 */
832token_t *
833au_to_seq(long audit_count)
834{
835 token_t *t;
836 u_char *dptr = NULL;
837
838 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
839
840 ADD_U_CHAR(dptr, AUT_SEQ);
841 ADD_U_INT32(dptr, audit_count);
842
843 return (t);
844}
845
846/*
847 * token ID 1 byte
848 * socket domain 2 bytes
849 * socket type 2 bytes
850 * address type 2 byte
851 * local port 2 bytes
852 * local address 4 bytes/16 bytes (IPv4/IPv6 address)
853 * remote port 2 bytes
854 * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
855 *
856 * Domain and type arguments to this routine are assumed to already have been
857 * converted to the BSM constant space, so we don't do that here.
858 */
859token_t *
860au_to_socket_ex(u_short so_domain, u_short so_type,
861 struct sockaddr *sa_local, struct sockaddr *sa_remote)
862{
863 token_t *t;
864 u_char *dptr = NULL;
865 struct sockaddr_in *sin;
866 struct sockaddr_in6 *sin6;
867
868 if (so_domain == AF_INET)
869 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
870 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
871 else if (so_domain == AF_INET6)
872 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
873 5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
874 else
875 return (NULL);
876
877 ADD_U_CHAR(dptr, AUT_SOCKET_EX);
878 ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
879 ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
880 if (so_domain == AF_INET) {
881 ADD_U_INT16(dptr, AU_IPv4);
882 sin = (struct sockaddr_in *)sa_local;
883 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
884 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
885 sin = (struct sockaddr_in *)sa_remote;
886 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
887 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
888 } else {
889 ADD_U_INT16(dptr, AU_IPv6);
890 sin6 = (struct sockaddr_in6 *)sa_local;
891 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
892 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
893 sin6 = (struct sockaddr_in6 *)sa_remote;
894 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
895 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
896 }
897
898 return (t);
899}
900
901/*
902 * Kernel-specific version of the above function.
903 *
904 * XXXRW: Should now use au_to_socket_ex() here.
905 */
906#ifdef _KERNEL
907token_t *
908kau_to_socket(struct socket_au_info *soi)
909{
910 token_t *t;
911 u_char *dptr;
912 u_int16_t so_type;
913
914 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
915 sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
916
917 ADD_U_CHAR(dptr, AUT_SOCKET);
918 /* Coerce the socket type into a short value */
919 so_type = soi->so_type;
920 ADD_U_INT16(dptr, so_type);
921 ADD_U_INT16(dptr, soi->so_lport);
922 ADD_U_INT32(dptr, soi->so_laddr);
923 ADD_U_INT16(dptr, soi->so_rport);
924 ADD_U_INT32(dptr, soi->so_raddr);
925
926 return (t);
927}
928#endif
929
930/*
931 * token ID 1 byte
932 * socket family 2 bytes
933 * path 104 bytes
933 * path (up to) 104 bytes + NULL (NULL terminated string)
934 */
935token_t *
936au_to_sock_unix(struct sockaddr_un *so)
937{
938 token_t *t;
939 u_char *dptr;
940
941 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
942
943 ADD_U_CHAR(dptr, AUT_SOCKUNIX);
944 /* BSM token has two bytes for family */
945 ADD_U_CHAR(dptr, 0);
946 ADD_U_CHAR(dptr, so->sun_family);
947 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
948
949 return (t);
950}
951
952/*
953 * token ID 1 byte
954 * socket family 2 bytes
955 * local port 2 bytes
956 * socket address 4 bytes
957 */
958token_t *
959au_to_sock_inet32(struct sockaddr_in *so)
960{
961 token_t *t;
962 u_char *dptr = NULL;
963 uint16_t family;
964
965 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
966 sizeof(uint32_t));
967
968 ADD_U_CHAR(dptr, AUT_SOCKINET32);
969 /*
970 * BSM defines the family field as 16 bits, but many operating
971 * systems have an 8-bit sin_family field. Extend to 16 bits before
972 * writing into the token. Assume that both the port and the address
973 * in the sockaddr_in are already in network byte order, but family
974 * is in local byte order.
975 *
976 * XXXRW: Should a name space conversion be taking place on the value
977 * of sin_family?
978 */
979 family = so->sin_family;
980 ADD_U_INT16(dptr, family);
981 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
982 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
983
984 return (t);
985}
986
987token_t *
988au_to_sock_inet128(struct sockaddr_in6 *so)
989{
990 token_t *t;
991 u_char *dptr = NULL;
992
993 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
994 4 * sizeof(u_int32_t));
995
996 ADD_U_CHAR(dptr, AUT_SOCKINET128);
997 /*
998 * In BSD, sin6_family is one octet, but BSM defines the token to
999 * store two. So we copy in a 0 first. XXXRW: Possibly should be
1000 * conditionally compiled.
1001 */
1002 ADD_U_CHAR(dptr, 0);
1003 ADD_U_CHAR(dptr, so->sin6_family);
1004
1005 ADD_U_INT16(dptr, so->sin6_port);
1006 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1007
1008 return (t);
1009}
1010
1011token_t *
1012au_to_sock_inet(struct sockaddr_in *so)
1013{
1014
1015 return (au_to_sock_inet32(so));
1016}
1017
1018/*
1019 * token ID 1 byte
1020 * audit ID 4 bytes
1021 * effective user ID 4 bytes
1022 * effective group ID 4 bytes
1023 * real user ID 4 bytes
1024 * real group ID 4 bytes
1025 * process ID 4 bytes
1026 * session ID 4 bytes
1027 * terminal ID
1028 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1029 * machine address 4 bytes
1030 */
1031token_t *
1032au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1033 pid_t pid, au_asid_t sid, au_tid_t *tid)
1034{
1035 token_t *t;
1036 u_char *dptr = NULL;
1037
1038 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1039
1040 ADD_U_CHAR(dptr, AUT_SUBJECT32);
1041 ADD_U_INT32(dptr, auid);
1042 ADD_U_INT32(dptr, euid);
1043 ADD_U_INT32(dptr, egid);
1044 ADD_U_INT32(dptr, ruid);
1045 ADD_U_INT32(dptr, rgid);
1046 ADD_U_INT32(dptr, pid);
1047 ADD_U_INT32(dptr, sid);
1048 ADD_U_INT32(dptr, tid->port);
1049 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1050
1051 return (t);
1052}
1053
1054token_t *
1055au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1056 pid_t pid, au_asid_t sid, au_tid_t *tid)
1057{
1058 token_t *t;
1059 u_char *dptr = NULL;
1060
1061 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1062 sizeof(u_int64_t) + sizeof(u_int32_t));
1063
1064 ADD_U_CHAR(dptr, AUT_SUBJECT64);
1065 ADD_U_INT32(dptr, auid);
1066 ADD_U_INT32(dptr, euid);
1067 ADD_U_INT32(dptr, egid);
1068 ADD_U_INT32(dptr, ruid);
1069 ADD_U_INT32(dptr, rgid);
1070 ADD_U_INT32(dptr, pid);
1071 ADD_U_INT32(dptr, sid);
1072 ADD_U_INT64(dptr, tid->port);
1073 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1074
1075 return (t);
1076}
1077
1078token_t *
1079au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1080 pid_t pid, au_asid_t sid, au_tid_t *tid)
1081{
1082
1083 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1084 tid));
1085}
1086
1087/*
1088 * token ID 1 byte
1089 * audit ID 4 bytes
1090 * effective user ID 4 bytes
1091 * effective group ID 4 bytes
1092 * real user ID 4 bytes
1093 * real group ID 4 bytes
1094 * process ID 4 bytes
1095 * session ID 4 bytes
1096 * terminal ID
1097 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1098 * address type/length 4 bytes
1099 * machine address 16 bytes
1100 */
1101token_t *
1102au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1103 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1104{
1105 token_t *t;
1106 u_char *dptr = NULL;
1107
1108 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1109 ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1110
1111 if (tid->at_type == AU_IPv4)
1112 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1113 sizeof(u_int32_t));
1114 else
1115 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1116 sizeof(u_int32_t));
1117
1118 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1119 ADD_U_INT32(dptr, auid);
1120 ADD_U_INT32(dptr, euid);
1121 ADD_U_INT32(dptr, egid);
1122 ADD_U_INT32(dptr, ruid);
1123 ADD_U_INT32(dptr, rgid);
1124 ADD_U_INT32(dptr, pid);
1125 ADD_U_INT32(dptr, sid);
1126 ADD_U_INT32(dptr, tid->at_port);
1127 ADD_U_INT32(dptr, tid->at_type);
1128 if (tid->at_type == AU_IPv6)
1129 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1130 else
1131 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1132
1133 return (t);
1134}
1135
1136token_t *
1137au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1138 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1139{
1140 token_t *t;
1141 u_char *dptr = NULL;
1142
1143 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1144 ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1145
1146 if (tid->at_type == AU_IPv4)
1147 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1148 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1149 2 * sizeof(u_int32_t));
1150 else
1151 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1152 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1153 5 * sizeof(u_int32_t));
1154
1155 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1156 ADD_U_INT32(dptr, auid);
1157 ADD_U_INT32(dptr, euid);
1158 ADD_U_INT32(dptr, egid);
1159 ADD_U_INT32(dptr, ruid);
1160 ADD_U_INT32(dptr, rgid);
1161 ADD_U_INT32(dptr, pid);
1162 ADD_U_INT32(dptr, sid);
1163 ADD_U_INT64(dptr, tid->at_port);
1164 ADD_U_INT32(dptr, tid->at_type);
1165 if (tid->at_type == AU_IPv6)
1166 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1167 else
1168 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1169
1170 return (t);
1171}
1172
1173token_t *
1174au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1175 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1176{
1177
1178 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1179 tid));
1180}
1181
1182#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1183/*
1184 * Collects audit information for the current process and creates a subject
1185 * token from it.
1186 */
1187token_t *
1188au_to_me(void)
1189{
1190 auditinfo_t auinfo;
934 */
935token_t *
936au_to_sock_unix(struct sockaddr_un *so)
937{
938 token_t *t;
939 u_char *dptr;
940
941 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
942
943 ADD_U_CHAR(dptr, AUT_SOCKUNIX);
944 /* BSM token has two bytes for family */
945 ADD_U_CHAR(dptr, 0);
946 ADD_U_CHAR(dptr, so->sun_family);
947 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
948
949 return (t);
950}
951
952/*
953 * token ID 1 byte
954 * socket family 2 bytes
955 * local port 2 bytes
956 * socket address 4 bytes
957 */
958token_t *
959au_to_sock_inet32(struct sockaddr_in *so)
960{
961 token_t *t;
962 u_char *dptr = NULL;
963 uint16_t family;
964
965 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
966 sizeof(uint32_t));
967
968 ADD_U_CHAR(dptr, AUT_SOCKINET32);
969 /*
970 * BSM defines the family field as 16 bits, but many operating
971 * systems have an 8-bit sin_family field. Extend to 16 bits before
972 * writing into the token. Assume that both the port and the address
973 * in the sockaddr_in are already in network byte order, but family
974 * is in local byte order.
975 *
976 * XXXRW: Should a name space conversion be taking place on the value
977 * of sin_family?
978 */
979 family = so->sin_family;
980 ADD_U_INT16(dptr, family);
981 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
982 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
983
984 return (t);
985}
986
987token_t *
988au_to_sock_inet128(struct sockaddr_in6 *so)
989{
990 token_t *t;
991 u_char *dptr = NULL;
992
993 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
994 4 * sizeof(u_int32_t));
995
996 ADD_U_CHAR(dptr, AUT_SOCKINET128);
997 /*
998 * In BSD, sin6_family is one octet, but BSM defines the token to
999 * store two. So we copy in a 0 first. XXXRW: Possibly should be
1000 * conditionally compiled.
1001 */
1002 ADD_U_CHAR(dptr, 0);
1003 ADD_U_CHAR(dptr, so->sin6_family);
1004
1005 ADD_U_INT16(dptr, so->sin6_port);
1006 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1007
1008 return (t);
1009}
1010
1011token_t *
1012au_to_sock_inet(struct sockaddr_in *so)
1013{
1014
1015 return (au_to_sock_inet32(so));
1016}
1017
1018/*
1019 * token ID 1 byte
1020 * audit ID 4 bytes
1021 * effective user ID 4 bytes
1022 * effective group ID 4 bytes
1023 * real user ID 4 bytes
1024 * real group ID 4 bytes
1025 * process ID 4 bytes
1026 * session ID 4 bytes
1027 * terminal ID
1028 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1029 * machine address 4 bytes
1030 */
1031token_t *
1032au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1033 pid_t pid, au_asid_t sid, au_tid_t *tid)
1034{
1035 token_t *t;
1036 u_char *dptr = NULL;
1037
1038 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1039
1040 ADD_U_CHAR(dptr, AUT_SUBJECT32);
1041 ADD_U_INT32(dptr, auid);
1042 ADD_U_INT32(dptr, euid);
1043 ADD_U_INT32(dptr, egid);
1044 ADD_U_INT32(dptr, ruid);
1045 ADD_U_INT32(dptr, rgid);
1046 ADD_U_INT32(dptr, pid);
1047 ADD_U_INT32(dptr, sid);
1048 ADD_U_INT32(dptr, tid->port);
1049 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1050
1051 return (t);
1052}
1053
1054token_t *
1055au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1056 pid_t pid, au_asid_t sid, au_tid_t *tid)
1057{
1058 token_t *t;
1059 u_char *dptr = NULL;
1060
1061 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1062 sizeof(u_int64_t) + sizeof(u_int32_t));
1063
1064 ADD_U_CHAR(dptr, AUT_SUBJECT64);
1065 ADD_U_INT32(dptr, auid);
1066 ADD_U_INT32(dptr, euid);
1067 ADD_U_INT32(dptr, egid);
1068 ADD_U_INT32(dptr, ruid);
1069 ADD_U_INT32(dptr, rgid);
1070 ADD_U_INT32(dptr, pid);
1071 ADD_U_INT32(dptr, sid);
1072 ADD_U_INT64(dptr, tid->port);
1073 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1074
1075 return (t);
1076}
1077
1078token_t *
1079au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1080 pid_t pid, au_asid_t sid, au_tid_t *tid)
1081{
1082
1083 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1084 tid));
1085}
1086
1087/*
1088 * token ID 1 byte
1089 * audit ID 4 bytes
1090 * effective user ID 4 bytes
1091 * effective group ID 4 bytes
1092 * real user ID 4 bytes
1093 * real group ID 4 bytes
1094 * process ID 4 bytes
1095 * session ID 4 bytes
1096 * terminal ID
1097 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1098 * address type/length 4 bytes
1099 * machine address 16 bytes
1100 */
1101token_t *
1102au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1103 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1104{
1105 token_t *t;
1106 u_char *dptr = NULL;
1107
1108 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1109 ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1110
1111 if (tid->at_type == AU_IPv4)
1112 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1113 sizeof(u_int32_t));
1114 else
1115 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1116 sizeof(u_int32_t));
1117
1118 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1119 ADD_U_INT32(dptr, auid);
1120 ADD_U_INT32(dptr, euid);
1121 ADD_U_INT32(dptr, egid);
1122 ADD_U_INT32(dptr, ruid);
1123 ADD_U_INT32(dptr, rgid);
1124 ADD_U_INT32(dptr, pid);
1125 ADD_U_INT32(dptr, sid);
1126 ADD_U_INT32(dptr, tid->at_port);
1127 ADD_U_INT32(dptr, tid->at_type);
1128 if (tid->at_type == AU_IPv6)
1129 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1130 else
1131 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1132
1133 return (t);
1134}
1135
1136token_t *
1137au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1138 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1139{
1140 token_t *t;
1141 u_char *dptr = NULL;
1142
1143 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1144 ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1145
1146 if (tid->at_type == AU_IPv4)
1147 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1148 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1149 2 * sizeof(u_int32_t));
1150 else
1151 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1152 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1153 5 * sizeof(u_int32_t));
1154
1155 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1156 ADD_U_INT32(dptr, auid);
1157 ADD_U_INT32(dptr, euid);
1158 ADD_U_INT32(dptr, egid);
1159 ADD_U_INT32(dptr, ruid);
1160 ADD_U_INT32(dptr, rgid);
1161 ADD_U_INT32(dptr, pid);
1162 ADD_U_INT32(dptr, sid);
1163 ADD_U_INT64(dptr, tid->at_port);
1164 ADD_U_INT32(dptr, tid->at_type);
1165 if (tid->at_type == AU_IPv6)
1166 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1167 else
1168 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1169
1170 return (t);
1171}
1172
1173token_t *
1174au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1175 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1176{
1177
1178 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1179 tid));
1180}
1181
1182#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1183/*
1184 * Collects audit information for the current process and creates a subject
1185 * token from it.
1186 */
1187token_t *
1188au_to_me(void)
1189{
1190 auditinfo_t auinfo;
1191 auditinfo_addr_t aia;
1191
1192
1192 if (getaudit(&auinfo) != 0)
1193 return (NULL);
1193 /*
1194 * Try to use getaudit_addr(2) first. If this kernel does not support
1195 * it, then fall back on to getaudit(2).
1196 */
1197 if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1198 if (errno == ENOSYS) {
1199 if (getaudit(&auinfo) != 0)
1200 return (NULL);
1201 return (au_to_subject32(auinfo.ai_auid, geteuid(),
1202 getegid(), getuid(), getgid(), getpid(),
1203 auinfo.ai_asid, &auinfo.ai_termid));
1204 } else {
1205 /* getaudit_addr(2) failed for some other reason. */
1206 return (NULL);
1207 }
1208 }
1194
1209
1195 return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1196 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1210 return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1211 getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1197}
1198#endif
1199
1200#if defined(_KERNEL) || defined(KERNEL)
1201static token_t *
1202au_to_exec_strings(char *strs, int count, u_char type)
1203{
1204 token_t *t;
1205 u_char *dptr = NULL;
1206 u_int32_t totlen;
1207 int ctr;
1208 char *p;
1209
1210 totlen = 0;
1211 ctr = count;
1212 p = strs;
1213 while (ctr-- > 0) {
1214 totlen += strlen(p) + 1;
1215 p = strs + totlen;
1216 }
1217 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1218 ADD_U_CHAR(dptr, type);
1219 ADD_U_INT32(dptr, count);
1220 ADD_STRING(dptr, strs, totlen);
1221
1222 return (t);
1223}
1224
1225/*
1226 * token ID 1 byte
1227 * count 4 bytes
1228 * text count null-terminated strings
1229 */
1230token_t *
1231au_to_exec_args(char *args, int argc)
1232{
1233
1234 return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1235}
1236
1237/*
1238 * token ID 1 byte
1239 * count 4 bytes
1240 * text count null-terminated strings
1241 */
1242token_t *
1243au_to_exec_env(char *envs, int envc)
1244{
1245
1246 return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1247}
1248#else
1249/*
1250 * token ID 1 byte
1251 * count 4 bytes
1252 * text count null-terminated strings
1253 */
1254token_t *
1255au_to_exec_args(char **argv)
1256{
1257 token_t *t;
1258 u_char *dptr = NULL;
1259 const char *nextarg;
1260 int i, count = 0;
1261 size_t totlen = 0;
1262
1263 nextarg = *argv;
1264
1265 while (nextarg != NULL) {
1266 int nextlen;
1267
1268 nextlen = strlen(nextarg);
1269 totlen += nextlen + 1;
1270 count++;
1271 nextarg = *(argv + count);
1272 }
1273
1274 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1275
1276 ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1277 ADD_U_INT32(dptr, count);
1278
1279 for (i = 0; i < count; i++) {
1280 nextarg = *(argv + i);
1281 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1282 }
1283
1284 return (t);
1285}
1286
1287/*
1288 * token ID 1 byte
1289 * count 4 bytes
1290 * text count null-terminated strings
1291 */
1292token_t *
1293au_to_exec_env(char **envp)
1294{
1295 token_t *t;
1296 u_char *dptr = NULL;
1297 int i, count = 0;
1298 size_t totlen = 0;
1299 const char *nextenv;
1300
1301 nextenv = *envp;
1302
1303 while (nextenv != NULL) {
1304 int nextlen;
1305
1306 nextlen = strlen(nextenv);
1307 totlen += nextlen + 1;
1308 count++;
1309 nextenv = *(envp + count);
1310 }
1311
1312 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1313
1314 ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1315 ADD_U_INT32(dptr, count);
1316
1317 for (i = 0; i < count; i++) {
1318 nextenv = *(envp + i);
1319 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1320 }
1321
1322 return (t);
1323}
1324#endif
1325
1326/*
1327 * token ID 1 byte
1328 * zonename length 2 bytes
1329 * zonename N bytes + 1 terminating NULL byte
1330 */
1331token_t *
1332au_to_zonename(const char *zonename)
1333{
1334 u_char *dptr = NULL;
1335 u_int16_t textlen;
1336 token_t *t;
1337
1338 textlen = strlen(zonename) + 1;
1339 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1340
1341 ADD_U_CHAR(dptr, AUT_ZONENAME);
1342 ADD_U_INT16(dptr, textlen);
1343 ADD_STRING(dptr, zonename, textlen);
1344 return (t);
1345}
1346
1347/*
1348 * token ID 1 byte
1349 * record byte count 4 bytes
1350 * version # 1 byte [2]
1351 * event type 2 bytes
1352 * event modifier 2 bytes
1353 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1354 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1355 */
1356token_t *
1357au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1358 struct timeval tm)
1359{
1360 token_t *t;
1361 u_char *dptr = NULL;
1362 u_int32_t timems;
1363
1364 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1365 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1366
1367 ADD_U_CHAR(dptr, AUT_HEADER32);
1368 ADD_U_INT32(dptr, rec_size);
1369 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1370 ADD_U_INT16(dptr, e_type);
1371 ADD_U_INT16(dptr, e_mod);
1372
1373 timems = tm.tv_usec/1000;
1374 /* Add the timestamp */
1375 ADD_U_INT32(dptr, tm.tv_sec);
1376 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1377
1378 return (t);
1379}
1380
1381/*
1382 * token ID 1 byte
1383 * record byte count 4 bytes
1384 * version # 1 byte [2]
1385 * event type 2 bytes
1386 * event modifier 2 bytes
1387 * address type/length 4 bytes
1388 * machine address 4 bytes/16 bytes (IPv4/IPv6 address)
1389 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1390 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1391 */
1392token_t *
1393au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1394 struct timeval tm, struct auditinfo_addr *aia)
1395{
1396 token_t *t;
1397 u_char *dptr = NULL;
1398 u_int32_t timems;
1399 au_tid_addr_t *tid;
1400
1401 tid = &aia->ai_termid;
1402 KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1403 ("au_to_header32_ex_tm: invalid address family"));
1404
1405 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1406 sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1407 sizeof(u_int32_t) + tid->at_type);
1408
1409 ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1410 ADD_U_INT32(dptr, rec_size);
1411 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1412 ADD_U_INT16(dptr, e_type);
1413 ADD_U_INT16(dptr, e_mod);
1414
1415 ADD_U_INT32(dptr, tid->at_type);
1416 if (tid->at_type == AU_IPv6)
1417 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1418 else
1419 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1420 timems = tm.tv_usec/1000;
1421 /* Add the timestamp */
1422 ADD_U_INT32(dptr, tm.tv_sec);
1423 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1424
1425 return (t);
1426}
1427
1428token_t *
1429au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1430 struct timeval tm)
1431{
1432 token_t *t;
1433 u_char *dptr = NULL;
1434 u_int32_t timems;
1435
1436 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1437 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1438
1439 ADD_U_CHAR(dptr, AUT_HEADER64);
1440 ADD_U_INT32(dptr, rec_size);
1441 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1442 ADD_U_INT16(dptr, e_type);
1443 ADD_U_INT16(dptr, e_mod);
1444
1445 timems = tm.tv_usec/1000;
1446 /* Add the timestamp */
1447 ADD_U_INT64(dptr, tm.tv_sec);
1448 ADD_U_INT64(dptr, timems); /* We need time in ms. */
1449
1450 return (t);
1451}
1452
1453#if !defined(KERNEL) && !defined(_KERNEL)
1454#ifdef HAVE_AUDIT_SYSCALLS
1455token_t *
1456au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1457{
1458 struct timeval tm;
1459 struct auditinfo_addr aia;
1460
1461 if (gettimeofday(&tm, NULL) == -1)
1462 return (NULL);
1463 if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1464 if (errno != ENOSYS)
1465 return (NULL);
1466 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1467 }
1468 return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1469}
1470#endif /* HAVE_AUDIT_SYSCALLS */
1471
1472token_t *
1473au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1474{
1475 struct timeval tm;
1476
1477 if (gettimeofday(&tm, NULL) == -1)
1478 return (NULL);
1479 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1480}
1481
1482token_t *
1483au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1484 __unused au_emod_t e_mod)
1485{
1486 struct timeval tm;
1487
1488 if (gettimeofday(&tm, NULL) == -1)
1489 return (NULL);
1490 return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1491}
1492
1493token_t *
1494au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1495{
1496
1497 return (au_to_header32(rec_size, e_type, e_mod));
1498}
1499
1500#ifdef HAVE_AUDIT_SYSCALLS
1501token_t *
1502au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1503{
1504
1505 return (au_to_header32_ex(rec_size, e_type, e_mod));
1506}
1507#endif /* HAVE_AUDIT_SYSCALLS */
1508#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1509
1510/*
1511 * token ID 1 byte
1512 * trailer magic number 2 bytes
1513 * record byte count 4 bytes
1514 */
1515token_t *
1516au_to_trailer(int rec_size)
1517{
1518 token_t *t;
1519 u_char *dptr = NULL;
1520 u_int16_t magic = AUT_TRAILER_MAGIC;
1521
1522 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1523 sizeof(u_int32_t));
1524
1525 ADD_U_CHAR(dptr, AUT_TRAILER);
1526 ADD_U_INT16(dptr, magic);
1527 ADD_U_INT32(dptr, rec_size);
1528
1529 return (t);
1530}
1212}
1213#endif
1214
1215#if defined(_KERNEL) || defined(KERNEL)
1216static token_t *
1217au_to_exec_strings(char *strs, int count, u_char type)
1218{
1219 token_t *t;
1220 u_char *dptr = NULL;
1221 u_int32_t totlen;
1222 int ctr;
1223 char *p;
1224
1225 totlen = 0;
1226 ctr = count;
1227 p = strs;
1228 while (ctr-- > 0) {
1229 totlen += strlen(p) + 1;
1230 p = strs + totlen;
1231 }
1232 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1233 ADD_U_CHAR(dptr, type);
1234 ADD_U_INT32(dptr, count);
1235 ADD_STRING(dptr, strs, totlen);
1236
1237 return (t);
1238}
1239
1240/*
1241 * token ID 1 byte
1242 * count 4 bytes
1243 * text count null-terminated strings
1244 */
1245token_t *
1246au_to_exec_args(char *args, int argc)
1247{
1248
1249 return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1250}
1251
1252/*
1253 * token ID 1 byte
1254 * count 4 bytes
1255 * text count null-terminated strings
1256 */
1257token_t *
1258au_to_exec_env(char *envs, int envc)
1259{
1260
1261 return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1262}
1263#else
1264/*
1265 * token ID 1 byte
1266 * count 4 bytes
1267 * text count null-terminated strings
1268 */
1269token_t *
1270au_to_exec_args(char **argv)
1271{
1272 token_t *t;
1273 u_char *dptr = NULL;
1274 const char *nextarg;
1275 int i, count = 0;
1276 size_t totlen = 0;
1277
1278 nextarg = *argv;
1279
1280 while (nextarg != NULL) {
1281 int nextlen;
1282
1283 nextlen = strlen(nextarg);
1284 totlen += nextlen + 1;
1285 count++;
1286 nextarg = *(argv + count);
1287 }
1288
1289 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1290
1291 ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1292 ADD_U_INT32(dptr, count);
1293
1294 for (i = 0; i < count; i++) {
1295 nextarg = *(argv + i);
1296 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1297 }
1298
1299 return (t);
1300}
1301
1302/*
1303 * token ID 1 byte
1304 * count 4 bytes
1305 * text count null-terminated strings
1306 */
1307token_t *
1308au_to_exec_env(char **envp)
1309{
1310 token_t *t;
1311 u_char *dptr = NULL;
1312 int i, count = 0;
1313 size_t totlen = 0;
1314 const char *nextenv;
1315
1316 nextenv = *envp;
1317
1318 while (nextenv != NULL) {
1319 int nextlen;
1320
1321 nextlen = strlen(nextenv);
1322 totlen += nextlen + 1;
1323 count++;
1324 nextenv = *(envp + count);
1325 }
1326
1327 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1328
1329 ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1330 ADD_U_INT32(dptr, count);
1331
1332 for (i = 0; i < count; i++) {
1333 nextenv = *(envp + i);
1334 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1335 }
1336
1337 return (t);
1338}
1339#endif
1340
1341/*
1342 * token ID 1 byte
1343 * zonename length 2 bytes
1344 * zonename N bytes + 1 terminating NULL byte
1345 */
1346token_t *
1347au_to_zonename(const char *zonename)
1348{
1349 u_char *dptr = NULL;
1350 u_int16_t textlen;
1351 token_t *t;
1352
1353 textlen = strlen(zonename) + 1;
1354 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1355
1356 ADD_U_CHAR(dptr, AUT_ZONENAME);
1357 ADD_U_INT16(dptr, textlen);
1358 ADD_STRING(dptr, zonename, textlen);
1359 return (t);
1360}
1361
1362/*
1363 * token ID 1 byte
1364 * record byte count 4 bytes
1365 * version # 1 byte [2]
1366 * event type 2 bytes
1367 * event modifier 2 bytes
1368 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1369 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1370 */
1371token_t *
1372au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1373 struct timeval tm)
1374{
1375 token_t *t;
1376 u_char *dptr = NULL;
1377 u_int32_t timems;
1378
1379 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1380 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1381
1382 ADD_U_CHAR(dptr, AUT_HEADER32);
1383 ADD_U_INT32(dptr, rec_size);
1384 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1385 ADD_U_INT16(dptr, e_type);
1386 ADD_U_INT16(dptr, e_mod);
1387
1388 timems = tm.tv_usec/1000;
1389 /* Add the timestamp */
1390 ADD_U_INT32(dptr, tm.tv_sec);
1391 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1392
1393 return (t);
1394}
1395
1396/*
1397 * token ID 1 byte
1398 * record byte count 4 bytes
1399 * version # 1 byte [2]
1400 * event type 2 bytes
1401 * event modifier 2 bytes
1402 * address type/length 4 bytes
1403 * machine address 4 bytes/16 bytes (IPv4/IPv6 address)
1404 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1405 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1406 */
1407token_t *
1408au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1409 struct timeval tm, struct auditinfo_addr *aia)
1410{
1411 token_t *t;
1412 u_char *dptr = NULL;
1413 u_int32_t timems;
1414 au_tid_addr_t *tid;
1415
1416 tid = &aia->ai_termid;
1417 KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1418 ("au_to_header32_ex_tm: invalid address family"));
1419
1420 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1421 sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1422 sizeof(u_int32_t) + tid->at_type);
1423
1424 ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1425 ADD_U_INT32(dptr, rec_size);
1426 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1427 ADD_U_INT16(dptr, e_type);
1428 ADD_U_INT16(dptr, e_mod);
1429
1430 ADD_U_INT32(dptr, tid->at_type);
1431 if (tid->at_type == AU_IPv6)
1432 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1433 else
1434 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1435 timems = tm.tv_usec/1000;
1436 /* Add the timestamp */
1437 ADD_U_INT32(dptr, tm.tv_sec);
1438 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1439
1440 return (t);
1441}
1442
1443token_t *
1444au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1445 struct timeval tm)
1446{
1447 token_t *t;
1448 u_char *dptr = NULL;
1449 u_int32_t timems;
1450
1451 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1452 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1453
1454 ADD_U_CHAR(dptr, AUT_HEADER64);
1455 ADD_U_INT32(dptr, rec_size);
1456 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1457 ADD_U_INT16(dptr, e_type);
1458 ADD_U_INT16(dptr, e_mod);
1459
1460 timems = tm.tv_usec/1000;
1461 /* Add the timestamp */
1462 ADD_U_INT64(dptr, tm.tv_sec);
1463 ADD_U_INT64(dptr, timems); /* We need time in ms. */
1464
1465 return (t);
1466}
1467
1468#if !defined(KERNEL) && !defined(_KERNEL)
1469#ifdef HAVE_AUDIT_SYSCALLS
1470token_t *
1471au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1472{
1473 struct timeval tm;
1474 struct auditinfo_addr aia;
1475
1476 if (gettimeofday(&tm, NULL) == -1)
1477 return (NULL);
1478 if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1479 if (errno != ENOSYS)
1480 return (NULL);
1481 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1482 }
1483 return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1484}
1485#endif /* HAVE_AUDIT_SYSCALLS */
1486
1487token_t *
1488au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1489{
1490 struct timeval tm;
1491
1492 if (gettimeofday(&tm, NULL) == -1)
1493 return (NULL);
1494 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1495}
1496
1497token_t *
1498au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1499 __unused au_emod_t e_mod)
1500{
1501 struct timeval tm;
1502
1503 if (gettimeofday(&tm, NULL) == -1)
1504 return (NULL);
1505 return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1506}
1507
1508token_t *
1509au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1510{
1511
1512 return (au_to_header32(rec_size, e_type, e_mod));
1513}
1514
1515#ifdef HAVE_AUDIT_SYSCALLS
1516token_t *
1517au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1518{
1519
1520 return (au_to_header32_ex(rec_size, e_type, e_mod));
1521}
1522#endif /* HAVE_AUDIT_SYSCALLS */
1523#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1524
1525/*
1526 * token ID 1 byte
1527 * trailer magic number 2 bytes
1528 * record byte count 4 bytes
1529 */
1530token_t *
1531au_to_trailer(int rec_size)
1532{
1533 token_t *t;
1534 u_char *dptr = NULL;
1535 u_int16_t magic = AUT_TRAILER_MAGIC;
1536
1537 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1538 sizeof(u_int32_t));
1539
1540 ADD_U_CHAR(dptr, AUT_TRAILER);
1541 ADD_U_INT16(dptr, magic);
1542 ADD_U_INT32(dptr, rec_size);
1543
1544 return (t);
1545}