| /* |
| * 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 2006 Sun Microsystems, Inc. All rights reserved. |
| * Use is subject to license terms. |
| */ |
| |
| #pragma ident "%Z%%M% %I% %E% SMI" |
| |
| /* |
| * Support routines for building audit records. |
| */ |
| |
| #include <sys/param.h> |
| #include <sys/systm.h> /* for rval */ |
| #include <sys/time.h> |
| #include <sys/types.h> |
| #include <sys/vnode.h> |
| #include <sys/mode.h> |
| #include <sys/user.h> |
| #include <sys/session.h> |
| #include <sys/acl.h> |
| #include <sys/ipc_impl.h> |
| #include <netinet/in_systm.h> |
| #include <netinet/in.h> |
| #include <netinet/ip.h> |
| #include <sys/socket.h> |
| #include <net/route.h> |
| #include <netinet/in_pcb.h> |
| #include <c2/audit.h> |
| #include <c2/audit_kernel.h> |
| #include <c2/audit_record.h> |
| #include <sys/model.h> /* for model_t */ |
| #include <sys/vmparam.h> /* for USRSTACK/USRSTACK32 */ |
| #include <sys/vfs.h> /* for sonode */ |
| #include <sys/socketvar.h> /* for sonode */ |
| #include <sys/zone.h> |
| #include <sys/tsol/label.h> |
| |
| /* |
| * These are the control tokens |
| */ |
| |
| /* |
| * au_to_header |
| * returns: |
| * pointer to au_membuf chain containing a header token. |
| */ |
| token_t * |
| au_to_header(int byte_count, short e_type, short e_mod) |
| { |
| adr_t adr; /* adr memory stream header */ |
| token_t *m; /* au_membuf pointer */ |
| #ifdef _LP64 |
| char data_header = AUT_HEADER64; /* header for this token */ |
| static int64_t zerotime[2]; |
| #else |
| char data_header = AUT_HEADER32; |
| static int32_t zerotime[2]; |
| #endif |
| char version = TOKEN_VERSION; /* version of token family */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); /* token ID */ |
| adr_int32(&adr, (int32_t *)&byte_count, 1); /* length of */ |
| /* audit record */ |
| adr_char(&adr, &version, 1); /* version of audit tokens */ |
| adr_short(&adr, &e_type, 1); /* event ID */ |
| adr_short(&adr, &e_mod, 1); /* event ID modifier */ |
| #ifdef _LP64 |
| adr_int64(&adr, zerotime, 2); /* time & date space */ |
| #else |
| adr_int32(&adr, zerotime, 2); |
| #endif |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| token_t * |
| au_to_header_ex(int byte_count, au_event_t e_type, au_emod_t e_mod) |
| { |
| adr_t adr; /* adr memory stream header */ |
| token_t *m; /* au_membuf pointer */ |
| au_kcontext_t *kctx = SET_KCTX_PZ; |
| |
| #ifdef _LP64 |
| char data_header = AUT_HEADER64_EX; /* header for this token */ |
| static int64_t zerotime[2]; |
| #else |
| char data_header = AUT_HEADER32_EX; |
| static int32_t zerotime[2]; |
| #endif |
| char version = TOKEN_VERSION; /* version of token family */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); /* token ID */ |
| adr_int32(&adr, (int32_t *)&byte_count, 1); /* length of */ |
| /* audit record */ |
| adr_char(&adr, &version, 1); /* version of audit tokens */ |
| adr_short(&adr, &e_type, 1); /* event ID */ |
| adr_short(&adr, &e_mod, 1); /* event ID modifier */ |
| adr_uint32(&adr, &kctx->auk_info.ai_termid.at_type, 1); |
| adr_char(&adr, (char *)&kctx->auk_info.ai_termid.at_addr[0], |
| (int)kctx->auk_info.ai_termid.at_type); |
| #ifdef _LP64 |
| adr_int64(&adr, zerotime, 2); /* time & date */ |
| #else |
| adr_int32(&adr, zerotime, 2); |
| #endif |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_trailer |
| * returns: |
| * pointer to au_membuf chain containing a trailer token. |
| */ |
| token_t * |
| au_to_trailer(int byte_count) |
| { |
| adr_t adr; /* adr memory stream header */ |
| token_t *m; /* au_membuf pointer */ |
| char data_header = AUT_TRAILER; /* header for this token */ |
| short magic = (short)AUT_TRAILER_MAGIC; /* trailer magic number */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); /* token ID */ |
| adr_short(&adr, &magic, 1); /* magic number */ |
| adr_int32(&adr, (int32_t *)&byte_count, 1); /* length of */ |
| /* audit record */ |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| /* |
| * These are the data tokens |
| */ |
| |
| /* |
| * au_to_data |
| * returns: |
| * pointer to au_membuf chain containing a data token. |
| */ |
| token_t * |
| au_to_data(char unit_print, char unit_type, char unit_count, char *p) |
| { |
| adr_t adr; /* adr memory stream header */ |
| token_t *m; /* au_membuf pointer */ |
| char data_header = AUT_DATA; /* header for this token */ |
| |
| ASSERT(p != NULL); |
| ASSERT(unit_count != 0); |
| |
| switch (unit_type) { |
| case AUR_SHORT: |
| if (sizeof (short) * unit_count >= AU_BUFSIZE) |
| return (au_to_text("au_to_data: unit count too big")); |
| break; |
| case AUR_INT32: |
| if (sizeof (int32_t) * unit_count >= AU_BUFSIZE) |
| return (au_to_text("au_to_data: unit count too big")); |
| break; |
| case AUR_INT64: |
| if (sizeof (int64_t) * unit_count >= AU_BUFSIZE) |
| return (au_to_text("au_to_data: unit count too big")); |
| break; |
| case AUR_BYTE: |
| default: |
| #ifdef _CHAR_IS_UNSIGNED |
| if (sizeof (char) * unit_count >= AU_BUFSIZE) |
| return (au_to_text("au_to_data: unit count too big")); |
| #endif |
| /* |
| * we used to check for this: |
| * sizeof (char) * (int)unit_count >= AU_BUFSIZE). |
| * but the compiler is smart enough to see that |
| * will never be >= AU_BUFSIZE, since that's 128 |
| * and unit_count maxes out at 127 (signed char), |
| * and complain. |
| */ |
| break; |
| } |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, &unit_print, 1); |
| adr_char(&adr, &unit_type, 1); |
| adr_char(&adr, &unit_count, 1); |
| |
| switch (unit_type) { |
| case AUR_SHORT: |
| adr_short(&adr, (short *)p, unit_count); |
| break; |
| case AUR_INT32: |
| adr_int32(&adr, (int32_t *)p, unit_count); |
| break; |
| case AUR_INT64: |
| adr_int64(&adr, (int64_t *)p, unit_count); |
| break; |
| case AUR_BYTE: |
| default: |
| adr_char(&adr, p, unit_count); |
| break; |
| } |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_process |
| * au_to_subject |
| * returns: |
| * pointer to au_membuf chain containing a process token. |
| */ |
| static token_t *au_to_any_process(char, uid_t, gid_t, uid_t, gid_t, |
| pid_t, au_id_t, au_asid_t, const au_tid_addr_t *atid); |
| |
| token_t * |
| au_to_process(uid_t uid, gid_t gid, uid_t ruid, gid_t rgid, pid_t pid, |
| au_id_t auid, au_asid_t asid, const au_tid_addr_t *atid) |
| { |
| char data_header; |
| |
| #ifdef _LP64 |
| if (atid->at_type == AU_IPv6) |
| data_header = AUT_PROCESS64_EX; |
| else |
| data_header = AUT_PROCESS64; |
| #else |
| if (atid->at_type == AU_IPv6) |
| data_header = AUT_PROCESS32_EX; |
| else |
| data_header = AUT_PROCESS32; |
| #endif |
| |
| return (au_to_any_process(data_header, uid, gid, ruid, |
| rgid, pid, auid, asid, atid)); |
| } |
| |
| token_t * |
| au_to_subject(uid_t uid, gid_t gid, uid_t ruid, gid_t rgid, pid_t pid, |
| au_id_t auid, au_asid_t asid, const au_tid_addr_t *atid) |
| { |
| char data_header; |
| |
| #ifdef _LP64 |
| if (atid->at_type == AU_IPv6) |
| data_header = AUT_SUBJECT64_EX; |
| else |
| data_header = AUT_SUBJECT64; |
| #else |
| if (atid->at_type == AU_IPv6) |
| data_header = AUT_SUBJECT32_EX; |
| else |
| data_header = AUT_SUBJECT32; |
| #endif |
| return (au_to_any_process(data_header, uid, gid, ruid, |
| rgid, pid, auid, asid, atid)); |
| } |
| |
| |
| static token_t * |
| au_to_any_process(char data_header, |
| uid_t uid, gid_t gid, uid_t ruid, gid_t rgid, pid_t pid, |
| au_id_t auid, au_asid_t asid, const au_tid_addr_t *atid) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| int32_t value; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| value = (int32_t)auid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)uid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)gid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)ruid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)rgid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)pid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)asid; |
| adr_int32(&adr, &value, 1); |
| #ifdef _LP64 |
| adr_int64(&adr, (int64_t *)&(atid->at_port), 1); |
| #else |
| adr_int32(&adr, (int32_t *)&(atid->at_port), 1); |
| #endif |
| if (atid->at_type == AU_IPv6) { |
| adr_uint32(&adr, (uint_t *)&atid->at_type, 1); |
| adr_char(&adr, (char *)&atid->at_addr[0], 16); |
| } else { |
| adr_char(&adr, (char *)&(atid->at_addr[0]), 4); |
| } |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_text |
| * returns: |
| * pointer to au_membuf chain containing a text token. |
| */ |
| token_t * |
| au_to_text(const char *text) |
| { |
| token_t *token; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_TEXT; /* header for this token */ |
| short bytes; /* length of string */ |
| |
| token = au_getclr(); |
| |
| bytes = (short)strlen(text) + 1; |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_short(&adr, &bytes, 1); |
| |
| token->len = (char)adr_count(&adr); |
| /* |
| * Now attach the text |
| */ |
| (void) au_append_buf(text, bytes, token); |
| |
| return (token); |
| } |
| |
| /* |
| * au_zonename_length |
| * returns: |
| * - length of zonename token to be generated |
| * - zone name up to ZONENAME_MAX + 1 in length |
| */ |
| #define ZONE_TOKEN_OVERHEAD 3 |
| /* |
| * the zone token is |
| * token id (1 byte) |
| * string length (2 bytes) |
| * the string (strlen(zonename) + 1) |
| */ |
| size_t |
| au_zonename_length() |
| { |
| return (strlen(curproc->p_zone->zone_name) + 1 + |
| ZONE_TOKEN_OVERHEAD); |
| } |
| |
| /* |
| * au_to_zonename |
| * |
| * A length of zero input to au_to_zonename means the length is not |
| * pre-calculated. |
| * |
| * The caller is responsible for checking the AUDIT_ZONENAME policy |
| * before calling au_zonename_length() and au_to_zonename(). If |
| * the policy changes between the calls, no harm is done, so the |
| * policy only needs to be checked once. |
| * |
| * returns: |
| * pointer to au_membuf chain containing a zonename token; NULL if |
| * policy is off. |
| * |
| * if the zonename token is generated at token generation close time, |
| * the length of the token is already known and it is ASSERTed that |
| * it has not changed. If not precalculated, zone_length must be |
| * zero. |
| */ |
| token_t * |
| au_to_zonename(size_t zone_length) |
| { |
| token_t *token; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_ZONENAME; /* header for this token */ |
| short bytes; /* length of string */ |
| |
| token = au_getclr(); |
| |
| bytes = (short)strlen(curproc->p_zone->zone_name) + 1; |
| /* |
| * If zone_length != 0, it was precalculated and is |
| * the token length, not the string length. |
| */ |
| ASSERT((zone_length == 0) || |
| (zone_length == (bytes + ZONE_TOKEN_OVERHEAD))); |
| |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_short(&adr, &bytes, 1); |
| |
| token->len = (char)adr_count(&adr); |
| (void) au_append_buf(curproc->p_zone->zone_name, bytes, token); |
| |
| return (token); |
| } |
| |
| /* |
| * au_to_strings |
| * returns: |
| * pointer to au_membuf chain containing a strings array token. |
| */ |
| token_t * |
| au_to_strings( |
| char header, /* token type */ |
| const char *kstrp, /* kernel string pointer */ |
| ssize_t count) /* count of arguments */ |
| { |
| token_t *token; /* local au_membuf */ |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| size_t len; |
| int32_t tlen; |
| |
| token = au_getclr(); |
| |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &header, 1); |
| tlen = (int32_t)count; |
| adr_int32(&adr, &tlen, 1); |
| |
| token->len = (char)adr_count(&adr); |
| |
| while (count-- > 0) { |
| m = au_getclr(); |
| len = strlen(kstrp) + 1; |
| (void) au_append_buf(kstrp, len, m); |
| (void) au_append_rec((token_t *)token, (token_t *)m, AU_PACK); |
| kstrp += len; |
| } |
| |
| return (token); |
| } |
| |
| /* |
| * au_to_exec_args |
| * returns: |
| * pointer to au_membuf chain containing a argv token. |
| */ |
| token_t * |
| au_to_exec_args(const char *kstrp, ssize_t argc) |
| { |
| return (au_to_strings(AUT_EXEC_ARGS, kstrp, argc)); |
| } |
| |
| /* |
| * au_to_exec_env |
| * returns: |
| * pointer to au_membuf chain containing a arge token. |
| */ |
| token_t * |
| au_to_exec_env(const char *kstrp, ssize_t envc) |
| { |
| return (au_to_strings(AUT_EXEC_ENV, kstrp, envc)); |
| } |
| |
| /* |
| * au_to_arg32 |
| * char n; argument # being used |
| * char *text; text describing argument |
| * uint32_t v; argument value |
| * returns: |
| * pointer to au_membuf chain containing an argument token. |
| */ |
| token_t * |
| au_to_arg32(char n, char *text, uint32_t v) |
| { |
| token_t *token; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_ARG32; /* header for this token */ |
| short bytes; /* length of string */ |
| |
| token = au_getclr(); |
| |
| bytes = strlen(text) + 1; |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &data_header, 1); /* token type */ |
| adr_char(&adr, &n, 1); /* argument id */ |
| adr_uint32(&adr, &v, 1); /* argument value */ |
| adr_short(&adr, &bytes, 1); |
| |
| token->len = adr_count(&adr); |
| /* |
| * Now add the description |
| */ |
| (void) au_append_buf(text, bytes, token); |
| |
| return (token); |
| } |
| |
| |
| /* |
| * au_to_arg64 |
| * char n; argument # being used |
| * char *text; text describing argument |
| * uint64_t v; argument value |
| * returns: |
| * pointer to au_membuf chain containing an argument token. |
| */ |
| token_t * |
| au_to_arg64(char n, char *text, uint64_t v) |
| { |
| token_t *token; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_ARG64; /* header for this token */ |
| short bytes; /* length of string */ |
| |
| token = au_getclr(); |
| |
| bytes = strlen(text) + 1; |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &data_header, 1); /* token type */ |
| adr_char(&adr, &n, 1); /* argument id */ |
| adr_uint64(&adr, &v, 1); /* argument value */ |
| adr_short(&adr, &bytes, 1); |
| |
| token->len = adr_count(&adr); |
| /* |
| * Now the description |
| */ |
| (void) au_append_buf(text, bytes, token); |
| |
| return (token); |
| } |
| |
| |
| /* |
| * au_to_path |
| * returns: |
| * pointer to au_membuf chain containing a path token. |
| */ |
| token_t * |
| au_to_path(struct audit_path *app) |
| { |
| token_t *token; /* local au_membuf */ |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_PATH; /* header for this token */ |
| short bytes; /* length of string */ |
| char *path = app->audp_sect[0]; |
| |
| bytes = (short)(app->audp_sect[1] - app->audp_sect[0]); |
| |
| /* |
| * generate path token header |
| */ |
| m = au_getclr(); |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_short(&adr, &bytes, 1); |
| m->len = adr_count(&adr); |
| |
| /* append path string */ |
| token = m; |
| (void) au_append_buf(path, bytes, token); |
| |
| if (app->audp_cnt > 1) { |
| /* generate attribute path strings token */ |
| m = au_to_strings(AUT_XATPATH, app->audp_sect[1], |
| app->audp_cnt - 1); |
| |
| token = au_append_token(token, m); |
| } |
| |
| return (token); |
| } |
| |
| /* |
| * au_to_ipc |
| * returns: |
| * pointer to au_membuf chain containing a System V IPC token. |
| */ |
| token_t * |
| au_to_ipc(char type, int id) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_IPC; /* header for this token */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, &type, 1); /* type of IPC object */ |
| adr_int32(&adr, (int32_t *)&id, 1); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_return32 |
| * returns: |
| * pointer to au_membuf chain containing a return value token. |
| */ |
| token_t * |
| au_to_return32(int error, int32_t rv) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_RETURN32; /* header for this token */ |
| int32_t val; |
| char ed = error; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, &ed, 1); |
| |
| if (error) { |
| val = -1; |
| adr_int32(&adr, &val, 1); |
| } else { |
| adr_int32(&adr, &rv, 1); |
| } |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_return64 |
| * returns: |
| * pointer to au_membuf chain containing a return value token. |
| */ |
| token_t * |
| au_to_return64(int error, int64_t rv) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_RETURN64; /* header for this token */ |
| int64_t val; |
| char ed = error; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, &ed, 1); |
| |
| if (error) { |
| val = -1; |
| adr_int64(&adr, &val, 1); |
| } else { |
| adr_int64(&adr, &rv, 1); |
| } |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| #ifdef AU_MAY_USE_SOMEDAY |
| /* |
| * au_to_opaque |
| * returns: |
| * pointer to au_membuf chain containing a opaque token. |
| */ |
| token_t * |
| au_to_opaque(short bytes, char *opaque) |
| { |
| token_t *token; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_OPAQUE; /* header for this token */ |
| |
| token = au_getclr(); |
| |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_short(&adr, &bytes, 1); |
| |
| token->len = adr_count(&adr); |
| |
| /* |
| * Now attach the data |
| */ |
| (void) au_append_buf(opaque, bytes, token); |
| |
| return (token); |
| } |
| #endif /* AU_MAY_USE_SOMEDAY */ |
| |
| /* |
| * au_to_ip |
| * returns: |
| * pointer to au_membuf chain containing a ip header token |
| */ |
| token_t * |
| au_to_ip(struct ip *ipp) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_IP; /* header for this token */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, (char *)ipp, 2); |
| adr_short(&adr, (short *)&(ipp->ip_len), 3); |
| adr_char(&adr, (char *)&(ipp->ip_ttl), 2); |
| adr_short(&adr, (short *)&(ipp->ip_sum), 1); |
| adr_int32(&adr, (int32_t *)&(ipp->ip_src), 2); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_iport |
| * returns: |
| * pointer to au_membuf chain containing a ip path token |
| */ |
| token_t * |
| au_to_iport(ushort_t iport) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_IPORT; /* header for this token */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_ushort(&adr, &iport, 1); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_in_addr |
| * returns: |
| * pointer to au_membuf chain containing a ip path token |
| */ |
| token_t * |
| au_to_in_addr(struct in_addr *internet_addr) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_IN_ADDR; /* header for this token */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, (char *)internet_addr, sizeof (struct in_addr)); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_in_addr_ex |
| * returns: |
| * pointer to au_membuf chain containing an ipv6 token |
| */ |
| token_t * |
| au_to_in_addr_ex(int32_t *internet_addr) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header_v4 = AUT_IN_ADDR; /* header for v4 token */ |
| char data_header_v6 = AUT_IN_ADDR_EX; /* header for v6 token */ |
| int32_t type = AU_IPv6; |
| |
| m = au_getclr(); |
| adr_start(&adr, memtod(m, char *)); |
| |
| if (IN6_IS_ADDR_V4MAPPED((in6_addr_t *)internet_addr)) { |
| adr_char(&adr, &data_header_v4, 1); |
| adr_char(&adr, (char *)internet_addr, sizeof (struct in_addr)); |
| } else { |
| adr_char(&adr, &data_header_v6, 1); |
| adr_int32(&adr, &type, 1); |
| adr_char(&adr, (char *)internet_addr, sizeof (struct in6_addr)); |
| } |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * The Modifier tokens |
| */ |
| |
| /* |
| * au_to_attr |
| * returns: |
| * pointer to au_membuf chain containing an attribute token. |
| */ |
| token_t * |
| au_to_attr(struct vattr *attr) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| #ifdef _LP64 |
| char data_header = AUT_ATTR64; /* header for this token */ |
| #else |
| char data_header = AUT_ATTR32; |
| #endif |
| int32_t value; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| value = (int32_t)attr->va_mode; |
| value |= (int32_t)(VTTOIF(attr->va_type)); |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)attr->va_uid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)attr->va_gid; |
| adr_int32(&adr, &value, 1); |
| adr_int32(&adr, (int32_t *)&(attr->va_fsid), 1); |
| adr_int64(&adr, (int64_t *)&(attr->va_nodeid), 1); |
| #ifdef _LP64 |
| adr_int64(&adr, (int64_t *)&(attr->va_rdev), 1); |
| #else |
| adr_int32(&adr, (int32_t *)&(attr->va_rdev), 1); |
| #endif |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| token_t * |
| au_to_acl(struct acl *aclp) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_ACL; /* header for this token */ |
| int32_t value; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| |
| value = (int32_t)aclp->a_type; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)aclp->a_id; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)aclp->a_perm; |
| adr_int32(&adr, &value, 1); |
| |
| m->len = adr_count(&adr); |
| return (m); |
| } |
| |
| /* |
| * au_to_ipc_perm |
| * returns: |
| * pointer to au_membuf chain containing a System V IPC attribute token. |
| */ |
| token_t * |
| au_to_ipc_perm(struct kipc_perm *perm) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_IPC_PERM; /* header for this token */ |
| int32_t value; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| value = (int32_t)perm->ipc_uid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)perm->ipc_gid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)perm->ipc_cuid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)perm->ipc_cgid; |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)perm->ipc_mode; |
| adr_int32(&adr, &value, 1); |
| value = 0; /* seq is now obsolete */ |
| adr_int32(&adr, &value, 1); |
| value = (int32_t)perm->ipc_key; |
| adr_int32(&adr, &value, 1); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| token_t * |
| au_to_groups(const gid_t *crgroups, uint_t crngroups) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_NEWGROUPS; /* header for this token */ |
| short n_groups; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| n_groups = (short)crngroups; |
| adr_short(&adr, &n_groups, 1); |
| adr_int32(&adr, (int32_t *)crgroups, (int)crngroups); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_socket_ex |
| * returns: |
| * pointer to au_membuf chain containing a socket token. |
| */ |
| token_t * |
| au_to_socket_ex(short dom, short type, char *l, char *f) |
| { |
| adr_t adr; |
| token_t *m; |
| char data_header = AUT_SOCKET_EX; |
| struct sockaddr_in6 *addr6; |
| struct sockaddr_in *addr4; |
| short size; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_short(&adr, &dom, 1); /* dom of socket */ |
| adr_short(&adr, &type, 1); /* type of socket */ |
| |
| if (dom == AF_INET6) { |
| size = AU_IPv6; |
| adr_short(&adr, &size, 1); /* type of addresses */ |
| addr6 = (struct sockaddr_in6 *)l; |
| adr_short(&adr, (short *)&addr6->sin6_port, 1); |
| adr_char(&adr, (char *)&addr6->sin6_addr, size); |
| addr6 = (struct sockaddr_in6 *)f; |
| adr_short(&adr, (short *)&addr6->sin6_port, 1); |
| adr_char(&adr, (char *)&addr6->sin6_addr, size); |
| } else if (dom == AF_INET) { |
| size = AU_IPv4; |
| adr_short(&adr, &size, 1); /* type of addresses */ |
| addr4 = (struct sockaddr_in *)l; |
| adr_short(&adr, (short *)&addr4->sin_port, 1); |
| adr_char(&adr, (char *)&addr4->sin_addr, size); |
| addr4 = (struct sockaddr_in *)f; |
| adr_short(&adr, (short *)&addr4->sin_port, 1); |
| adr_char(&adr, (char *)&addr4->sin_addr, size); |
| } |
| |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| /* |
| * au_to_seq |
| * returns: |
| * pointer to au_membuf chain containing a sequence token. |
| */ |
| token_t * |
| au_to_seq() |
| { |
| adr_t adr; |
| token_t *m; |
| char data_header = AUT_SEQ; |
| static int32_t zerocount; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| |
| adr_char(&adr, &data_header, 1); |
| |
| adr_int32(&adr, &zerocount, 1); |
| |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |
| |
| token_t * |
| au_to_sock_inet(struct sockaddr_in *s_inet) |
| { |
| adr_t adr; |
| token_t *m; |
| char data_header = AUT_SOCKET; |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_short(&adr, (short *)&s_inet->sin_family, 1); |
| adr_short(&adr, (short *)&s_inet->sin_port, 1); |
| |
| /* remote addr */ |
| adr_int32(&adr, (int32_t *)&s_inet->sin_addr.s_addr, 1); |
| |
| m->len = (uchar_t)adr_count(&adr); |
| |
| return (m); |
| } |
| |
| extern int maxprivbytes; |
| |
| token_t * |
| au_to_privset( |
| const char *set, |
| const priv_set_t *pset, |
| char data_header, |
| int success) |
| { |
| token_t *token, *m; |
| adr_t adr; |
| int priv; |
| const char *pname; |
| char sf = (char)success; |
| char *buf, *q; |
| short sz; |
| boolean_t full; |
| |
| token = au_getclr(); |
| |
| adr_start(&adr, memtod(token, char *)); |
| adr_char(&adr, &data_header, 1); |
| /* |
| * set is not used for AUT_UPRIV and sf (== success) is not |
| * used for AUT_PRIV |
| */ |
| if (data_header == AUT_UPRIV) { |
| adr_char(&adr, &sf, 1); |
| } else { |
| sz = strlen(set) + 1; |
| adr_short(&adr, &sz, 1); |
| |
| token->len = (uchar_t)adr_count(&adr); |
| m = au_getclr(); |
| |
| (void) au_append_buf(set, sz, m); |
| (void) au_append_rec(token, m, AU_PACK); |
| adr.adr_now += sz; |
| } |
| |
| full = priv_isfullset(pset); |
| |
| if (full) { |
| buf = "ALL"; |
| sz = strlen(buf) + 1; |
| } else { |
| q = buf = kmem_alloc(maxprivbytes, KM_SLEEP); |
| *buf = '\0'; |
| |
| for (priv = 0; (pname = priv_getbynum(priv)) != NULL; priv++) { |
| if (priv_ismember(pset, priv)) { |
| if (q != buf) |
| *q++ = ','; |
| (void) strcpy(q, pname); |
| q += strlen(q); |
| } |
| } |
| sz = (q - buf) + 1; |
| } |
| |
| adr_short(&adr, &sz, 1); |
| token->len = (uchar_t)adr_count(&adr); |
| |
| m = au_getclr(); |
| (void) au_append_buf(buf, sz, m); |
| (void) au_append_rec(token, m, AU_PACK); |
| |
| if (!full) |
| kmem_free(buf, maxprivbytes); |
| |
| return (token); |
| } |
| |
| /* |
| * au_to_label |
| * returns: |
| * pointer to au_membuf chain containing a sensitivity label token. |
| */ |
| token_t * |
| au_to_label(bslabel_t *label) |
| { |
| token_t *m; /* local au_membuf */ |
| adr_t adr; /* adr memory stream header */ |
| char data_header = AUT_LABEL; /* header for this token */ |
| |
| m = au_getclr(); |
| |
| adr_start(&adr, memtod(m, char *)); |
| adr_char(&adr, &data_header, 1); |
| adr_char(&adr, (char *)label, sizeof (bslabel_t)); |
| m->len = adr_count(&adr); |
| |
| return (m); |
| } |