xref: /titanic_51/usr/src/uts/common/c2/audit_token.c (revision 52ccf843e173e2a4a657360b0a22853fd413905f)
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 #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 = GET_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 		in_addr_t in4;
817 
818 		/*
819 		 * An IPv4-mapped IPv6 address is really an IPv4 address
820 		 * in IPv6 format.
821 		 */
822 		IN6_V4MAPPED_TO_IPADDR((in6_addr_t *)internet_addr, in4);
823 
824 		adr_char(&adr, &data_header_v4, 1);
825 		adr_char(&adr, (char *)&in4, sizeof (struct in_addr));
826 	} else {
827 		adr_char(&adr, &data_header_v6, 1);
828 		adr_int32(&adr, &type, 1);
829 		adr_char(&adr, (char *)internet_addr, sizeof (struct in6_addr));
830 	}
831 
832 	m->len = adr_count(&adr);
833 
834 	return (m);
835 }
836 
837 /*
838  * The Modifier tokens
839  */
840 
841 /*
842  * au_to_attr
843  * returns:
844  *	pointer to au_membuf chain containing an attribute token.
845  */
846 token_t *
847 au_to_attr(struct vattr *attr)
848 {
849 	token_t *m;			/* local au_membuf */
850 	adr_t adr;			/* adr memory stream header */
851 #ifdef _LP64
852 	char data_header = AUT_ATTR64;	/* header for this token */
853 #else
854 	char data_header = AUT_ATTR32;
855 #endif
856 	int32_t value;
857 
858 	m = au_getclr();
859 
860 	adr_start(&adr, memtod(m, char *));
861 	adr_char(&adr, &data_header, 1);
862 	value = (int32_t)attr->va_mode;
863 	value |= (int32_t)(VTTOIF(attr->va_type));
864 	adr_int32(&adr, &value, 1);
865 	value = (int32_t)attr->va_uid;
866 	adr_int32(&adr, &value, 1);
867 	value = (int32_t)attr->va_gid;
868 	adr_int32(&adr, &value, 1);
869 	adr_int32(&adr, (int32_t *)&(attr->va_fsid), 1);
870 	adr_int64(&adr, (int64_t *)&(attr->va_nodeid), 1);
871 #ifdef _LP64
872 	adr_int64(&adr, (int64_t *)&(attr->va_rdev), 1);
873 #else
874 	adr_int32(&adr, (int32_t *)&(attr->va_rdev), 1);
875 #endif
876 
877 	m->len = adr_count(&adr);
878 
879 	return (m);
880 }
881 
882 token_t *
883 au_to_acl(struct acl *aclp)
884 {
885 	token_t *m;				/* local au_membuf */
886 	adr_t adr;				/* adr memory stream header */
887 	char data_header = AUT_ACL;		/* header for this token */
888 	int32_t value;
889 
890 	m = au_getclr();
891 
892 	adr_start(&adr, memtod(m, char *));
893 	adr_char(&adr, &data_header, 1);
894 
895 	value = (int32_t)aclp->a_type;
896 	adr_int32(&adr, &value, 1);
897 	value = (int32_t)aclp->a_id;
898 	adr_int32(&adr, &value, 1);
899 	value = (int32_t)aclp->a_perm;
900 	adr_int32(&adr, &value, 1);
901 
902 	m->len = adr_count(&adr);
903 	return (m);
904 }
905 
906 token_t *
907 au_to_ace(ace_t *acep)
908 {
909 	token_t *m;				/* local au_membuf */
910 	adr_t adr;				/* adr memory stream header */
911 	char data_header = AUT_ACE;		/* header for this token */
912 
913 	m = au_getclr();
914 
915 	adr_start(&adr, memtod(m, char *));
916 	adr_char(&adr, &data_header, 1);
917 
918 	adr_uint32(&adr, &(acep->a_who), 1);
919 	adr_uint32(&adr, &(acep->a_access_mask), 1);
920 	adr_ushort(&adr, &(acep->a_flags), 1);
921 	adr_ushort(&adr, &(acep->a_type), 1);
922 
923 	m->len = adr_count(&adr);
924 	return (m);
925 }
926 
927 /*
928  * au_to_ipc_perm
929  * returns:
930  *	pointer to au_membuf chain containing a System V IPC attribute token.
931  */
932 token_t *
933 au_to_ipc_perm(struct kipc_perm *perm)
934 {
935 	token_t *m;				/* local au_membuf */
936 	adr_t adr;				/* adr memory stream header */
937 	char data_header = AUT_IPC_PERM;	/* header for this token */
938 	int32_t value;
939 
940 	m = au_getclr();
941 
942 	adr_start(&adr, memtod(m, char *));
943 	adr_char(&adr, &data_header, 1);
944 	value = (int32_t)perm->ipc_uid;
945 	adr_int32(&adr, &value, 1);
946 	value = (int32_t)perm->ipc_gid;
947 	adr_int32(&adr, &value, 1);
948 	value = (int32_t)perm->ipc_cuid;
949 	adr_int32(&adr, &value, 1);
950 	value = (int32_t)perm->ipc_cgid;
951 	adr_int32(&adr, &value, 1);
952 	value = (int32_t)perm->ipc_mode;
953 	adr_int32(&adr, &value, 1);
954 	value = 0;			/* seq is now obsolete */
955 	adr_int32(&adr, &value, 1);
956 	value = (int32_t)perm->ipc_key;
957 	adr_int32(&adr, &value, 1);
958 
959 	m->len = adr_count(&adr);
960 
961 	return (m);
962 }
963 
964 token_t *
965 au_to_groups(const gid_t *crgroups, uint_t crngroups)
966 {
967 	token_t *m;			/* local au_membuf */
968 	adr_t adr;			/* adr memory stream header */
969 	char data_header = AUT_NEWGROUPS;	/* header for this token */
970 	short n_groups;
971 
972 	m = au_getclr();
973 
974 	adr_start(&adr, memtod(m, char *));
975 	adr_char(&adr, &data_header, 1);
976 	n_groups = (short)crngroups;
977 	adr_short(&adr, &n_groups, 1);
978 	adr_int32(&adr, (int32_t *)crgroups, (int)crngroups);
979 
980 	m->len = adr_count(&adr);
981 
982 	return (m);
983 }
984 
985 /*
986  * au_to_socket_ex
987  * returns:
988  *	pointer to au_membuf chain containing a socket token.
989  */
990 token_t *
991 au_to_socket_ex(short dom, short type, char *l, char *f)
992 {
993 	adr_t adr;
994 	token_t *m;
995 	char data_header = AUT_SOCKET_EX;
996 	struct sockaddr_in6 *addr6;
997 	struct sockaddr_in  *addr4;
998 	short size;
999 
1000 	m = au_getclr();
1001 
1002 	adr_start(&adr, memtod(m, char *));
1003 	adr_char(&adr, &data_header, 1);
1004 	adr_short(&adr, &dom, 1);		/* dom of socket */
1005 	adr_short(&adr, &type, 1);		/* type of socket */
1006 
1007 	if (dom == AF_INET6) {
1008 		size = AU_IPv6;
1009 		adr_short(&adr, &size, 1);	/* type of addresses */
1010 		addr6 = (struct sockaddr_in6 *)l;
1011 		adr_short(&adr, (short *)&addr6->sin6_port, 1);
1012 		adr_char(&adr, (char *)&addr6->sin6_addr, size);
1013 		addr6 = (struct sockaddr_in6 *)f;
1014 		adr_short(&adr, (short *)&addr6->sin6_port, 1);
1015 		adr_char(&adr, (char *)&addr6->sin6_addr, size);
1016 	} else if (dom == AF_INET) {
1017 		size = AU_IPv4;
1018 		adr_short(&adr, &size, 1);	/* type of addresses */
1019 		addr4 = (struct sockaddr_in *)l;
1020 		adr_short(&adr, (short *)&addr4->sin_port, 1);
1021 		adr_char(&adr, (char *)&addr4->sin_addr, size);
1022 		addr4 = (struct sockaddr_in *)f;
1023 		adr_short(&adr, (short *)&addr4->sin_port, 1);
1024 		adr_char(&adr, (char *)&addr4->sin_addr, size);
1025 	}
1026 
1027 
1028 	m->len = adr_count(&adr);
1029 
1030 	return (m);
1031 }
1032 
1033 /*
1034  * au_to_seq
1035  * returns:
1036  *	pointer to au_membuf chain containing a sequence token.
1037  */
1038 token_t *
1039 au_to_seq()
1040 {
1041 	adr_t adr;
1042 	token_t *m;
1043 	char data_header = AUT_SEQ;
1044 	static int32_t zerocount;
1045 
1046 	m = au_getclr();
1047 
1048 	adr_start(&adr, memtod(m, char *));
1049 
1050 	adr_char(&adr, &data_header, 1);
1051 
1052 	adr_int32(&adr, &zerocount, 1);
1053 
1054 	m->len = adr_count(&adr);
1055 
1056 	return (m);
1057 }
1058 
1059 token_t *
1060 au_to_sock_inet(struct sockaddr_in *s_inet)
1061 {
1062 	adr_t adr;
1063 	token_t *m;
1064 	char data_header = AUT_SOCKET;
1065 
1066 	m = au_getclr();
1067 
1068 	adr_start(&adr, memtod(m, char *));
1069 	adr_char(&adr, &data_header, 1);
1070 	adr_short(&adr, (short *)&s_inet->sin_family, 1);
1071 	adr_short(&adr, (short *)&s_inet->sin_port, 1);
1072 
1073 	/* remote addr */
1074 	adr_int32(&adr, (int32_t *)&s_inet->sin_addr.s_addr, 1);
1075 
1076 	m->len = (uchar_t)adr_count(&adr);
1077 
1078 	return (m);
1079 }
1080 
1081 extern int maxprivbytes;
1082 
1083 token_t *
1084 au_to_privset(
1085     const char *set,
1086     const priv_set_t *pset,
1087     char data_header,
1088     int success)
1089 {
1090 	token_t *token, *m;
1091 	adr_t adr;
1092 	int priv;
1093 	const char *pname;
1094 	char sf = (char)success;
1095 	char *buf, *q;
1096 	short sz;
1097 	boolean_t full;
1098 
1099 	token = au_getclr();
1100 
1101 	adr_start(&adr, memtod(token, char *));
1102 	adr_char(&adr, &data_header, 1);
1103 	/*
1104 	 * set is not used for AUT_UPRIV and sf (== success) is not
1105 	 * used for AUT_PRIV
1106 	 */
1107 	if (data_header == AUT_UPRIV) {
1108 		adr_char(&adr, &sf, 1);
1109 	} else {
1110 		sz = strlen(set) + 1;
1111 		adr_short(&adr, &sz, 1);
1112 
1113 		token->len = (uchar_t)adr_count(&adr);
1114 		m = au_getclr();
1115 
1116 		(void) au_append_buf(set, sz, m);
1117 		(void) au_append_rec(token, m, AU_PACK);
1118 		adr.adr_now += sz;
1119 	}
1120 
1121 	full = priv_isfullset(pset);
1122 
1123 	if (full) {
1124 		buf = "ALL";
1125 		sz = strlen(buf) + 1;
1126 	} else {
1127 		q = buf = kmem_alloc(maxprivbytes, KM_SLEEP);
1128 		*buf = '\0';
1129 
1130 		for (priv = 0; (pname = priv_getbynum(priv)) != NULL; priv++) {
1131 			if (priv_ismember(pset, priv)) {
1132 				if (q != buf)
1133 					*q++ = ',';
1134 				(void) strcpy(q, pname);
1135 				q += strlen(q);
1136 			}
1137 		}
1138 		sz = (q - buf) + 1;
1139 	}
1140 
1141 	adr_short(&adr, &sz, 1);
1142 	token->len = (uchar_t)adr_count(&adr);
1143 
1144 	m = au_getclr();
1145 	(void) au_append_buf(buf, sz, m);
1146 	(void) au_append_rec(token, m, AU_PACK);
1147 
1148 	if (!full)
1149 		kmem_free(buf, maxprivbytes);
1150 
1151 	return (token);
1152 }
1153 
1154 /*
1155  * au_to_label
1156  * returns:
1157  *	pointer to au_membuf chain containing a label token.
1158  */
1159 token_t *
1160 au_to_label(bslabel_t *label)
1161 {
1162 	token_t *m;			/* local au_membuf */
1163 	adr_t adr;			/* adr memory stream header */
1164 	char data_header = AUT_LABEL;	/* header for this token */
1165 
1166 	m = au_getclr();
1167 
1168 	adr_start(&adr, memtod(m, char *));
1169 	adr_char(&adr, &data_header, 1);
1170 	adr_char(&adr, (char *)label, sizeof (bslabel_t));
1171 	m->len = adr_count(&adr);
1172 
1173 	return (m);
1174 }
1175