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