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