diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/auditreduce/token.c | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/auditreduce/token.c')
-rw-r--r-- | usr/src/cmd/auditreduce/token.c | 1966 |
1 files changed, 1966 insertions, 0 deletions
diff --git a/usr/src/cmd/auditreduce/token.c b/usr/src/cmd/auditreduce/token.c new file mode 100644 index 0000000000..a9a6df9350 --- /dev/null +++ b/usr/src/cmd/auditreduce/token.c @@ -0,0 +1,1966 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Token processing for auditreduce. + */ + +#include <locale.h> +#include <sys/zone.h> +#include "auditr.h" +#include "toktable.h" + +extern int re_exec2(char *); + +static void anchor_path(char *path); +static char *collapse_path(char *s); +static void get_string(adr_t *adr, char **p); +static int ipc_type_match(int flag, char type); +static void skip_string(adr_t *adr); +static int xgeneric(adr_t *adr); + +#if AUDIT_REC +void +print_id(int id) +{ + char *suffix; + + if ((id < 0) || (id > MAXTOKEN) || + (tokentable[id].func == NOFUNC)) { + (void) fprintf(stderr, + "token_processing: token %d not found\n", id); + return; + } + + switch (id) { + case AUT_NEWGROUPS: + suffix = "_new"; + break; + case AUT_ATTR32: + suffix = "32"; + break; + case AUT_ARG64: + case AUT_RETURN64: + case AUT_ATTR64: + case AUT_HEADER64: + case AUT_SUBJECT64: + case AUT_PROCESS64: + case AUT_OTHER_FILE64: + suffix = "64"; + break; + case AUT_SOCKET_EX: + case AUT_IN_ADDR_EX: + suffix = "_ex"; + break; + case AUT_HEADER32_EX: + case AUT_SUBJECT32_EX: + case AUT_PROCESS32_EX: + suffix = "32_ex"; + break; + case AUT_HEADER64_EX: + case AUT_SUBJECT64_EX: + case AUT_PROCESS64_EX: + suffix = "64_ex"; + break; + default: + suffix = ""; + break; + } + (void) fprintf(stderr, "token_processing: %s%s\n", + tokentable[id].t_name, suffix); +} +#endif /* AUDIT_REC */ + +/* + * Process a token in a record to determine whether the record is interesting. + */ + +int +token_processing(adr_t *adr, int tokenid) +{ + if ((tokenid > 0) && (tokenid <= MAXTOKEN) && + (tokentable[tokenid].func != NOFUNC)) { +#if AUDIT_REC + print_id(tokenid); +#endif /* AUDIT_REC */ + return ((*tokentable[tokenid].func)(adr)); + } + + /* here if token id is not in table */ + return (-2); +} + + +/* There should not be any file or header tokens in the middle of a record */ + +/* ARGSUSED */ +int +file_token(adr_t *adr) +{ + return (-2); +} + +/* ARGSUSED */ +int +file64_token(adr_t *adr) +{ + return (-2); +} + +/* ARGSUSED */ +int +header_token(adr_t *adr) +{ + return (-2); +} + +/* ARGSUSED */ +int +header32_ex_token(adr_t *adr) +{ + return (-2); +} + +/* ARGSUSED */ +int +header64_ex_token(adr_t *adr) +{ + return (-2); +} + +/* ARGSUSED */ +int +header64_token(adr_t *adr) +{ + return (-2); +} + + +/* + * ====================================================== + * The following token processing routines return + * -1: if the record is not interesting + * -2: if an error is found + * ====================================================== + */ + +int +trailer_token(adr_t *adr) +{ + short magic_number; + uint32_t bytes; + + adrm_u_short(adr, (ushort_t *)&magic_number, 1); + if (magic_number != AUT_TRAILER_MAGIC) { + (void) fprintf(stderr, "%s\n", + gettext("auditreduce: Bad trailer token")); + return (-2); + } + adrm_u_int32(adr, &bytes, 1); + + return (-1); +} + + +/* + * Format of arbitrary data token: + * arbitrary data token id adr char + * how to print adr_char + * basic unit adr_char + * unit count adr_char, specifying number of units of + * data items depends on basic unit + * + */ +int +arbitrary_data_token(adr_t *adr) +{ + int i; + char c1; + short c2; + int32_t c3; + int64_t c4; + char how_to_print, basic_unit, unit_count; + + /* get how_to_print, basic_unit, and unit_count */ + adrm_char(adr, &how_to_print, 1); + adrm_char(adr, &basic_unit, 1); + adrm_char(adr, &unit_count, 1); + for (i = 0; i < unit_count; i++) { + switch (basic_unit) { + /* case AUR_BYTE: has same value as AUR_CHAR */ + case AUR_CHAR: + adrm_char(adr, &c1, 1); + break; + case AUR_SHORT: + adrm_short(adr, &c2, 1); + break; + case AUR_INT32: + adrm_int32(adr, (int32_t *)&c3, 1); + break; + case AUR_INT64: + adrm_int64(adr, (int64_t *)&c4, 1); + break; + default: + return (-2); + break; + } + } + return (-1); +} + + +/* + * Format of opaque token: + * opaque token id adr_char + * size adr_short + * data adr_char, size times + * + */ +int +opaque_token(adr_t *adr) +{ + skip_string(adr); + return (-1); +} + + + +/* + * Format of return32 value token: + * return value token id adr_char + * error number adr_char + * return value adr_u_int32 + * + */ +int +return_value32_token(adr_t *adr) +{ + char errnum; + uint32_t value; + + adrm_char(adr, &errnum, 1); + adrm_u_int32(adr, &value, 1); + if ((flags & M_SORF) && + ((global_class & mask.am_success) && (errnum == 0)) || + ((global_class & mask.am_failure) && (errnum != 0))) { + checkflags |= M_SORF; + } + return (-1); +} + +/* + * Format of return64 value token: + * return value token id adr_char + * error number adr_char + * return value adr_u_int64 + * + */ +int +return_value64_token(adr_t *adr) +{ + char errnum; + uint64_t value; + + adrm_char(adr, &errnum, 1); + adrm_u_int64(adr, &value, 1); + if ((flags & M_SORF) && + ((global_class & mask.am_success) && (errnum == 0)) || + ((global_class & mask.am_failure) && (errnum != 0))) { + checkflags |= M_SORF; + } + return (-1); +} + + +/* + * Format of sequence token: + * sequence token id adr_char + * audit_count int32_t + * + */ +int +sequence_token(adr_t *adr) +{ + int32_t audit_count; + + adrm_int32(adr, &audit_count, 1); + return (-1); +} + + +/* + * Format of text token: + * text token id adr_char + * text adr_string + * + */ +int +text_token(adr_t *adr) +{ + skip_string(adr); + return (-1); +} + + +/* + * Format of ip_addr token: + * ip token id adr_char + * address adr_int32 + * + */ +int +ip_addr_token(adr_t *adr) +{ + int32_t address; + + adrm_char(adr, (char *)&address, 4); + + return (-1); +} + +/* + * Format of ip_addr_ex token: + * ip token id adr_char + * ip type adr_int32 + * address 4*adr_int32 + * + */ +int +ip_addr_ex_token(adr_t *adr) +{ + int32_t address[4]; + int32_t type; + + adrm_int32(adr, (int32_t *)&type, 1); + adrm_int32(adr, (int32_t *)&address, 4); + + return (-1); +} + +/* + * Format of ip token: + * ip header token id adr_char + * version adr_char + * type of service adr_char + * length adr_short + * id adr_u_short + * offset adr_u_short + * ttl adr_char + * protocol adr_char + * checksum adr_u_short + * source address adr_int32 + * destination address adr_int32 + * + */ +int +ip_token(adr_t *adr) +{ + char version; + char type; + short len; + unsigned short id, offset, checksum; + char ttl, protocol; + int32_t src, dest; + + adrm_char(adr, &version, 1); + adrm_char(adr, &type, 1); + adrm_short(adr, &len, 1); + adrm_u_short(adr, &id, 1); + adrm_u_short(adr, &offset, 1); + adrm_char(adr, &ttl, 1); + adrm_char(adr, &protocol, 1); + adrm_u_short(adr, &checksum, 1); + adrm_char(adr, (char *)&src, 4); + adrm_char(adr, (char *)&dest, 4); + + return (-1); +} + + +/* + * Format of iport token: + * ip port address token id adr_char + * port address adr_short + * + */ +int +iport_token(adr_t *adr) +{ + short address; + + adrm_short(adr, &address, 1); + + return (-1); +} + + +/* + * Format of groups token: + * group token id adr_char + * group list adr_int32, 16 times + * + */ +int +group_token(adr_t *adr) +{ + int gid[16]; + int i; + int flag = 0; + + for (i = 0; i < 16; i++) { + adrm_int32(adr, (int32_t *)&gid[i], 1); + if (flags & M_GROUPR) { + if ((unsigned short)m_groupr == gid[i]) + flag = 1; + } + } + + if (flags & M_GROUPR) { + if (flag) + checkflags |= M_GROUPR; + } + return (-1); +} + +/* + * Format of newgroups token: + * group token id adr_char + * number of groups adr_short + * group list adr_int32, "number" times + * + */ +int +newgroup_token(adr_t *adr) +{ + gid_t gid; + int i; + short int number; + + adrm_short(adr, &number, 1); + + for (i = 0; i < number; i++) { + adrm_int32(adr, (int32_t *)&gid, 1); + if (flags & M_GROUPR) { + if (m_groupr == gid) + checkflags |= M_GROUPR; + } + } + + return (-1); +} + +/* + * Format of argument32 token: + * argument token id adr_char + * argument number adr_char + * argument value adr_int32 + * argument description adr_string + * + */ +int +argument32_token(adr_t *adr) +{ + char arg_num; + int32_t arg_val; + + adrm_char(adr, &arg_num, 1); + adrm_int32(adr, &arg_val, 1); + skip_string(adr); + + return (-1); +} + +/* + * Format of argument64 token: + * argument token id adr_char + * argument number adr_char + * argument value adr_int64 + * argument description adr_string + * + */ +int +argument64_token(adr_t *adr) +{ + char arg_num; + int64_t arg_val; + + adrm_char(adr, &arg_num, 1); + adrm_int64(adr, &arg_val, 1); + skip_string(adr); + + return (-1); +} + +int +acl_token(adr_t *adr) +{ + + int32_t id; + int32_t mode; + int32_t type; + + adrm_int32(adr, &type, 1); + adrm_int32(adr, &id, 1); + adrm_int32(adr, &mode, 1); + + return (-1); +} + +/* + * Format of attribute token: (old pre SunOS 5.7 format) + * attribute token id adr_char + * mode adr_int32 (printed in octal) + * uid adr_int32 + * gid adr_int32 + * file system id adr_int32 + * node id adr_int32 + * device adr_int32 + * + */ +int +attribute_token(adr_t *adr) +{ + int32_t dev; + int32_t file_sysid; + int32_t gid; + int32_t mode; + int32_t nodeid; + int32_t uid; + + adrm_int32(adr, &mode, 1); + adrm_int32(adr, &uid, 1); + adrm_int32(adr, &gid, 1); + adrm_int32(adr, &file_sysid, 1); + adrm_int32(adr, &nodeid, 1); + adrm_int32(adr, &dev, 1); + + if (!new_mode && (flags & M_USERE)) { + if (m_usere == uid) + checkflags |= M_USERE; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == gid) + checkflags |= M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_FGROUP) && + (obj_group == gid)) + checkflags |= M_OBJECT; + else if ((obj_flag & OBJ_FOWNER) && + (obj_owner == uid)) + checkflags |= M_OBJECT; + } + return (-1); +} + +/* + * Format of attribute32 token: + * attribute token id adr_char + * mode adr_int32 (printed in octal) + * uid adr_int32 + * gid adr_int32 + * file system id adr_int32 + * node id adr_int64 + * device adr_int32 + * + */ +int +attribute32_token(adr_t *adr) +{ + int32_t dev; + int32_t file_sysid; + int32_t gid; + int32_t mode; + int64_t nodeid; + int32_t uid; + + adrm_int32(adr, &mode, 1); + adrm_int32(adr, &uid, 1); + adrm_int32(adr, &gid, 1); + adrm_int32(adr, &file_sysid, 1); + adrm_int64(adr, &nodeid, 1); + adrm_int32(adr, &dev, 1); + + if (!new_mode && (flags & M_USERE)) { + if (m_usere == uid) + checkflags |= M_USERE; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == gid) + checkflags |= M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_FGROUP) && + (obj_group == gid)) + checkflags |= M_OBJECT; + else if ((obj_flag & OBJ_FOWNER) && + (obj_owner == uid)) + checkflags |= M_OBJECT; + } + return (-1); +} + +/* + * Format of attribute64 token: + * attribute token id adr_char + * mode adr_int32 (printed in octal) + * uid adr_int32 + * gid adr_int32 + * file system id adr_int32 + * node id adr_int64 + * device adr_int64 + * + */ +int +attribute64_token(adr_t *adr) +{ + int64_t dev; + int32_t file_sysid; + int32_t gid; + int32_t mode; + int64_t nodeid; + int32_t uid; + + adrm_int32(adr, &mode, 1); + adrm_int32(adr, &uid, 1); + adrm_int32(adr, &gid, 1); + adrm_int32(adr, &file_sysid, 1); + adrm_int64(adr, &nodeid, 1); + adrm_int64(adr, &dev, 1); + + if (!new_mode && (flags & M_USERE)) { + if (m_usere == uid) + checkflags |= M_USERE; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == gid) + checkflags |= M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_FGROUP) && + (obj_group == gid)) + checkflags |= M_OBJECT; + else if ((obj_flag & OBJ_FOWNER) && + (obj_owner == uid)) + checkflags |= M_OBJECT; + } + return (-1); +} + + +/* + * Format of command token: + * attribute token id adr_char + * argc adr_short + * argv len adr_short variable amount of argv len + * argv text argv len and text + * . + * . + * . + * envp count adr_short variable amount of envp len + * envp len adr_short and text + * envp text envp len + * . + * . + * . + * + */ +int +cmd_token(adr_t *adr) +{ + short cnt; + short i; + + adrm_short(adr, &cnt, 1); + + for (i = 0; i < cnt; i++) + skip_string(adr); + + adrm_short(adr, &cnt, 1); + + for (i = 0; i < cnt; i++) + skip_string(adr); + + return (-1); +} + + +/* + * Format of exit token: + * attribute token id adr_char + * return value adr_int32 + * errno adr_int32 + * + */ +int +exit_token(adr_t *adr) +{ + int32_t retval; + int32_t errno; + + adrm_int32(adr, &retval, 1); + adrm_int32(adr, &errno, 1); + return (-1); +} + +/* + * Format of strings array token: + * token id adr_char + * count value adr_int32 + * strings null terminated strings + */ +static int +strings_common_token(adr_t *adr) +{ + int count, i; + char c; + + adrm_int32(adr, (int32_t *)&count, 1); + for (i = 1; i <= count; i++) { + adrm_char(adr, &c, 1); + while (c != (char)0) + adrm_char(adr, &c, 1); + } + /* no dump option here, since we will have variable length fields */ + return (-1); +} + +int +path_attr_token(adr_t *adr) +{ + return (strings_common_token(adr)); +} + +int +exec_args_token(adr_t *adr) +{ + return (strings_common_token(adr)); +} + +int +exec_env_token(adr_t *adr) +{ + return (strings_common_token(adr)); +} + +/* + * Format of liaison token: + */ +int +liaison_token(adr_t *adr) +{ + int32_t li; + + adrm_int32(adr, &li, 1); + return (-1); +} + + +/* + * Format of path token: + * path adr_string + */ +int +path_token(adr_t *adr) +{ + if ((flags & M_OBJECT) && (obj_flag == OBJ_PATH)) { + char *path; + + get_string(adr, &path); + if (path[0] != '/') + /* + * anchor the path. user apps may not do it. + */ + anchor_path(path); + /* + * match against the collapsed path. that is what user sees. + */ + if (re_exec2(collapse_path(path)) == 1) + checkflags |= M_OBJECT; + free(path); + } else { + skip_string(adr); + } + return (-1); +} + + +/* + * Format of System V IPC permission token: + * System V IPC permission token id adr_char + * uid adr_int32 + * gid adr_int32 + * cuid adr_int32 + * cgid adr_int32 + * mode adr_int32 + * seq adr_int32 + * key adr_int32 + * label adr_opaque, sizeof (bslabel_t) + * bytes + */ +int +s5_IPC_perm_token(adr_t *adr) +{ + int32_t uid, gid, cuid, cgid, mode, seq; + int32_t key; + + adrm_int32(adr, &uid, 1); + adrm_int32(adr, &gid, 1); + adrm_int32(adr, &cuid, 1); + adrm_int32(adr, &cgid, 1); + adrm_int32(adr, &mode, 1); + adrm_int32(adr, &seq, 1); + adrm_int32(adr, &key, 1); + + if (!new_mode && (flags & M_USERE)) { + if (m_usere == uid) + checkflags |= M_USERE; + } + + if (!new_mode && (flags & M_USERE)) { + if (m_usere == cuid) + checkflags |= M_USERE; + } + + if (!new_mode && (flags & M_GROUPR)) { + if (m_groupr == gid) + checkflags |= M_GROUPR; + } + + if (!new_mode && (flags & M_GROUPR)) { + if (m_groupr == cgid) + checkflags |= M_GROUPR; + } + + if ((flags & M_OBJECT) && + ((obj_owner == uid) || + (obj_owner == cuid) || + (obj_group == gid) || + (obj_group == cgid))) { + + switch (obj_flag) { + case OBJ_MSGGROUP: + case OBJ_MSGOWNER: + if (ipc_type_match(OBJ_MSG, ipc_type)) + checkflags |= M_OBJECT; + break; + case OBJ_SEMGROUP: + case OBJ_SEMOWNER: + if (ipc_type_match(OBJ_SEM, ipc_type)) + checkflags |= M_OBJECT; + break; + case OBJ_SHMGROUP: + case OBJ_SHMOWNER: + if (ipc_type_match(OBJ_SHM, ipc_type)) + checkflags |= M_OBJECT; + break; + } + } + return (-1); +} + + +/* + * Format of process32 token: + * process token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int32*2 + * + */ +int +process32_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int32_t port, machine; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int32(adr, &port, 1); + adrm_int32(adr, &machine, 1); + + if (!new_mode && (flags & M_USERA)) { + if (m_usera == auid) + checkflags |= M_USERA; + } + if (!new_mode && (flags & M_USERE)) { + if (m_usere == euid) + checkflags |= M_USERE; + } + if (!new_mode && (flags & M_USERR)) { + if (m_userr == ruid) + checkflags |= M_USERR; + } + if (!new_mode && (flags & M_GROUPR)) { + if (m_groupr == rgid) + checkflags |= M_GROUPR; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == egid) + checkflags |= M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_PROC) && + (obj_id == pid)) { + checkflags |= M_OBJECT; + } else if ((obj_flag & OBJ_PGROUP) && + ((obj_group == egid) || + (obj_group == rgid))) { + checkflags |= M_OBJECT; + } else if ((obj_flag & OBJ_POWNER) && + ((obj_owner == euid) || + (obj_group == ruid))) { + checkflags |= M_OBJECT; + } + } + return (-1); +} + +/* + * Format of process32 token: + * process token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int32*6 + * + */ +int +process32_ex_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int32_t port, type, addr[4]; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int32(adr, &port, 1); + adrm_int32(adr, &type, 1); + adrm_int32(adr, &addr[0], 4); + + if (!new_mode && (flags & M_USERA)) { + if (m_usera == auid) + checkflags = checkflags | M_USERA; + } + if (!new_mode && (flags & M_USERE)) { + if (m_usere == euid) + checkflags = checkflags | M_USERE; + } + if (!new_mode && (flags & M_USERR)) { + if (m_userr == ruid) + checkflags = checkflags | M_USERR; + } + if (!new_mode && (flags & M_GROUPR)) { + if (m_groupr == egid) + checkflags = checkflags | M_GROUPR; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == egid) + checkflags = checkflags | M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_PROC) && + (obj_id == pid)) { + checkflags = checkflags | M_OBJECT; + } else if ((obj_flag & OBJ_PGROUP) && + ((obj_group == egid) || + (obj_group == rgid))) { + checkflags = checkflags | M_OBJECT; + } else if ((obj_flag & OBJ_POWNER) && + ((obj_owner == euid) || + (obj_group == ruid))) { + checkflags = checkflags | M_OBJECT; + } + } + return (-1); +} + +/* + * Format of process64 token: + * process token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int64+adr_int32 + * + */ +int +process64_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int64_t port; + int32_t machine; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int64(adr, &port, 1); + adrm_int32(adr, &machine, 1); + + if (!new_mode && (flags & M_USERA)) { + if (m_usera == auid) + checkflags |= M_USERA; + } + if (!new_mode && (flags & M_USERE)) { + if (m_usere == euid) + checkflags |= M_USERE; + } + if (!new_mode && (flags & M_USERR)) { + if (m_userr == ruid) + checkflags |= M_USERR; + } + if (!new_mode && (flags & M_GROUPR)) { + if (m_groupr == rgid) + checkflags |= M_GROUPR; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == egid) + checkflags |= M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_PROC) && + (obj_id == pid)) { + checkflags |= M_OBJECT; + } else if ((obj_flag & OBJ_PGROUP) && + ((obj_group == egid) || + (obj_group == rgid))) { + checkflags |= M_OBJECT; + } else if ((obj_flag & OBJ_POWNER) && + ((obj_owner == euid) || + (obj_group == ruid))) { + checkflags |= M_OBJECT; + } + } + return (-1); +} + +/* + * Format of process64 token: + * process token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int64+5*adr_int32 + * + */ +int +process64_ex_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int64_t port; + int32_t type, addr[4]; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int64(adr, &port, 1); + adrm_int32(adr, &type, 1); + adrm_int32(adr, &addr[0], 4); + + if (!new_mode && (flags & M_USERA)) { + if (m_usera == auid) + checkflags = checkflags | M_USERA; + } + if (!new_mode && (flags & M_USERE)) { + if (m_usere == euid) + checkflags = checkflags | M_USERE; + } + if (!new_mode && (flags & M_USERR)) { + if (m_userr == ruid) + checkflags = checkflags | M_USERR; + } + if (!new_mode && (flags & M_GROUPR)) { + if (m_groupr == egid) + checkflags = checkflags | M_GROUPR; + } + if (!new_mode && (flags & M_GROUPE)) { + if (m_groupe == egid) + checkflags = checkflags | M_GROUPE; + } + + if (flags & M_OBJECT) { + if ((obj_flag & OBJ_PROC) && + (obj_id == pid)) { + checkflags = checkflags | M_OBJECT; + } else if ((obj_flag & OBJ_PGROUP) && + ((obj_group == egid) || + (obj_group == rgid))) { + checkflags = checkflags | M_OBJECT; + } else if ((obj_flag & OBJ_POWNER) && + ((obj_owner == euid) || + (obj_group == ruid))) { + checkflags = checkflags | M_OBJECT; + } + } + return (-1); +} + +/* + * Format of System V IPC token: + * System V IPC token id adr_char + * object id adr_int32 + * + */ +int +s5_IPC_token(adr_t *adr) +{ + int32_t ipc_id; + + adrm_char(adr, &ipc_type, 1); /* Global */ + adrm_int32(adr, &ipc_id, 1); + + if ((flags & M_OBJECT) && + ipc_type_match(obj_flag, ipc_type) && + (obj_id == ipc_id)) + checkflags |= M_OBJECT; + + return (-1); +} + + +/* + * Format of socket token: + * socket_type adrm_short + * remote_port adrm_short + * remote_inaddr adrm_int32 + * + */ +int +socket_token(adr_t *adr) +{ + short socket_type; + short remote_port; + int32_t remote_inaddr; + + adrm_short(adr, &socket_type, 1); + adrm_short(adr, &remote_port, 1); + adrm_char(adr, (char *)&remote_inaddr, 4); + + if ((flags & M_OBJECT) && (obj_flag == OBJ_SOCK)) { + if (socket_flag == SOCKFLG_MACHINE) { + if (remote_inaddr == obj_id) + checkflags |= M_OBJECT; + } else if (socket_flag == SOCKFLG_PORT) { + if (remote_port == obj_id) + checkflags |= M_OBJECT; + } + } + return (-1); +} + + +/* + * Format of socket token: + * socket_type adrm_short + * remote_port adrm_short + * remote_inaddr adrm_int32 + * + */ +int +socket_ex_token(adr_t *adr) +{ + short socket_domain; + short socket_type; + short ip_size; + short local_port; + int32_t local_inaddr[4]; + short remote_port; + int32_t remote_inaddr[4]; + + adrm_short(adr, &socket_domain, 1); + adrm_short(adr, &socket_type, 1); + adrm_short(adr, &ip_size, 1); + + /* validate ip size */ + if ((ip_size != AU_IPv6) && (ip_size != AU_IPv4)) + return (0); + + adrm_short(adr, &local_port, 1); + adrm_char(adr, (char *)local_inaddr, ip_size); + + adrm_short(adr, &remote_port, 1); + adrm_char(adr, (char *)remote_inaddr, ip_size); + + /* if IP type mis-match, then nothing to do */ + if (ip_size != ip_type) + return (-1); + + if ((flags & M_OBJECT) && (obj_flag == OBJ_SOCK)) { + if (socket_flag == SOCKFLG_MACHINE) { + if (ip_type == AU_IPv4) { + if ((local_inaddr[0] == obj_id) || + (remote_inaddr[0] == obj_id)) + checkflags |= M_OBJECT; + } else { + if (((local_inaddr[0] == ip_ipv6[0]) && + (local_inaddr[1] == ip_ipv6[1]) && + (local_inaddr[2] == ip_ipv6[2]) && + (local_inaddr[3] == ip_ipv6[3])) || + ((remote_inaddr[0] == ip_ipv6[0]) && + (remote_inaddr[1] == ip_ipv6[1]) && + (remote_inaddr[2] == ip_ipv6[2]) && + (remote_inaddr[3] == ip_ipv6[3]))) + checkflags |= M_OBJECT; + } + } else if (socket_flag == SOCKFLG_PORT) { + if ((local_port == obj_id) || (remote_port == obj_id)) + checkflags |= M_OBJECT; + } + } + return (-1); +} + + +/* + * Format of subject32 token: + * subject token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int32*2 + * + */ +int +subject32_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int32_t port, machine; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int32(adr, &port, 1); + adrm_int32(adr, &machine, 1); + + if (flags & M_SUBJECT) { + if (subj_id == pid) + checkflags |= M_SUBJECT; + } + if (flags & M_USERA) { + if (m_usera == auid) + checkflags |= M_USERA; + } + if (flags & M_USERE) { + if (m_usere == euid) + checkflags |= M_USERE; + } + if (flags & M_USERR) { + if (m_userr == ruid) + checkflags |= M_USERR; + } + if (flags & M_GROUPR) { + if (m_groupr == rgid) + checkflags |= M_GROUPR; + } + if (flags & M_GROUPE) { + if (m_groupe == egid) + checkflags |= M_GROUPE; + } + return (-1); +} + +/* + * Format of subject32_ex token: + * subject token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid_addr adr_int32*6 + * + */ +int +subject32_ex_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int32_t port, type, addr[4]; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int32(adr, &port, 1); + adrm_int32(adr, &type, 1); + adrm_int32(adr, &addr[0], 4); + + if (flags & M_SUBJECT) { + if (subj_id == pid) + checkflags = checkflags | M_SUBJECT; + } + if (flags & M_USERA) { + if (m_usera == auid) + checkflags = checkflags | M_USERA; + } + if (flags & M_USERE) { + if (m_usere == euid) + checkflags = checkflags | M_USERE; + } + if (flags & M_USERR) { + if (m_userr == ruid) + checkflags = checkflags | M_USERR; + } + if (flags & M_GROUPR) { + if (m_groupr == egid) + checkflags = checkflags | M_GROUPR; + } + if (flags & M_GROUPE) { + if (m_groupe == egid) + checkflags = checkflags | M_GROUPE; + } + return (-1); +} + +/* + * Format of subject64 token: + * subject token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int64+adr_int32 + * + */ +int +subject64_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int64_t port; + int32_t machine; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int64(adr, &port, 1); + adrm_int32(adr, &machine, 1); + + if (flags & M_SUBJECT) { + if (subj_id == pid) + checkflags |= M_SUBJECT; + } + if (flags & M_USERA) { + if (m_usera == auid) + checkflags |= M_USERA; + } + if (flags & M_USERE) { + if (m_usere == euid) + checkflags |= M_USERE; + } + if (flags & M_USERR) { + if (m_userr == ruid) + checkflags |= M_USERR; + } + if (flags & M_GROUPR) { + if (m_groupr == rgid) + checkflags |= M_GROUPR; + } + if (flags & M_GROUPE) { + if (m_groupe == egid) + checkflags |= M_GROUPE; + } + return (-1); +} + +/* + * Format of subject64 token: + * subject token id adr_char + * auid adr_int32 + * euid adr_int32 + * egid adr_int32 + * ruid adr_int32 + * rgid adr_int32 + * pid adr_int32 + * sid adr_int32 + * termid adr_int64+5*adr_int32 + * + */ +int +subject64_ex_token(adr_t *adr) +{ + int32_t auid, euid, egid, ruid, rgid, pid; + int32_t sid; + int64_t port; + int32_t type, addr[4]; + + adrm_int32(adr, &auid, 1); + adrm_int32(adr, &euid, 1); + adrm_int32(adr, &egid, 1); + adrm_int32(adr, &ruid, 1); + adrm_int32(adr, &rgid, 1); + adrm_int32(adr, &pid, 1); + adrm_int32(adr, &sid, 1); + adrm_int64(adr, &port, 1); + adrm_int32(adr, &type, 1); + adrm_int32(adr, &addr[0], 4); + + if (flags & M_SUBJECT) { + if (subj_id == pid) + checkflags = checkflags | M_SUBJECT; + } + if (flags & M_USERA) { + if (m_usera == auid) + checkflags = checkflags | M_USERA; + } + if (flags & M_USERE) { + if (m_usere == euid) + checkflags = checkflags | M_USERE; + } + if (flags & M_USERR) { + if (m_userr == ruid) + checkflags = checkflags | M_USERR; + } + if (flags & M_GROUPR) { + if (m_groupr == egid) + checkflags = checkflags | M_GROUPR; + } + if (flags & M_GROUPE) { + if (m_groupe == egid) + checkflags = checkflags | M_GROUPE; + } + return (-1); +} + +/* + * ----------------------------------------------------------------------- + * tid_token(): Process tid token and display contents + * + * Format of tid token: + * tid token id adr_char + * address type adr_char + * For address type of AU_IPADR... + * remote port adr_short + * local port adr_short + * IP type adr_int32 + * IP addr adr_int32 if IPv4 + * IP addr 4 x adr_int32 if IPv6 + * address types other than AU_IPADR are not yet defined + * ----------------------------------------------------------------------- + */ +int +tid_token(adr_t *adr) +{ + int32_t address[4]; + int32_t ip_type; + char tid_type; + short rport; + short lport; + + adrm_char(adr, &tid_type, 1); + switch (tid_type) { + case AU_IPADR: + adrm_short(adr, &rport, 1); + adrm_short(adr, &lport, 1); + adrm_int32(adr, &ip_type, 1); + adrm_char(adr, (char *)&address, ip_type); + break; + default: + return (0); + } + return (-1); +} + +/* + * ----------------------------------------------------------------------- + * zonename_token(): Process zonename token and display contents + * + * Format of zonename token: + * zonename token id adr_char + * zone name adr_string + * ----------------------------------------------------------------------- + */ +int +zonename_token(adr_t *adr) +{ + char *name; + + if (flags & M_ZONENAME) { + get_string(adr, &name); + if (strncmp(zonename, name, ZONENAME_MAX) == 0) + checkflags |= M_ZONENAME; + free(name); + } else { + skip_string(adr); + } + return (-1); +} + +/* + * Format of xatom token: + */ +int +xatom_token(adr_t *adr) +{ + skip_string(adr); + + return (-1); +} + +/* + * Format of xselect token: + */ +int +xselect_token(adr_t *adr) +{ + skip_string(adr); + skip_string(adr); + skip_string(adr); + + return (-1); +} + +/* + * anchor a path name with a slash + * assume we have enough space + */ +void +anchor_path(char *path) +{ + (void) memmove((void *)(path + 1), (void *)path, strlen(path) + 1); + *path = '/'; +} + + +/* + * copy path to collapsed path. + * collapsed path does not contain: + * successive slashes + * instances of dot-slash + * instances of dot-dot-slash + * passed path must be anchored with a '/' + */ +char * +collapse_path(char *s) +{ + int id; /* index of where we are in destination string */ + int is; /* index of where we are in source string */ + int slashseen; /* have we seen a slash */ + int ls; /* length of source string */ + + ls = strlen(s) + 1; + + slashseen = 0; + for (is = 0, id = 0; is < ls; is++) { + /* thats all folks, we've reached the end of input */ + if (s[is] == '\0') { + if (id > 1 && s[id-1] == '/') { + --id; + } + s[id++] = '\0'; + break; + } + /* previous character was a / */ + if (slashseen) { + if (s[is] == '/') + continue; /* another slash, ignore it */ + } else if (s[is] == '/') { + /* we see a /, just copy it and try again */ + slashseen = 1; + s[id++] = '/'; + continue; + } + /* /./ seen */ + if (s[is] == '.' && s[is+1] == '/') { + is += 1; + continue; + } + /* XXX/. seen */ + if (s[is] == '.' && s[is+1] == '\0') { + if (id > 1) + id--; + continue; + } + /* XXX/.. seen */ + if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') { + is += 1; + if (id > 0) + id--; + while (id > 0 && s[--id] != '/'); + id++; + continue; + } + /* XXX/../ seen */ + if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') { + is += 2; + if (id > 0) + id--; + while (id > 0 && s[--id] != '/'); + id++; + continue; + } + while (is < ls && (s[id++] = s[is++]) != '/'); + is--; + } + return (s); +} + + +int +ipc_type_match(int flag, char type) +{ + if (flag == OBJ_SEM && type == AT_IPC_SEM) + return (1); + + if (flag == OBJ_MSG && type == AT_IPC_MSG) + return (1); + + if (flag == OBJ_SHM && type == AT_IPC_SHM) + return (1); + + return (0); +} + + +void +skip_string(adr_t *adr) +{ + ushort_t c; + + adrm_u_short(adr, &c, 1); + adr->adr_now += c; +} + + +void +get_string(adr_t *adr, char **p) +{ + ushort_t c; + + adrm_u_short(adr, &c, 1); + *p = a_calloc(1, (size_t)c); + adrm_char(adr, *p, c); +} + + +/* + * Format of host token: + * host ard_uint32 + */ +int +host_token(adr_t *adr) +{ + uint32_t host; + + adrm_u_int32(adr, &host, 1); + + return (-1); +} + +/* + * Format of useofauth token: + * uauth token id adr_char + * uauth adr_string + * + */ +int +useofauth_token(adr_t *adr) +{ + skip_string(adr); + return (-1); +} + +int +xcolormap_token(adr_t *adr) +{ + return (xgeneric(adr)); +} + +int +xcursor_token(adr_t *adr) +{ + return (xgeneric(adr)); +} + +int +xfont_token(adr_t *adr) +{ + return (xgeneric(adr)); +} + +int +xgc_token(adr_t *adr) +{ + return (xgeneric(adr)); +} + +int +xpixmap_token(adr_t *adr) +{ + return (xgeneric(adr)); +} + +int +xwindow_token(adr_t *adr) +{ + return (xgeneric(adr)); +} + + +/* + * Format of xgeneric token: + * XID adr_int32 + * creator UID adr_int32 + * + * Includes: xcolormap, xcursor, xfont, xgc, xpixmap, and xwindow + */ +int +xgeneric(adr_t *adr) +{ + int32_t xid; + int32_t uid; + + adrm_int32(adr, &xid, 1); + adrm_int32(adr, &uid, 1); + + if (flags & M_USERE) { + if (m_usere == uid) + checkflags = checkflags | M_USERE; + } + + return (-1); +} + + +/* + * Format of xproperty token: + * XID adr_int32 + * creator UID adr_int32 + * atom string adr_string + */ +int +xproperty_token(adr_t *adr) +{ + int32_t xid; + int32_t uid; + + adrm_int32(adr, &xid, 1); + adrm_int32(adr, &uid, 1); + skip_string(adr); + + if (flags & M_USERE) { + if (m_usere == uid) + checkflags = checkflags | M_USERE; + } + + return (-1); +} + + +/* + * Format of xclient token: + * xclient id adr_int32 + */ +int +xclient_token(adr_t *adr) +{ + int32_t client_id; + + adrm_int32(adr, &client_id, 1); + + return (-1); +} + +/* + * Format of clearance token: + * clearance adr_char*(sizeof (bclear_t)) + */ +#ifndef TSOL +/* ARGSUSED */ +#endif /* !TSOL */ +int +clearance_token(adr_t *adr) +{ +#ifdef TSOL + bclear_t clearance; + + adrm_char(adr, (char *)&clearance, sizeof (bclear_t)); + return (-1); +#else /* !TSOL */ + return (-2); +#endif /* TSOL */ +} + + +/* + * Format of ilabel token: + * ilabel adr_char*(sizeof (bilabel_t)) + */ +#ifndef TSOL +/* ARGSUSED */ +#endif /* !TSOL */ +int +ilabel_token(adr_t *adr) +{ +#ifdef TSOL + bilabel_t ilabel; + + adrm_char(adr, (char *)&ilabel, sizeof (ilabel)); + + return (-1); +#else /* !TSOL */ + return (-2); +#endif /* TSOL */ +} + +/* + * Format of privilege set token: + * priv_set type string + * priv_set string + */ + +int +privilege_token(adr_t *adr) +{ + skip_string(adr); /* set type name */ + skip_string(adr); /* privilege set */ + return (-1); +} + +/* + * Format of slabel token: + * slabel adr_char*(sizeof (bslabel_t)) + */ +#ifndef TSOL +/* ARGSUSED */ +#endif /* !TSOL */ +int +slabel_token(adr_t *adr) +{ +#ifdef TSOL + bslabel_t slabel; + + adrm_char(adr, (char *)&slabel, sizeof (slabel)); + + if (flags & M_SLABEL) { + if (blinrange(&slabel, &m_slabel)) + checkflags = checkflags | M_SLABEL; + } + + return (-1); +#else /* !TSOL */ + return (-2); +#endif /* TSOL */ +} + + +/* + * Format of useofpriv token: + * success/failure adr_char + * TSOL: + * privilege adr_int32 + * SOL: + * privilege(s) adr_string + */ +#ifndef TSOL +/* ARGSUSED */ +#endif /* !TSOL */ +int +useofpriv_token(adr_t *adr) +{ + char flag; + +#ifdef TSOL + priv_t priv; + + adrm_char(adr, &flag, 1); + adrm_int32(adr, (int32_t *)&priv, 1); + + return (-1); +#else /* !TSOL */ + + adrm_char(adr, &flag, 1); + skip_string(adr); + return (-1); +#endif /* TSOL */ +} |