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