diff options
author | rwatson <rwatson@FreeBSD.org> | 2008-11-12 23:48:20 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2008-11-12 23:48:20 +0000 |
commit | 2bd138f9edd4a43ef97291f03523af35e1ae18f8 (patch) | |
tree | e103f4f6bb4ebb161c9702d64560b216d1990d94 /libbsm/bsm_io.c | |
parent | 280c17909566cfd4eff091c2747edb9d747f7343 (diff) | |
download | FreeBSD-src-2bd138f9edd4a43ef97291f03523af35e1ae18f8.zip FreeBSD-src-2bd138f9edd4a43ef97291f03523af35e1ae18f8.tar.gz |
Flatten OpenBSM vendor tree in preparation for new OpenBSM vendor
import.
Diffstat (limited to 'libbsm/bsm_io.c')
-rw-r--r-- | libbsm/bsm_io.c | 4513 |
1 files changed, 4513 insertions, 0 deletions
diff --git a/libbsm/bsm_io.c b/libbsm/bsm_io.c new file mode 100644 index 0000000..29fdc87 --- /dev/null +++ b/libbsm/bsm_io.c @@ -0,0 +1,4513 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. + * Copyright (c) 2005 SPARTA, Inc. + * Copyright (c) 2006 Robert N. M. Watson + * Copyright (c) 2006 Martin Voros + * All rights reserved. + * + * This code was developed in part by Robert N. M. Watson, Senior Principal + * Scientist, SPARTA, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_io.c#50 $ + */ + +#include <sys/types.h> + +#include <config/config.h> +#ifdef HAVE_SYS_ENDIAN_H +#include <sys/endian.h> +#else /* !HAVE_SYS_ENDIAN_H */ +#ifdef HAVE_MACHINE_ENDIAN_H +#include <machine/endian.h> +#else /* !HAVE_MACHINE_ENDIAN_H */ +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#else /* !HAVE_ENDIAN_H */ +#error "No supported endian.h" +#endif /* !HAVE_ENDIAN_H */ +#endif /* !HAVE_MACHINE_ENDIAN_H */ +#include <compat/endian.h> +#endif /* !HAVE_SYS_ENDIAN_H */ +#ifdef HAVE_FULL_QUEUE_H +#include <sys/queue.h> +#else /* !HAVE_FULL_QUEUE_H */ +#include <compat/queue.h> +#endif /* !HAVE_FULL_QUEUE_H */ + +#include <sys/stat.h> +#include <sys/socket.h> + +#include <bsm/libbsm.h> + +#include <unistd.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <pwd.h> +#include <grp.h> + +#include <bsm/audit_internal.h> + +#define READ_TOKEN_BYTES(buf, len, dest, size, bytesread, err) do { \ + if (bytesread + size > len) { \ + err = 1; \ + } else { \ + memcpy(dest, buf + bytesread, size); \ + bytesread += size; \ + } \ +} while (0) + +#define READ_TOKEN_U_CHAR(buf, len, dest, bytesread, err) do { \ + if (bytesread + sizeof(u_char) <= len) { \ + dest = buf[bytesread]; \ + bytesread += sizeof(u_char); \ + } else \ + err = 1; \ +} while (0) + +#define READ_TOKEN_U_INT16(buf, len, dest, bytesread, err) do { \ + if (bytesread + sizeof(u_int16_t) <= len) { \ + dest = be16dec(buf + bytesread); \ + bytesread += sizeof(u_int16_t); \ + } else \ + err = 1; \ +} while (0) + +#define READ_TOKEN_U_INT32(buf, len, dest, bytesread, err) do { \ + if (bytesread + sizeof(u_int32_t) <= len) { \ + dest = be32dec(buf + bytesread); \ + bytesread += sizeof(u_int32_t); \ + } else \ + err = 1; \ +} while (0) + +#define READ_TOKEN_U_INT64(buf, len, dest, bytesread, err) do { \ + if (bytesread + sizeof(u_int64_t) <= len) { \ + dest = be64dec(buf + bytesread); \ + bytesread += sizeof(u_int64_t); \ + } else \ + err = 1; \ +} while (0) + +#define SET_PTR(buf, len, ptr, size, bytesread, err) do { \ + if ((bytesread) + (size) > (len)) \ + (err) = 1; \ + else { \ + (ptr) = (buf) + (bytesread); \ + (bytesread) += (size); \ + } \ +} while (0) + +/* + * XML option. + */ +#define AU_PLAIN 0 +#define AU_XML 1 + +/* + * Prints the delimiter string. + */ +static void +print_delim(FILE *fp, const char *del) +{ + + fprintf(fp, "%s", del); +} + +/* + * Prints a single byte in the given format. + */ +static void +print_1_byte(FILE *fp, u_char val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Print 2 bytes in the given format. + */ +static void +print_2_bytes(FILE *fp, u_int16_t val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Prints 4 bytes in the given format. + */ +static void +print_4_bytes(FILE *fp, u_int32_t val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Prints 8 bytes in the given format. + */ +static void +print_8_bytes(FILE *fp, u_int64_t val, const char *format) +{ + + fprintf(fp, format, val); +} + +/* + * Prints the given size of data bytes in hex. + */ +static void +print_mem(FILE *fp, u_char *data, size_t len) +{ + int i; + + if (len > 0) { + fprintf(fp, "0x"); + for (i = 0; i < len; i++) + fprintf(fp, "%x", data[i]); + } +} + +/* + * Prints the given data bytes as a string. + */ +static void +print_string(FILE *fp, const char *str, size_t len) +{ + int i; + + if (len > 0) { + for (i = 0; i < len; i++) { + if (str[i] != '\0') + fprintf(fp, "%c", str[i]); + } + } +} + +/* + * Prints the beggining of attribute. + */ +static void +open_attr(FILE *fp, const char *str) +{ + + fprintf(fp,"%s=\"", str); +} + +/* + * Prints the end of attribute. + */ +static void +close_attr(FILE *fp) +{ + + fprintf(fp,"\" "); +} + +/* + * Prints the end of tag. + */ +static void +close_tag(FILE *fp, u_char type) +{ + + switch(type) { + case AUT_HEADER32: + fprintf(fp, ">"); + break; + + case AUT_HEADER32_EX: + fprintf(fp, ">"); + break; + + case AUT_HEADER64: + fprintf(fp, ">"); + break; + + case AUT_HEADER64_EX: + fprintf(fp, ">"); + break; + + case AUT_ARG32: + fprintf(fp, "/>"); + break; + + case AUT_ARG64: + fprintf(fp, "/>"); + break; + + case AUT_ATTR32: + fprintf(fp, "/>"); + break; + + case AUT_ATTR64: + fprintf(fp, "/>"); + break; + + case AUT_EXIT: + fprintf(fp, "/>"); + break; + + case AUT_EXEC_ARGS: + fprintf(fp, "</exec_args>"); + break; + + case AUT_EXEC_ENV: + fprintf(fp, "</exec_env>"); + break; + + case AUT_OTHER_FILE32: + fprintf(fp, "</file>"); + break; + + case AUT_NEWGROUPS: + fprintf(fp, "</group>"); + break; + + case AUT_IN_ADDR: + fprintf(fp, "</ip_address>"); + break; + + case AUT_IN_ADDR_EX: + fprintf(fp, "</ip_address>"); + break; + + case AUT_IP: + fprintf(fp, "/>"); + break; + + case AUT_IPC: + fprintf(fp, "/>"); + break; + + case AUT_IPC_PERM: + fprintf(fp, "/>"); + break; + + case AUT_IPORT: + fprintf(fp, "</ip_port>"); + break; + + case AUT_OPAQUE: + fprintf(fp, "</opaque>"); + break; + + case AUT_PATH: + fprintf(fp, "</path>"); + break; + + case AUT_PROCESS32: + fprintf(fp, "/>"); + break; + + case AUT_PROCESS32_EX: + fprintf(fp, "/>"); + break; + + case AUT_PROCESS64: + fprintf(fp, "/>"); + break; + + case AUT_PROCESS64_EX: + fprintf(fp, "/>"); + break; + + case AUT_RETURN32: + fprintf(fp, "/>"); + break; + + case AUT_RETURN64: + fprintf(fp, "/>"); + break; + + case AUT_SEQ: + fprintf(fp, "/>"); + break; + + case AUT_SOCKET: + fprintf(fp, "/>"); + break; + + case AUT_SOCKINET32: + fprintf(fp, "/>"); + break; + + case AUT_SOCKUNIX: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT32: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT64: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT32_EX: + fprintf(fp, "/>"); + break; + + case AUT_SUBJECT64_EX: + fprintf(fp, "/>"); + break; + + case AUT_TEXT: + fprintf(fp, "</text>"); + break; + + case AUT_SOCKET_EX: + fprintf(fp, "/>"); + break; + + case AUT_DATA: + fprintf(fp, "</arbitrary>"); + break; + + case AUT_ZONENAME: + fprintf(fp, "/>"); + break; + } +} + +/* + * Prints the token type in either the raw or the default form. + */ +static void +print_tok_type(FILE *fp, u_char type, const char *tokname, char raw, int xml) +{ + + if (xml) { + switch(type) { + case AUT_HEADER32: + fprintf(fp, "<record "); + break; + + case AUT_HEADER32_EX: + fprintf(fp, "<record "); + break; + + case AUT_HEADER64: + fprintf(fp, "<record "); + break; + + case AUT_HEADER64_EX: + fprintf(fp, "<record "); + break; + + case AUT_TRAILER: + fprintf(fp, "</record>"); + break; + + case AUT_ARG32: + fprintf(fp, "<argument "); + break; + + case AUT_ARG64: + fprintf(fp, "<argument "); + break; + + case AUT_ATTR32: + fprintf(fp, "<attribute "); + break; + + case AUT_ATTR64: + fprintf(fp, "<attribute "); + break; + + case AUT_EXIT: + fprintf(fp, "<exit "); + break; + + case AUT_EXEC_ARGS: + fprintf(fp, "<exec_args>"); + break; + + case AUT_EXEC_ENV: + fprintf(fp, "<exec_env>"); + break; + + case AUT_OTHER_FILE32: + fprintf(fp, "<file "); + break; + + case AUT_NEWGROUPS: + fprintf(fp, "<group>"); + break; + + case AUT_IN_ADDR: + fprintf(fp, "<ip_address>"); + break; + + case AUT_IN_ADDR_EX: + fprintf(fp, "<ip_address>"); + break; + + case AUT_IP: + fprintf(fp, "<ip "); + break; + + case AUT_IPC: + fprintf(fp, "<IPC"); + break; + + case AUT_IPC_PERM: + fprintf(fp, "<IPC_perm "); + break; + + case AUT_IPORT: + fprintf(fp, "<ip_port>"); + break; + + case AUT_OPAQUE: + fprintf(fp, "<opaque>"); + break; + + case AUT_PATH: + fprintf(fp, "<path>"); + break; + + case AUT_PROCESS32: + fprintf(fp, "<process "); + break; + + case AUT_PROCESS32_EX: + fprintf(fp, "<process "); + break; + + case AUT_PROCESS64: + fprintf(fp, "<process "); + break; + + case AUT_PROCESS64_EX: + fprintf(fp, "<process "); + break; + + case AUT_RETURN32: + fprintf(fp, "<return "); + break; + + case AUT_RETURN64: + fprintf(fp, "<return "); + break; + + case AUT_SEQ: + fprintf(fp, "<sequence "); + break; + + case AUT_SOCKET: + fprintf(fp, "<socket "); + break; + + case AUT_SOCKINET32: + fprintf(fp, "<old_socket"); + break; + + case AUT_SOCKUNIX: + fprintf(fp, "<old_socket"); + break; + + case AUT_SUBJECT32: + fprintf(fp, "<subject "); + break; + + case AUT_SUBJECT64: + fprintf(fp, "<subject "); + break; + + case AUT_SUBJECT32_EX: + fprintf(fp, "<subject "); + break; + + case AUT_SUBJECT64_EX: + fprintf(fp, "<subject "); + break; + + case AUT_TEXT: + fprintf(fp, "<text>"); + break; + + case AUT_SOCKET_EX: + fprintf(fp, "<socket "); + break; + + case AUT_DATA: + fprintf(fp, "<arbitrary "); + break; + + case AUT_ZONENAME: + fprintf(fp, "<zone "); + break; + } + } else { + if (raw) + fprintf(fp, "%u", type); + else + fprintf(fp, "%s", tokname); + } +} + +/* + * Prints a user value. + */ +static void +print_user(FILE *fp, u_int32_t usr, char raw) +{ + struct passwd *pwent; + + if (raw) + fprintf(fp, "%d", usr); + else { + pwent = getpwuid(usr); + if (pwent != NULL) + fprintf(fp, "%s", pwent->pw_name); + else + fprintf(fp, "%d", usr); + } +} + +/* + * Prints a group value. + */ +static void +print_group(FILE *fp, u_int32_t grp, char raw) +{ + struct group *grpent; + + if (raw) + fprintf(fp, "%d", grp); + else { + grpent = getgrgid(grp); + if (grpent != NULL) + fprintf(fp, "%s", grpent->gr_name); + else + fprintf(fp, "%d", grp); + } +} + +/* + * Prints the event from the header token in either the short, default or raw + * form. + */ +static void +print_event(FILE *fp, u_int16_t ev, char raw, char sfrm) +{ + char event_ent_name[AU_EVENT_NAME_MAX]; + char event_ent_desc[AU_EVENT_DESC_MAX]; + struct au_event_ent e, *ep; + + bzero(&e, sizeof(e)); + bzero(event_ent_name, sizeof(event_ent_name)); + bzero(event_ent_desc, sizeof(event_ent_desc)); + e.ae_name = event_ent_name; + e.ae_desc = event_ent_desc; + + ep = getauevnum_r(&e, ev); + if (ep == NULL) { + fprintf(fp, "%u", ev); + return; + } + + if (raw) + fprintf(fp, "%u", ev); + else if (sfrm) + fprintf(fp, "%s", e.ae_name); + else + fprintf(fp, "%s", e.ae_desc); +} + + +/* + * Prints the event modifier from the header token in either the default or + * raw form. + */ +static void +print_evmod(FILE *fp, u_int16_t evmod, char raw) +{ + if (raw) + fprintf(fp, "%u", evmod); + else + fprintf(fp, "%u", evmod); +} + +/* + * Prints seconds in the ctime format. + */ +static void +print_sec32(FILE *fp, u_int32_t sec, char raw) +{ + time_t timestamp; + char timestr[26]; + + if (raw) + fprintf(fp, "%u", sec); + else { + timestamp = (time_t)sec; + ctime_r(×tamp, timestr); + timestr[24] = '\0'; /* No new line */ + fprintf(fp, "%s", timestr); + } +} + +/* + * XXXRW: 64-bit token streams make use of 64-bit time stamps; since we + * assume a 32-bit time_t, we simply truncate for now. + */ +static void +print_sec64(FILE *fp, u_int64_t sec, char raw) +{ + time_t timestamp; + char timestr[26]; + + if (raw) + fprintf(fp, "%u", (u_int32_t)sec); + else { + timestamp = (time_t)sec; + ctime_r(×tamp, timestr); + timestr[24] = '\0'; /* No new line */ + fprintf(fp, "%s", timestr); + } +} + +/* + * Prints the excess milliseconds. + */ +static void +print_msec32(FILE *fp, u_int32_t msec, char raw) +{ + if (raw) + fprintf(fp, "%u", msec); + else + fprintf(fp, " + %u msec", msec); +} + +/* + * XXXRW: 64-bit token streams make use of 64-bit time stamps; since we assume + * a 32-bit msec, we simply truncate for now. + */ +static void +print_msec64(FILE *fp, u_int64_t msec, char raw) +{ + + msec &= 0xffffffff; + if (raw) + fprintf(fp, "%u", (u_int32_t)msec); + else + fprintf(fp, " + %u msec", (u_int32_t)msec); +} + +/* + * Prints a dotted form for the IP address. + */ +static void +print_ip_address(FILE *fp, u_int32_t ip) +{ + struct in_addr ipaddr; + + ipaddr.s_addr = ip; + fprintf(fp, "%s", inet_ntoa(ipaddr)); +} + +/* + * Prints a string value for the given ip address. + */ +static void +print_ip_ex_address(FILE *fp, u_int32_t type, u_int32_t *ipaddr) +{ + struct in_addr ipv4; + struct in6_addr ipv6; + char dst[INET6_ADDRSTRLEN]; + + switch (type) { + case AU_IPv4: + ipv4.s_addr = (in_addr_t)(ipaddr[0]); + fprintf(fp, "%s", inet_ntop(AF_INET, &ipv4, dst, + INET6_ADDRSTRLEN)); + break; + + case AU_IPv6: + bcopy(ipaddr, &ipv6, sizeof(ipv6)); + fprintf(fp, "%s", inet_ntop(AF_INET6, &ipv6, dst, + INET6_ADDRSTRLEN)); + break; + + default: + fprintf(fp, "invalid"); + } +} + +/* + * Prints return value as success or failure. + */ +static void +print_retval(FILE *fp, u_char status, char raw) +{ + if (raw) + fprintf(fp, "%u", status); + else { + if (status == 0) + fprintf(fp, "success"); + else + fprintf(fp, "failure : %s", strerror(status)); + } +} + +/* + * Prints the exit value. + */ +static void +print_errval(FILE *fp, u_int32_t val) +{ + + fprintf(fp, "Error %u", val); +} + +/* + * Prints IPC type. + */ +static void +print_ipctype(FILE *fp, u_char type, char raw) +{ + if (raw) + fprintf(fp, "%u", type); + else { + if (type == AT_IPC_MSG) + fprintf(fp, "Message IPC"); + else if (type == AT_IPC_SEM) + fprintf(fp, "Semaphore IPC"); + else if (type == AT_IPC_SHM) + fprintf(fp, "Shared Memory IPC"); + else + fprintf(fp, "%u", type); + } +} + +/* + * Print XML header. + */ +void +au_print_xml_header(FILE *outfp) +{ + + fprintf(outfp, "<?xml version='1.0' ?>\n"); + fprintf(outfp, "<audit>\n"); +} + +/* + * Print XML footer. + */ +void +au_print_xml_footer(FILE *outfp) +{ + + fprintf(outfp, "</audit>\n"); +} + +/* + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + */ +static int +fetch_header32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr32.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, char sfrm, + int xml) +{ + + print_tok_type(fp, tok->id, "header", raw, xml); + if (xml) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr32.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr32.e_type, raw, sfrm); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr32.e_mod, raw); + close_attr(fp); + open_attr(fp, "time"); + print_sec32(fp, tok->tt.hdr32.s, raw); + close_attr(fp); + open_attr(fp, "msec"); + print_msec32(fp, tok->tt.hdr32.ms, 1); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr32.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr32.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr32.e_type, raw, sfrm); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr32.e_mod, raw); + print_delim(fp, del); + print_sec32(fp, tok->tt.hdr32.s, raw); + print_delim(fp, del); + print_msec32(fp, tok->tt.hdr32.ms, raw); + } +} + +/* + * The Solaris specifications for AUE_HEADER32_EX seem to differ a bit + * depending on the bit of the specifications found. The OpenSolaris source + * code uses a 4-byte address length, followed by some number of bytes of + * address data. This contrasts with the Solaris audit.log.5 man page, which + * specifies a 1-byte length field. We use the Solaris 10 definition so that + * we can parse audit trails from that system. + * + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 4 bytes + * [ Solaris man page: address type/length 1 byte] + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32/64-bits) + * nanoseconds of time 4 bytes/8 bytes (32/64-bits) + */ +static int +fetch_header32_ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr32_ex.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32_ex.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr32_ex.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.ad_type, tok->len, err); + if (err) + return (-1); + + bzero(tok->tt.hdr32_ex.addr, sizeof(tok->tt.hdr32_ex.addr)); + switch (tok->tt.hdr32_ex.ad_type) { + case AU_IPv4: + READ_TOKEN_BYTES(buf, len, &tok->tt.hdr32_ex.addr[0], + sizeof(tok->tt.hdr32_ex.addr[0]), tok->len, err); + if (err) + return (-1); + break; + + case AU_IPv6: + READ_TOKEN_BYTES(buf, len, tok->tt.hdr32_ex.addr, + sizeof(tok->tt.hdr32_ex.addr), tok->len, err); + break; + } + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr32_ex.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header32_ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "header_ex", raw, xml); + if (xml) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr32_ex.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr32_ex.e_type, raw, sfrm); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr32_ex.e_mod, raw); + close_attr(fp); + /* + * No attribute for additional types. + * + print_ip_ex_address(fp, tok->tt.hdr32_ex.ad_type, + tok->tt.hdr32_ex.addr); + */ + open_attr(fp, "time"); + print_sec32(fp, tok->tt.hdr32_ex.s, raw); + close_attr(fp); + open_attr(fp, "msec"); + print_msec32(fp, tok->tt.hdr32_ex.ms, raw); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr32_ex.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr32_ex.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr32_ex.e_type, raw, sfrm); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr32_ex.e_mod, raw); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.hdr32_ex.ad_type, + tok->tt.hdr32_ex.addr); + print_delim(fp, del); + print_sec32(fp, tok->tt.hdr32_ex.s, raw); + print_delim(fp, del); + print_msec32(fp, tok->tt.hdr32_ex.ms, raw); + } +} + +/* + * record byte count 4 bytes + * event type 2 bytes + * event modifier 2 bytes + * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) + * version # + */ +static int +fetch_header64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr64.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, char sfrm, + int xml) +{ + + print_tok_type(fp, tok->id, "header", raw, xml); + if (xml) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr64.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr64.e_type, raw, sfrm); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr64.e_mod, raw); + close_attr(fp); + open_attr(fp, "time"); + print_sec64(fp, tok->tt.hdr64.s, raw); + close_attr(fp); + open_attr(fp, "msec"); + print_msec64(fp, tok->tt.hdr64.ms, raw); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr64.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr64.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr64.e_type, raw, sfrm); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr64.e_mod, raw); + print_delim(fp, del); + print_sec64(fp, tok->tt.hdr64.s, raw); + print_delim(fp, del); + print_msec64(fp, tok->tt.hdr64.ms, raw); + } +} + +/* + * record byte count 4 bytes + * version # 1 byte [2] + * event type 2 bytes + * event modifier 2 bytes + * address type/length 4 bytes + * [ Solaris man page: address type/length 1 byte] + * machine address 4 bytes/16 bytes (IPv4/IPv6 address) + * seconds of time 4 bytes/8 bytes (32/64-bits) + * nanoseconds of time 4 bytes/8 bytes (32/64-bits) + * + * XXXAUDIT: See comment by fetch_header32_ex_tok() for details on the + * accuracy of the BSM spec. + */ +static int +fetch_header64_ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64_ex.size, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.hdr64_ex.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64_ex.e_type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.hdr64_ex.e_mod, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.hdr64_ex.ad_type, tok->len, err); + if (err) + return (-1); + + bzero(tok->tt.hdr64_ex.addr, sizeof(tok->tt.hdr64_ex.addr)); + switch (tok->tt.hdr64_ex.ad_type) { + case AU_IPv4: + READ_TOKEN_BYTES(buf, len, &tok->tt.hdr64_ex.addr[0], + sizeof(tok->tt.hdr64_ex.addr[0]), tok->len, err); + if (err) + return (-1); + break; + + case AU_IPv6: + READ_TOKEN_BYTES(buf, len, tok->tt.hdr64_ex.addr, + sizeof(tok->tt.hdr64_ex.addr), tok->len, err); + break; + } + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64_ex.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.hdr64_ex.ms, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_header64_ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "header_ex", raw, xml); + if (xml) { + open_attr(fp, "version"); + print_1_byte(fp, tok->tt.hdr64_ex.version, "%u"); + close_attr(fp); + open_attr(fp, "event"); + print_event(fp, tok->tt.hdr64_ex.e_type, raw, sfrm); + close_attr(fp); + open_attr(fp, "modifier"); + print_evmod(fp, tok->tt.hdr64_ex.e_mod, raw); + close_attr(fp); + /* + * No attribute for additional types. + * + print_ip_ex_address(fp, tok->tt.hdr64_ex.ad_type, + tok->tt.hdr64_ex.addr); + */ + open_attr(fp, "time"); + print_sec64(fp, tok->tt.hdr64_ex.s, raw); + close_attr(fp); + open_attr(fp, "msec"); + print_msec64(fp, tok->tt.hdr64_ex.ms, raw); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.hdr64_ex.size, "%u"); + print_delim(fp, del); + print_1_byte(fp, tok->tt.hdr64_ex.version, "%u"); + print_delim(fp, del); + print_event(fp, tok->tt.hdr64_ex.e_type, raw, sfrm); + print_delim(fp, del); + print_evmod(fp, tok->tt.hdr64_ex.e_mod, raw); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.hdr64_ex.ad_type, + tok->tt.hdr64_ex.addr); + print_delim(fp, del); + print_sec64(fp, tok->tt.hdr64_ex.s, raw); + print_delim(fp, del); + print_msec64(fp, tok->tt.hdr64_ex.ms, raw); + } +} + +/* + * trailer magic 2 bytes + * record size 4 bytes + */ +static int +fetch_trailer_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.trail.magic, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.trail.count, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_trailer_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "trailer", raw, xml); + if (!xml) { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.trail.count, "%u"); + } +} + +/* + * argument # 1 byte + * argument value 4 bytes/8 bytes (32-bit/64-bit value) + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +static int +fetch_arg32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arg32.no, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.arg32.val, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.arg32.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.arg32.text, tok->tt.arg32.len, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_arg32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "argument", raw, xml); + if (xml) { + open_attr(fp, "arg-num"); + print_1_byte(fp, tok->tt.arg32.no, "%u"); + close_attr(fp); + open_attr(fp, "value"); + print_4_bytes(fp, tok->tt.arg32.val, "0x%x"); + close_attr(fp); + open_attr(fp, "desc"); + print_string(fp, tok->tt.arg32.text, tok->tt.arg32.len); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_1_byte(fp, tok->tt.arg32.no, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.arg32.val, "0x%x"); + print_delim(fp, del); + print_string(fp, tok->tt.arg32.text, tok->tt.arg32.len); + } +} + +static int +fetch_arg64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arg64.no, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.arg64.val, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.arg64.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.arg64.text, tok->tt.arg64.len, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_arg64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "argument", raw, xml); + if (xml) { + open_attr(fp, "arg-num"); + print_1_byte(fp, tok->tt.arg64.no, "%u"); + close_attr(fp); + open_attr(fp, "value"); + print_8_bytes(fp, tok->tt.arg64.val, "0x%llx"); + close_attr(fp); + open_attr(fp, "desc"); + print_string(fp, tok->tt.arg64.text, tok->tt.arg64.len); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_1_byte(fp, tok->tt.arg64.no, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.arg64.val, "0x%llx"); + print_delim(fp, del); + print_string(fp, tok->tt.arg64.text, tok->tt.arg64.len); + } +} + +/* + * how to print 1 byte + * basic unit 1 byte + * unit count 1 byte + * data items (depends on basic unit) + */ +static int +fetch_arb_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + int datasize; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.howtopr, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.bu, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.arb.uc, tok->len, err); + if (err) + return (-1); + + /* + * Determine the size of the basic unit. + */ + switch(tok->tt.arb.bu) { + case AUR_BYTE: + /* case AUR_CHAR: */ + datasize = AUR_BYTE_SIZE; + break; + + case AUR_SHORT: + datasize = AUR_SHORT_SIZE; + break; + + case AUR_INT32: + /* case AUR_INT: */ + datasize = AUR_INT32_SIZE; + break; + + case AUR_INT64: + datasize = AUR_INT64_SIZE; + break; + + default: + return (-1); + } + + SET_PTR(buf, len, tok->tt.arb.data, datasize * tok->tt.arb.uc, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_arb_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + char *str; + char *format; + size_t size; + int i; + + print_tok_type(fp, tok->id, "arbitrary", raw, xml); + if (!xml) + print_delim(fp, del); + + switch(tok->tt.arb.howtopr) { + case AUP_BINARY: + str = "binary"; + format = " %c"; + break; + + case AUP_OCTAL: + str = "octal"; + format = " %o"; + break; + + case AUP_DECIMAL: + str = "decimal"; + format = " %d"; + break; + + case AUP_HEX: + str = "hex"; + format = " %x"; + break; + + case AUP_STRING: + str = "string"; + format = "%c"; + break; + + default: + return; + } + + if (xml) { + open_attr(fp, "print"); + fprintf(fp, "%s",str); + close_attr(fp); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + } + switch(tok->tt.arb.bu) { + case AUR_BYTE: + /* case AUR_CHAR: */ + str = "byte"; + size = AUR_BYTE_SIZE; + if (xml) { + open_attr(fp, "type"); + fprintf(fp, "%u", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i<tok->tt.arb.uc; i++) + fprintf(fp, format, *(tok->tt.arb.data + + (size * i))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i<tok->tt.arb.uc; i++) + fprintf(fp, format, *(tok->tt.arb.data + + (size * i))); + } + break; + + case AUR_SHORT: + str = "short"; + size = AUR_SHORT_SIZE; + if (xml) { + open_attr(fp, "type"); + fprintf(fp, "%u", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int16_t *)(tok->tt.arb.data + + (size * i)))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int16_t *)(tok->tt.arb.data + + (size * i)))); + } + break; + + case AUR_INT32: + /* case AUR_INT: */ + str = "int"; + size = AUR_INT32_SIZE; + if (xml) { + open_attr(fp, "type"); + fprintf(fp, "%u", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int32_t *)(tok->tt.arb.data + + (size * i)))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int32_t *)(tok->tt.arb.data + + (size * i)))); + } + break; + + case AUR_INT64: + str = "int64"; + size = AUR_INT64_SIZE; + if (xml) { + open_attr(fp, "type"); + fprintf(fp, "%u", size); + close_attr(fp); + open_attr(fp, "count"); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + close_attr(fp); + fprintf(fp, ">"); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int64_t *)(tok->tt.arb.data + + (size * i)))); + close_tag(fp, tok->id); + } else { + print_string(fp, str, strlen(str)); + print_delim(fp, del); + print_1_byte(fp, tok->tt.arb.uc, "%u"); + print_delim(fp, del); + for (i = 0; i < tok->tt.arb.uc; i++) + fprintf(fp, format, + *((u_int64_t *)(tok->tt.arb.data + + (size * i)))); + } + break; + + default: + return; + } +} + +/* + * file access mode 4 bytes + * owner user ID 4 bytes + * owner group ID 4 bytes + * file system ID 4 bytes + * node ID 8 bytes + * device 4 bytes/8 bytes (32-bit/64-bit) + */ +static int +fetch_attr32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.mode, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.uid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.gid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.fsid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.attr32.nid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr32.dev, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_attr32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "attribute", raw, xml); + if (xml) { + open_attr(fp, "mode"); + print_4_bytes(fp, tok->tt.attr32.mode, "%o"); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.attr32.uid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.attr32.gid, raw); + close_attr(fp); + open_attr(fp, "fsid"); + print_4_bytes(fp, tok->tt.attr32.fsid, "%u"); + close_attr(fp); + open_attr(fp, "nodeid"); + print_8_bytes(fp, tok->tt.attr32.nid, "%lld"); + close_attr(fp); + open_attr(fp, "device"); + print_4_bytes(fp, tok->tt.attr32.dev, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr32.mode, "%o"); + print_delim(fp, del); + print_user(fp, tok->tt.attr32.uid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.attr32.gid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr32.fsid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.attr32.nid, "%lld"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr32.dev, "%u"); + } +} + +/* + * file access mode 4 bytes + * owner user ID 4 bytes + * owner group ID 4 bytes + * file system ID 4 bytes + * node ID 8 bytes + * device 4 bytes/8 bytes (32-bit/64-bit) + */ +static int +fetch_attr64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.mode, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.uid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.gid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.attr64.fsid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.attr64.nid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.attr64.dev, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_attr64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "attribute", raw, xml); + if (xml) { + open_attr(fp, "mode"); + print_4_bytes(fp, tok->tt.attr64.mode, "%o"); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.attr64.uid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.attr64.gid, raw); + close_attr(fp); + open_attr(fp, "fsid"); + print_4_bytes(fp, tok->tt.attr64.fsid, "%u"); + close_attr(fp); + open_attr(fp, "nodeid"); + print_8_bytes(fp, tok->tt.attr64.nid, "%lld"); + close_attr(fp); + open_attr(fp, "device"); + print_8_bytes(fp, tok->tt.attr64.dev, "%llu"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr64.mode, "%o"); + print_delim(fp, del); + print_user(fp, tok->tt.attr64.uid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.attr64.gid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.attr64.fsid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.attr64.nid, "%lld"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.attr64.dev, "%llu"); + } +} + +/* + * status 4 bytes + * return value 4 bytes + */ +static int +fetch_exit_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.exit.status, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.exit.ret, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_exit_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "exit", raw, xml); + if (xml) { + open_attr(fp, "errval"); + print_errval(fp, tok->tt.exit.status); + close_attr(fp); + open_attr(fp, "retval"); + print_4_bytes(fp, tok->tt.exit.ret, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_errval(fp, tok->tt.exit.status); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.exit.ret, "%u"); + } +} + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +static int +fetch_execarg_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + int i; + u_char *bptr; + + READ_TOKEN_U_INT32(buf, len, tok->tt.execarg.count, tok->len, err); + if (err) + return (-1); + + for (i = 0; i < tok->tt.execarg.count; i++) { + bptr = buf + tok->len; + if (i < AUDIT_MAX_ARGS) + tok->tt.execarg.text[i] = (char*)bptr; + + /* Look for a null terminated string. */ + while (bptr && (*bptr != '\0')) { + if (++tok->len >=len) + return (-1); + bptr = buf + tok->len; + } + if (!bptr) + return (-1); + tok->len++; /* \0 character */ + } + if (tok->tt.execarg.count > AUDIT_MAX_ARGS) + tok->tt.execarg.count = AUDIT_MAX_ARGS; + + return (0); +} + +static void +print_execarg_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + int i; + + print_tok_type(fp, tok->id, "exec arg", raw, xml); + for (i = 0; i < tok->tt.execarg.count; i++) { + if (xml) { + fprintf(fp, "<arg>"); + print_string(fp, tok->tt.execarg.text[i], + strlen(tok->tt.execarg.text[i])); + fprintf(fp, "</arg>"); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.execarg.text[i], + strlen(tok->tt.execarg.text[i])); + } + } + if (xml) + close_tag(fp, tok->id); +} + +/* + * count 4 bytes + * text count null-terminated string(s) + */ +static int +fetch_execenv_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + int i; + u_char *bptr; + + READ_TOKEN_U_INT32(buf, len, tok->tt.execenv.count, tok->len, err); + if (err) + return (-1); + + for (i = 0; i < tok->tt.execenv.count; i++) { + bptr = buf + tok->len; + if (i < AUDIT_MAX_ENV) + tok->tt.execenv.text[i] = (char*)bptr; + + /* Look for a null terminated string. */ + while (bptr && (*bptr != '\0')) { + if (++tok->len >=len) + return (-1); + bptr = buf + tok->len; + } + if (!bptr) + return (-1); + tok->len++; /* \0 character */ + } + if (tok->tt.execenv.count > AUDIT_MAX_ENV) + tok->tt.execenv.count = AUDIT_MAX_ENV; + + return (0); +} + +static void +print_execenv_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + int i; + + print_tok_type(fp, tok->id, "exec env", raw, xml); + for (i = 0; i< tok->tt.execenv.count; i++) { + if (xml) { + fprintf(fp, "<env>"); + print_string(fp, tok->tt.execenv.text[i], + strlen(tok->tt.execenv.text[i])); + fprintf(fp, "</env>"); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.execenv.text[i], + strlen(tok->tt.execenv.text[i])); + } + } + if (xml) + close_tag(fp, tok->id); +} + +/* + * seconds of time 4 bytes + * milliseconds of time 4 bytes + * file name len 2 bytes + * file pathname N bytes + 1 terminating NULL byte + */ +static int +fetch_file_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.file.s, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.file.ms, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT16(buf, len, tok->tt.file.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.file.name, tok->tt.file.len, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_file_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "file", raw, xml); + if (xml) { + open_attr(fp, "time"); + print_sec32(fp, tok->tt.file.s, raw); + close_attr(fp); + open_attr(fp, "msec"); + print_msec32(fp, tok->tt.file.ms, raw); + close_attr(fp); + fprintf(fp, ">"); + print_string(fp, tok->tt.file.name, tok->tt.file.len); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_sec32(fp, tok->tt.file.s, raw); + print_delim(fp, del); + print_msec32(fp, tok->tt.file.ms, raw); + print_delim(fp, del); + print_string(fp, tok->tt.file.name, tok->tt.file.len); + } +} + +/* + * number groups 2 bytes + * group list count * 4 bytes + */ +static int +fetch_newgroups_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int i; + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.grps.no, tok->len, err); + if (err) + return (-1); + + for (i = 0; i<tok->tt.grps.no; i++) { + READ_TOKEN_U_INT32(buf, len, tok->tt.grps.list[i], tok->len, + err); + if (err) + return (-1); + } + + return (0); +} + +static void +print_newgroups_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + int i; + + print_tok_type(fp, tok->id, "group", raw, xml); + for (i = 0; i < tok->tt.grps.no; i++) { + if (xml) { + fprintf(fp, "<gid>"); + print_group(fp, tok->tt.grps.list[i], raw); + fprintf(fp, "</gid>"); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_group(fp, tok->tt.grps.list[i], raw); + } + } +} + +/* + * Internet addr 4 bytes + */ +static int +fetch_inaddr_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_BYTES(buf, len, &tok->tt.inaddr.addr, sizeof(uint32_t), + tok->len, err); + if (err) + return (-1); + + return (0); + +} + +static void +print_inaddr_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "ip addr", raw, xml); + if (xml) { + print_ip_address(fp, tok->tt.inaddr.addr); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_ip_address(fp, tok->tt.inaddr.addr); + } +} + +/* + * type 4 bytes + * address 16 bytes + */ +static int +fetch_inaddr_ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.inaddr_ex.type, tok->len, err); + if (err) + return (-1); + + if (tok->tt.inaddr_ex.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.inaddr_ex.addr[0], + sizeof(tok->tt.inaddr_ex.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.inaddr_ex.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.inaddr_ex.addr, + sizeof(tok->tt.inaddr_ex.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_inaddr_ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "ip addr ex", raw, xml); + if (xml) { + print_ip_ex_address(fp, tok->tt.inaddr_ex.type, + tok->tt.inaddr_ex.addr); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.inaddr_ex.type, + tok->tt.inaddr_ex.addr); + } +} + +/* + * ip header 20 bytes + */ +static int +fetch_ip_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.version, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.tos, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.len, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.id, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.offset, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.ttl, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ip.prot, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.chksm, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.src, sizeof(tok->tt.ip.src), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.ip.dest, sizeof(tok->tt.ip.dest), + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_ip_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "ip", raw, xml); + if (xml) { + open_attr(fp, "version"); + print_mem(fp, (u_char *)(&tok->tt.ip.version), + sizeof(u_char)); + close_attr(fp); + open_attr(fp, "service_type"); + print_mem(fp, (u_char *)(&tok->tt.ip.tos), sizeof(u_char)); + close_attr(fp); + open_attr(fp, "len"); + print_2_bytes(fp, ntohs(tok->tt.ip.len), "%u"); + close_attr(fp); + open_attr(fp, "id"); + print_2_bytes(fp, ntohs(tok->tt.ip.id), "%u"); + close_attr(fp); + open_attr(fp, "offset"); + print_2_bytes(fp, ntohs(tok->tt.ip.offset), "%u"); + close_attr(fp); + open_attr(fp, "time_to_live"); + print_mem(fp, (u_char *)(&tok->tt.ip.ttl), sizeof(u_char)); + close_attr(fp); + open_attr(fp, "protocol"); + print_mem(fp, (u_char *)(&tok->tt.ip.prot), sizeof(u_char)); + close_attr(fp); + open_attr(fp, "cksum"); + print_2_bytes(fp, ntohs(tok->tt.ip.chksm), "%u"); + close_attr(fp); + open_attr(fp, "src_addr"); + print_ip_address(fp, tok->tt.ip.src); + close_attr(fp); + open_attr(fp, "dest_addr"); + print_ip_address(fp, tok->tt.ip.dest); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.version), + sizeof(u_char)); + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.tos), sizeof(u_char)); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.len), "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.id), "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.offset), "%u"); + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.ttl), sizeof(u_char)); + print_delim(fp, del); + print_mem(fp, (u_char *)(&tok->tt.ip.prot), sizeof(u_char)); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.ip.chksm), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.ip.src); + print_delim(fp, del); + print_ip_address(fp, tok->tt.ip.dest); + } +} + +/* + * object ID type 1 byte + * Object ID 4 bytes + */ +static int +fetch_ipc_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ipc.type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipc.id, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_ipc_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "IPC", raw, xml); + if (xml) { + open_attr(fp, "ipc-type"); + print_ipctype(fp, tok->tt.ipc.type, raw); + close_attr(fp); + open_attr(fp, "ipc-id"); + print_4_bytes(fp, tok->tt.ipc.id, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_ipctype(fp, tok->tt.ipc.type, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipc.id, "%u"); + } +} + +/* + * owner user id 4 bytes + * owner group id 4 bytes + * creator user id 4 bytes + * creator group id 4 bytes + * access mode 4 bytes + * slot seq 4 bytes + * key 4 bytes + */ +static int +fetch_ipcperm_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.uid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.gid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.puid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.pgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.mode, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.seq, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ipcperm.key, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_ipcperm_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "IPC perm", raw, xml); + if (xml) { + open_attr(fp, "uid"); + print_user(fp, tok->tt.ipcperm.uid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.ipcperm.gid, raw); + close_attr(fp); + open_attr(fp, "creator-uid"); + print_user(fp, tok->tt.ipcperm.puid, raw); + close_attr(fp); + open_attr(fp, "creator-gid"); + print_group(fp, tok->tt.ipcperm.pgid, raw); + close_attr(fp); + open_attr(fp, "mode"); + print_4_bytes(fp, tok->tt.ipcperm.mode, "%o"); + close_attr(fp); + open_attr(fp, "seq"); + print_4_bytes(fp, tok->tt.ipcperm.seq, "%u"); + close_attr(fp); + open_attr(fp, "key"); + print_4_bytes(fp, tok->tt.ipcperm.key, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.ipcperm.uid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.ipcperm.gid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.ipcperm.puid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.ipcperm.pgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipcperm.mode, "%o"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipcperm.seq, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ipcperm.key, "%u"); + } +} + +/* + * port Ip address 2 bytes + */ +static int +fetch_iport_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_BYTES(buf, len, &tok->tt.iport.port, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_iport_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "ip port", raw, xml); + if (xml) { + print_2_bytes(fp, ntohs(tok->tt.iport.port), "%#x"); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.iport.port), "%#x"); + } +} + +/* + * size 2 bytes + * data size bytes + */ +static int +fetch_opaque_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.opaque.size, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.opaque.data, tok->tt.opaque.size, + tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_opaque_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "opaque", raw, xml); + if (xml) { + print_mem(fp, (u_char*)tok->tt.opaque.data, + tok->tt.opaque.size); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.opaque.size, "%u"); + print_delim(fp, del); + print_mem(fp, (u_char*)tok->tt.opaque.data, + tok->tt.opaque.size); + } +} + +/* + * size 2 bytes + * data size bytes + */ +static int +fetch_path_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.path.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.path.path, tok->tt.path.len, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_path_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "path", raw, xml); + if (xml) { + print_string(fp, tok->tt.path.path, tok->tt.path.len); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.path.path, tok->tt.path.len); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes + * machine id 4 bytes + */ +static int +fetch_process32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.proc32.tid.addr, + sizeof(tok->tt.proc32.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_process32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "process", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc32.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc32.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc32.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc32.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc32.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc32.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc32.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_4_bytes(fp, tok->tt.proc32.tid.port, "%u"); + print_ip_address(fp, tok->tt.proc32.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc32.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc32.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc32.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc32.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc32.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32.tid.port, "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.proc32.tid.addr); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 8 bytes + * machine id 4 bytes + */ +static int +fetch_process64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.proc64.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.proc64.tid.addr, + sizeof(tok->tt.proc64.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_process64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + print_tok_type(fp, tok->id, "process", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc64.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc64.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc64.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc64.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc64.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc64.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc64.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.proc64.tid.port, "%llu"); + print_ip_address(fp, tok->tt.proc64.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc64.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc64.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc64.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc64.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc64.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.proc64.tid.port, "%llu"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.proc64.tid.addr); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 4 bytes + * address type-len 4 bytes + * machine address 16 bytes + */ +static int +fetch_process32ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc32_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.proc32_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.proc32_ex.tid.addr[0], + sizeof(tok->tt.proc32_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.proc32_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.proc32_ex.tid.addr, + sizeof(tok->tt.proc32_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_process32ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "process_ex", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc32_ex.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc32_ex.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc32_ex.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc32_ex.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc32_ex.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc32_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_4_bytes(fp, tok->tt.proc32_ex.tid.port, "%u"); + print_ip_ex_address(fp, tok->tt.proc32_ex.tid.type, + tok->tt.proc32_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc32_ex.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc32_ex.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc32_ex.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc32_ex.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc32_ex.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32_ex.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc32_ex.tid.port, "%u"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.proc32_ex.tid.type, + tok->tt.proc32_ex.tid.addr); + } +} + +/* + * token ID 1 byte + * audit ID 4 bytes + * effective user ID 4 bytes + * effective group ID 4 bytes + * real user ID 4 bytes + * real group ID 4 bytes + * process ID 4 bytes + * session ID 4 bytes + * terminal ID + * port ID 8 bytes + * address type-len 4 bytes + * machine address 16 bytes + */ +static int +fetch_process64ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.proc64_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.proc64_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.proc64_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.proc64_ex.tid.addr[0], + sizeof(tok->tt.proc64_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.proc64_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.proc64_ex.tid.addr, + sizeof(tok->tt.proc64_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_process64ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + print_tok_type(fp, tok->id, "process_ex", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.proc64_ex.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.proc64_ex.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.proc64_ex.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.proc64_ex.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.proc64_ex.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.proc64_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.proc64_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.proc64_ex.tid.port, "%llu"); + print_ip_ex_address(fp, tok->tt.proc64_ex.tid.type, + tok->tt.proc64_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.proc64_ex.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc64_ex.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc64_ex.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.proc64_ex.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.proc64_ex.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.proc64_ex.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.proc64_ex.tid.port, "%llu"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.proc64_ex.tid.type, + tok->tt.proc64_ex.tid.addr); + } +} + +/* + * errno 1 byte + * return value 4 bytes + */ +static int +fetch_return32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ret32.status, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.ret32.ret, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_return32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "return", raw, xml); + if (xml) { + open_attr(fp ,"errval"); + print_retval(fp, tok->tt.ret32.status, raw); + close_attr(fp); + open_attr(fp, "retval"); + print_4_bytes(fp, tok->tt.ret32.ret, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_retval(fp, tok->tt.ret32.status, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.ret32.ret, "%u"); + } +} + +static int +fetch_return64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_CHAR(buf, len, tok->tt.ret64.err, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.ret64.val, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_return64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "return", raw, xml); + if (xml) { + open_attr(fp, "errval"); + print_retval(fp, tok->tt.ret64.err, raw); + close_attr(fp); + open_attr(fp, "retval"); + print_8_bytes(fp, tok->tt.ret64.val, "%lld"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_retval(fp, tok->tt.ret64.err, raw); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.ret64.val, "%lld"); + } +} + +/* + * seq 4 bytes + */ +static int +fetch_seq_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.seq.seqno, tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_seq_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "sequence", raw, xml); + if (xml) { + open_attr(fp, "seq-num"); + print_4_bytes(fp, tok->tt.seq.seqno, "%u"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_4_bytes(fp, tok->tt.seq.seqno, "%u"); + } +} + +/* + * socket family 2 bytes + * local port 2 bytes + * socket address 4 bytes + */ +static int +fetch_sock_inet32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.sockinet32.family, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet32.port, + sizeof(uint16_t), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.sockinet32.addr, + sizeof(tok->tt.sockinet32.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_sock_inet32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "socket-inet", raw, xml); + if (xml) { + open_attr(fp, "type"); + print_2_bytes(fp, tok->tt.sockinet32.family, "%u"); + close_attr(fp); + open_attr(fp, "port"); + print_2_bytes(fp, ntohs(tok->tt.sockinet32.port), "%u"); + close_attr(fp); + open_attr(fp, "addr"); + print_ip_address(fp, tok->tt.sockinet32.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.sockinet32.family, "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.sockinet32.port), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.sockinet32.addr); + } +} + +/* + * socket family 2 bytes + * path 104 bytes + */ +static int +fetch_sock_unix_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.sockunix.family, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, tok->tt.sockunix.path, 104, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_sock_unix_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "socket-unix", raw, xml); + if (xml) { + open_attr(fp, "type"); + print_2_bytes(fp, tok->tt.sockunix.family, "%u"); + close_attr(fp); + open_attr(fp, "port"); + close_attr(fp); + open_attr(fp, "addr"); + print_string(fp, tok->tt.sockunix.path, + strlen(tok->tt.sockunix.path)); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.sockunix.family, "%u"); + print_delim(fp, del); + print_string(fp, tok->tt.sockunix.path, + strlen(tok->tt.sockunix.path)); + } +} + +/* + * socket type 2 bytes + * local port 2 bytes + * local address 4 bytes + * remote port 2 bytes + * remote address 4 bytes + */ +static int +fetch_socket_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.socket.type, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_port, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_addr, + sizeof(tok->tt.socket.l_addr), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.r_port, sizeof(uint16_t), + tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket.l_addr, + sizeof(tok->tt.socket.r_addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_socket_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "socket", raw, xml); + if (xml) { + open_attr(fp, "sock_type"); + print_2_bytes(fp, tok->tt.socket.type, "%u"); + close_attr(fp); + open_attr(fp, "lport"); + print_2_bytes(fp, ntohs(tok->tt.socket.l_port), "%u"); + close_attr(fp); + open_attr(fp, "laddr"); + print_ip_address(fp, tok->tt.socket.l_addr); + close_attr(fp); + open_attr(fp, "fport"); + print_2_bytes(fp, ntohs(tok->tt.socket.r_port), "%u"); + close_attr(fp); + open_attr(fp, "faddr"); + print_ip_address(fp, tok->tt.socket.r_addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.socket.type, "%u"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.socket.l_port), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.socket.l_addr); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.socket.r_port), "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.socket.r_addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes/8 bytes (32-bit/64-bit value) + * machine id 4 bytes + */ +static int +fetch_subject32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.subj32.tid.addr, + sizeof(tok->tt.subj32.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_subject32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "subject", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj32.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj32.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj32.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj32.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj32.rgid, raw); + close_attr(fp); + open_attr(fp,"pid"); + print_4_bytes(fp, tok->tt.subj32.pid, "%u"); + close_attr(fp); + open_attr(fp,"sid"); + print_4_bytes(fp, tok->tt.subj32.sid, "%u"); + close_attr(fp); + open_attr(fp,"tid"); + print_4_bytes(fp, tok->tt.subj32.tid.port, "%u "); + print_ip_address(fp, tok->tt.subj32.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj32.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj32.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj32.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj32.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj32.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32.tid.port, "%u"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.subj32.tid.addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes/8 bytes (32-bit/64-bit value) + * machine id 4 bytes + */ +static int +fetch_subject64_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.subj64.tid.port, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.subj64.tid.addr, + sizeof(tok->tt.subj64.tid.addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_subject64_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "subject", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj64.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj64.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj64.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj64.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj64.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.subj64.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.subj64.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.subj64.tid.port, "%llu"); + print_ip_address(fp, tok->tt.subj64.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj64.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj64.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj64.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj64.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj64.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.subj64.tid.port, "%llu"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.subj64.tid.addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 4 bytes + * type 4 bytes + * machine id 16 bytes + */ +static int +fetch_subject32ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj32_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.subj32_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.subj32_ex.tid.addr[0], + sizeof(tok->tt.subj32_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.subj32_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.subj32_ex.tid.addr, + sizeof(tok->tt.subj32_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_subject32ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "subject_ex", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj32_ex.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj32_ex.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj32_ex.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj32_ex.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj32_ex.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.subj32_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_4_bytes(fp, tok->tt.subj32_ex.tid.port, "%u"); + print_ip_ex_address(fp, tok->tt.subj32_ex.tid.type, + tok->tt.subj32_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj32_ex.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj32_ex.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj32_ex.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj32_ex.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj32_ex.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32_ex.sid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj32_ex.tid.port, "%u"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.subj32_ex.tid.type, + tok->tt.subj32_ex.tid.addr); + } +} + +/* + * audit ID 4 bytes + * euid 4 bytes + * egid 4 bytes + * ruid 4 bytes + * rgid 4 bytes + * pid 4 bytes + * sessid 4 bytes + * terminal ID + * portid 8 bytes + * type 4 bytes + * machine id 16 bytes + */ +static int +fetch_subject64ex_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.auid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.euid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.egid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.ruid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.rgid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.pid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.sid, tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT64(buf, len, tok->tt.subj64_ex.tid.port, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.subj64_ex.tid.type, tok->len, + err); + if (err) + return (-1); + + if (tok->tt.subj64_ex.tid.type == AU_IPv4) { + READ_TOKEN_BYTES(buf, len, &tok->tt.subj64_ex.tid.addr[0], + sizeof(tok->tt.subj64_ex.tid.addr[0]), tok->len, err); + if (err) + return (-1); + } else if (tok->tt.subj64_ex.tid.type == AU_IPv6) { + READ_TOKEN_BYTES(buf, len, tok->tt.subj64_ex.tid.addr, + sizeof(tok->tt.subj64_ex.tid.addr), tok->len, err); + if (err) + return (-1); + } else + return (-1); + + return (0); +} + +static void +print_subject64ex_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + print_tok_type(fp, tok->id, "subject_ex", raw, xml); + if (xml) { + open_attr(fp, "audit-uid"); + print_user(fp, tok->tt.subj64_ex.auid, raw); + close_attr(fp); + open_attr(fp, "uid"); + print_user(fp, tok->tt.subj64_ex.euid, raw); + close_attr(fp); + open_attr(fp, "gid"); + print_group(fp, tok->tt.subj64_ex.egid, raw); + close_attr(fp); + open_attr(fp, "ruid"); + print_user(fp, tok->tt.subj64_ex.ruid, raw); + close_attr(fp); + open_attr(fp, "rgid"); + print_group(fp, tok->tt.subj64_ex.rgid, raw); + close_attr(fp); + open_attr(fp, "pid"); + print_4_bytes(fp, tok->tt.subj64_ex.pid, "%u"); + close_attr(fp); + open_attr(fp, "sid"); + print_4_bytes(fp, tok->tt.subj64_ex.sid, "%u"); + close_attr(fp); + open_attr(fp, "tid"); + print_8_bytes(fp, tok->tt.subj64_ex.tid.port, "%llu"); + print_ip_ex_address(fp, tok->tt.subj64_ex.tid.type, + tok->tt.subj64_ex.tid.addr); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_user(fp, tok->tt.subj64_ex.auid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj64_ex.euid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj64_ex.egid, raw); + print_delim(fp, del); + print_user(fp, tok->tt.subj64_ex.ruid, raw); + print_delim(fp, del); + print_group(fp, tok->tt.subj64_ex.rgid, raw); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64_ex.pid, "%u"); + print_delim(fp, del); + print_4_bytes(fp, tok->tt.subj64_ex.sid, "%u"); + print_delim(fp, del); + print_8_bytes(fp, tok->tt.subj64_ex.tid.port, "%llu"); + print_delim(fp, del); + print_ip_ex_address(fp, tok->tt.subj64_ex.tid.type, + tok->tt.subj64_ex.tid.addr); + } +} + +/* + * size 2 bytes + * data size bytes + */ +static int +fetch_text_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.text.len, tok->len, err); + if (err) + return (-1); + + SET_PTR((char*)buf, len, tok->tt.text.text, tok->tt.text.len, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_text_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "text", raw, xml); + if (xml) { + print_string(fp, tok->tt.text.text, tok->tt.text.len); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.text.text, tok->tt.text.len); + } +} + +/* + * socket type 2 bytes + * local port 2 bytes + * address type/length 4 bytes + * local Internet address 4 bytes + * remote port 4 bytes + * address type/length 4 bytes + * remote Internet address 4 bytes + */ +static int +fetch_socketex32_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.socket_ex32.type, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_port, + sizeof(uint16_t), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.l_ad_type, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.l_addr, + sizeof(tok->tt.socket_ex32.l_addr), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_port, + sizeof(uint16_t), tok->len, err); + if (err) + return (-1); + + READ_TOKEN_U_INT32(buf, len, tok->tt.socket_ex32.r_ad_type, tok->len, + err); + if (err) + return (-1); + + READ_TOKEN_BYTES(buf, len, &tok->tt.socket_ex32.r_addr, + sizeof(tok->tt.socket_ex32.r_addr), tok->len, err); + if (err) + return (-1); + + return (0); +} + +static void +print_socketex32_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "socket", raw, xml); + if (xml) { + open_attr(fp, "sock_type"); + print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x"); + close_attr(fp); + open_attr(fp, "lport"); + print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x"); + close_attr(fp); + open_attr(fp, "laddr"); + print_ip_address(fp, tok->tt.socket_ex32.l_addr); + close_attr(fp); + open_attr(fp, "faddr"); + print_ip_address(fp, tok->tt.socket_ex32.r_addr); + close_attr(fp); + open_attr(fp, "fport"); + print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x"); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_2_bytes(fp, tok->tt.socket_ex32.type, "%#x"); + print_delim(fp, del); + print_2_bytes(fp, ntohs(tok->tt.socket_ex32.l_port), "%#x"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.socket_ex32.l_addr); + print_delim(fp, del); + print_4_bytes(fp, ntohs(tok->tt.socket_ex32.r_port), "%#x"); + print_delim(fp, del); + print_ip_address(fp, tok->tt.socket_ex32.r_addr); + } +} + +static int +fetch_invalid_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + int recoversize; + + recoversize = len - (tok->len + AUDIT_TRAILER_SIZE); + if (recoversize <= 0) + return (-1); + + tok->tt.invalid.length = recoversize; + + SET_PTR((char*)buf, len, tok->tt.invalid.data, recoversize, tok->len, + err); + if (err) + return (-1); + + return (0); +} + +static void +print_invalid_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + if (!xml) { + print_tok_type(fp, tok->id, "unknown", raw, 0); + print_delim(fp, del); + print_mem(fp, (u_char*)tok->tt.invalid.data, + tok->tt.invalid.length); + } +} + + +/* + * size 2 bytes; + * zonename size bytes; + */ +static int +fetch_zonename_tok(tokenstr_t *tok, u_char *buf, int len) +{ + int err = 0; + + READ_TOKEN_U_INT16(buf, len, tok->tt.zonename.len, tok->len, err); + if (err) + return (-1); + SET_PTR((char *)buf, len, tok->tt.zonename.zonename, tok->tt.zonename.len, + tok->len, err); + if (err) + return (-1); + return (0); +} + +static void +print_zonename_tok(FILE *fp, tokenstr_t *tok, char *del, char raw, + __unused char sfrm, int xml) +{ + + print_tok_type(fp, tok->id, "zone", raw, xml); + if (xml) { + open_attr(fp, "name"); + print_string(fp, tok->tt.zonename.zonename, + tok->tt.zonename.len); + close_attr(fp); + close_tag(fp, tok->id); + } else { + print_delim(fp, del); + print_string(fp, tok->tt.zonename.zonename, + tok->tt.zonename.len); + } +} + +/* + * Reads the token beginning at buf into tok. + */ +int +au_fetch_tok(tokenstr_t *tok, u_char *buf, int len) +{ + + if (len <= 0) + return (-1); + + tok->len = 1; + tok->data = buf; + tok->id = *buf; + + switch(tok->id) { + case AUT_HEADER32: + return (fetch_header32_tok(tok, buf, len)); + + case AUT_HEADER32_EX: + return (fetch_header32_ex_tok(tok, buf, len)); + + case AUT_HEADER64: + return (fetch_header64_tok(tok, buf, len)); + + case AUT_HEADER64_EX: + return (fetch_header64_ex_tok(tok, buf, len)); + + case AUT_TRAILER: + return (fetch_trailer_tok(tok, buf, len)); + + case AUT_ARG32: + return (fetch_arg32_tok(tok, buf, len)); + + case AUT_ARG64: + return (fetch_arg64_tok(tok, buf, len)); + + case AUT_ATTR32: + return (fetch_attr32_tok(tok, buf, len)); + + case AUT_ATTR64: + return (fetch_attr64_tok(tok, buf, len)); + + case AUT_EXIT: + return (fetch_exit_tok(tok, buf, len)); + + case AUT_EXEC_ARGS: + return (fetch_execarg_tok(tok, buf, len)); + + case AUT_EXEC_ENV: + return (fetch_execenv_tok(tok, buf, len)); + + case AUT_OTHER_FILE32: + return (fetch_file_tok(tok, buf, len)); + + case AUT_NEWGROUPS: + return (fetch_newgroups_tok(tok, buf, len)); + + case AUT_IN_ADDR: + return (fetch_inaddr_tok(tok, buf, len)); + + case AUT_IN_ADDR_EX: + return (fetch_inaddr_ex_tok(tok, buf, len)); + + case AUT_IP: + return (fetch_ip_tok(tok, buf, len)); + + case AUT_IPC: + return (fetch_ipc_tok(tok, buf, len)); + + case AUT_IPC_PERM: + return (fetch_ipcperm_tok(tok, buf, len)); + + case AUT_IPORT: + return (fetch_iport_tok(tok, buf, len)); + + case AUT_OPAQUE: + return (fetch_opaque_tok(tok, buf, len)); + + case AUT_PATH: + return (fetch_path_tok(tok, buf, len)); + + case AUT_PROCESS32: + return (fetch_process32_tok(tok, buf, len)); + + case AUT_PROCESS32_EX: + return (fetch_process32ex_tok(tok, buf, len)); + + case AUT_PROCESS64: + return (fetch_process64_tok(tok, buf, len)); + + case AUT_PROCESS64_EX: + return (fetch_process64ex_tok(tok, buf, len)); + + case AUT_RETURN32: + return (fetch_return32_tok(tok, buf, len)); + + case AUT_RETURN64: + return (fetch_return64_tok(tok, buf, len)); + + case AUT_SEQ: + return (fetch_seq_tok(tok, buf, len)); + + case AUT_SOCKET: + return (fetch_socket_tok(tok, buf, len)); + + case AUT_SOCKINET32: + return (fetch_sock_inet32_tok(tok, buf, len)); + + case AUT_SOCKUNIX: + return (fetch_sock_unix_tok(tok, buf, len)); + + case AUT_SUBJECT32: + return (fetch_subject32_tok(tok, buf, len)); + + case AUT_SUBJECT32_EX: + return (fetch_subject32ex_tok(tok, buf, len)); + + case AUT_SUBJECT64: + return (fetch_subject64_tok(tok, buf, len)); + + case AUT_SUBJECT64_EX: + return (fetch_subject64ex_tok(tok, buf, len)); + + case AUT_TEXT: + return (fetch_text_tok(tok, buf, len)); + + case AUT_SOCKET_EX: + return (fetch_socketex32_tok(tok, buf, len)); + + case AUT_DATA: + return (fetch_arb_tok(tok, buf, len)); + + case AUT_ZONENAME: + return (fetch_zonename_tok(tok, buf, len)); + + default: + return (fetch_invalid_tok(tok, buf, len)); + } +} + +/* + * 'prints' the token out to outfp. + */ +void +au_print_tok(FILE *outfp, tokenstr_t *tok, char *del, char raw, char sfrm) +{ + + switch(tok->id) { + case AUT_HEADER32: + print_header32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_HEADER32_EX: + print_header32_ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_HEADER64: + print_header64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_HEADER64_EX: + print_header64_ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_TRAILER: + print_trailer_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_ARG32: + print_arg32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_ARG64: + print_arg64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_DATA: + print_arb_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_ATTR32: + print_attr32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_ATTR64: + print_attr64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_EXIT: + print_exit_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_EXEC_ARGS: + print_execarg_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_EXEC_ENV: + print_execenv_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_OTHER_FILE32: + print_file_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_NEWGROUPS: + print_newgroups_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_IN_ADDR: + print_inaddr_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_IN_ADDR_EX: + print_inaddr_ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_IP: + print_ip_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_IPC: + print_ipc_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_IPC_PERM: + print_ipcperm_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_IPORT: + print_iport_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_OPAQUE: + print_opaque_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_PATH: + print_path_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_PROCESS32: + print_process32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_PROCESS32_EX: + print_process32ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_PROCESS64: + print_process64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_PROCESS64_EX: + print_process64ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_RETURN32: + print_return32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_RETURN64: + print_return64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SEQ: + print_seq_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SOCKET: + print_socket_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SOCKINET32: + print_sock_inet32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SOCKUNIX: + print_sock_unix_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SUBJECT32: + print_subject32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SUBJECT64: + print_subject64_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SUBJECT32_EX: + print_subject32ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SUBJECT64_EX: + print_subject64ex_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_TEXT: + print_text_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_SOCKET_EX: + print_socketex32_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + case AUT_ZONENAME: + print_zonename_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + return; + + default: + print_invalid_tok(outfp, tok, del, raw, sfrm, AU_PLAIN); + } +} + +/* + * 'prints' the token out to outfp in XML format. + */ +void +au_print_tok_xml(FILE *outfp, tokenstr_t *tok, char *del, char raw, + char sfrm) +{ + + switch(tok->id) { + case AUT_HEADER32: + print_header32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_HEADER32_EX: + print_header32_ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_HEADER64: + print_header64_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_HEADER64_EX: + print_header64_ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_TRAILER: + print_trailer_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_ARG32: + print_arg32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_ARG64: + print_arg64_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_DATA: + print_arb_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_ATTR32: + print_attr32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_ATTR64: + print_attr64_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_EXIT: + print_exit_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_EXEC_ARGS: + print_execarg_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_EXEC_ENV: + print_execenv_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_OTHER_FILE32: + print_file_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_NEWGROUPS: + print_newgroups_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_IN_ADDR: + print_inaddr_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_IN_ADDR_EX: + print_inaddr_ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_IP: + print_ip_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_IPC: + print_ipc_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_IPC_PERM: + print_ipcperm_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_IPORT: + print_iport_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_OPAQUE: + print_opaque_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_PATH: + print_path_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_PROCESS32: + print_process32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_PROCESS32_EX: + print_process32ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_PROCESS64: + print_process64_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_PROCESS64_EX: + print_process64ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_RETURN32: + print_return32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_RETURN64: + print_return64_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SEQ: + print_seq_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SOCKET: + print_socket_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SOCKINET32: + print_sock_inet32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SOCKUNIX: + print_sock_unix_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SUBJECT32: + print_subject32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SUBJECT64: + print_subject64_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SUBJECT32_EX: + print_subject32ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SUBJECT64_EX: + print_subject64ex_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_TEXT: + print_text_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_SOCKET_EX: + print_socketex32_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + case AUT_ZONENAME: + print_zonename_tok(outfp, tok, del, raw, sfrm, AU_XML); + return; + + default: + print_invalid_tok(outfp, tok, del, raw, sfrm, AU_XML); + } +} + +/* + * Read a record from the file pointer, store data in buf memory for buf is + * also allocated in this function and has to be free'd outside this call. + * + * au_read_rec() handles two possibilities: a stand-alone file token, or a + * complete audit record. + * + * XXXRW: Note that if we hit an error, we leave the stream in an unusable + * state, because it will be partly offset into a record. We should rewind + * or do something more intelligent. Particularly interesting is the case + * where we perform a partial read of a record from a non-blockable file + * descriptor. We should return the partial read and continue...? + */ +int +au_read_rec(FILE *fp, u_char **buf) +{ + u_char *bptr; + u_int32_t recsize; + u_int32_t bytestoread; + u_char type; + + u_int32_t sec, msec; + u_int16_t filenamelen; + + type = fgetc(fp); + + switch (type) { + case AUT_HEADER32: + case AUT_HEADER32_EX: + case AUT_HEADER64: + case AUT_HEADER64_EX: + /* read the record size from the token */ + if (fread(&recsize, 1, sizeof(u_int32_t), fp) < + sizeof(u_int32_t)) { + errno = EINVAL; + return (-1); + } + recsize = be32toh(recsize); + + /* Check for recsize sanity */ + if (recsize < (sizeof(u_int32_t) + sizeof(u_char))) { + errno = EINVAL; + return (-1); + } + + *buf = malloc(recsize * sizeof(u_char)); + if (*buf == NULL) + return (-1); + bptr = *buf; + memset(bptr, 0, recsize); + + /* store the token contents already read, back to the buffer*/ + *bptr = type; + bptr++; + be32enc(bptr, recsize); + bptr += sizeof(u_int32_t); + + /* now read remaining record bytes */ + bytestoread = recsize - (sizeof(u_int32_t) + sizeof(u_char)); + + if (fread(bptr, 1, bytestoread, fp) < bytestoread) { + free(*buf); + errno = EINVAL; + return (-1); + } + break; + + case AUT_OTHER_FILE32: + /* + * The file token is variable-length, as it includes a + * pathname. As a result, we have to read incrementally + * until we know the total length, then allocate space and + * read the rest. + */ + if (fread(&sec, 1, sizeof(sec), fp) < sizeof(sec)) { + errno = EINVAL; + return (-1); + } + if (fread(&msec, 1, sizeof(msec), fp) < sizeof(msec)) { + errno = EINVAL; + return (-1); + } + if (fread(&filenamelen, 1, sizeof(filenamelen), fp) < + sizeof(filenamelen)) { + errno = EINVAL; + return (-1); + } + recsize = sizeof(type) + sizeof(sec) + sizeof(msec) + + sizeof(filenamelen) + ntohs(filenamelen); + *buf = malloc(recsize); + if (*buf == NULL) + return (-1); + bptr = *buf; + + bcopy(&type, bptr, sizeof(type)); + bptr += sizeof(type); + bcopy(&sec, bptr, sizeof(sec)); + bptr += sizeof(sec); + bcopy(&msec, bptr, sizeof(msec)); + bptr += sizeof(msec); + bcopy(&filenamelen, bptr, sizeof(filenamelen)); + bptr += sizeof(filenamelen); + + if (fread(bptr, 1, ntohs(filenamelen), fp) < + ntohs(filenamelen)) { + free(buf); + errno = EINVAL; + return (-1); + } + break; + + default: + errno = EINVAL; + return (-1); + } + + return (recsize); +} |