xref: /illumos-gate/usr/src/uts/common/c2/audit_token.c (revision 1d7bfecd)
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 2007 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(zone_t *zone)
382 {
383 	if (zone == NULL)
384 		zone = curproc->p_zone;
385 	return (strlen(zone->zone_name) + 1 +
386 	    ZONE_TOKEN_OVERHEAD);
387 }
388 
389 /*
390  * au_to_zonename
391  *
392  * A length of zero input to au_to_zonename means the length is not
393  * pre-calculated.
394  *
395  * The caller is responsible for checking the AUDIT_ZONENAME policy
396  * before calling au_zonename_length() and au_to_zonename().  If
397  * the policy changes between the calls, no harm is done, so the
398  * policy only needs to be checked once.
399  *
400  * returns:
401  *	pointer to au_membuf chain containing a zonename token; NULL if
402  *	policy is off.
403  *
404  *	if the zonename token is generated at token generation close time,
405  *	the length of the token is already known and it is ASSERTed that
406  *	it has not changed.  If not precalculated, zone_length must be
407  *	zero.
408  */
409 token_t *
410 au_to_zonename(size_t zone_length, zone_t *zone)
411 {
412 	token_t *token;			/* local au_membuf */
413 	adr_t adr;			/* adr memory stream header */
414 	char data_header = AUT_ZONENAME;	/* header for this token */
415 	short bytes;			/* length of string */
416 
417 	token = au_getclr();
418 
419 	if (zone == NULL)
420 		zone = curproc->p_zone;
421 	bytes = (short)strlen(zone->zone_name) + 1;
422 	/*
423 	 * If zone_length != 0, it was precalculated and is
424 	 * the token length, not the string length.
425 	 */
426 	ASSERT((zone_length == 0) ||
427 	    (zone_length == (bytes + ZONE_TOKEN_OVERHEAD)));
428 
429 	adr_start(&adr, memtod(token, char *));
430 	adr_char(&adr, &data_header, 1);
431 	adr_short(&adr, &bytes, 1);
432 
433 	token->len = (char)adr_count(&adr);
434 	(void) au_append_buf(zone->zone_name, bytes, token);
435 
436 	return (token);
437 }
438 
439 /*
440  * au_to_strings
441  * returns:
442  *	pointer to au_membuf chain containing a strings array token.
443  */
444 token_t *
445 au_to_strings(
446 	char header,		/* token type */
447 	const char *kstrp,	/* kernel string pointer */
448 	ssize_t count)		/* count of arguments */
449 {
450 	token_t *token;			/* local au_membuf */
451 	token_t *m;			/* local au_membuf */
452 	adr_t adr;			/* adr memory stream header */
453 	size_t len;
454 	int32_t tlen;
455 
456 	token = au_getclr();
457 
458 	adr_start(&adr, memtod(token, char *));
459 	adr_char(&adr, &header, 1);
460 	tlen = (int32_t)count;
461 	adr_int32(&adr, &tlen, 1);
462 
463 	token->len = (char)adr_count(&adr);
464 
465 	while (count-- > 0) {
466 		m = au_getclr();
467 		len = strlen(kstrp) + 1;
468 		(void) au_append_buf(kstrp, len, m);
469 		(void) au_append_rec((token_t *)token, (token_t *)m, AU_PACK);
470 		kstrp += len;
471 	}
472 
473 	return (token);
474 }
475 
476 /*
477  * au_to_exec_args
478  * returns:
479  *	pointer to au_membuf chain containing a argv token.
480  */
481 token_t *
482 au_to_exec_args(const char *kstrp, ssize_t argc)
483 {
484 	return (au_to_strings(AUT_EXEC_ARGS, kstrp, argc));
485 }
486 
487 /*
488  * au_to_exec_env
489  * returns:
490  *	pointer to au_membuf chain containing a arge token.
491  */
492 token_t *
493 au_to_exec_env(const char *kstrp, ssize_t envc)
494 {
495 	return (au_to_strings(AUT_EXEC_ENV, kstrp, envc));
496 }
497 
498 /*
499  * au_to_arg32
500  *	char   n;	argument # being used
501  *	char  *text;	text describing argument
502  *	uint32_t v;	argument value
503  * returns:
504  *	pointer to au_membuf chain containing an argument token.
505  */
506 token_t *
507 au_to_arg32(char n, char *text, uint32_t v)
508 {
509 	token_t *token;			/* local au_membuf */
510 	adr_t adr;			/* adr memory stream header */
511 	char data_header = AUT_ARG32;	/* header for this token */
512 	short bytes;			/* length of string */
513 
514 	token = au_getclr();
515 
516 	bytes = strlen(text) + 1;
517 	adr_start(&adr, memtod(token, char *));
518 	adr_char(&adr, &data_header, 1);	/* token type */
519 	adr_char(&adr, &n, 1);			/* argument id */
520 	adr_uint32(&adr, &v, 1);		/* argument value */
521 	adr_short(&adr, &bytes, 1);
522 
523 	token->len = adr_count(&adr);
524 	/*
525 	 * Now add the description
526 	 */
527 	(void) au_append_buf(text, bytes, token);
528 
529 	return (token);
530 }
531 
532 
533 /*
534  * au_to_arg64
535  *	char		n;	argument # being used
536  *	char		*text;	text describing argument
537  *	uint64_t	v;	argument value
538  * returns:
539  *	pointer to au_membuf chain containing an argument token.
540  */
541 token_t *
542 au_to_arg64(char n, char *text, uint64_t v)
543 {
544 	token_t *token;			/* local au_membuf */
545 	adr_t adr;			/* adr memory stream header */
546 	char data_header = AUT_ARG64;	/* header for this token */
547 	short bytes;			/* length of string */
548 
549 	token = au_getclr();
550 
551 	bytes = strlen(text) + 1;
552 	adr_start(&adr, memtod(token, char *));
553 	adr_char(&adr, &data_header, 1);	/* token type */
554 	adr_char(&adr, &n, 1);			/* argument id */
555 	adr_uint64(&adr, &v, 1);		/* argument value */
556 	adr_short(&adr, &bytes, 1);
557 
558 	token->len = adr_count(&adr);
559 	/*
560 	 * Now the description
561 	 */
562 	(void) au_append_buf(text, bytes, token);
563 
564 	return (token);
565 }
566 
567 
568 /*
569  * au_to_path
570  * returns:
571  *	pointer to au_membuf chain containing a path token.
572  */
573 token_t *
574 au_to_path(struct audit_path *app)
575 {
576 	token_t *token;			/* local au_membuf */
577 	token_t *m;			/* local au_membuf */
578 	adr_t adr;			/* adr memory stream header */
579 	char data_header = AUT_PATH;	/* header for this token */
580 	short bytes;			/* length of string */
581 	char *path = app->audp_sect[0];
582 
583 	bytes = (short)(app->audp_sect[1] - app->audp_sect[0]);
584 
585 	/*
586 	 * generate path token header
587 	 */
588 	m = au_getclr();
589 	adr_start(&adr, memtod(m, char *));
590 	adr_char(&adr, &data_header, 1);
591 	adr_short(&adr, &bytes, 1);
592 	m->len = adr_count(&adr);
593 
594 	/* append path string */
595 	token = m;
596 	(void) au_append_buf(path, bytes, token);
597 
598 	if (app->audp_cnt > 1) {
599 		/* generate attribute path strings token */
600 		m = au_to_strings(AUT_XATPATH, app->audp_sect[1],
601 		    app->audp_cnt - 1);
602 
603 		token = au_append_token(token, m);
604 	}
605 
606 	return (token);
607 }
608 
609 /*
610  * au_to_ipc
611  * returns:
612  *	pointer to au_membuf chain containing a System V IPC token.
613  */
614 token_t *
615 au_to_ipc(char type, int id)
616 {
617 	token_t *m;			/* local au_membuf */
618 	adr_t adr;			/* adr memory stream header */
619 	char data_header = AUT_IPC;	/* header for this token */
620 
621 	m = au_getclr();
622 
623 	adr_start(&adr, memtod(m, char *));
624 	adr_char(&adr, &data_header, 1);
625 	adr_char(&adr, &type, 1);		/* type of IPC object */
626 	adr_int32(&adr, (int32_t *)&id, 1);
627 
628 	m->len = adr_count(&adr);
629 
630 	return (m);
631 }
632 
633 /*
634  * au_to_return32
635  * returns:
636  *	pointer to au_membuf chain containing a return value token.
637  */
638 token_t *
639 au_to_return32(int error, int32_t rv)
640 {
641 	token_t *m;			/* local au_membuf */
642 	adr_t adr;			/* adr memory stream header */
643 	char data_header = AUT_RETURN32; /* header for this token */
644 	int32_t val;
645 	char ed = error;
646 
647 	m = au_getclr();
648 
649 	adr_start(&adr, memtod(m, char *));
650 	adr_char(&adr, &data_header, 1);
651 	adr_char(&adr, &ed, 1);
652 
653 	if (error) {
654 		val = -1;
655 		adr_int32(&adr, &val, 1);
656 	} else {
657 		adr_int32(&adr, &rv, 1);
658 	}
659 	m->len = adr_count(&adr);
660 
661 	return (m);
662 }
663 
664 /*
665  * au_to_return64
666  * returns:
667  *	pointer to au_membuf chain containing a return value token.
668  */
669 token_t *
670 au_to_return64(int error, int64_t rv)
671 {
672 	token_t *m;			/* local au_membuf */
673 	adr_t adr;			/* adr memory stream header */
674 	char data_header = AUT_RETURN64; /* header for this token */
675 	int64_t val;
676 	char ed = error;
677 
678 	m = au_getclr();
679 
680 	adr_start(&adr, memtod(m, char *));
681 	adr_char(&adr, &data_header, 1);
682 	adr_char(&adr, &ed, 1);
683 
684 	if (error) {
685 		val = -1;
686 		adr_int64(&adr, &val, 1);
687 	} else {
688 		adr_int64(&adr, &rv, 1);
689 	}
690 	m->len = adr_count(&adr);
691 
692 	return (m);
693 }
694 
695 #ifdef	AU_MAY_USE_SOMEDAY
696 /*
697  * au_to_opaque
698  * returns:
699  *	pointer to au_membuf chain containing a opaque token.
700  */
701 token_t *
702 au_to_opaque(short bytes, char *opaque)
703 {
704 	token_t *token;			/* local au_membuf */
705 	adr_t adr;			/* adr memory stream header */
706 	char data_header = AUT_OPAQUE;	/* header for this token */
707 
708 	token = au_getclr();
709 
710 	adr_start(&adr, memtod(token, char *));
711 	adr_char(&adr, &data_header, 1);
712 	adr_short(&adr, &bytes, 1);
713 
714 	token->len = adr_count(&adr);
715 
716 	/*
717 	 * Now attach the data
718 	 */
719 	(void) au_append_buf(opaque, bytes, token);
720 
721 	return (token);
722 }
723 #endif	/* AU_MAY_USE_SOMEDAY */
724 
725 /*
726  * au_to_ip
727  * returns:
728  *	pointer to au_membuf chain containing a ip header token
729  */
730 token_t *
731 au_to_ip(struct ip *ipp)
732 {
733 	token_t *m;			/* local au_membuf */
734 	adr_t adr;			/* adr memory stream header */
735 	char data_header = AUT_IP;	/* header for this token */
736 
737 	m = au_getclr();
738 
739 	adr_start(&adr, memtod(m, char *));
740 	adr_char(&adr, &data_header, 1);
741 	adr_char(&adr, (char *)ipp, 2);
742 	adr_short(&adr, (short *)&(ipp->ip_len), 3);
743 	adr_char(&adr, (char *)&(ipp->ip_ttl), 2);
744 	adr_short(&adr, (short *)&(ipp->ip_sum), 1);
745 	adr_int32(&adr, (int32_t *)&(ipp->ip_src), 2);
746 
747 	m->len = adr_count(&adr);
748 
749 	return (m);
750 }
751 
752 /*
753  * au_to_iport
754  * returns:
755  *	pointer to au_membuf chain containing a ip path token
756  */
757 token_t *
758 au_to_iport(ushort_t iport)
759 {
760 	token_t *m;			/* local au_membuf */
761 	adr_t adr;			/* adr memory stream header */
762 	char data_header = AUT_IPORT;	/* header for this token */
763 
764 	m = au_getclr();
765 
766 	adr_start(&adr, memtod(m, char *));
767 	adr_char(&adr, &data_header, 1);
768 	adr_ushort(&adr, &iport, 1);
769 
770 	m->len = adr_count(&adr);
771 
772 	return (m);
773 }
774 
775 /*
776  * au_to_in_addr
777  * returns:
778  *	pointer to au_membuf chain containing a ip path token
779  */
780 token_t *
781 au_to_in_addr(struct in_addr *internet_addr)
782 {
783 	token_t *m;			/* local au_membuf */
784 	adr_t adr;			/* adr memory stream header */
785 	char data_header = AUT_IN_ADDR;	/* header for this token */
786 
787 	m = au_getclr();
788 
789 	adr_start(&adr, memtod(m, char *));
790 	adr_char(&adr, &data_header, 1);
791 	adr_char(&adr, (char *)internet_addr, sizeof (struct in_addr));
792 
793 	m->len = adr_count(&adr);
794 
795 	return (m);
796 }
797 
798 /*
799  * au_to_in_addr_ex
800  * returns:
801  *	pointer to au_membuf chain containing an ipv6 token
802  */
803 token_t *
804 au_to_in_addr_ex(int32_t *internet_addr)
805 {
806 	token_t *m;			/* local au_membuf */
807 	adr_t adr;			/* adr memory stream header */
808 	char data_header_v4 = AUT_IN_ADDR;	/* header for v4 token */
809 	char data_header_v6 = AUT_IN_ADDR_EX;	/* header for v6 token */
810 	int32_t type = AU_IPv6;
811 
812 	m = au_getclr();
813 	adr_start(&adr, memtod(m, char *));
814 
815 	if (IN6_IS_ADDR_V4MAPPED((in6_addr_t *)internet_addr)) {
816 		adr_char(&adr, &data_header_v4, 1);
817 		adr_char(&adr, (char *)internet_addr, sizeof (struct in_addr));
818 	} else {
819 		adr_char(&adr, &data_header_v6, 1);
820 		adr_int32(&adr, &type, 1);
821 		adr_char(&adr, (char *)internet_addr, sizeof (struct in6_addr));
822 	}
823 
824 	m->len = adr_count(&adr);
825 
826 	return (m);
827 }
828 
829 /*
830  * The Modifier tokens
831  */
832 
833 /*
834  * au_to_attr
835  * returns:
836  *	pointer to au_membuf chain containing an attribute token.
837  */
838 token_t *
839 au_to_attr(struct vattr *attr)
840 {
841 	token_t *m;			/* local au_membuf */
842 	adr_t adr;			/* adr memory stream header */
843 #ifdef _LP64
844 	char data_header = AUT_ATTR64;	/* header for this token */
845 #else
846 	char data_header = AUT_ATTR32;
847 #endif
848 	int32_t value;
849 
850 	m = au_getclr();
851 
852 	adr_start(&adr, memtod(m, char *));
853 	adr_char(&adr, &data_header, 1);
854 	value = (int32_t)attr->va_mode;
855 	value |= (int32_t)(VTTOIF(attr->va_type));
856 	adr_int32(&adr, &value, 1);
857 	value = (int32_t)attr->va_uid;
858 	adr_int32(&adr, &value, 1);
859 	value = (int32_t)attr->va_gid;
860 	adr_int32(&adr, &value, 1);
861 	adr_int32(&adr, (int32_t *)&(attr->va_fsid), 1);
862 	adr_int64(&adr, (int64_t *)&(attr->va_nodeid), 1);
863 #ifdef _LP64
864 	adr_int64(&adr, (int64_t *)&(attr->va_rdev), 1);
865 #else
866 	adr_int32(&adr, (int32_t *)&(attr->va_rdev), 1);
867 #endif
868 
869 	m->len = adr_count(&adr);
870 
871 	return (m);
872 }
873 
874 token_t *
875 au_to_acl(struct acl *aclp)
876 {
877 	token_t *m;				/* local au_membuf */
878 	adr_t adr;				/* adr memory stream header */
879 	char data_header = AUT_ACL;		/* header for this token */
880 	int32_t value;
881 
882 	m = au_getclr();
883 
884 	adr_start(&adr, memtod(m, char *));
885 	adr_char(&adr, &data_header, 1);
886 
887 	value = (int32_t)aclp->a_type;
888 	adr_int32(&adr, &value, 1);
889 	value = (int32_t)aclp->a_id;
890 	adr_int32(&adr, &value, 1);
891 	value = (int32_t)aclp->a_perm;
892 	adr_int32(&adr, &value, 1);
893 
894 	m->len = adr_count(&adr);
895 	return (m);
896 }
897 
898 /*
899  * au_to_ipc_perm
900  * returns:
901  *	pointer to au_membuf chain containing a System V IPC attribute token.
902  */
903 token_t *
904 au_to_ipc_perm(struct kipc_perm *perm)
905 {
906 	token_t *m;				/* local au_membuf */
907 	adr_t adr;				/* adr memory stream header */
908 	char data_header = AUT_IPC_PERM;	/* header for this token */
909 	int32_t value;
910 
911 	m = au_getclr();
912 
913 	adr_start(&adr, memtod(m, char *));
914 	adr_char(&adr, &data_header, 1);
915 	value = (int32_t)perm->ipc_uid;
916 	adr_int32(&adr, &value, 1);
917 	value = (int32_t)perm->ipc_gid;
918 	adr_int32(&adr, &value, 1);
919 	value = (int32_t)perm->ipc_cuid;
920 	adr_int32(&adr, &value, 1);
921 	value = (int32_t)perm->ipc_cgid;
922 	adr_int32(&adr, &value, 1);
923 	value = (int32_t)perm->ipc_mode;
924 	adr_int32(&adr, &value, 1);
925 	value = 0;			/* seq is now obsolete */
926 	adr_int32(&adr, &value, 1);
927 	value = (int32_t)perm->ipc_key;
928 	adr_int32(&adr, &value, 1);
929 
930 	m->len = adr_count(&adr);
931 
932 	return (m);
933 }
934 
935 token_t *
936 au_to_groups(const gid_t *crgroups, uint_t crngroups)
937 {
938 	token_t *m;			/* local au_membuf */
939 	adr_t adr;			/* adr memory stream header */
940 	char data_header = AUT_NEWGROUPS;	/* header for this token */
941 	short n_groups;
942 
943 	m = au_getclr();
944 
945 	adr_start(&adr, memtod(m, char *));
946 	adr_char(&adr, &data_header, 1);
947 	n_groups = (short)crngroups;
948 	adr_short(&adr, &n_groups, 1);
949 	adr_int32(&adr, (int32_t *)crgroups, (int)crngroups);
950 
951 	m->len = adr_count(&adr);
952 
953 	return (m);
954 }
955 
956 /*
957  * au_to_socket_ex
958  * returns:
959  *	pointer to au_membuf chain containing a socket token.
960  */
961 token_t *
962 au_to_socket_ex(short dom, short type, char *l, char *f)
963 {
964 	adr_t adr;
965 	token_t *m;
966 	char data_header = AUT_SOCKET_EX;
967 	struct sockaddr_in6 *addr6;
968 	struct sockaddr_in  *addr4;
969 	short size;
970 
971 	m = au_getclr();
972 
973 	adr_start(&adr, memtod(m, char *));
974 	adr_char(&adr, &data_header, 1);
975 	adr_short(&adr, &dom, 1);		/* dom of socket */
976 	adr_short(&adr, &type, 1);		/* type of socket */
977 
978 	if (dom == AF_INET6) {
979 		size = AU_IPv6;
980 		adr_short(&adr, &size, 1);	/* type of addresses */
981 		addr6 = (struct sockaddr_in6 *)l;
982 		adr_short(&adr, (short *)&addr6->sin6_port, 1);
983 		adr_char(&adr, (char *)&addr6->sin6_addr, size);
984 		addr6 = (struct sockaddr_in6 *)f;
985 		adr_short(&adr, (short *)&addr6->sin6_port, 1);
986 		adr_char(&adr, (char *)&addr6->sin6_addr, size);
987 	} else if (dom == AF_INET) {
988 		size = AU_IPv4;
989 		adr_short(&adr, &size, 1);	/* type of addresses */
990 		addr4 = (struct sockaddr_in *)l;
991 		adr_short(&adr, (short *)&addr4->sin_port, 1);
992 		adr_char(&adr, (char *)&addr4->sin_addr, size);
993 		addr4 = (struct sockaddr_in *)f;
994 		adr_short(&adr, (short *)&addr4->sin_port, 1);
995 		adr_char(&adr, (char *)&addr4->sin_addr, size);
996 	}
997 
998 
999 	m->len = adr_count(&adr);
1000 
1001 	return (m);
1002 }
1003 
1004 /*
1005  * au_to_seq
1006  * returns:
1007  *	pointer to au_membuf chain containing a sequence token.
1008  */
1009 token_t *
1010 au_to_seq()
1011 {
1012 	adr_t adr;
1013 	token_t *m;
1014 	char data_header = AUT_SEQ;
1015 	static int32_t zerocount;
1016 
1017 	m = au_getclr();
1018 
1019 	adr_start(&adr, memtod(m, char *));
1020 
1021 	adr_char(&adr, &data_header, 1);
1022 
1023 	adr_int32(&adr, &zerocount, 1);
1024 
1025 	m->len = adr_count(&adr);
1026 
1027 	return (m);
1028 }
1029 
1030 token_t *
1031 au_to_sock_inet(struct sockaddr_in *s_inet)
1032 {
1033 	adr_t adr;
1034 	token_t *m;
1035 	char data_header = AUT_SOCKET;
1036 
1037 	m = au_getclr();
1038 
1039 	adr_start(&adr, memtod(m, char *));
1040 	adr_char(&adr, &data_header, 1);
1041 	adr_short(&adr, (short *)&s_inet->sin_family, 1);
1042 	adr_short(&adr, (short *)&s_inet->sin_port, 1);
1043 
1044 	/* remote addr */
1045 	adr_int32(&adr, (int32_t *)&s_inet->sin_addr.s_addr, 1);
1046 
1047 	m->len = (uchar_t)adr_count(&adr);
1048 
1049 	return (m);
1050 }
1051 
1052 extern int maxprivbytes;
1053 
1054 token_t *
1055 au_to_privset(
1056     const char *set,
1057     const priv_set_t *pset,
1058     char data_header,
1059     int success)
1060 {
1061 	token_t *token, *m;
1062 	adr_t adr;
1063 	int priv;
1064 	const char *pname;
1065 	char sf = (char)success;
1066 	char *buf, *q;
1067 	short sz;
1068 	boolean_t full;
1069 
1070 	token = au_getclr();
1071 
1072 	adr_start(&adr, memtod(token, char *));
1073 	adr_char(&adr, &data_header, 1);
1074 	/*
1075 	 * set is not used for AUT_UPRIV and sf (== success) is not
1076 	 * used for AUT_PRIV
1077 	 */
1078 	if (data_header == AUT_UPRIV) {
1079 		adr_char(&adr, &sf, 1);
1080 	} else {
1081 		sz = strlen(set) + 1;
1082 		adr_short(&adr, &sz, 1);
1083 
1084 		token->len = (uchar_t)adr_count(&adr);
1085 		m = au_getclr();
1086 
1087 		(void) au_append_buf(set, sz, m);
1088 		(void) au_append_rec(token, m, AU_PACK);
1089 		adr.adr_now += sz;
1090 	}
1091 
1092 	full = priv_isfullset(pset);
1093 
1094 	if (full) {
1095 		buf = "ALL";
1096 		sz = strlen(buf) + 1;
1097 	} else {
1098 		q = buf = kmem_alloc(maxprivbytes, KM_SLEEP);
1099 		*buf = '\0';
1100 
1101 		for (priv = 0; (pname = priv_getbynum(priv)) != NULL; priv++) {
1102 			if (priv_ismember(pset, priv)) {
1103 				if (q != buf)
1104 					*q++ = ',';
1105 				(void) strcpy(q, pname);
1106 				q += strlen(q);
1107 			}
1108 		}
1109 		sz = (q - buf) + 1;
1110 	}
1111 
1112 	adr_short(&adr, &sz, 1);
1113 	token->len = (uchar_t)adr_count(&adr);
1114 
1115 	m = au_getclr();
1116 	(void) au_append_buf(buf, sz, m);
1117 	(void) au_append_rec(token, m, AU_PACK);
1118 
1119 	if (!full)
1120 		kmem_free(buf, maxprivbytes);
1121 
1122 	return (token);
1123 }
1124 
1125 /*
1126  * au_to_label
1127  * returns:
1128  *	pointer to au_membuf chain containing a label token.
1129  */
1130 token_t *
1131 au_to_label(bslabel_t *label)
1132 {
1133 	token_t *m;			/* local au_membuf */
1134 	adr_t adr;			/* adr memory stream header */
1135 	char data_header = AUT_LABEL;	/* header for this token */
1136 
1137 	m = au_getclr();
1138 
1139 	adr_start(&adr, memtod(m, char *));
1140 	adr_char(&adr, &data_header, 1);
1141 	adr_char(&adr, (char *)label, sizeof (bslabel_t));
1142 	m->len = adr_count(&adr);
1143 
1144 	return (m);
1145 }
1146