]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/security/audit/audit_bsm_token.c
This commit was generated by cvs2svn to compensate for changes in r168988,
[FreeBSD/FreeBSD.git] / sys / security / audit / audit_bsm_token.c
1 /*
2  * Copyright (c) 2004 Apple Computer, 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 Computer, 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  * $FreeBSD$
34  */
35
36 #include <sys/types.h>
37 #include <sys/endian.h>
38 #include <sys/queue.h>
39 #include <sys/socket.h>
40 #include <sys/time.h>
41
42 #include <sys/ipc.h>
43 #include <sys/libkern.h>
44 #include <sys/malloc.h>
45 #include <sys/un.h>
46
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/ip.h>
50
51
52 #include <bsm/audit.h>
53 #include <bsm/audit_internal.h>
54 #include <bsm/audit_record.h>
55 #include <security/audit/audit.h>
56 #include <security/audit/audit_private.h>
57
58 #define GET_TOKEN_AREA(t, dptr, length) do {                            \
59         t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);              \
60         t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);      \
61         t->len = length;                                                \
62         dptr = t->t_data;                                               \
63 } while (0)
64
65 /*
66  * token ID                1 byte
67  * argument #              1 byte
68  * argument value          4 bytes/8 bytes (32-bit/64-bit value)
69  * text length             2 bytes
70  * text                    N bytes + 1 terminating NULL byte
71  */
72 token_t *
73 au_to_arg32(char n, char *text, u_int32_t v)
74 {
75         token_t *t;
76         u_char *dptr = NULL;
77         u_int16_t textlen;
78
79         textlen = strlen(text);
80         textlen += 1;
81
82         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
83             sizeof(u_int16_t) + textlen);
84
85         ADD_U_CHAR(dptr, AUT_ARG32);
86         ADD_U_CHAR(dptr, n);
87         ADD_U_INT32(dptr, v);
88         ADD_U_INT16(dptr, textlen);
89         ADD_STRING(dptr, text, textlen);
90
91         return (t);
92
93 }
94
95 token_t *
96 au_to_arg64(char n, char *text, u_int64_t v)
97 {
98         token_t *t;
99         u_char *dptr = NULL;
100         u_int16_t textlen;
101
102         textlen = strlen(text);
103         textlen += 1;
104
105         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
106             sizeof(u_int16_t) + textlen);
107
108         ADD_U_CHAR(dptr, AUT_ARG64);
109         ADD_U_CHAR(dptr, n);
110         ADD_U_INT64(dptr, v);
111         ADD_U_INT16(dptr, textlen);
112         ADD_STRING(dptr, text, textlen);
113
114         return (t);
115
116 }
117
118 token_t *
119 au_to_arg(char n, char *text, u_int32_t v)
120 {
121
122         return (au_to_arg32(n, text, v));
123 }
124
125 #if defined(_KERNEL) || defined(KERNEL)
126 /*
127  * token ID                1 byte
128  * file access mode        4 bytes
129  * owner user ID           4 bytes
130  * owner group ID          4 bytes
131  * file system ID          4 bytes
132  * node ID                 8 bytes
133  * device                  4 bytes/8 bytes (32-bit/64-bit)
134  */
135 token_t *
136 au_to_attr32(struct vnode_au_info *vni)
137 {
138         token_t *t;
139         u_char *dptr = NULL;
140         u_int16_t pad0_16 = 0;
141         u_int16_t pad0_32 = 0;
142
143         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
144             3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
145
146         ADD_U_CHAR(dptr, AUT_ATTR32);
147
148         /*
149          * Darwin defines the size for the file mode
150          * as 2 bytes; BSM defines 4 so pad with 0
151          */
152         ADD_U_INT16(dptr, pad0_16);
153         ADD_U_INT16(dptr, vni->vn_mode);
154
155         ADD_U_INT32(dptr, vni->vn_uid);
156         ADD_U_INT32(dptr, vni->vn_gid);
157         ADD_U_INT32(dptr, vni->vn_fsid);
158
159         /*
160          * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
161          * Attempt to handle both, and let the compiler sort it out.  If we
162          * could pick this out at compile-time, it would be better, so as to
163          * avoid the else case below.
164          */
165         if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
166                 ADD_U_INT32(dptr, pad0_32);
167                 ADD_U_INT32(dptr, vni->vn_fileid);
168         } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
169                 ADD_U_INT64(dptr, vni->vn_fileid);
170         else
171                 ADD_U_INT64(dptr, 0LL);
172
173         ADD_U_INT32(dptr, vni->vn_dev);
174
175         return (t);
176 }
177
178 token_t *
179 au_to_attr64(struct vnode_au_info *vni)
180 {
181         token_t *t;
182         u_char *dptr = NULL;
183         u_int16_t pad0_16 = 0;
184         u_int16_t pad0_32 = 0;
185
186         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
187             3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
188
189         ADD_U_CHAR(dptr, AUT_ATTR64);
190
191         /*
192          * Darwin defines the size for the file mode
193          * as 2 bytes; BSM defines 4 so pad with 0
194          */
195         ADD_U_INT16(dptr, pad0_16);
196         ADD_U_INT16(dptr, vni->vn_mode);
197
198         ADD_U_INT32(dptr, vni->vn_uid);
199         ADD_U_INT32(dptr, vni->vn_gid);
200         ADD_U_INT32(dptr, vni->vn_fsid);
201
202         /*
203          * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
204          * Attempt to handle both, and let the compiler sort it out.  If we
205          * could pick this out at compile-time, it would be better, so as to
206          * avoid the else case below.
207          */
208         if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
209                 ADD_U_INT32(dptr, pad0_32);
210                 ADD_U_INT32(dptr, vni->vn_fileid);
211         } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
212                 ADD_U_INT64(dptr, vni->vn_fileid);
213         else
214                 ADD_U_INT64(dptr, 0LL);
215
216         ADD_U_INT64(dptr, vni->vn_dev);
217
218         return (t);
219 }
220
221 token_t *
222 au_to_attr(struct vnode_au_info *vni)
223 {
224
225         return (au_to_attr32(vni));
226 }
227 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
228
229 /*
230  * token ID                1 byte
231  * how to print            1 byte
232  * basic unit              1 byte
233  * unit count              1 byte
234  * data items              (depends on basic unit)
235  */
236 token_t *
237 au_to_data(char unit_print, char unit_type, char unit_count, char *p)
238 {
239         token_t *t;
240         u_char *dptr = NULL;
241         size_t datasize, totdata;
242
243         /* Determine the size of the basic unit. */
244         switch (unit_type) {
245         case AUR_BYTE:
246         /* case AUR_CHAR: */
247                 datasize = AUR_BYTE_SIZE;
248                 break;
249
250         case AUR_SHORT:
251                 datasize = AUR_SHORT_SIZE;
252                 break;
253
254         case AUR_INT32:
255         /* case AUR_INT: */
256                 datasize = AUR_INT32_SIZE;
257                 break;
258
259         case AUR_INT64:
260                 datasize = AUR_INT64_SIZE;
261                 break;
262
263         default:
264                 return (NULL);
265         }
266
267         totdata = datasize * unit_count;
268
269         GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
270
271         ADD_U_CHAR(dptr, AUT_DATA);
272         ADD_U_CHAR(dptr, unit_print);
273         ADD_U_CHAR(dptr, unit_type);
274         ADD_U_CHAR(dptr, unit_count);
275         ADD_MEM(dptr, p, totdata);
276
277         return (t);
278 }
279
280
281 /*
282  * token ID                1 byte
283  * status                  4 bytes
284  * return value            4 bytes
285  */
286 token_t *
287 au_to_exit(int retval, int err)
288 {
289         token_t *t;
290         u_char *dptr = NULL;
291
292         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
293
294         ADD_U_CHAR(dptr, AUT_EXIT);
295         ADD_U_INT32(dptr, err);
296         ADD_U_INT32(dptr, retval);
297
298         return (t);
299 }
300
301 /*
302  */
303 token_t *
304 au_to_groups(int *groups)
305 {
306
307         return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t*)groups));
308 }
309
310 /*
311  * token ID                1 byte
312  * number groups           2 bytes
313  * group list              count * 4 bytes
314  */
315 token_t *
316 au_to_newgroups(u_int16_t n, gid_t *groups)
317 {
318         token_t *t;
319         u_char *dptr = NULL;
320         int i;
321
322         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
323             n * sizeof(u_int32_t));
324
325         ADD_U_CHAR(dptr, AUT_NEWGROUPS);
326         ADD_U_INT16(dptr, n);
327         for (i = 0; i < n; i++)
328                 ADD_U_INT32(dptr, groups[i]);
329
330         return (t);
331 }
332
333 /*
334  * token ID                1 byte
335  * internet address        4 bytes
336  */
337 token_t *
338 au_to_in_addr(struct in_addr *internet_addr)
339 {
340         token_t *t;
341         u_char *dptr = NULL;
342
343         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
344
345         ADD_U_CHAR(dptr, AUT_IN_ADDR);
346         ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
347
348         return (t);
349 }
350
351 /*
352  * token ID                1 byte
353  * address type/length     4 bytes
354  * Address                16 bytes
355  */
356 token_t *
357 au_to_in_addr_ex(struct in6_addr *internet_addr)
358 {
359         token_t *t;
360         u_char *dptr = NULL;
361         u_int32_t type = AF_INET6;
362
363         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
364
365         ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
366         ADD_U_INT32(dptr, type);
367         ADD_MEM(dptr, internet_addr, 5 * sizeof(uint32_t));
368
369         return (t);
370 }
371
372 /*
373  * token ID                1 byte
374  * ip header               20 bytes
375  *
376  * The IP header should be submitted in network byte order.
377  */
378 token_t *
379 au_to_ip(struct ip *ip)
380 {
381         token_t *t;
382         u_char *dptr = NULL;
383
384         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
385
386         ADD_U_CHAR(dptr, AUT_IP);
387         ADD_MEM(dptr, ip, sizeof(struct ip));
388
389         return (t);
390 }
391
392 /*
393  * token ID                1 byte
394  * object ID type          1 byte
395  * object ID               4 bytes
396  */
397 token_t *
398 au_to_ipc(char type, int id)
399 {
400         token_t *t;
401         u_char *dptr = NULL;
402
403         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
404
405         ADD_U_CHAR(dptr, AUT_IPC);
406         ADD_U_CHAR(dptr, type);
407         ADD_U_INT32(dptr, id);
408
409         return (t);
410 }
411
412 /*
413  * token ID                1 byte
414  * owner user ID           4 bytes
415  * owner group ID          4 bytes
416  * creator user ID         4 bytes
417  * creator group ID        4 bytes
418  * access mode             4 bytes
419  * slot sequence #         4 bytes
420  * key                     4 bytes
421  */
422 token_t *
423 au_to_ipc_perm(struct ipc_perm *perm)
424 {
425         token_t *t;
426         u_char *dptr = NULL;
427         u_int16_t pad0 = 0;
428
429         GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
430
431         ADD_U_CHAR(dptr, AUT_IPC_PERM);
432
433         /*
434          * Darwin defines the sizes for ipc_perm members
435          * as 2 bytes; BSM defines 4 so pad with 0
436          */
437         ADD_U_INT16(dptr, pad0);
438         ADD_U_INT16(dptr, perm->uid);
439
440         ADD_U_INT16(dptr, pad0);
441         ADD_U_INT16(dptr, perm->gid);
442
443         ADD_U_INT16(dptr, pad0);
444         ADD_U_INT16(dptr, perm->cuid);
445
446         ADD_U_INT16(dptr, pad0);
447         ADD_U_INT16(dptr, perm->cgid);
448
449         ADD_U_INT16(dptr, pad0);
450         ADD_U_INT16(dptr, perm->mode);
451
452         ADD_U_INT16(dptr, pad0);
453         ADD_U_INT16(dptr, perm->seq);
454
455         ADD_U_INT32(dptr, perm->key);
456
457         return (t);
458 }
459
460 /*
461  * token ID                1 byte
462  * port IP address         2 bytes
463  */
464 token_t *
465 au_to_iport(u_int16_t iport)
466 {
467         token_t *t;
468         u_char *dptr = NULL;
469
470         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
471
472         ADD_U_CHAR(dptr, AUT_IPORT);
473         ADD_U_INT16(dptr, iport);
474
475         return (t);
476 }
477
478 /*
479  * token ID                1 byte
480  * size                    2 bytes
481  * data                    size bytes
482  */
483 token_t *
484 au_to_opaque(char *data, u_int16_t bytes)
485 {
486         token_t *t;
487         u_char *dptr = NULL;
488
489         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
490
491         ADD_U_CHAR(dptr, AUT_OPAQUE);
492         ADD_U_INT16(dptr, bytes);
493         ADD_MEM(dptr, data, bytes);
494
495         return (t);
496 }
497
498 /*
499  * token ID                1 byte
500  * seconds of time         4 bytes
501  * milliseconds of time    4 bytes
502  * file name len           2 bytes
503  * file pathname           N bytes + 1 terminating NULL byte
504  */
505 token_t *
506 au_to_file(char *file, struct timeval tm)
507 {
508         token_t *t;
509         u_char *dptr = NULL;
510         u_int16_t filelen;
511         u_int32_t timems;
512
513         filelen = strlen(file);
514         filelen += 1;
515
516         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
517             sizeof(u_int16_t) + filelen);
518
519         timems = tm.tv_usec/1000;
520
521         ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
522         ADD_U_INT32(dptr, tm.tv_sec);
523         ADD_U_INT32(dptr, timems);      /* We need time in ms. */
524         ADD_U_INT16(dptr, filelen);
525         ADD_STRING(dptr, file, filelen);
526
527         return (t);
528 }
529
530 /*
531  * token ID                1 byte
532  * text length             2 bytes
533  * text                    N bytes + 1 terminating NULL byte
534  */
535 token_t *
536 au_to_text(char *text)
537 {
538         token_t *t;
539         u_char *dptr = NULL;
540         u_int16_t textlen;
541
542         textlen = strlen(text);
543         textlen += 1;
544
545         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
546
547         ADD_U_CHAR(dptr, AUT_TEXT);
548         ADD_U_INT16(dptr, textlen);
549         ADD_STRING(dptr, text, textlen);
550
551         return (t);
552 }
553
554 /*
555  * token ID                1 byte
556  * path length             2 bytes
557  * path                    N bytes + 1 terminating NULL byte
558  */
559 token_t *
560 au_to_path(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         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
570
571         ADD_U_CHAR(dptr, AUT_PATH);
572         ADD_U_INT16(dptr, textlen);
573         ADD_STRING(dptr, text, textlen);
574
575         return (t);
576 }
577
578 /*
579  * token ID                1 byte
580  * audit ID                4 bytes
581  * effective user ID       4 bytes
582  * effective group ID      4 bytes
583  * real user ID            4 bytes
584  * real group ID           4 bytes
585  * process ID              4 bytes
586  * session ID              4 bytes
587  * terminal ID
588  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
589  *   machine address       4 bytes
590  */
591 token_t *
592 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
593     pid_t pid, au_asid_t sid, au_tid_t *tid)
594 {
595         token_t *t;
596         u_char *dptr = NULL;
597
598         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
599
600         ADD_U_CHAR(dptr, AUT_PROCESS32);
601         ADD_U_INT32(dptr, auid);
602         ADD_U_INT32(dptr, euid);
603         ADD_U_INT32(dptr, egid);
604         ADD_U_INT32(dptr, ruid);
605         ADD_U_INT32(dptr, rgid);
606         ADD_U_INT32(dptr, pid);
607         ADD_U_INT32(dptr, sid);
608         ADD_U_INT32(dptr, tid->port);
609         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
610
611         return (t);
612 }
613
614 token_t *
615 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
616     pid_t pid, au_asid_t sid, au_tid_t *tid)
617 {
618         token_t *t;
619         u_char *dptr = NULL;
620
621         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
622             sizeof(u_int64_t));
623
624         ADD_U_CHAR(dptr, AUT_PROCESS64);
625         ADD_U_INT32(dptr, auid);
626         ADD_U_INT32(dptr, euid);
627         ADD_U_INT32(dptr, egid);
628         ADD_U_INT32(dptr, ruid);
629         ADD_U_INT32(dptr, rgid);
630         ADD_U_INT32(dptr, pid);
631         ADD_U_INT32(dptr, sid);
632         ADD_U_INT64(dptr, tid->port);
633         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
634
635         return (t);
636 }
637
638 token_t *
639 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
640     pid_t pid, au_asid_t sid, au_tid_t *tid)
641 {
642
643         return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
644             tid));
645 }
646
647 /*
648  * token ID                1 byte
649  * audit ID                4 bytes
650  * effective user ID       4 bytes
651  * effective group ID      4 bytes
652  * real user ID            4 bytes
653  * real group ID           4 bytes
654  * process ID              4 bytes
655  * session ID              4 bytes
656  * terminal ID
657  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
658  *   address type-len      4 bytes
659  *   machine address    4/16 bytes
660  */
661 token_t *
662 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
663     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
664 {
665         token_t *t;
666         u_char *dptr = NULL;
667
668         KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
669             ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
670         if (tid->at_type == AU_IPv6)
671                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
672                     sizeof(u_int32_t));
673         else
674                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
675                     sizeof(u_int32_t));
676
677         ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
678         ADD_U_INT32(dptr, auid);
679         ADD_U_INT32(dptr, euid);
680         ADD_U_INT32(dptr, egid);
681         ADD_U_INT32(dptr, ruid);
682         ADD_U_INT32(dptr, rgid);
683         ADD_U_INT32(dptr, pid);
684         ADD_U_INT32(dptr, sid);
685         ADD_U_INT32(dptr, tid->at_port);
686         ADD_U_INT32(dptr, tid->at_type);
687         if (tid->at_type == AU_IPv6)
688                 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
689         else
690                 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
691         return (t);
692 }
693
694 token_t *
695 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
696     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
697 {
698         token_t *t;
699         u_char *dptr = NULL;
700
701         if (tid->at_type == AU_IPv4)
702                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
703                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
704                     2 * sizeof(u_int32_t));
705         else if (tid->at_type == AU_IPv6)
706                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
707                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
708                     5 * sizeof(u_int32_t));
709         else
710                 panic("au_to_process64_ex: invalidate at_type (%d)",
711                     tid->at_type);
712
713         ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
714         ADD_U_INT32(dptr, auid);
715         ADD_U_INT32(dptr, euid);
716         ADD_U_INT32(dptr, egid);
717         ADD_U_INT32(dptr, ruid);
718         ADD_U_INT32(dptr, rgid);
719         ADD_U_INT32(dptr, pid);
720         ADD_U_INT32(dptr, sid);
721         ADD_U_INT64(dptr, tid->at_port);
722         ADD_U_INT32(dptr, tid->at_type);
723         ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
724         if (tid->at_type == AU_IPv6) {
725                 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
726                 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
727                 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
728         }
729
730         return (t);
731 }
732
733 token_t *
734 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
735     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
736 {
737
738         return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
739             tid));
740 }
741
742 /*
743  * token ID                1 byte
744  * error status            1 byte
745  * return value            4 bytes/8 bytes (32-bit/64-bit value)
746  */
747 token_t *
748 au_to_return32(char status, u_int32_t ret)
749 {
750         token_t *t;
751         u_char *dptr = NULL;
752
753         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
754
755         ADD_U_CHAR(dptr, AUT_RETURN32);
756         ADD_U_CHAR(dptr, status);
757         ADD_U_INT32(dptr, ret);
758
759         return (t);
760 }
761
762 token_t *
763 au_to_return64(char status, u_int64_t ret)
764 {
765         token_t *t;
766         u_char *dptr = NULL;
767
768         GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
769
770         ADD_U_CHAR(dptr, AUT_RETURN64);
771         ADD_U_CHAR(dptr, status);
772         ADD_U_INT64(dptr, ret);
773
774         return (t);
775 }
776
777 token_t *
778 au_to_return(char status, u_int32_t ret)
779 {
780
781         return (au_to_return32(status, ret));
782 }
783
784 /*
785  * token ID                1 byte
786  * sequence number         4 bytes
787  */
788 token_t *
789 au_to_seq(long audit_count)
790 {
791         token_t *t;
792         u_char *dptr = NULL;
793
794         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
795
796         ADD_U_CHAR(dptr, AUT_SEQ);
797         ADD_U_INT32(dptr, audit_count);
798
799         return (t);
800 }
801
802 /*
803  * token ID                1 byte
804  * socket type             2 bytes
805  * local port              2 bytes
806  * local Internet address  4 bytes
807  * remote port             2 bytes
808  * remote Internet address 4 bytes
809  */
810 token_t *
811 au_to_socket(struct socket *so)
812 {
813
814         /* XXXRW ... */
815         return (NULL);
816 }
817
818 /*
819  * Kernel-specific version of the above function.
820  */
821 #ifdef _KERNEL
822 token_t *
823 kau_to_socket(struct socket_au_info *soi)
824 {
825         token_t *t;
826         u_char *dptr;
827         u_int16_t so_type;
828
829         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
830             sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
831                                                  
832         ADD_U_CHAR(dptr, AU_SOCK_TOKEN);
833         /* Coerce the socket type into a short value */
834         so_type = soi->so_type;
835         ADD_U_INT16(dptr, so_type);
836         ADD_U_INT16(dptr, soi->so_lport);
837         ADD_U_INT32(dptr, soi->so_laddr);
838         ADD_U_INT16(dptr, soi->so_rport);
839         ADD_U_INT32(dptr, soi->so_raddr);
840
841         return (t);
842 }
843 #endif
844
845 /*
846  * token ID                1 byte
847  * socket type             2 bytes
848  * local port              2 bytes
849  * address type/length     4 bytes
850  * local Internet address  4 bytes/16 bytes (IPv4/IPv6 address)
851  * remote port             4 bytes
852  * address type/length     4 bytes
853  * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
854  */
855 token_t *
856 au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
857     struct sockaddr *ra)
858 {
859
860         return (NULL);
861 }
862
863 token_t *
864 au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
865     struct sockaddr *ra)
866 {
867
868         return (NULL);
869 }
870
871 /*
872  * token ID                1 byte
873  * socket family           2 bytes
874  * path                    104 bytes
875  */
876 token_t *
877 au_to_sock_unix(struct sockaddr_un *so)
878 {
879         token_t *t;
880         u_char *dptr;
881
882         GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
883
884         ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
885         /* BSM token has two bytes for family */
886         ADD_U_CHAR(dptr, 0);
887         ADD_U_CHAR(dptr, so->sun_family);
888         ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
889
890         return (t);
891 }
892
893 /*
894  * token ID                1 byte
895  * socket family           2 bytes
896  * local port              2 bytes
897  * socket address          4 bytes
898  */
899 token_t *
900 au_to_sock_inet32(struct sockaddr_in *so)
901 {
902         token_t *t;
903         u_char *dptr = NULL;
904         uint16_t family;
905
906         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
907             sizeof(uint32_t));
908
909         ADD_U_CHAR(dptr, AUT_SOCKINET32);
910         /*
911          * BSM defines the family field as 16 bits, but many operating
912          * systems have an 8-bit sin_family field.  Extend to 16 bits before
913          * writing into the token.  Assume that both the port and the address
914          * in the sockaddr_in are already in network byte order, but family
915          * is in local byte order.
916          *
917          * XXXRW: Should a name space conversion be taking place on the value
918          * of sin_family?
919          */
920         family = so->sin_family;
921         ADD_U_INT16(dptr, family);
922         ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
923         ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
924
925         return (t);
926
927 }
928
929 token_t *
930 au_to_sock_inet128(struct sockaddr_in6 *so)
931 {
932         token_t *t;
933         u_char *dptr = NULL;
934
935         GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
936             4 * sizeof(u_int32_t));
937
938         ADD_U_CHAR(dptr, AUT_SOCKINET128);
939         /*
940          * In Darwin, sin6_family is one octet, but BSM defines the token
941          * to store two. So we copy in a 0 first.
942          */
943         ADD_U_CHAR(dptr, 0);
944         ADD_U_CHAR(dptr, so->sin6_family);
945
946         ADD_U_INT16(dptr, so->sin6_port);
947         ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
948
949         return (t);
950
951 }
952
953 token_t *
954 au_to_sock_inet(struct sockaddr_in *so)
955 {
956
957         return (au_to_sock_inet32(so));
958 }
959
960 /*
961  * token ID                1 byte
962  * audit ID                4 bytes
963  * effective user ID       4 bytes
964  * effective group ID      4 bytes
965  * real user ID            4 bytes
966  * real group ID           4 bytes
967  * process ID              4 bytes
968  * session ID              4 bytes
969  * terminal ID
970  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
971  *   machine address       4 bytes
972  */
973 token_t *
974 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
975     pid_t pid, au_asid_t sid, au_tid_t *tid)
976 {
977         token_t *t;
978         u_char *dptr = NULL;
979
980         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
981
982         ADD_U_CHAR(dptr, AUT_SUBJECT32);
983         ADD_U_INT32(dptr, auid);
984         ADD_U_INT32(dptr, euid);
985         ADD_U_INT32(dptr, egid);
986         ADD_U_INT32(dptr, ruid);
987         ADD_U_INT32(dptr, rgid);
988         ADD_U_INT32(dptr, pid);
989         ADD_U_INT32(dptr, sid);
990         ADD_U_INT32(dptr, tid->port);
991         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
992
993         return (t);
994 }
995
996 token_t *
997 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
998     pid_t pid, au_asid_t sid, au_tid_t *tid)
999 {
1000         token_t *t;
1001         u_char *dptr = NULL;
1002
1003         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1004             sizeof(u_int64_t) + sizeof(u_int32_t));
1005
1006         ADD_U_CHAR(dptr, AUT_SUBJECT64);
1007         ADD_U_INT32(dptr, auid);
1008         ADD_U_INT32(dptr, euid);
1009         ADD_U_INT32(dptr, egid);
1010         ADD_U_INT32(dptr, ruid);
1011         ADD_U_INT32(dptr, rgid);
1012         ADD_U_INT32(dptr, pid);
1013         ADD_U_INT32(dptr, sid);
1014         ADD_U_INT64(dptr, tid->port);
1015         ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1016
1017         return (t);
1018 }
1019
1020 token_t *
1021 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1022     pid_t pid, au_asid_t sid, au_tid_t *tid)
1023 {
1024
1025         return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1026             tid));
1027 }
1028
1029 /*
1030  * token ID                1 byte
1031  * audit ID                4 bytes
1032  * effective user ID       4 bytes
1033  * effective group ID      4 bytes
1034  * real user ID            4 bytes
1035  * real group ID           4 bytes
1036  * process ID              4 bytes
1037  * session ID              4 bytes
1038  * terminal ID
1039  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1040  *   address type/length   4 bytes
1041  *   machine address    4/16 bytes
1042  */
1043 token_t *
1044 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1045     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1046 {
1047         token_t *t;
1048         u_char *dptr = NULL;
1049
1050         KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1051             ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1052         if (tid->at_type == AU_IPv6)
1053                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1054                     sizeof(u_int32_t));
1055         else
1056                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1057                     sizeof(u_int32_t));
1058
1059         ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1060         ADD_U_INT32(dptr, auid);
1061         ADD_U_INT32(dptr, euid);
1062         ADD_U_INT32(dptr, egid);
1063         ADD_U_INT32(dptr, ruid);
1064         ADD_U_INT32(dptr, rgid);
1065         ADD_U_INT32(dptr, pid);
1066         ADD_U_INT32(dptr, sid);
1067         ADD_U_INT32(dptr, tid->at_port);
1068         ADD_U_INT32(dptr, tid->at_type);
1069         if (tid->at_type == AU_IPv6)  
1070                 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1071         else    
1072                 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1073         return (t);
1074 }
1075
1076 token_t *
1077 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1078     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1079 {
1080         token_t *t;
1081         u_char *dptr = NULL;
1082
1083         if (tid->at_type == AU_IPv4)
1084                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1085                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1086                     2 * sizeof(u_int32_t));
1087         else if (tid->at_type == AU_IPv6)
1088                 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1089                     7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1090                     5 * sizeof(u_int32_t));
1091         else
1092                 panic("au_to_subject64_ex: invalid at_type (%d)",
1093                     tid->at_type);
1094
1095         ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1096         ADD_U_INT32(dptr, auid);
1097         ADD_U_INT32(dptr, euid);
1098         ADD_U_INT32(dptr, egid);
1099         ADD_U_INT32(dptr, ruid);
1100         ADD_U_INT32(dptr, rgid);
1101         ADD_U_INT32(dptr, pid);
1102         ADD_U_INT32(dptr, sid);
1103         ADD_U_INT64(dptr, tid->at_port);
1104         ADD_U_INT32(dptr, tid->at_type);
1105         if (tid->at_type == AU_IPv6)
1106                 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1107         else
1108                 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1109
1110         return (t);
1111 }
1112
1113 token_t *
1114 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1115     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1116 {
1117
1118         return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1119             tid));
1120 }
1121
1122 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1123 /*
1124  * Collects audit information for the current process
1125  * and creates a subject token from it
1126  */
1127 token_t *
1128 au_to_me(void)
1129 {
1130         auditinfo_t auinfo;
1131
1132         if (getaudit(&auinfo) != 0)
1133                 return (NULL);
1134
1135         return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1136             getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1137 }
1138 #endif
1139
1140 #if defined(_KERNEL) || defined(KERNEL)
1141 static token_t *
1142 au_to_exec_strings(char *strs, int count, u_char type)
1143 {
1144         token_t *t;
1145         u_char *dptr = NULL;
1146         u_int32_t totlen;
1147         int ctr;
1148         char *p;
1149
1150         totlen = 0;
1151         ctr = count;
1152         p = strs;
1153         while (ctr-- > 0) {
1154                 totlen += strlen(p) + 1;
1155                 p = strs + totlen;
1156         }
1157         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1158         ADD_U_CHAR(dptr, type);
1159         ADD_U_INT32(dptr, count);
1160         ADD_STRING(dptr, strs, totlen);
1161
1162         return (t);
1163 }
1164
1165 /*
1166  * token ID                             1 byte
1167  * count                                4 bytes
1168  * text                                 count null-terminated strings
1169  */
1170 token_t *
1171 au_to_exec_args(char *args, int argc)
1172 {
1173
1174         return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1175 }
1176
1177 /*
1178  * token ID                             1 byte
1179  * count                                4 bytes
1180  * text                                 count null-terminated strings
1181  */
1182 token_t *
1183 au_to_exec_env(char *envs, int envc)
1184 {
1185
1186         return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1187 }
1188 #else
1189 /*
1190  * token ID                             1 byte
1191  * count                                4 bytes
1192  * text                                 count null-terminated strings
1193  */
1194 token_t *
1195 au_to_exec_args(char **argv)
1196 {
1197         token_t *t;
1198         u_char *dptr = NULL;
1199         const char *nextarg;
1200         int i, count = 0;
1201         size_t totlen = 0;
1202
1203         nextarg = *argv;
1204
1205         while (nextarg != NULL) {
1206                 int nextlen;
1207
1208                 nextlen = strlen(nextarg);
1209                 totlen += nextlen + 1;
1210                 count++;
1211                 nextarg = *(argv + count);
1212         }
1213
1214         totlen += count * sizeof(char); /* nul terminations. */
1215         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1216
1217         ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1218         ADD_U_INT32(dptr, count);
1219
1220         for (i = 0; i < count; i++) {
1221                 nextarg = *(argv + i);
1222                 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1223         }
1224
1225         return (t);
1226 }
1227
1228 /*
1229  * token ID                1 byte
1230  * zonename length         2 bytes
1231  * zonename                N bytes + 1 terminating NULL byte
1232  */
1233 token_t *
1234 au_to_zonename(char *zonename)
1235 {
1236         u_char *dptr = NULL;
1237         u_int16_t textlen;
1238         token_t *t;
1239
1240         textlen = strlen(zonename);
1241         textlen += 1;
1242         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1243         ADD_U_CHAR(dptr, AUT_ZONENAME);
1244         ADD_U_INT16(dptr, textlen);
1245         ADD_STRING(dptr, zonename, textlen);
1246         return (t);
1247 }
1248
1249 /*
1250  * token ID                             1 byte
1251  * count                                4 bytes
1252  * text                                 count null-terminated strings
1253  */
1254 token_t *
1255 au_to_exec_env(char **envp)
1256 {
1257         token_t *t;
1258         u_char *dptr = NULL;
1259         int i, count = 0;
1260         size_t totlen = 0;
1261         const char *nextenv;
1262
1263         nextenv = *envp;
1264
1265         while (nextenv != NULL) {
1266                 int nextlen;
1267
1268                 nextlen = strlen(nextenv);
1269                 totlen += nextlen + 1;
1270                 count++;
1271                 nextenv = *(envp + count);
1272         }
1273
1274         totlen += sizeof(char) * count;
1275         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1276
1277         ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1278         ADD_U_INT32(dptr, count);
1279
1280         for (i = 0; i < count; i++) {
1281                 nextenv = *(envp + i);
1282                 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1283         }
1284
1285         return (t);
1286 }
1287 #endif
1288
1289 /*
1290  * token ID                1 byte
1291  * record byte count       4 bytes
1292  * version #               1 byte    [2]
1293  * event type              2 bytes
1294  * event modifier          2 bytes
1295  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1296  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1297  */
1298 token_t *
1299 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1300     struct timeval tm)
1301 {
1302         token_t *t;
1303         u_char *dptr = NULL;
1304         u_int32_t timems;
1305
1306         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1307             sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1308
1309         ADD_U_CHAR(dptr, AUT_HEADER32);
1310         ADD_U_INT32(dptr, rec_size);
1311         ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1312         ADD_U_INT16(dptr, e_type);
1313         ADD_U_INT16(dptr, e_mod);
1314
1315         timems = tm.tv_usec/1000;
1316         /* Add the timestamp */
1317         ADD_U_INT32(dptr, tm.tv_sec);
1318         ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1319
1320         return (t);
1321 }
1322
1323 token_t *
1324 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1325     struct timeval tm)
1326 {
1327         token_t *t;
1328         u_char *dptr = NULL;
1329         u_int32_t timems;
1330
1331         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1332             sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1333
1334         ADD_U_CHAR(dptr, AUT_HEADER64);
1335         ADD_U_INT32(dptr, rec_size);
1336         ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1337         ADD_U_INT16(dptr, e_type);
1338         ADD_U_INT16(dptr, e_mod);
1339
1340         timems = tm.tv_usec/1000;
1341         /* Add the timestamp */
1342         ADD_U_INT64(dptr, tm.tv_sec);
1343         ADD_U_INT64(dptr, timems);      /* We need time in ms. */
1344
1345         return (t);
1346 }
1347
1348 /*
1349  * token ID                1 byte
1350  * trailer magic number    2 bytes
1351  * record byte count       4 bytes
1352  */
1353 token_t *
1354 au_to_trailer(int rec_size)
1355 {
1356         token_t *t;
1357         u_char *dptr = NULL;
1358         u_int16_t magic = TRAILER_PAD_MAGIC;
1359
1360         GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1361             sizeof(u_int32_t));
1362
1363         ADD_U_CHAR(dptr, AUT_TRAILER);
1364         ADD_U_INT16(dptr, magic);
1365         ADD_U_INT32(dptr, rec_size);
1366
1367         return (t);
1368 }