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