diff options
Diffstat (limited to 'contrib/openbsm/libbsm/bsm_token.c')
-rw-r--r-- | contrib/openbsm/libbsm/bsm_token.c | 1219 |
1 files changed, 1219 insertions, 0 deletions
diff --git a/contrib/openbsm/libbsm/bsm_token.c b/contrib/openbsm/libbsm/bsm_token.c new file mode 100644 index 0000000..d7eadb2 --- /dev/null +++ b/contrib/openbsm/libbsm/bsm_token.c @@ -0,0 +1,1219 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. + * Copyright (c) 2005 SPARTA, Inc. + * 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_token.c#34 $ + */ + +#include <sys/types.h> +#ifdef __APPLE__ +#include <compat/endian.h> +#else /* !__APPLE__ */ +#include <sys/endian.h> +#endif /* __APPLE__*/ +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/un.h> + +#include <sys/ipc.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> + +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/socketvar.h> + +#include <bsm/audit_internal.h> +#include <bsm/libbsm.h> + +#define GET_TOKEN_AREA(t, dptr, length) do { \ + (t) = malloc(sizeof(token_t)); \ + if ((t) != NULL) { \ + (t)->len = (length); \ + (dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \ + if ((dptr) == NULL) { \ + free(t); \ + (t) = NULL; \ + } else \ + memset((dptr), 0, (length)); \ + } else \ + (dptr) = NULL; \ + assert(t == NULL || dptr != NULL); \ +} while (0) + +/* + * token ID 1 byte + * 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 + */ +token_t * +au_to_arg32(char n, char *text, u_int32_t v) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) + + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ARG32); + ADD_U_CHAR(dptr, n); + ADD_U_INT32(dptr, v); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); + +} + +token_t * +au_to_arg64(char n, char *text, u_int64_t v) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) + + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ARG64); + ADD_U_CHAR(dptr, n); + ADD_U_INT64(dptr, v); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); + +} + +token_t * +au_to_arg(char n, char *text, u_int32_t v) +{ + + return (au_to_arg32(n, text, v)); +} + +#if defined(_KERNEL) || defined(KERNEL) +/* + * token ID 1 byte + * 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) + */ +token_t * +au_to_attr32(struct vnode_au_info *vni) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t pad0_16 = 0; + u_int16_t pad0_32 = 0; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + + 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_ATTR32); + + /* + * Darwin defines the size for the file mode + * as 2 bytes; BSM defines 4 so pad with 0 + */ + ADD_U_INT16(dptr, pad0_16); + ADD_U_INT16(dptr, vni->vn_mode); + + ADD_U_INT32(dptr, vni->vn_uid); + ADD_U_INT32(dptr, vni->vn_gid); + ADD_U_INT32(dptr, vni->vn_fsid); + + /* + * Some systems use 32-bit file ID's, other's use 64-bit file IDs. + * Attempt to handle both, and let the compiler sort it out. If we + * could pick this out at compile-time, it would be better, so as to + * avoid the else case below. + */ + if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { + ADD_U_INT32(dptr, pad0_32); + ADD_U_INT32(dptr, vni->vn_fileid); + } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) + ADD_U_INT64(dptr, vni->vn_fileid); + else + ADD_U_INT64(dptr, 0LL); + + ADD_U_INT32(dptr, vni->vn_dev); + + return (t); +} + +token_t * +au_to_attr64(struct vnode_au_info *vni) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_attr(struct vnode_au_info *vni) +{ + + return (au_to_attr32(vni)); +} +#endif /* !(defined(_KERNEL) || defined(KERNEL) */ + +/* + * token ID 1 byte + * how to print 1 byte + * basic unit 1 byte + * unit count 1 byte + * data items (depends on basic unit) + */ +token_t * +au_to_data(char unit_print, char unit_type, char unit_count, char *p) +{ + token_t *t; + u_char *dptr = NULL; + size_t datasize, totdata; + + /* Determine the size of the basic unit. */ + switch (unit_type) { + case AUR_BYTE: + datasize = AUR_BYTE_SIZE; + break; + + case AUR_SHORT: + datasize = AUR_SHORT_SIZE; + break; + + case AUR_LONG: + datasize = AUR_LONG_SIZE; + break; + + default: + errno = EINVAL; + return (NULL); + } + + totdata = datasize * unit_count; + + GET_TOKEN_AREA(t, dptr, totdata + 4 * sizeof(u_char)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_DATA); + ADD_U_CHAR(dptr, unit_print); + ADD_U_CHAR(dptr, unit_type); + ADD_U_CHAR(dptr, unit_count); + ADD_MEM(dptr, p, totdata); + + return (t); +} + + +/* + * token ID 1 byte + * status 4 bytes + * return value 4 bytes + */ +token_t * +au_to_exit(int retval, int err) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_EXIT); + ADD_U_INT32(dptr, err); + ADD_U_INT32(dptr, retval); + + return (t); +} + +/* + */ +token_t * +au_to_groups(int *groups) +{ + + return (au_to_newgroups(BSM_MAX_GROUPS, groups)); +} + +/* + * token ID 1 byte + * number groups 2 bytes + * group list count * 4 bytes + */ +token_t * +au_to_newgroups(u_int16_t n, gid_t *groups) +{ + token_t *t; + u_char *dptr = NULL; + int i; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + + n * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_NEWGROUPS); + ADD_U_INT16(dptr, n); + for (i = 0; i < n; i++) + ADD_U_INT32(dptr, groups[i]); + + return (t); +} + +/* + * token ID 1 byte + * internet address 4 bytes + */ +token_t * +au_to_in_addr(struct in_addr *internet_addr) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IN_ADDR); + ADD_U_INT32(dptr, internet_addr->s_addr); + + return (t); +} + +/* + * token ID 1 byte + * address type/length 4 bytes + * Address 16 bytes + */ +token_t * +au_to_in_addr_ex(struct in6_addr *internet_addr) +{ + token_t *t; + u_char *dptr = NULL; + u_int32_t type = AF_INET6; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); + ADD_U_INT32(dptr, type); + ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[0]); + ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[1]); + ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[2]); + ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[3]); + + return (t); +} + +/* + * token ID 1 byte + * ip header 20 bytes + */ +token_t * +au_to_ip(struct ip *ip) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IP); + /* + * XXXRW: Any byte order work needed on the IP header before writing? + */ + ADD_MEM(dptr, ip, sizeof(struct ip)); + + return (t); +} + +/* + * token ID 1 byte + * object ID type 1 byte + * object ID 4 bytes + */ +token_t * +au_to_ipc(char type, int id) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IPC); + ADD_U_CHAR(dptr, type); + ADD_U_INT32(dptr, id); + + return (t); +} + +/* + * token ID 1 byte + * 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 sequence # 4 bytes + * key 4 bytes + */ +token_t * +au_to_ipc_perm(struct ipc_perm *perm) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t pad0 = 0; + + GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IPC_PERM); + + /* + * Darwin defines the sizes for ipc_perm members + * as 2 bytes; BSM defines 4 so pad with 0 + */ + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->uid); + + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->gid); + + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->cuid); + + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->cgid); + + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->mode); + + ADD_U_INT16(dptr, pad0); + ADD_U_INT16(dptr, perm->seq); + + ADD_U_INT32(dptr, perm->key); + + return (t); +} + +/* + * token ID 1 byte + * port IP address 2 bytes + */ +token_t * +au_to_iport(u_int16_t iport) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_IPORT); + ADD_U_INT16(dptr, iport); + + return (t); +} + +/* + * token ID 1 byte + * size 2 bytes + * data size bytes + */ +token_t * +au_to_opaque(char *data, u_int16_t bytes) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_OPAQUE); + ADD_U_INT16(dptr, bytes); + ADD_MEM(dptr, data, bytes); + + return (t); +} + +/* + * token ID 1 byte + * seconds of time 4 bytes + * milliseconds of time 4 bytes + * file name len 2 bytes + * file pathname N bytes + 1 terminating NULL byte + */ +token_t * +#if defined(KERNEL) || defined(_KERNEL) +au_to_file(char *file, struct timeval tm) +#else +au_to_file(char *file) +#endif +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t filelen; + u_int32_t timems; +#if !defined(KERNEL) && !defined(_KERNEL) + struct timeval tm; + struct timezone tzp; + + if (gettimeofday(&tm, &tzp) == -1) + return (NULL); +#endif + + filelen = strlen(file); + filelen += 1; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + + sizeof(u_int16_t) + filelen); + if (t == NULL) + return (NULL); + + timems = tm.tv_usec/1000; + + ADD_U_CHAR(dptr, AUT_OTHER_FILE32); + ADD_U_INT32(dptr, tm.tv_sec); + ADD_U_INT32(dptr, timems); /* We need time in ms. */ + ADD_U_INT16(dptr, filelen); + ADD_STRING(dptr, file, filelen); + + return (t); +} + +/* + * token ID 1 byte + * text length 2 bytes + * text N bytes + 1 terminating NULL byte + */ +token_t * +au_to_text(char *text) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_TEXT); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); +} + +/* + * token ID 1 byte + * path length 2 bytes + * path N bytes + 1 terminating NULL byte + */ +token_t * +au_to_path(char *text) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t textlen; + + textlen = strlen(text); + textlen += 1; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PATH); + ADD_U_INT16(dptr, textlen); + ADD_STRING(dptr, text, textlen); + + return (t); +} + +/* + * 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/8 bytes (32-bit/64-bit value) + * machine address 4 bytes + */ +token_t * +au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, + pid_t pid, au_asid_t sid, au_tid_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PROCESS32); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->port); + ADD_U_INT32(dptr, tid->machine); + + return (t); +} + +token_t * +au_to_process64(__unused au_id_t auid, __unused uid_t euid, + __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, + __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_process(__unused au_id_t auid, __unused uid_t euid, + __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, + __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) +{ + + return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +/* + * 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/8 bytes (32-bit/64-bit value) + * address type-len 4 bytes + * machine address 16 bytes + */ +token_t * +au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_PROCESS32_EX); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->at_port); + ADD_U_INT32(dptr, tid->at_type); + ADD_U_INT32(dptr, tid->at_addr[0]); + ADD_U_INT32(dptr, tid->at_addr[1]); + ADD_U_INT32(dptr, tid->at_addr[2]); + ADD_U_INT32(dptr, tid->at_addr[3]); + + return (t); +} + +token_t * +au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) +{ + + return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +/* + * token ID 1 byte + * error status 1 byte + * return value 4 bytes/8 bytes (32-bit/64-bit value) + */ +token_t * +au_to_return32(char status, u_int32_t ret) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_RETURN32); + ADD_U_CHAR(dptr, status); + ADD_U_INT32(dptr, ret); + + return (t); +} + +token_t * +au_to_return64(char status, u_int64_t ret) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_RETURN64); + ADD_U_CHAR(dptr, status); + ADD_U_INT64(dptr, ret); + + return (t); +} + +token_t * +au_to_return(char status, u_int32_t ret) +{ + + return (au_to_return32(status, ret)); +} + +/* + * token ID 1 byte + * sequence number 4 bytes + */ +token_t * +au_to_seq(long audit_count) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SEQ); + ADD_U_INT32(dptr, audit_count); + + return (t); +} + +/* + * token ID 1 byte + * socket type 2 bytes + * local port 2 bytes + * local Internet address 4 bytes + * remote port 2 bytes + * remote Internet address 4 bytes + */ +token_t * +au_to_socket(struct socket *so) +{ + + errno = ENOTSUP; + return (NULL); +} + +/* + * token ID 1 byte + * socket type 2 bytes + * local port 2 bytes + * address type/length 4 bytes + * local Internet address 4 bytes/16 bytes (IPv4/IPv6 address) + * remote port 4 bytes + * address type/length 4 bytes + * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address) + */ +token_t * +au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la, + struct sockaddr *ra) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la, + struct sockaddr *ra) +{ + + errno = ENOTSUP; + return (NULL); +} + +/* + * token ID 1 byte + * socket family 2 bytes + * path 104 bytes + */ +token_t * +au_to_sock_unix(struct sockaddr_un *so) +{ + token_t *t; + u_char *dptr; + + GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN); + /* BSM token has two bytes for family */ + ADD_U_CHAR(dptr, 0); + ADD_U_CHAR(dptr, so->sun_family); + ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); + + return (t); +} + +/* + * token ID 1 byte + * socket family 2 bytes + * local port 2 bytes + * socket address 4 bytes + */ +token_t * +au_to_sock_inet32(struct sockaddr_in *so) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SOCKINET32); + /* + * In Darwin, sin_family is one octet, but BSM defines the token + * to store two. So we copy in a 0 first. + */ + ADD_U_CHAR(dptr, 0); + ADD_U_CHAR(dptr, so->sin_family); + ADD_U_INT16(dptr, so->sin_port); + ADD_U_INT32(dptr, so->sin_addr.s_addr); + + return (t); + +} + +token_t * +au_to_sock_inet128(struct sockaddr_in6 *so) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + + 4 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SOCKINET128); + /* + * In Darwin, sin6_family is one octet, but BSM defines the token + * to store two. So we copy in a 0 first. + */ + ADD_U_CHAR(dptr, 0); + ADD_U_CHAR(dptr, so->sin6_family); + + ADD_U_INT16(dptr, so->sin6_port); + ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[0]); + ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[1]); + ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[2]); + ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[3]); + + return (t); + +} + +token_t * +au_to_sock_inet(struct sockaddr_in *so) +{ + + return (au_to_sock_inet32(so)); +} + +/* + * 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/8 bytes (32-bit/64-bit value) + * machine address 4 bytes + */ +token_t * +au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, + pid_t pid, au_asid_t sid, au_tid_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SUBJECT32); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->port); + ADD_U_INT32(dptr, tid->machine); + + return (t); +} + +token_t * +au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, + pid_t pid, au_asid_t sid, au_tid_t *tid) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, + pid_t pid, au_asid_t sid, au_tid_t *tid) +{ + + return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +/* + * 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/8 bytes (32-bit/64-bit value) + * address type/length 4 bytes + * machine address 16 bytes + */ +token_t * +au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) +{ + token_t *t; + u_char *dptr = NULL; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); + ADD_U_INT32(dptr, auid); + ADD_U_INT32(dptr, euid); + ADD_U_INT32(dptr, egid); + ADD_U_INT32(dptr, ruid); + ADD_U_INT32(dptr, rgid); + ADD_U_INT32(dptr, pid); + ADD_U_INT32(dptr, sid); + ADD_U_INT32(dptr, tid->at_port); + ADD_U_INT32(dptr, tid->at_type); + ADD_U_INT32(dptr, tid->at_addr[0]); + ADD_U_INT32(dptr, tid->at_addr[1]); + ADD_U_INT32(dptr, tid->at_addr[2]); + ADD_U_INT32(dptr, tid->at_addr[3]); + + return (t); +} + +token_t * +au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, + gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) +{ + + return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid, + tid)); +} + +#if !defined(_KERNEL) && !defined(KERNEL) +/* + * Collects audit information for the current process + * and creates a subject token from it + */ +token_t * +au_to_me(void) +{ + auditinfo_t auinfo; + + if (getaudit(&auinfo) != 0) + return (NULL); + + return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(), + getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid)); +} +#endif + +/* + * token ID 1 byte + * count 4 bytes + * text count null-terminated strings + */ +token_t * +au_to_exec_args(const char **args) +{ + token_t *t; + u_char *dptr = NULL; + const char *nextarg; + int i, count = 0; + size_t totlen = 0; + + nextarg = *args; + + while (nextarg != NULL) { + int nextlen; + + nextlen = strlen(nextarg); + totlen += nextlen + 1; + count++; + nextarg = *(args + count); + } + + totlen += count * sizeof(char); /* nul terminations. */ + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_EXEC_ARGS); + ADD_U_INT32(dptr, count); + + for (i = 0; i < count; i++) { + nextarg = *(args + i); + ADD_MEM(dptr, nextarg, strlen(nextarg) + 1); + } + + return (t); +} + +/* + * token ID 1 byte + * count 4 bytes + * text count null-terminated strings + */ +token_t * +au_to_exec_env(const char **env) +{ + token_t *t; + u_char *dptr = NULL; + int i, count = 0; + size_t totlen = 0; + const char *nextenv; + + nextenv = *env; + + while (nextenv != NULL) { + int nextlen; + + nextlen = strlen(nextenv); + totlen += nextlen + 1; + count++; + nextenv = *(env + count); + } + + totlen += sizeof(char) * count; + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_EXEC_ENV); + ADD_U_INT32(dptr, count); + + for (i = 0; i < count; i++) { + nextenv = *(env + i); + ADD_MEM(dptr, nextenv, strlen(nextenv) + 1); + } + + return (t); +} + +/* + * token ID 1 byte + * 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) + */ +token_t * +#if defined(KERNEL) || defined(_KERNEL) +au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod, + struct timeval tm) +#else +au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) +#endif +{ + token_t *t; + u_char *dptr = NULL; + u_int32_t timems; +#if !defined(KERNEL) && !defined(_KERNEL) + struct timeval tm; + struct timezone tzp; + + if (gettimeofday(&tm, &tzp) == -1) + return (NULL); +#endif + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + + sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_HEADER32); + ADD_U_INT32(dptr, rec_size); + ADD_U_CHAR(dptr, HEADER_VERSION); + ADD_U_INT16(dptr, e_type); + ADD_U_INT16(dptr, e_mod); + + timems = tm.tv_usec/1000; + /* Add the timestamp */ + ADD_U_INT32(dptr, tm.tv_sec); + ADD_U_INT32(dptr, timems); /* We need time in ms. */ + + return (t); +} + +token_t * +au_to_header64(__unused int rec_size, __unused au_event_t e_type, + __unused au_emod_t e_mod) +{ + + errno = ENOTSUP; + return (NULL); +} + +token_t * +au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod) +{ + + return (au_to_header32(rec_size, e_type, e_mod)); +} + +/* + * token ID 1 byte + * trailer magic number 2 bytes + * record byte count 4 bytes + */ +token_t * +au_to_trailer(int rec_size) +{ + token_t *t; + u_char *dptr = NULL; + u_int16_t magic = TRAILER_PAD_MAGIC; + + GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + + sizeof(u_int32_t)); + if (t == NULL) + return (NULL); + + ADD_U_CHAR(dptr, AUT_TRAILER); + ADD_U_INT16(dptr, magic); + ADD_U_INT32(dptr, rec_size); + + return (t); +} |