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