1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <sys/types.h> 31 #include <sys/varargs.h> 32 #include <bsm/audit.h> 33 #include <bsm/libbsm.h> 34 #include <bsm/audit_record.h> 35 36 #include "praudit.h" 37 38 39 /* 40 * pr_adr_char - pull out characters 41 */ 42 int 43 pr_adr_char(pr_context_t *context, char *cp, int count) 44 { 45 int err; 46 adr_t *adr = context->audit_adr; 47 adrf_t *adrf = context->audit_adrf; 48 49 if (context->data_mode == FILEMODE) { 50 err = adrf_char(adrf, cp, count); 51 if (err) { 52 errno = EIO; 53 return (-1); 54 } else 55 return (0); 56 } 57 58 /* adrm routines don't return error, so check before calling */ 59 if (!pr_input_remaining(context, (sizeof (char) * count))) { 60 errno = EIO; 61 return (-1); 62 } 63 64 adrm_char(adr, cp, count); 65 return (0); 66 } 67 68 /* 69 * pr_adr_short - pull out shorts 70 */ 71 int 72 pr_adr_short(pr_context_t *context, short *sp, int count) 73 { 74 int err; 75 adr_t *adr = context->audit_adr; 76 adrf_t *adrf = context->audit_adrf; 77 78 if (context->data_mode == FILEMODE) { 79 err = adrf_short(adrf, sp, count); 80 if (err) { 81 errno = EIO; 82 return (-1); 83 } else 84 return (0); 85 } 86 87 /* adrm routines don't return error, so check before calling */ 88 if (!pr_input_remaining(context, (sizeof (short) * count))) { 89 errno = EIO; 90 return (-1); 91 } 92 93 adrm_short(adr, sp, count); 94 return (0); 95 } 96 97 /* 98 * pr_adr_int32 - pull out int32 99 */ 100 int 101 pr_adr_int32(pr_context_t *context, int32_t *lp, int count) 102 { 103 int err; 104 adr_t *adr = context->audit_adr; 105 adrf_t *adrf = context->audit_adrf; 106 107 if (context->data_mode == FILEMODE) { 108 err = adrf_int32(adrf, lp, count); 109 if (err) { 110 errno = EIO; 111 return (-1); 112 } else 113 return (0); 114 } 115 116 /* adrm routines don't return error, so check before calling */ 117 if (!pr_input_remaining(context, (sizeof (int32_t) * count))) { 118 errno = EIO; 119 return (-1); 120 } 121 122 adrm_int32(adr, lp, count); 123 return (0); 124 } 125 126 int 127 pr_adr_int64(pr_context_t *context, int64_t *lp, int count) 128 { 129 int err; 130 adr_t *adr = context->audit_adr; 131 adrf_t *adrf = context->audit_adrf; 132 133 if (context->data_mode == FILEMODE) { 134 err = adrf_int64(adrf, lp, count); 135 if (err) { 136 errno = EIO; 137 return (-1); 138 } else 139 return (0); 140 } 141 142 /* adrm routines don't return error, so check before calling */ 143 if (!pr_input_remaining(context, (sizeof (int64_t) * count))) { 144 errno = EIO; 145 return (-1); 146 } 147 148 adrm_int64(adr, lp, count); 149 return (0); 150 } 151 152 int 153 pr_adr_u_int32(pr_context_t *context, uint32_t *cp, int count) 154 { 155 return (pr_adr_int32(context, (int32_t *)cp, count)); 156 } 157 158 int 159 pr_adr_u_char(pr_context_t *context, uchar_t *cp, int count) 160 { 161 return (pr_adr_char(context, (char *)cp, count)); 162 } 163 164 int 165 pr_adr_u_int64(pr_context_t *context, uint64_t *lp, int count) 166 { 167 return (pr_adr_int64(context, (int64_t *)lp, count)); 168 } 169 170 int 171 pr_adr_u_short(pr_context_t *context, ushort_t *sp, int count) 172 { 173 return (pr_adr_short(context, (short *)sp, count)); 174 } 175 176 int 177 pr_putchar(pr_context_t *context, char c) 178 { 179 if (context->data_mode == FILEMODE) { 180 (void) putchar(c); 181 return (0); 182 } 183 /* Buffer-based output processing otherwise... */ 184 185 /* Need at least room for char + null-byte */ 186 if (context->outbuf_remain_len < 2) { 187 /* no space left */ 188 errno = ENOSPC; 189 return (-1); 190 } 191 192 *(context->outbuf_p) = c; 193 context->outbuf_p += 1; 194 context->outbuf_remain_len -= 1; 195 196 return (0); 197 } 198 199 int 200 pr_printf(pr_context_t *context, const char *fmt, ...) 201 { 202 int addlen; 203 va_list ap; 204 205 va_start(ap, fmt); 206 207 if (context->data_mode == FILEMODE) { 208 (void) vprintf(fmt, ap); 209 va_end(ap); 210 return (0); 211 } 212 /* Buffer-based output processing otherwise... */ 213 214 if (context->outbuf_remain_len < 2) { 215 /* no space at all left */ 216 va_end(ap); 217 errno = ENOSPC; 218 return (-1); 219 } 220 221 /* Attempt to tack on this string */ 222 addlen = vsnprintf(context->outbuf_p, context->outbuf_remain_len - 1, 223 fmt, ap); 224 va_end(ap); 225 if (addlen < 0) { 226 /* output error */ 227 errno = EPERM; 228 return (-1); 229 } 230 if (addlen >= context->outbuf_remain_len - 1) { 231 /* not enough space; bail out */ 232 errno = ENOSPC; 233 return (-1); 234 } 235 236 /* 237 * vsnprintf was successful; update pointers and counters 238 * as needed. If no bytes were written, treat it as a no-op 239 * and don't need to update anything. 240 */ 241 if (addlen >= 1) { 242 context->outbuf_remain_len -= addlen; 243 context->outbuf_p += addlen; 244 } 245 246 return (0); 247 } 248 249 250 /* 251 * pr_input_remaining - Check whether size bytes (or more) are remaining in 252 * the inbuf. 253 * returns 1 - there are enough bytes remaining 254 * 0 - not enough bytes left 255 */ 256 int 257 pr_input_remaining(pr_context_t *context, size_t size) 258 { 259 adr_t *adr = context->audit_adr; 260 261 /* no-op if not doing buf mode */ 262 if (context->data_mode != BUFMODE) 263 return (1); 264 265 if ((adr_count(adr) + size) > context->inbuf_totalsize) 266 return (0); 267 else 268 return (1); 269 } 270