xref: /titanic_50/usr/src/uts/common/c2/audit_token.c (revision cd3e933325e68e23516a196a8fea7f49b1e497c3)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * Support routines for building audit records.
28  */
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>		/* for rval */
32 #include <sys/time.h>
33 #include <sys/types.h>
34 #include <sys/vnode.h>
35 #include <sys/mode.h>
36 #include <sys/user.h>
37 #include <sys/session.h>
38 #include <sys/acl.h>
39 #include <sys/ipc_impl.h>
40 #include <netinet/in_systm.h>
41 #include <netinet/in.h>
42 #include <netinet/ip.h>
43 #include <sys/socket.h>
44 #include <net/route.h>
45 #include <netinet/in_pcb.h>
46 #include <c2/audit.h>
47 #include <c2/audit_kernel.h>
48 #include <c2/audit_record.h>
49 #include <sys/model.h>		/* for model_t */
50 #include <sys/vmparam.h>	/* for USRSTACK/USRSTACK32 */
51 #include <sys/vfs.h>		/* for sonode */
52 #include <sys/socketvar.h>	/* for sonode */
53 #include <sys/zone.h>
54 #include <sys/tsol/label.h>
55 
56 /*
57  * These are the control tokens
58  */
59 
60 /*
61  * au_to_header
62  * returns:
63  *	pointer to au_membuf chain containing a header token.
64  */
65 token_t *
66 au_to_header(int byte_count, au_event_t e_type, au_emod_t e_mod)
67 {
68 	adr_t adr;			/* adr memory stream header */
69 	token_t *m;			/* au_membuf pointer */
70 #ifdef _LP64
71 	char data_header = AUT_HEADER64;	/* header for this token */
72 	static int64_t zerotime[2];
73 #else
74 	char data_header = AUT_HEADER32;
75 	static int32_t zerotime[2];
76 #endif
77 	char version = TOKEN_VERSION;	/* version of token family */
78 
79 	m = au_getclr();
80 
81 	adr_start(&adr, memtod(m, char *));
82 	adr_char(&adr, &data_header, 1);	/* token ID */
83 	adr_int32(&adr, (int32_t *)&byte_count, 1);	/* length of */
84 							/* audit record */
85 	adr_char(&adr, &version, 1);		/* version of audit tokens */
86 	adr_ushort(&adr, &e_type, 1);		/* event ID */
87 	adr_ushort(&adr, &e_mod, 1);		/* event ID modifier */
88 #ifdef _LP64
89 	adr_int64(&adr, zerotime, 2);		/* time & date space */
90 #else
91 	adr_int32(&adr, zerotime, 2);
92 #endif
93 	m->len = adr_count(&adr);
94 
95 	return (m);
96 }
97 
98 token_t *
99 au_to_header_ex(int byte_count, au_event_t e_type, au_emod_t e_mod)
100 {
101 	adr_t adr;			/* adr memory stream header */
102 	token_t *m;			/* au_membuf pointer */
103 	au_kcontext_t	*kctx = GET_KCTX_PZ;
104 
105 #ifdef _LP64
106 	char data_header = AUT_HEADER64_EX;	/* header for this token */
107 	static int64_t zerotime[2];
108 #else
109 	char data_header = AUT_HEADER32_EX;
110 	static int32_t zerotime[2];
111 #endif
112 	char version = TOKEN_VERSION;	/* version of token family */
113 
114 	m = au_getclr();
115 
116 	adr_start(&adr, memtod(m, char *));
117 	adr_char(&adr, &data_header, 1);	/* token ID */
118 	adr_int32(&adr, (int32_t *)&byte_count, 1);	/* length of */
119 							/* audit record */
120 	adr_char(&adr, &version, 1);		/* version of audit tokens */
121 	adr_ushort(&adr, &e_type, 1);		/* event ID */
122 	adr_ushort(&adr, &e_mod, 1);		/* event ID modifier */
123 	adr_uint32(&adr, &kctx->auk_info.ai_termid.at_type, 1);
124 	adr_char(&adr, (char *)&kctx->auk_info.ai_termid.at_addr[0],
125 	    (int)kctx->auk_info.ai_termid.at_type);
126 #ifdef _LP64
127 	adr_int64(&adr, zerotime, 2);		/* time & date */
128 #else
129 	adr_int32(&adr, zerotime, 2);
130 #endif
131 	m->len = adr_count(&adr);
132 
133 	return (m);
134 }
135 
136 /*
137  * au_to_trailer
138  * returns:
139  *	pointer to au_membuf chain containing a trailer token.
140  */
141 token_t *
142 au_to_trailer(int byte_count)
143 {
144 	adr_t adr;				/* adr memory stream header */
145 	token_t *m;				/* au_membuf pointer */
146 	char data_header = AUT_TRAILER;		/* header for this token */
147 	short magic = (short)AUT_TRAILER_MAGIC; /* trailer magic number */
148 
149 	m = au_getclr();
150 
151 	adr_start(&adr, memtod(m, char *));
152 	adr_char(&adr, &data_header, 1);		/* token ID */
153 	adr_short(&adr, &magic, 1);			/* magic number */
154 	adr_int32(&adr, (int32_t *)&byte_count, 1);	/* length of */
155 							/* audit record */
156 
157 	m->len = adr_count(&adr);
158 
159 	return (m);
160 }
161 /*
162  * These are the data tokens
163  */
164 
165 /*
166  * au_to_data
167  * returns:
168  *	pointer to au_membuf chain containing a data token.
169  */
170 token_t *
171 au_to_data(char unit_print, char unit_type, char unit_count, char *p)
172 {
173 	adr_t adr;			/* adr memory stream header */
174 	token_t *m;			/* au_membuf pointer */
175 	char data_header = AUT_DATA;	/* header for this token */
176 
177 	ASSERT(p != NULL);
178 	ASSERT(unit_count != 0);
179 
180 	switch (unit_type) {
181 	case AUR_SHORT:
182 		if (sizeof (short) * unit_count >= AU_BUFSIZE)
183 			return (au_to_text("au_to_data: unit count too big"));
184 		break;
185 	case AUR_INT32:
186 		if (sizeof (int32_t) * unit_count >= AU_BUFSIZE)
187 			return (au_to_text("au_to_data: unit count too big"));
188 		break;
189 	case AUR_INT64:
190 		if (sizeof (int64_t) * unit_count >= AU_BUFSIZE)
191 			return (au_to_text("au_to_data: unit count too big"));
192 		break;
193 	case AUR_BYTE:
194 	default:
195 #ifdef _CHAR_IS_UNSIGNED
196 		if (sizeof (char) * unit_count >= AU_BUFSIZE)
197 			return (au_to_text("au_to_data: unit count too big"));
198 #endif
199 		/*
200 		 * we used to check for this:
201 		 * sizeof (char) * (int)unit_count >= AU_BUFSIZE).
202 		 * but the compiler is smart enough to see that
203 		 * will never be >= AU_BUFSIZE, since that's 128
204 		 * and unit_count maxes out at 127 (signed char),
205 		 * and complain.
206 		 */
207 		break;
208 	}
209 
210 	m = au_getclr();
211 
212 	adr_start(&adr, memtod(m, char *));
213 	adr_char(&adr, &data_header, 1);
214 	adr_char(&adr, &unit_print, 1);
215 	adr_char(&adr, &unit_type, 1);
216 	adr_char(&adr, &unit_count, 1);
217 
218 	switch (unit_type) {
219 	case AUR_SHORT:
220 		adr_short(&adr, (short *)p, unit_count);
221 		break;
222 	case AUR_INT32:
223 		adr_int32(&adr, (int32_t *)p, unit_count);
224 		break;
225 	case AUR_INT64:
226 		adr_int64(&adr, (int64_t *)p, unit_count);
227 		break;
228 	case AUR_BYTE:
229 	default:
230 		adr_char(&adr, p, unit_count);
231 		break;
232 	}
233 
234 	m->len = adr_count(&adr);
235 
236 	return (m);
237 }
238 
239 /*
240  * au_to_process
241  * au_to_subject
242  * returns:
243  *	pointer to au_membuf chain containing a process token.
244  */
245 static token_t *au_to_any_process(char, uid_t, gid_t, uid_t, gid_t,
246     pid_t, au_id_t, au_asid_t, const au_tid_addr_t *atid);
247 
248 token_t *
249 au_to_process(uid_t uid, gid_t gid, uid_t ruid, gid_t rgid, pid_t pid,
250     au_id_t auid, au_asid_t asid, const au_tid_addr_t *atid)
251 {
252 	char data_header;
253 
254 #ifdef _LP64
255 	if (atid->at_type == AU_IPv6)
256 		data_header = AUT_PROCESS64_EX;
257 	else
258 		data_header = AUT_PROCESS64;
259 #else
260 	if (atid->at_type == AU_IPv6)
261 		data_header = AUT_PROCESS32_EX;
262 	else
263 		data_header = AUT_PROCESS32;
264 #endif
265 
266 	return (au_to_any_process(data_header, uid, gid, ruid,
267 	    rgid, pid, auid, asid, atid));
268 }
269 
270 token_t *
271 au_to_subject(uid_t uid, gid_t gid, uid_t ruid, gid_t rgid, pid_t pid,
272     au_id_t auid, au_asid_t asid, const au_tid_addr_t *atid)
273 {
274 	char data_header;
275 
276 #ifdef _LP64
277 	if (atid->at_type == AU_IPv6)
278 		data_header = AUT_SUBJECT64_EX;
279 	else
280 		data_header = AUT_SUBJECT64;
281 #else
282 	if (atid->at_type == AU_IPv6)
283 		data_header = AUT_SUBJECT32_EX;
284 	else
285 		data_header = AUT_SUBJECT32;
286 #endif
287 	return (au_to_any_process(data_header, uid, gid, ruid,
288 	    rgid, pid, auid, asid, atid));
289 }
290 
291 
292 static token_t *
293 au_to_any_process(char data_header,
294     uid_t uid, gid_t gid, uid_t ruid, gid_t rgid, pid_t pid,
295     au_id_t auid, au_asid_t asid, const au_tid_addr_t *atid)
296 {
297 	token_t *m;	/* local au_membuf */
298 	adr_t adr;	/* adr memory stream header */
299 	int32_t value;
300 
301 	m = au_getclr();
302 
303 	adr_start(&adr, memtod(m, char *));
304 	adr_char(&adr, &data_header, 1);
305 	value = (int32_t)auid;
306 	adr_int32(&adr, &value, 1);
307 	value = (int32_t)uid;
308 	adr_int32(&adr, &value, 1);
309 	value = (int32_t)gid;
310 	adr_int32(&adr, &value, 1);
311 	value = (int32_t)ruid;
312 	adr_int32(&adr, &value, 1);
313 	value = (int32_t)rgid;
314 	adr_int32(&adr, &value, 1);
315 	value = (int32_t)pid;
316 	adr_int32(&adr, &value, 1);
317 	value = (int32_t)asid;
318 	adr_int32(&adr, &value, 1);
319 #ifdef _LP64
320 	adr_int64(&adr, (int64_t *)&(atid->at_port), 1);
321 #else
322 	adr_int32(&adr, (int32_t *)&(atid->at_port), 1);
323 #endif
324 	if (atid->at_type == AU_IPv6) {
325 		adr_uint32(&adr, (uint_t *)&atid->at_type, 1);
326 		adr_char(&adr, (char *)&atid->at_addr[0], 16);
327 	} else {
328 		adr_char(&adr, (char *)&(atid->at_addr[0]), 4);
329 	}
330 
331 	m->len = adr_count(&adr);
332 
333 	return (m);
334 }
335 
336 /*
337  * au_to_text
338  * returns:
339  *	pointer to au_membuf chain containing a text token.
340  */
341 token_t *
342 au_to_text(const char *text)
343 {
344 	token_t *token;			/* local au_membuf */
345 	adr_t adr;			/* adr memory stream header */
346 	char data_header = AUT_TEXT;	/* header for this token */
347 	short bytes;			/* length of string */
348 
349 	token = au_getclr();
350 
351 	bytes = (short)strlen(text) + 1;
352 	adr_start(&adr, memtod(token, char *));
353 	adr_char(&adr, &data_header, 1);
354 	adr_short(&adr, &bytes, 1);
355 
356 	token->len = (char)adr_count(&adr);
357 	/*
358 	 * Now attach the text
359 	 */
360 	(void) au_append_buf(text, bytes, token);
361 
362 	return (token);
363 }
364 
365 /*
366  * au_zonename_length
367  * returns:
368  * -	length of zonename token to be generated
369  * -	zone name up to ZONENAME_MAX + 1 in length
370  */
371 #define	ZONE_TOKEN_OVERHEAD 3
372 	/*
373 	 * the zone token is
374 	 * token id (1 byte)
375 	 * string length (2 bytes)
376 	 * the string (strlen(zonename) + 1)
377 	 */
378 size_t
379 au_zonename_length(zone_t *zone)
380 {
381 	if (zone == NULL)
382 		zone = curproc->p_zone;
383 	return (strlen(zone->zone_name) + 1 +
384 	    ZONE_TOKEN_OVERHEAD);
385 }
386 
387 /*
388  * au_to_zonename
389  *
390  * A length of zero input to au_to_zonename means the length is not
391  * pre-calculated.
392  *
393  * The caller is responsible for checking the AUDIT_ZONENAME policy
394  * before calling au_zonename_length() and au_to_zonename().  If
395  * the policy changes between the calls, no harm is done, so the
396  * policy only needs to be checked once.
397  *
398  * returns:
399  *	pointer to au_membuf chain containing a zonename token; NULL if
400  *	policy is off.
401  *
402  *	if the zonename token is generated at token generation close time,
403  *	the length of the token is already known and it is ASSERTed that
404  *	it has not changed.  If not precalculated, zone_length must be
405  *	zero.
406  */
407 token_t *
408 au_to_zonename(size_t zone_length, zone_t *zone)
409 {
410 	token_t *token;			/* local au_membuf */
411 	adr_t adr;			/* adr memory stream header */
412 	char data_header = AUT_ZONENAME;	/* header for this token */
413 	short bytes;			/* length of string */
414 
415 	token = au_getclr();
416 
417 	if (zone == NULL)
418 		zone = curproc->p_zone;
419 	bytes = (short)strlen(zone->zone_name) + 1;
420 	/*
421 	 * If zone_length != 0, it was precalculated and is
422 	 * the token length, not the string length.
423 	 */
424 	ASSERT((zone_length == 0) ||
425 	    (zone_length == (bytes + ZONE_TOKEN_OVERHEAD)));
426 
427 	adr_start(&adr, memtod(token, char *));
428 	adr_char(&adr, &data_header, 1);
429 	adr_short(&adr, &bytes, 1);
430 
431 	token->len = (char)adr_count(&adr);
432 	(void) au_append_buf(zone->zone_name, bytes, token);
433 
434 	return (token);
435 }
436 
437 /*
438  * au_to_strings
439  * returns:
440  *	pointer to au_membuf chain containing a strings array token.
441  */
442 token_t *
443 au_to_strings(
444 	char header,		/* token type */
445 	const char *kstrp,	/* kernel string pointer */
446 	ssize_t count)		/* count of arguments */
447 {
448 	token_t *token;			/* local au_membuf */
449 	token_t *m;			/* local au_membuf */
450 	adr_t adr;			/* adr memory stream header */
451 	size_t len;
452 	int32_t tlen;
453 
454 	token = au_getclr();
455 
456 	adr_start(&adr, memtod(token, char *));
457 	adr_char(&adr, &header, 1);
458 	tlen = (int32_t)count;
459 	adr_int32(&adr, &tlen, 1);
460 
461 	token->len = (char)adr_count(&adr);
462 
463 	while (count-- > 0) {
464 		m = au_getclr();
465 		len = strlen(kstrp) + 1;
466 		(void) au_append_buf(kstrp, len, m);
467 		(void) au_append_rec((token_t *)token, (token_t *)m, AU_PACK);
468 		kstrp += len;
469 	}
470 
471 	return (token);
472 }
473 
474 /*
475  * au_to_exec_args
476  * returns:
477  *	pointer to au_membuf chain containing a argv token.
478  */
479 token_t *
480 au_to_exec_args(const char *kstrp, ssize_t argc)
481 {
482 	return (au_to_strings(AUT_EXEC_ARGS, kstrp, argc));
483 }
484 
485 /*
486  * au_to_exec_env
487  * returns:
488  *	pointer to au_membuf chain containing a arge token.
489  */
490 token_t *
491 au_to_exec_env(const char *kstrp, ssize_t envc)
492 {
493 	return (au_to_strings(AUT_EXEC_ENV, kstrp, envc));
494 }
495 
496 /*
497  * au_to_arg32
498  *	char   n;	argument # being used
499  *	char  *text;	text describing argument
500  *	uint32_t v;	argument value
501  * returns:
502  *	pointer to au_membuf chain containing an argument token.
503  */
504 token_t *
505 au_to_arg32(char n, char *text, uint32_t v)
506 {
507 	token_t *token;			/* local au_membuf */
508 	adr_t adr;			/* adr memory stream header */
509 	char data_header = AUT_ARG32;	/* header for this token */
510 	short bytes;			/* length of string */
511 
512 	token = au_getclr();
513 
514 	bytes = strlen(text) + 1;
515 	adr_start(&adr, memtod(token, char *));
516 	adr_char(&adr, &data_header, 1);	/* token type */
517 	adr_char(&adr, &n, 1);			/* argument id */
518 	adr_uint32(&adr, &v, 1);		/* argument value */
519 	adr_short(&adr, &bytes, 1);
520 
521 	token->len = adr_count(&adr);
522 	/*
523 	 * Now add the description
524 	 */
525 	(void) au_append_buf(text, bytes, token);
526 
527 	return (token);
528 }
529 
530 
531 /*
532  * au_to_arg64
533  *	char		n;	argument # being used
534  *	char		*text;	text describing argument
535  *	uint64_t	v;	argument value
536  * returns:
537  *	pointer to au_membuf chain containing an argument token.
538  */
539 token_t *
540 au_to_arg64(char n, char *text, uint64_t v)
541 {
542 	token_t *token;			/* local au_membuf */
543 	adr_t adr;			/* adr memory stream header */
544 	char data_header = AUT_ARG64;	/* header for this token */
545 	short bytes;			/* length of string */
546 
547 	token = au_getclr();
548 
549 	bytes = strlen(text) + 1;
550 	adr_start(&adr, memtod(token, char *));
551 	adr_char(&adr, &data_header, 1);	/* token type */
552 	adr_char(&adr, &n, 1);			/* argument id */
553 	adr_uint64(&adr, &v, 1);		/* argument value */
554 	adr_short(&adr, &bytes, 1);
555 
556 	token->len = adr_count(&adr);
557 	/*
558 	 * Now the description
559 	 */
560 	(void) au_append_buf(text, bytes, token);
561 
562 	return (token);
563 }
564 
565 
566 /*
567  * au_to_path
568  * returns:
569  *	pointer to au_membuf chain containing a path token.
570  */
571 token_t *
572 au_to_path(struct audit_path *app)
573 {
574 	token_t *token;			/* local au_membuf */
575 	token_t *m;			/* local au_membuf */
576 	adr_t adr;			/* adr memory stream header */
577 	char data_header = AUT_PATH;	/* header for this token */
578 	short bytes;			/* length of string */
579 	char *path = app->audp_sect[0];
580 
581 	bytes = (short)(app->audp_sect[1] - app->audp_sect[0]);
582 
583 	/*
584 	 * generate path token header
585 	 */
586 	m = au_getclr();
587 	adr_start(&adr, memtod(m, char *));
588 	adr_char(&adr, &data_header, 1);
589 	adr_short(&adr, &bytes, 1);
590 	m->len = adr_count(&adr);
591 
592 	/* append path string */
593 	token = m;
594 	(void) au_append_buf(path, bytes, token);
595 
596 	if (app->audp_cnt > 1) {
597 		/* generate attribute path strings token */
598 		m = au_to_strings(AUT_XATPATH, app->audp_sect[1],
599 		    app->audp_cnt - 1);
600 
601 		token = au_append_token(token, m);
602 	}
603 
604 	return (token);
605 }
606 
607 /*
608  * au_to_ipc
609  * returns:
610  *	pointer to au_membuf chain containing a System V IPC token.
611  */
612 token_t *
613 au_to_ipc(char type, int id)
614 {
615 	token_t *m;			/* local au_membuf */
616 	adr_t adr;			/* adr memory stream header */
617 	char data_header = AUT_IPC;	/* header for this token */
618 
619 	m = au_getclr();
620 
621 	adr_start(&adr, memtod(m, char *));
622 	adr_char(&adr, &data_header, 1);
623 	adr_char(&adr, &type, 1);		/* type of IPC object */
624 	adr_int32(&adr, (int32_t *)&id, 1);
625 
626 	m->len = adr_count(&adr);
627 
628 	return (m);
629 }
630 
631 /*
632  * au_to_return32
633  * returns:
634  *	pointer to au_membuf chain containing a return value token.
635  */
636 token_t *
637 au_to_return32(int error, int32_t rv)
638 {
639 	token_t *m;			/* local au_membuf */
640 	adr_t adr;			/* adr memory stream header */
641 	char data_header = AUT_RETURN32; /* header for this token */
642 	int32_t val;
643 	char ed = error;
644 
645 	m = au_getclr();
646 
647 	adr_start(&adr, memtod(m, char *));
648 	adr_char(&adr, &data_header, 1);
649 	adr_char(&adr, &ed, 1);
650 
651 	if (error) {
652 		val = -1;
653 		adr_int32(&adr, &val, 1);
654 	} else {
655 		adr_int32(&adr, &rv, 1);
656 	}
657 	m->len = adr_count(&adr);
658 
659 	return (m);
660 }
661 
662 /*
663  * au_to_return64
664  * returns:
665  *	pointer to au_membuf chain containing a return value token.
666  */
667 token_t *
668 au_to_return64(int error, int64_t rv)
669 {
670 	token_t *m;			/* local au_membuf */
671 	adr_t adr;			/* adr memory stream header */
672 	char data_header = AUT_RETURN64; /* header for this token */
673 	int64_t val;
674 	char ed = error;
675 
676 	m = au_getclr();
677 
678 	adr_start(&adr, memtod(m, char *));
679 	adr_char(&adr, &data_header, 1);
680 	adr_char(&adr, &ed, 1);
681 
682 	if (error) {
683 		val = -1;
684 		adr_int64(&adr, &val, 1);
685 	} else {
686 		adr_int64(&adr, &rv, 1);
687 	}
688 	m->len = adr_count(&adr);
689 
690 	return (m);
691 }
692 
693 #ifdef	AU_MAY_USE_SOMEDAY
694 /*
695  * au_to_opaque
696  * returns:
697  *	pointer to au_membuf chain containing a opaque token.
698  */
699 token_t *
700 au_to_opaque(short bytes, char *opaque)
701 {
702 	token_t *token;			/* local au_membuf */
703 	adr_t adr;			/* adr memory stream header */
704 	char data_header = AUT_OPAQUE;	/* header for this token */
705 
706 	token = au_getclr();
707 
708 	adr_start(&adr, memtod(token, char *));
709 	adr_char(&adr, &data_header, 1);
710 	adr_short(&adr, &bytes, 1);
711 
712 	token->len = adr_count(&adr);
713 
714 	/*
715 	 * Now attach the data
716 	 */
717 	(void) au_append_buf(opaque, bytes, token);
718 
719 	return (token);
720 }
721 #endif	/* AU_MAY_USE_SOMEDAY */
722 
723 /*
724  * au_to_ip
725  * returns:
726  *	pointer to au_membuf chain containing a ip header token
727  */
728 token_t *
729 au_to_ip(struct ip *ipp)
730 {
731 	token_t *m;			/* local au_membuf */
732 	adr_t adr;			/* adr memory stream header */
733 	char data_header = AUT_IP;	/* header for this token */
734 
735 	m = au_getclr();
736 
737 	adr_start(&adr, memtod(m, char *));
738 	adr_char(&adr, &data_header, 1);
739 	adr_char(&adr, (char *)ipp, 2);
740 	adr_short(&adr, (short *)&(ipp->ip_len), 3);
741 	adr_char(&adr, (char *)&(ipp->ip_ttl), 2);
742 	adr_short(&adr, (short *)&(ipp->ip_sum), 1);
743 	adr_int32(&adr, (int32_t *)&(ipp->ip_src), 2);
744 
745 	m->len = adr_count(&adr);
746 
747 	return (m);
748 }
749 
750 /*
751  * au_to_iport
752  * returns:
753  *	pointer to au_membuf chain containing a ip path token
754  */
755 token_t *
756 au_to_iport(ushort_t iport)
757 {
758 	token_t *m;			/* local au_membuf */
759 	adr_t adr;			/* adr memory stream header */
760 	char data_header = AUT_IPORT;	/* header for this token */
761 
762 	m = au_getclr();
763 
764 	adr_start(&adr, memtod(m, char *));
765 	adr_char(&adr, &data_header, 1);
766 	adr_ushort(&adr, &iport, 1);
767 
768 	m->len = adr_count(&adr);
769 
770 	return (m);
771 }
772 
773 /*
774  * au_to_in_addr
775  * returns:
776  *	pointer to au_membuf chain containing a ip path token
777  */
778 token_t *
779 au_to_in_addr(struct in_addr *internet_addr)
780 {
781 	token_t *m;			/* local au_membuf */
782 	adr_t adr;			/* adr memory stream header */
783 	char data_header = AUT_IN_ADDR;	/* header for this token */
784 
785 	m = au_getclr();
786 
787 	adr_start(&adr, memtod(m, char *));
788 	adr_char(&adr, &data_header, 1);
789 	adr_char(&adr, (char *)internet_addr, sizeof (struct in_addr));
790 
791 	m->len = adr_count(&adr);
792 
793 	return (m);
794 }
795 
796 /*
797  * au_to_in_addr_ex
798  * returns:
799  *	pointer to au_membuf chain containing an ipv6 token
800  */
801 token_t *
802 au_to_in_addr_ex(int32_t *internet_addr)
803 {
804 	token_t *m;			/* local au_membuf */
805 	adr_t adr;			/* adr memory stream header */
806 	char data_header_v4 = AUT_IN_ADDR;	/* header for v4 token */
807 	char data_header_v6 = AUT_IN_ADDR_EX;	/* header for v6 token */
808 	int32_t type = AU_IPv6;
809 
810 	m = au_getclr();
811 	adr_start(&adr, memtod(m, char *));
812 
813 	if (IN6_IS_ADDR_V4MAPPED((in6_addr_t *)internet_addr)) {
814 		ipaddr_t in4;
815 
816 		/*
817 		 * An IPv4-mapped IPv6 address is really an IPv4 address
818 		 * in IPv6 format.
819 		 */
820 		IN6_V4MAPPED_TO_IPADDR((in6_addr_t *)internet_addr, in4);
821 
822 		adr_char(&adr, &data_header_v4, 1);
823 		adr_char(&adr, (char *)&in4, sizeof (ipaddr_t));
824 	} else {
825 		adr_char(&adr, &data_header_v6, 1);
826 		adr_int32(&adr, &type, 1);
827 		adr_char(&adr, (char *)internet_addr, sizeof (struct in6_addr));
828 	}
829 
830 	m->len = adr_count(&adr);
831 
832 	return (m);
833 }
834 
835 /*
836  * The Modifier tokens
837  */
838 
839 /*
840  * au_to_attr
841  * returns:
842  *	pointer to au_membuf chain containing an attribute token.
843  */
844 token_t *
845 au_to_attr(struct vattr *attr)
846 {
847 	token_t *m;			/* local au_membuf */
848 	adr_t adr;			/* adr memory stream header */
849 #ifdef _LP64
850 	char data_header = AUT_ATTR64;	/* header for this token */
851 #else
852 	char data_header = AUT_ATTR32;
853 #endif
854 	int32_t value;
855 
856 	m = au_getclr();
857 
858 	adr_start(&adr, memtod(m, char *));
859 	adr_char(&adr, &data_header, 1);
860 	value = (int32_t)attr->va_mode;
861 	value |= (int32_t)(VTTOIF(attr->va_type));
862 	adr_int32(&adr, &value, 1);
863 	value = (int32_t)attr->va_uid;
864 	adr_int32(&adr, &value, 1);
865 	value = (int32_t)attr->va_gid;
866 	adr_int32(&adr, &value, 1);
867 	adr_int32(&adr, (int32_t *)&(attr->va_fsid), 1);
868 	adr_int64(&adr, (int64_t *)&(attr->va_nodeid), 1);
869 #ifdef _LP64
870 	adr_int64(&adr, (int64_t *)&(attr->va_rdev), 1);
871 #else
872 	adr_int32(&adr, (int32_t *)&(attr->va_rdev), 1);
873 #endif
874 
875 	m->len = adr_count(&adr);
876 
877 	return (m);
878 }
879 
880 token_t *
881 au_to_acl(struct acl *aclp)
882 {
883 	token_t *m;				/* local au_membuf */
884 	adr_t adr;				/* adr memory stream header */
885 	char data_header = AUT_ACL;		/* header for this token */
886 	int32_t value;
887 
888 	m = au_getclr();
889 
890 	adr_start(&adr, memtod(m, char *));
891 	adr_char(&adr, &data_header, 1);
892 
893 	value = (int32_t)aclp->a_type;
894 	adr_int32(&adr, &value, 1);
895 	value = (int32_t)aclp->a_id;
896 	adr_int32(&adr, &value, 1);
897 	value = (int32_t)aclp->a_perm;
898 	adr_int32(&adr, &value, 1);
899 
900 	m->len = adr_count(&adr);
901 	return (m);
902 }
903 
904 token_t *
905 au_to_ace(ace_t *acep)
906 {
907 	token_t *m;				/* local au_membuf */
908 	adr_t adr;				/* adr memory stream header */
909 	char data_header = AUT_ACE;		/* header for this token */
910 
911 	m = au_getclr();
912 
913 	adr_start(&adr, memtod(m, char *));
914 	adr_char(&adr, &data_header, 1);
915 
916 	adr_uint32(&adr, &(acep->a_who), 1);
917 	adr_uint32(&adr, &(acep->a_access_mask), 1);
918 	adr_ushort(&adr, &(acep->a_flags), 1);
919 	adr_ushort(&adr, &(acep->a_type), 1);
920 
921 	m->len = adr_count(&adr);
922 	return (m);
923 }
924 
925 /*
926  * au_to_ipc_perm
927  * returns:
928  *	pointer to au_membuf chain containing a System V IPC attribute token.
929  */
930 token_t *
931 au_to_ipc_perm(struct kipc_perm *perm)
932 {
933 	token_t *m;				/* local au_membuf */
934 	adr_t adr;				/* adr memory stream header */
935 	char data_header = AUT_IPC_PERM;	/* header for this token */
936 	int32_t value;
937 
938 	m = au_getclr();
939 
940 	adr_start(&adr, memtod(m, char *));
941 	adr_char(&adr, &data_header, 1);
942 	value = (int32_t)perm->ipc_uid;
943 	adr_int32(&adr, &value, 1);
944 	value = (int32_t)perm->ipc_gid;
945 	adr_int32(&adr, &value, 1);
946 	value = (int32_t)perm->ipc_cuid;
947 	adr_int32(&adr, &value, 1);
948 	value = (int32_t)perm->ipc_cgid;
949 	adr_int32(&adr, &value, 1);
950 	value = (int32_t)perm->ipc_mode;
951 	adr_int32(&adr, &value, 1);
952 	value = 0;			/* seq is now obsolete */
953 	adr_int32(&adr, &value, 1);
954 	value = (int32_t)perm->ipc_key;
955 	adr_int32(&adr, &value, 1);
956 
957 	m->len = adr_count(&adr);
958 
959 	return (m);
960 }
961 
962 token_t *
963 au_to_groups(const gid_t *crgroups, uint_t crngroups)
964 {
965 	token_t *m;			/* local au_membuf */
966 	adr_t adr;			/* adr memory stream header */
967 	char data_header = AUT_NEWGROUPS;	/* header for this token */
968 	short n_groups;
969 
970 	m = au_getclr();
971 
972 	adr_start(&adr, memtod(m, char *));
973 	adr_char(&adr, &data_header, 1);
974 	n_groups = (short)crngroups;
975 	adr_short(&adr, &n_groups, 1);
976 	adr_int32(&adr, (int32_t *)crgroups, (int)crngroups);
977 
978 	m->len = adr_count(&adr);
979 
980 	return (m);
981 }
982 
983 /*
984  * au_to_socket_ex
985  * returns:
986  *	pointer to au_membuf chain containing a socket token.
987  */
988 token_t *
989 au_to_socket_ex(short dom, short type, char *l, char *f)
990 {
991 	adr_t adr;
992 	token_t *m;
993 	char data_header = AUT_SOCKET_EX;
994 	struct sockaddr_in6 *addr6;
995 	struct sockaddr_in  *addr4;
996 	short size;
997 
998 	m = au_getclr();
999 
1000 	adr_start(&adr, memtod(m, char *));
1001 	adr_char(&adr, &data_header, 1);
1002 	adr_short(&adr, &dom, 1);		/* dom of socket */
1003 	adr_short(&adr, &type, 1);		/* type of socket */
1004 
1005 	if (dom == AF_INET6) {
1006 		size = AU_IPv6;
1007 		adr_short(&adr, &size, 1);	/* type of addresses */
1008 		addr6 = (struct sockaddr_in6 *)l;
1009 		adr_short(&adr, (short *)&addr6->sin6_port, 1);
1010 		adr_char(&adr, (char *)&addr6->sin6_addr, size);
1011 		addr6 = (struct sockaddr_in6 *)f;
1012 		adr_short(&adr, (short *)&addr6->sin6_port, 1);
1013 		adr_char(&adr, (char *)&addr6->sin6_addr, size);
1014 	} else if (dom == AF_INET) {
1015 		size = AU_IPv4;
1016 		adr_short(&adr, &size, 1);	/* type of addresses */
1017 		addr4 = (struct sockaddr_in *)l;
1018 		adr_short(&adr, (short *)&addr4->sin_port, 1);
1019 		adr_char(&adr, (char *)&addr4->sin_addr, size);
1020 		addr4 = (struct sockaddr_in *)f;
1021 		adr_short(&adr, (short *)&addr4->sin_port, 1);
1022 		adr_char(&adr, (char *)&addr4->sin_addr, size);
1023 	}
1024 
1025 
1026 	m->len = adr_count(&adr);
1027 
1028 	return (m);
1029 }
1030 
1031 /*
1032  * au_to_seq
1033  * returns:
1034  *	pointer to au_membuf chain containing a sequence token.
1035  */
1036 token_t *
1037 au_to_seq()
1038 {
1039 	adr_t adr;
1040 	token_t *m;
1041 	char data_header = AUT_SEQ;
1042 	static int32_t zerocount;
1043 
1044 	m = au_getclr();
1045 
1046 	adr_start(&adr, memtod(m, char *));
1047 
1048 	adr_char(&adr, &data_header, 1);
1049 
1050 	adr_int32(&adr, &zerocount, 1);
1051 
1052 	m->len = adr_count(&adr);
1053 
1054 	return (m);
1055 }
1056 
1057 token_t *
1058 au_to_sock_inet(struct sockaddr_in *s_inet)
1059 {
1060 	adr_t adr;
1061 	token_t *m;
1062 	char data_header = AUT_SOCKET;
1063 
1064 	m = au_getclr();
1065 
1066 	adr_start(&adr, memtod(m, char *));
1067 	adr_char(&adr, &data_header, 1);
1068 	adr_short(&adr, (short *)&s_inet->sin_family, 1);
1069 	adr_short(&adr, (short *)&s_inet->sin_port, 1);
1070 
1071 	/* remote addr */
1072 	adr_int32(&adr, (int32_t *)&s_inet->sin_addr.s_addr, 1);
1073 
1074 	m->len = (uchar_t)adr_count(&adr);
1075 
1076 	return (m);
1077 }
1078 
1079 extern int maxprivbytes;
1080 
1081 token_t *
1082 au_to_privset(
1083     const char *set,
1084     const priv_set_t *pset,
1085     char data_header,
1086     int success)
1087 {
1088 	token_t *token, *m;
1089 	adr_t adr;
1090 	int priv;
1091 	const char *pname;
1092 	char sf = (char)success;
1093 	char *buf, *q;
1094 	short sz;
1095 	boolean_t full;
1096 
1097 	token = au_getclr();
1098 
1099 	adr_start(&adr, memtod(token, char *));
1100 	adr_char(&adr, &data_header, 1);
1101 	/*
1102 	 * set is not used for AUT_UPRIV and sf (== success) is not
1103 	 * used for AUT_PRIV
1104 	 */
1105 	if (data_header == AUT_UPRIV) {
1106 		adr_char(&adr, &sf, 1);
1107 	} else {
1108 		sz = strlen(set) + 1;
1109 		adr_short(&adr, &sz, 1);
1110 
1111 		token->len = (uchar_t)adr_count(&adr);
1112 		m = au_getclr();
1113 
1114 		(void) au_append_buf(set, sz, m);
1115 		(void) au_append_rec(token, m, AU_PACK);
1116 		adr.adr_now += sz;
1117 	}
1118 
1119 	full = priv_isfullset(pset);
1120 
1121 	if (full) {
1122 		buf = "ALL";
1123 		sz = strlen(buf) + 1;
1124 	} else {
1125 		q = buf = kmem_alloc(maxprivbytes, KM_SLEEP);
1126 		*buf = '\0';
1127 
1128 		for (priv = 0; (pname = priv_getbynum(priv)) != NULL; priv++) {
1129 			if (priv_ismember(pset, priv)) {
1130 				if (q != buf)
1131 					*q++ = ',';
1132 				(void) strcpy(q, pname);
1133 				q += strlen(q);
1134 			}
1135 		}
1136 		sz = (q - buf) + 1;
1137 	}
1138 
1139 	adr_short(&adr, &sz, 1);
1140 	token->len = (uchar_t)adr_count(&adr);
1141 
1142 	m = au_getclr();
1143 	(void) au_append_buf(buf, sz, m);
1144 	(void) au_append_rec(token, m, AU_PACK);
1145 
1146 	if (!full)
1147 		kmem_free(buf, maxprivbytes);
1148 
1149 	return (token);
1150 }
1151 
1152 /*
1153  * au_to_label
1154  * returns:
1155  *	pointer to au_membuf chain containing a label token.
1156  */
1157 token_t *
1158 au_to_label(bslabel_t *label)
1159 {
1160 	token_t *m;			/* local au_membuf */
1161 	adr_t adr;			/* adr memory stream header */
1162 	char data_header = AUT_LABEL;	/* header for this token */
1163 
1164 	m = au_getclr();
1165 
1166 	adr_start(&adr, memtod(m, char *));
1167 	adr_char(&adr, &data_header, 1);
1168 	adr_char(&adr, (char *)label, sizeof (_mac_label_impl_t));
1169 
1170 	m->len = adr_count(&adr);
1171 
1172 	return (m);
1173 }
1174