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