/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Token processing for auditreduce. */ #include #include #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); } /* * Format of acl token: * acl token id adr_char * acl type adr_u_int32 * acl value adr_u_int32 (depends on type) * file mode adr_u_int (in octal) */ 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 ace token: * ace token id adr_char * ace who adr_u_int32 (uid/gid) * access mask adr_u_int32 * ace flags adr_u_int16 * ace type adr_u_int16 */ int ace_token(adr_t *adr) { uid_t who; uint32_t access_mask; uint16_t flags, type; adrm_uid(adr, &who, 1); adrm_u_int32(adr, &access_mask, 1); adrm_u_short(adr, &flags, 1); adrm_u_short(adr, &type, 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 */ 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; } if (flags & M_SID) { if (m_sid == sid) checkflags |= M_SID; } 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; } if (flags & M_SID) { if (m_sid == sid) checkflags = checkflags | M_SID; } 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; } if (flags & M_SID) { if (m_sid == sid) checkflags |= M_SID; } 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; } if (flags & M_SID) { if (m_sid == sid) checkflags = checkflags | M_SID; } 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); } /* * fmri_token(): * * Format of fmri token: * fmri adr_string */ int fmri_token(adr_t *adr) { if ((flags & M_OBJECT) && (obj_flag == OBJ_FMRI)) { char *fmri_name; get_string(adr, &fmri_name); /* match token against service instance */ if (scf_cmp_pattern(fmri_name, &fmri) == 1) { checkflags |= M_OBJECT; } free(fmri_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 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 label token: * label ID 1 byte * compartment length 1 byte * classification 2 bytes * compartment words * 4 bytes */ int label_token(adr_t *adr) { static m_label_t *label = NULL; static size_t l_size; int len; if (label == NULL) { label = m_label_alloc(MAC_LABEL); l_size = blabel_size() - 4; } if (label == NULL) { /* out of memory, should never happen; skip label */ char l; /* length */ adr->adr_now += sizeof (char); adrm_char(adr, (char *)&l, 1); adr->adr_now += sizeof (short) + (4 * l); return (-1); } adrm_char(adr, (char *)label, 4); len = (int)(((char *)label)[1] * 4); if (len > l_size) { return (-1); } adrm_char(adr, &((char *)label)[4], len); if (flags & M_LABEL) { if (blinrange(label, m_label)) checkflags = checkflags | M_LABEL; } return (-1); } /* * Format of useofpriv token: * success/failure adr_char * privilege(s) adr_string */ /* ARGSUSED */ int useofpriv_token(adr_t *adr) { char flag; adrm_char(adr, &flag, 1); skip_string(adr); return (-1); }