]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/security/audit/audit_bsm_token.c
Merge OpenBSM alpha 5 from OpenBSM vendor branch to head, both
[FreeBSD/FreeBSD.git] / sys / security / audit / audit_bsm_token.c
1 /*-
2  * Copyright (c) 2004-2008 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#72
34  */
35
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
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  */
75 token_t *
76 au_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
97 token_t *
98 au_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
119 token_t *
120 au_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  */
136 token_t *
137 au_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_int16_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
183 token_t *
184 au_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_int16_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
230 token_t *
231 au_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  */
245 token_t *
246 au_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  */
299 token_t *
300 au_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  */
316 token_t *
317 au_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  */
328 token_t *
329 au_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  */
350 token_t *
351 au_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  */
369 token_t *
370 au_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  */
391 token_t *
392 au_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  */
410 token_t *
411 au_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  */
435 token_t *
436 au_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, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
443
444         ADD_U_CHAR(dptr, AUT_IPC_PERM);
445
446         /*
447          * Systems vary significantly in what types they use in struct
448          * ipc_perm; at least a few still use 16-bit uid's and gid's, so
449          * allow for that, as BSM define 32-bit values here.
450          * Some systems define the sizes for ipc_perm members as 2 bytes;
451          * BSM defines 4 so pad with 0.
452          *
453          * XXXRW: Possibly shoulid be conditionally compiled, and more cases
454          * need to be handled.
455          */
456         if (sizeof(perm->uid) != sizeof(u_int32_t)) {
457                 ADD_U_INT16(dptr, pad0);
458                 ADD_U_INT16(dptr, perm->uid);
459                 ADD_U_INT16(dptr, pad0);
460                 ADD_U_INT16(dptr, perm->gid);
461                 ADD_U_INT16(dptr, pad0);
462                 ADD_U_INT16(dptr, perm->cuid);
463                 ADD_U_INT16(dptr, pad0);
464                 ADD_U_INT16(dptr, perm->cgid);
465         } else {
466                 ADD_U_INT32(dptr, perm->uid);
467                 ADD_U_INT32(dptr, perm->gid);
468                 ADD_U_INT32(dptr, perm->cuid);
469                 ADD_U_INT32(dptr, perm->cgid);
470         }
471
472         ADD_U_INT16(dptr, pad0);
473         ADD_U_INT16(dptr, perm->mode);
474
475         ADD_U_INT16(dptr, pad0);
476
477         ADD_U_INT16(dptr, perm->seq);
478
479         ADD_U_INT32(dptr, perm->key);
480
481         return (t);
482 }
483
484 /*
485  * token ID                1 byte
486  * port IP address         2 bytes
487  */
488 token_t *
489 au_to_iport(u_int16_t iport)
490 {
491         token_t *t;
492         u_char *dptr = NULL;
493
494         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
495
496         ADD_U_CHAR(dptr, AUT_IPORT);
497         ADD_U_INT16(dptr, iport);
498
499         return (t);
500 }
501
502 /*
503  * token ID                1 byte
504  * size                    2 bytes
505  * data                    size bytes
506  */
507 token_t *
508 au_to_opaque(const char *data, u_int16_t bytes)
509 {
510         token_t *t;
511         u_char *dptr = NULL;
512
513         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
514
515         ADD_U_CHAR(dptr, AUT_OPAQUE);
516         ADD_U_INT16(dptr, bytes);
517         ADD_MEM(dptr, data, bytes);
518
519         return (t);
520 }
521
522 /*
523  * token ID                1 byte
524  * seconds of time         4 bytes
525  * milliseconds of time    4 bytes
526  * file name len           2 bytes
527  * file pathname           N bytes + 1 terminating NULL byte
528  */
529 token_t *
530 au_to_file(const char *file, struct timeval tm)
531 {
532         token_t *t;
533         u_char *dptr = NULL;
534         u_int16_t filelen;
535         u_int32_t timems;
536
537         filelen = strlen(file);
538         filelen += 1;
539
540         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
541             sizeof(u_int16_t) + filelen);
542
543         timems = tm.tv_usec/1000;
544
545         ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
546         ADD_U_INT32(dptr, tm.tv_sec);
547         ADD_U_INT32(dptr, timems);      /* We need time in ms. */
548         ADD_U_INT16(dptr, filelen);
549         ADD_STRING(dptr, file, filelen);
550
551         return (t);
552 }
553
554 /*
555  * token ID                1 byte
556  * text length             2 bytes
557  * text                    N bytes + 1 terminating NULL byte
558  */
559 token_t *
560 au_to_text(const char *text)
561 {
562         token_t *t;
563         u_char *dptr = NULL;
564         u_int16_t textlen;
565
566         textlen = strlen(text);
567         textlen += 1;
568
569         /* XXXRW: Should validate length against token size limit. */
570
571         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
572
573         ADD_U_CHAR(dptr, AUT_TEXT);
574         ADD_U_INT16(dptr, textlen);
575         ADD_STRING(dptr, text, textlen);
576
577         return (t);
578 }
579
580 /*
581  * token ID                1 byte
582  * path length             2 bytes
583  * path                    N bytes + 1 terminating NULL byte
584  */
585 token_t *
586 au_to_path(const char *text)
587 {
588         token_t *t;
589         u_char *dptr = NULL;
590         u_int16_t textlen;
591
592         textlen = strlen(text);
593         textlen += 1;
594
595         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
596
597         ADD_U_CHAR(dptr, AUT_PATH);
598         ADD_U_INT16(dptr, textlen);
599         ADD_STRING(dptr, text, textlen);
600
601         return (t);
602 }
603
604 /*
605  * token ID                1 byte
606  * audit ID                4 bytes
607  * effective user ID       4 bytes
608  * effective group ID      4 bytes
609  * real user ID            4 bytes
610  * real group ID           4 bytes
611  * process ID              4 bytes
612  * session ID              4 bytes
613  * terminal ID
614  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
615  *   machine address       4 bytes
616  */
617 token_t *
618 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
619     pid_t pid, au_asid_t sid, au_tid_t *tid)
620 {
621         token_t *t;
622         u_char *dptr = NULL;
623
624         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
625
626         ADD_U_CHAR(dptr, AUT_PROCESS32);
627         ADD_U_INT32(dptr, auid);
628         ADD_U_INT32(dptr, euid);
629         ADD_U_INT32(dptr, egid);
630         ADD_U_INT32(dptr, ruid);
631         ADD_U_INT32(dptr, rgid);
632         ADD_U_INT32(dptr, pid);
633         ADD_U_INT32(dptr, sid);
634         ADD_U_INT32(dptr, tid->port);
635
636         /*
637          * Note: Solaris will write out IPv6 addresses here as a 32-bit
638          * address type and 16 bytes of address, but for IPv4 addresses it
639          * simply writes the 4-byte address directly.  We support only IPv4
640          * addresses for process32 tokens.
641          */
642         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
643
644         return (t);
645 }
646
647 token_t *
648 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
649     pid_t pid, au_asid_t sid, au_tid_t *tid)
650 {
651         token_t *t;
652         u_char *dptr = NULL;
653
654         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
655             sizeof(u_int64_t));
656
657         ADD_U_CHAR(dptr, AUT_PROCESS64);
658         ADD_U_INT32(dptr, auid);
659         ADD_U_INT32(dptr, euid);
660         ADD_U_INT32(dptr, egid);
661         ADD_U_INT32(dptr, ruid);
662         ADD_U_INT32(dptr, rgid);
663         ADD_U_INT32(dptr, pid);
664         ADD_U_INT32(dptr, sid);
665         ADD_U_INT64(dptr, tid->port);
666
667         /*
668          * Note: Solaris will write out IPv6 addresses here as a 32-bit
669          * address type and 16 bytes of address, but for IPv4 addresses it
670          * simply writes the 4-byte address directly.  We support only IPv4
671          * addresses for process64 tokens.
672          */
673         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
674
675         return (t);
676 }
677
678 token_t *
679 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
680     pid_t pid, au_asid_t sid, au_tid_t *tid)
681 {
682
683         return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
684             tid));
685 }
686
687 /*
688  * token ID                1 byte
689  * audit ID                4 bytes
690  * effective user ID       4 bytes
691  * effective group ID      4 bytes
692  * real user ID            4 bytes
693  * real group ID           4 bytes
694  * process ID              4 bytes
695  * session ID              4 bytes
696  * terminal ID
697  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
698  *   address type-len      4 bytes
699  *   machine address      16 bytes
700  */
701 token_t *
702 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
703     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
704 {
705         token_t *t;
706         u_char *dptr = NULL;
707
708         KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
709             ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
710         if (tid->at_type == AU_IPv4)
711                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
712                     10 * sizeof(u_int32_t));
713         else
714                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
715                     13 * sizeof(u_int32_t));
716
717         ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
718         ADD_U_INT32(dptr, auid);
719         ADD_U_INT32(dptr, euid);
720         ADD_U_INT32(dptr, egid);
721         ADD_U_INT32(dptr, ruid);
722         ADD_U_INT32(dptr, rgid);
723         ADD_U_INT32(dptr, pid);
724         ADD_U_INT32(dptr, sid);
725         ADD_U_INT32(dptr, tid->at_port);
726         ADD_U_INT32(dptr, tid->at_type);
727         ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
728         if (tid->at_type == AU_IPv6) {
729                 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
730                 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
731                 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
732         }
733
734         return (t);
735 }
736
737 token_t *
738 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
739     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
740 {
741         token_t *t;
742         u_char *dptr = NULL;
743
744         if (tid->at_type == AU_IPv4)
745                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
746                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
747                     2 * sizeof(u_int32_t));
748         else if (tid->at_type == AU_IPv6)
749                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
750                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
751                     5 * sizeof(u_int32_t));
752         else
753                 panic("au_to_process64_ex: invalidate at_type (%d)",
754                     tid->at_type);
755
756         ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
757         ADD_U_INT32(dptr, auid);
758         ADD_U_INT32(dptr, euid);
759         ADD_U_INT32(dptr, egid);
760         ADD_U_INT32(dptr, ruid);
761         ADD_U_INT32(dptr, rgid);
762         ADD_U_INT32(dptr, pid);
763         ADD_U_INT32(dptr, sid);
764         ADD_U_INT64(dptr, tid->at_port);
765         ADD_U_INT32(dptr, tid->at_type);
766         ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
767         if (tid->at_type == AU_IPv6) {
768                 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
769                 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
770                 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
771         }
772
773         return (t);
774 }
775
776 token_t *
777 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
778     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
779 {
780
781         return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
782             tid));
783 }
784
785 /*
786  * token ID                1 byte
787  * error status            1 byte
788  * return value            4 bytes/8 bytes (32-bit/64-bit value)
789  */
790 token_t *
791 au_to_return32(char status, u_int32_t ret)
792 {
793         token_t *t;
794         u_char *dptr = NULL;
795
796         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
797
798         ADD_U_CHAR(dptr, AUT_RETURN32);
799         ADD_U_CHAR(dptr, status);
800         ADD_U_INT32(dptr, ret);
801
802         return (t);
803 }
804
805 token_t *
806 au_to_return64(char status, u_int64_t ret)
807 {
808         token_t *t;
809         u_char *dptr = NULL;
810
811         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
812
813         ADD_U_CHAR(dptr, AUT_RETURN64);
814         ADD_U_CHAR(dptr, status);
815         ADD_U_INT64(dptr, ret);
816
817         return (t);
818 }
819
820 token_t *
821 au_to_return(char status, u_int32_t ret)
822 {
823
824         return (au_to_return32(status, ret));
825 }
826
827 /*
828  * token ID                1 byte
829  * sequence number         4 bytes
830  */
831 token_t *
832 au_to_seq(long audit_count)
833 {
834         token_t *t;
835         u_char *dptr = NULL;
836
837         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
838
839         ADD_U_CHAR(dptr, AUT_SEQ);
840         ADD_U_INT32(dptr, audit_count);
841
842         return (t);
843 }
844
845 /*
846  * token ID                1 byte
847  * socket domain           2 bytes
848  * socket type             2 bytes
849  * address type            2 byte
850  * local port              2 bytes
851  * local address           4 bytes/16 bytes (IPv4/IPv6 address)
852  * remote port             2 bytes
853  * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
854  *
855  * Domain and type arguments to this routine are assumed to already have been
856  * converted to the BSM constant space, so we don't do that here.
857  */
858 token_t *
859 au_to_socket_ex(u_short so_domain, u_short so_type,
860     struct sockaddr *sa_local, struct sockaddr *sa_remote)
861 {
862         token_t *t;
863         u_char *dptr = NULL;
864         struct sockaddr_in *sin;
865         struct sockaddr_in6 *sin6;
866
867         if (so_domain == AF_INET)
868                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
869                     5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
870         else if (so_domain == AF_INET6)
871                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
872                     5 * sizeof(u_int16_t) + 16 * sizeof(u_int32_t));
873         else
874                 return (NULL);
875
876         ADD_U_CHAR(dptr, AUT_SOCKET_EX);
877         ADD_U_INT16(dptr, so_domain);   /* XXXRW: explicitly convert? */
878         ADD_U_INT16(dptr, so_type);     /* XXXRW: explicitly convert? */
879         if (so_domain == AF_INET) {
880                 ADD_U_INT16(dptr, AU_IPv4);
881                 sin = (struct sockaddr_in *)sa_local;
882                 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
883                 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
884                 sin = (struct sockaddr_in *)sa_remote;
885                 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
886                 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
887         } else {
888                 ADD_U_INT16(dptr, AU_IPv6);
889                 sin6 = (struct sockaddr_in6 *)sa_local;
890                 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
891                 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
892                 sin6 = (struct sockaddr_in6 *)sa_remote;
893                 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
894                 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
895         }
896
897         return (t);
898 }
899
900 /*
901  * Kernel-specific version of the above function.
902  *
903  * XXXRW: Should now use au_to_socket_ex() here.
904  */
905 #ifdef _KERNEL
906 token_t *
907 kau_to_socket(struct socket_au_info *soi)
908 {
909         token_t *t;
910         u_char *dptr;
911         u_int16_t so_type;
912
913         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
914             sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
915                                                  
916         ADD_U_CHAR(dptr, AUT_SOCKET);
917         /* Coerce the socket type into a short value */
918         so_type = soi->so_type;
919         ADD_U_INT16(dptr, so_type);
920         ADD_U_INT16(dptr, soi->so_lport);
921         ADD_U_INT32(dptr, soi->so_laddr);
922         ADD_U_INT16(dptr, soi->so_rport);
923         ADD_U_INT32(dptr, soi->so_raddr);
924
925         return (t);
926 }
927 #endif
928
929 /*
930  * token ID                1 byte
931  * socket family           2 bytes
932  * path                    104 bytes
933  */
934 token_t *
935 au_to_sock_unix(struct sockaddr_un *so)
936 {
937         token_t *t;
938         u_char *dptr;
939
940         GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
941
942         ADD_U_CHAR(dptr, AUT_SOCKUNIX);
943         /* BSM token has two bytes for family */
944         ADD_U_CHAR(dptr, 0);
945         ADD_U_CHAR(dptr, so->sun_family);
946         ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
947
948         return (t);
949 }
950
951 /*
952  * token ID                1 byte
953  * socket family           2 bytes
954  * local port              2 bytes
955  * socket address          4 bytes
956  */
957 token_t *
958 au_to_sock_inet32(struct sockaddr_in *so)
959 {
960         token_t *t;
961         u_char *dptr = NULL;
962         uint16_t family;
963
964         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
965             sizeof(uint32_t));
966
967         ADD_U_CHAR(dptr, AUT_SOCKINET32);
968         /*
969          * BSM defines the family field as 16 bits, but many operating
970          * systems have an 8-bit sin_family field.  Extend to 16 bits before
971          * writing into the token.  Assume that both the port and the address
972          * in the sockaddr_in are already in network byte order, but family
973          * is in local byte order.
974          *
975          * XXXRW: Should a name space conversion be taking place on the value
976          * of sin_family?
977          */
978         family = so->sin_family;
979         ADD_U_INT16(dptr, family);
980         ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
981         ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
982
983         return (t);
984 }
985
986 token_t *
987 au_to_sock_inet128(struct sockaddr_in6 *so)
988 {
989         token_t *t;
990         u_char *dptr = NULL;
991
992         GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
993             4 * sizeof(u_int32_t));
994
995         ADD_U_CHAR(dptr, AUT_SOCKINET128);
996         /*
997          * In BSD, sin6_family is one octet, but BSM defines the token to
998          * store two. So we copy in a 0 first.  XXXRW: Possibly should be
999          * conditionally compiled.
1000          */
1001         ADD_U_CHAR(dptr, 0);
1002         ADD_U_CHAR(dptr, so->sin6_family);
1003
1004         ADD_U_INT16(dptr, so->sin6_port);
1005         ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1006
1007         return (t);
1008 }
1009
1010 token_t *
1011 au_to_sock_inet(struct sockaddr_in *so)
1012 {
1013
1014         return (au_to_sock_inet32(so));
1015 }
1016
1017 /*
1018  * token ID                1 byte
1019  * audit ID                4 bytes
1020  * effective user ID       4 bytes
1021  * effective group ID      4 bytes
1022  * real user ID            4 bytes
1023  * real group ID           4 bytes
1024  * process ID              4 bytes
1025  * session ID              4 bytes
1026  * terminal ID
1027  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1028  *   machine address       4 bytes
1029  */
1030 token_t *
1031 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1032     pid_t pid, au_asid_t sid, au_tid_t *tid)
1033 {
1034         token_t *t;
1035         u_char *dptr = NULL;
1036
1037         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1038
1039         ADD_U_CHAR(dptr, AUT_SUBJECT32);
1040         ADD_U_INT32(dptr, auid);
1041         ADD_U_INT32(dptr, euid);
1042         ADD_U_INT32(dptr, egid);
1043         ADD_U_INT32(dptr, ruid);
1044         ADD_U_INT32(dptr, rgid);
1045         ADD_U_INT32(dptr, pid);
1046         ADD_U_INT32(dptr, sid);
1047         ADD_U_INT32(dptr, tid->port);
1048         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1049
1050         return (t);
1051 }
1052
1053 token_t *
1054 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1055     pid_t pid, au_asid_t sid, au_tid_t *tid)
1056 {
1057         token_t *t;
1058         u_char *dptr = NULL;
1059
1060         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1061             sizeof(u_int64_t) + sizeof(u_int32_t));
1062
1063         ADD_U_CHAR(dptr, AUT_SUBJECT64);
1064         ADD_U_INT32(dptr, auid);
1065         ADD_U_INT32(dptr, euid);
1066         ADD_U_INT32(dptr, egid);
1067         ADD_U_INT32(dptr, ruid);
1068         ADD_U_INT32(dptr, rgid);
1069         ADD_U_INT32(dptr, pid);
1070         ADD_U_INT32(dptr, sid);
1071         ADD_U_INT64(dptr, tid->port);
1072         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1073
1074         return (t);
1075 }
1076
1077 token_t *
1078 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1079     pid_t pid, au_asid_t sid, au_tid_t *tid)
1080 {
1081
1082         return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1083             tid));
1084 }
1085
1086 /*
1087  * token ID                1 byte
1088  * audit ID                4 bytes
1089  * effective user ID       4 bytes
1090  * effective group ID      4 bytes
1091  * real user ID            4 bytes
1092  * real group ID           4 bytes
1093  * process ID              4 bytes
1094  * session ID              4 bytes
1095  * terminal ID
1096  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1097  *   address type/length   4 bytes
1098  *   machine address      16 bytes
1099  */
1100 token_t *
1101 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1102     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1103 {
1104         token_t *t;
1105         u_char *dptr = NULL;
1106
1107         KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1108             ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1109
1110         if (tid->at_type == AU_IPv4)
1111                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1112                     sizeof(u_int32_t));
1113         else
1114                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1115                     sizeof(u_int32_t));
1116
1117         ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1118         ADD_U_INT32(dptr, auid);
1119         ADD_U_INT32(dptr, euid);
1120         ADD_U_INT32(dptr, egid);
1121         ADD_U_INT32(dptr, ruid);
1122         ADD_U_INT32(dptr, rgid);
1123         ADD_U_INT32(dptr, pid);
1124         ADD_U_INT32(dptr, sid);
1125         ADD_U_INT32(dptr, tid->at_port);
1126         ADD_U_INT32(dptr, tid->at_type);
1127         if (tid->at_type == AU_IPv6)
1128                 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1129         else
1130                 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1131
1132         return (t);
1133 }
1134
1135 token_t *
1136 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1137     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1138 {
1139         token_t *t;
1140         u_char *dptr = NULL;
1141
1142         KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1143             ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1144
1145         if (tid->at_type == AU_IPv4)
1146                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1147                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1148                     2 * sizeof(u_int32_t));
1149         else
1150                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1151                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1152                     5 * sizeof(u_int32_t));
1153
1154         ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1155         ADD_U_INT32(dptr, auid);
1156         ADD_U_INT32(dptr, euid);
1157         ADD_U_INT32(dptr, egid);
1158         ADD_U_INT32(dptr, ruid);
1159         ADD_U_INT32(dptr, rgid);
1160         ADD_U_INT32(dptr, pid);
1161         ADD_U_INT32(dptr, sid);
1162         ADD_U_INT64(dptr, tid->at_port);
1163         ADD_U_INT32(dptr, tid->at_type);
1164         if (tid->at_type == AU_IPv6)
1165                 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1166         else
1167                 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1168
1169         return (t);
1170 }
1171
1172 token_t *
1173 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1174     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1175 {
1176
1177         return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1178             tid));
1179 }
1180
1181 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1182 /*
1183  * Collects audit information for the current process and creates a subject
1184  * token from it.
1185  */
1186 token_t *
1187 au_to_me(void)
1188 {
1189         auditinfo_t auinfo;
1190
1191         if (getaudit(&auinfo) != 0)
1192                 return (NULL);
1193
1194         return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1195             getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1196 }
1197 #endif
1198
1199 #if defined(_KERNEL) || defined(KERNEL)
1200 static token_t *
1201 au_to_exec_strings(char *strs, int count, u_char type)
1202 {
1203         token_t *t;
1204         u_char *dptr = NULL;
1205         u_int32_t totlen;
1206         int ctr;
1207         char *p;
1208
1209         totlen = 0;
1210         ctr = count;
1211         p = strs;
1212         while (ctr-- > 0) {
1213                 totlen += strlen(p) + 1;
1214                 p = strs + totlen;
1215         }
1216         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1217         ADD_U_CHAR(dptr, type);
1218         ADD_U_INT32(dptr, count);
1219         ADD_STRING(dptr, strs, totlen);
1220
1221         return (t);
1222 }
1223
1224 /*
1225  * token ID                             1 byte
1226  * count                                4 bytes
1227  * text                                 count null-terminated strings
1228  */
1229 token_t *
1230 au_to_exec_args(char *args, int argc)
1231 {
1232
1233         return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1234 }
1235
1236 /*
1237  * token ID                             1 byte
1238  * count                                4 bytes
1239  * text                                 count null-terminated strings
1240  */
1241 token_t *
1242 au_to_exec_env(char *envs, int envc)
1243 {
1244
1245         return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1246 }
1247 #else
1248 /*
1249  * token ID                             1 byte
1250  * count                                4 bytes
1251  * text                                 count null-terminated strings
1252  */
1253 token_t *
1254 au_to_exec_args(char **argv)
1255 {
1256         token_t *t;
1257         u_char *dptr = NULL;
1258         const char *nextarg;
1259         int i, count = 0;
1260         size_t totlen = 0;
1261
1262         nextarg = *argv;
1263
1264         while (nextarg != NULL) {
1265                 int nextlen;
1266
1267                 nextlen = strlen(nextarg);
1268                 totlen += nextlen + 1;
1269                 count++;
1270                 nextarg = *(argv + count);
1271         }
1272
1273         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1274
1275         ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1276         ADD_U_INT32(dptr, count);
1277
1278         for (i = 0; i < count; i++) {
1279                 nextarg = *(argv + i);
1280                 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1281         }
1282
1283         return (t);
1284 }
1285
1286 /*
1287  * token ID                             1 byte
1288  * count                                4 bytes
1289  * text                                 count null-terminated strings
1290  */
1291 token_t *
1292 au_to_exec_env(char **envp)
1293 {
1294         token_t *t;
1295         u_char *dptr = NULL;
1296         int i, count = 0;
1297         size_t totlen = 0;
1298         const char *nextenv;
1299
1300         nextenv = *envp;
1301
1302         while (nextenv != NULL) {
1303                 int nextlen;
1304
1305                 nextlen = strlen(nextenv);
1306                 totlen += nextlen + 1;
1307                 count++;
1308                 nextenv = *(envp + count);
1309         }
1310
1311         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1312
1313         ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1314         ADD_U_INT32(dptr, count);
1315
1316         for (i = 0; i < count; i++) {
1317                 nextenv = *(envp + i);
1318                 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1319         }
1320
1321         return (t);
1322 }
1323 #endif
1324
1325 /*
1326  * token ID                1 byte
1327  * zonename length         2 bytes
1328  * zonename                N bytes + 1 terminating NULL byte
1329  */
1330 token_t *
1331 au_to_zonename(const char *zonename)
1332 {
1333         u_char *dptr = NULL;
1334         u_int16_t textlen;
1335         token_t *t;
1336
1337         textlen = strlen(zonename) + 1;
1338         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1339
1340         ADD_U_CHAR(dptr, AUT_ZONENAME);
1341         ADD_U_INT16(dptr, textlen);
1342         ADD_STRING(dptr, zonename, textlen);
1343         return (t);
1344 }
1345
1346 /*
1347  * token ID                1 byte
1348  * record byte count       4 bytes
1349  * version #               1 byte    [2]
1350  * event type              2 bytes
1351  * event modifier          2 bytes
1352  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1353  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1354  */
1355 token_t *
1356 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1357     struct timeval tm)
1358 {
1359         token_t *t;
1360         u_char *dptr = NULL;
1361         u_int32_t timems;
1362
1363         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1364             sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1365
1366         ADD_U_CHAR(dptr, AUT_HEADER32);
1367         ADD_U_INT32(dptr, rec_size);
1368         ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1369         ADD_U_INT16(dptr, e_type);
1370         ADD_U_INT16(dptr, e_mod);
1371
1372         timems = tm.tv_usec/1000;
1373         /* Add the timestamp */
1374         ADD_U_INT32(dptr, tm.tv_sec);
1375         ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1376
1377         return (t);
1378 }
1379
1380 /*
1381  * token ID                1 byte
1382  * record byte count       4 bytes
1383  * version #               1 byte    [2]
1384  * event type              2 bytes
1385  * event modifier          2 bytes
1386  * address type/length     4 bytes
1387  * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1388  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1389  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1390  */
1391 token_t *
1392 au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1393     struct timeval tm, struct auditinfo_addr *aia)
1394 {
1395         token_t *t;
1396         u_char *dptr = NULL;
1397         u_int32_t timems;
1398         au_tid_addr_t *tid;
1399
1400         tid = &aia->ai_termid;
1401         KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1402             ("au_to_header32_ex_tm: invalid address family"));
1403
1404         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1405             sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1406             sizeof(u_int32_t) + tid->at_type);
1407
1408         ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1409         ADD_U_INT32(dptr, rec_size);
1410         ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1411         ADD_U_INT16(dptr, e_type);
1412         ADD_U_INT16(dptr, e_mod);
1413
1414         ADD_U_INT32(dptr, tid->at_type);
1415         if (tid->at_type == AU_IPv6)
1416                 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1417         else
1418                 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1419         timems = tm.tv_usec/1000;
1420         /* Add the timestamp */
1421         ADD_U_INT32(dptr, tm.tv_sec);
1422         ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1423
1424         return (t);   
1425 }
1426
1427 token_t *
1428 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1429     struct timeval tm)
1430 {
1431         token_t *t;
1432         u_char *dptr = NULL;
1433         u_int32_t timems;
1434
1435         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1436             sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1437
1438         ADD_U_CHAR(dptr, AUT_HEADER64);
1439         ADD_U_INT32(dptr, rec_size);
1440         ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1441         ADD_U_INT16(dptr, e_type);
1442         ADD_U_INT16(dptr, e_mod);
1443
1444         timems = tm.tv_usec/1000;
1445         /* Add the timestamp */
1446         ADD_U_INT64(dptr, tm.tv_sec);
1447         ADD_U_INT64(dptr, timems);      /* We need time in ms. */
1448
1449         return (t);
1450 }
1451
1452 #if !defined(KERNEL) && !defined(_KERNEL)
1453 #ifdef HAVE_AUDIT_SYSCALLS
1454 token_t *
1455 au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1456 {
1457         struct timeval tm;
1458         struct auditinfo_addr aia;
1459
1460         if (gettimeofday(&tm, NULL) == -1)
1461                 return (NULL);
1462         if (auditon(A_GETKAUDIT, &aia, sizeof(aia)) < 0) {
1463                 if (errno != ENOSYS)
1464                         return (NULL);
1465                 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1466         }
1467         return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1468 }
1469 #endif /* HAVE_AUDIT_SYSCALLS */
1470
1471 token_t *
1472 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1473 {
1474         struct timeval tm;
1475
1476         if (gettimeofday(&tm, NULL) == -1)
1477                 return (NULL);
1478         return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1479 }
1480
1481 token_t *
1482 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1483     __unused au_emod_t e_mod)
1484 {
1485         struct timeval tm;
1486
1487         if (gettimeofday(&tm, NULL) == -1)
1488                 return (NULL);
1489         return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1490 }
1491
1492 token_t *
1493 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1494 {
1495
1496         return (au_to_header32(rec_size, e_type, e_mod));
1497 }
1498
1499 #ifdef HAVE_AUDIT_SYSCALLS
1500 token_t *
1501 au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1502 {
1503
1504         return (au_to_header32_ex(rec_size, e_type, e_mod));
1505 }
1506 #endif /* HAVE_AUDIT_SYSCALLS */
1507 #endif /* !defined(KERNEL) && !defined(_KERNEL) */
1508
1509 /*
1510  * token ID                1 byte
1511  * trailer magic number    2 bytes
1512  * record byte count       4 bytes
1513  */
1514 token_t *
1515 au_to_trailer(int rec_size)
1516 {
1517         token_t *t;
1518         u_char *dptr = NULL;
1519         u_int16_t magic = AUT_TRAILER_MAGIC;
1520
1521         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1522             sizeof(u_int32_t));
1523
1524         ADD_U_CHAR(dptr, AUT_TRAILER);
1525         ADD_U_INT16(dptr, magic);
1526         ADD_U_INT32(dptr, rec_size);
1527
1528         return (t);
1529 }