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 #include <stdio.h> 28 #include <sys/types.h> 29 #include <sys/varargs.h> 30 #include <bsm/audit.h> 31 #include <bsm/libbsm.h> 32 #include <bsm/audit_record.h> 33 34 #include "praudit.h" 35 36 37 /* 38 * pr_adr_char - pull out characters 39 */ 40 int 41 pr_adr_char(pr_context_t *context, char *cp, int count) 42 { 43 int err; 44 adr_t *adr = context->audit_adr; 45 adrf_t *adrf = context->audit_adrf; 46 47 if (context->data_mode == FILEMODE) { 48 err = adrf_char(adrf, cp, count); 49 if (err) { 50 errno = EIO; 51 return (-1); 52 } else 53 return (0); 54 } 55 56 /* adrm routines don't return error, so check before calling */ 57 if (!pr_input_remaining(context, (sizeof (char) * count))) { 58 errno = EIO; 59 return (-1); 60 } 61 62 adrm_char(adr, cp, count); 63 return (0); 64 } 65 66 /* 67 * pr_adr_short - pull out shorts 68 */ 69 int 70 pr_adr_short(pr_context_t *context, short *sp, int count) 71 { 72 int err; 73 adr_t *adr = context->audit_adr; 74 adrf_t *adrf = context->audit_adrf; 75 76 if (context->data_mode == FILEMODE) { 77 err = adrf_short(adrf, sp, count); 78 if (err) { 79 errno = EIO; 80 return (-1); 81 } else 82 return (0); 83 } 84 85 /* adrm routines don't return error, so check before calling */ 86 if (!pr_input_remaining(context, (sizeof (short) * count))) { 87 errno = EIO; 88 return (-1); 89 } 90 91 adrm_short(adr, sp, count); 92 return (0); 93 } 94 95 /* 96 * pr_adr_int32 - pull out int32 97 */ 98 int 99 pr_adr_int32(pr_context_t *context, int32_t *lp, int count) 100 { 101 int err; 102 adr_t *adr = context->audit_adr; 103 adrf_t *adrf = context->audit_adrf; 104 105 if (context->data_mode == FILEMODE) { 106 err = adrf_int32(adrf, lp, count); 107 if (err) { 108 errno = EIO; 109 return (-1); 110 } else 111 return (0); 112 } 113 114 /* adrm routines don't return error, so check before calling */ 115 if (!pr_input_remaining(context, (sizeof (int32_t) * count))) { 116 errno = EIO; 117 return (-1); 118 } 119 120 adrm_int32(adr, lp, count); 121 return (0); 122 } 123 124 int 125 pr_adr_int64(pr_context_t *context, int64_t *lp, int count) 126 { 127 int err; 128 adr_t *adr = context->audit_adr; 129 adrf_t *adrf = context->audit_adrf; 130 131 if (context->data_mode == FILEMODE) { 132 err = adrf_int64(adrf, lp, count); 133 if (err) { 134 errno = EIO; 135 return (-1); 136 } else 137 return (0); 138 } 139 140 /* adrm routines don't return error, so check before calling */ 141 if (!pr_input_remaining(context, (sizeof (int64_t) * count))) { 142 errno = EIO; 143 return (-1); 144 } 145 146 adrm_int64(adr, lp, count); 147 return (0); 148 } 149 150 int 151 pr_adr_u_int32(pr_context_t *context, uint32_t *cp, int count) 152 { 153 return (pr_adr_int32(context, (int32_t *)cp, count)); 154 } 155 156 int 157 pr_adr_u_char(pr_context_t *context, uchar_t *cp, int count) 158 { 159 return (pr_adr_char(context, (char *)cp, count)); 160 } 161 162 int 163 pr_adr_u_int64(pr_context_t *context, uint64_t *lp, int count) 164 { 165 return (pr_adr_int64(context, (int64_t *)lp, count)); 166 } 167 168 int 169 pr_adr_u_short(pr_context_t *context, ushort_t *sp, int count) 170 { 171 return (pr_adr_short(context, (short *)sp, count)); 172 } 173 174 int 175 pr_putchar(pr_context_t *context, char c) 176 { 177 if (context->data_mode == FILEMODE) { 178 (void) putchar(c); 179 return (0); 180 } 181 /* Buffer-based output processing otherwise... */ 182 183 /* Need at least room for char + null-byte */ 184 if (context->outbuf_remain_len < 2) { 185 /* no space left */ 186 errno = ENOSPC; 187 return (-1); 188 } 189 190 *(context->outbuf_p) = c; 191 context->outbuf_p += 1; 192 context->outbuf_remain_len -= 1; 193 194 return (0); 195 } 196 197 int 198 pr_printf(pr_context_t *context, const char *fmt, ...) 199 { 200 int addlen; 201 va_list ap; 202 203 va_start(ap, fmt); 204 205 if (context->data_mode == FILEMODE) { 206 (void) vprintf(fmt, ap); 207 va_end(ap); 208 return (0); 209 } 210 /* Buffer-based output processing otherwise... */ 211 212 if (context->outbuf_remain_len < 2) { 213 /* no space at all left */ 214 va_end(ap); 215 errno = ENOSPC; 216 return (-1); 217 } 218 219 /* Attempt to tack on this string */ 220 addlen = vsnprintf(context->outbuf_p, context->outbuf_remain_len - 1, 221 fmt, ap); 222 va_end(ap); 223 if (addlen < 0) { 224 /* output error */ 225 errno = EPERM; 226 return (-1); 227 } 228 if (addlen >= context->outbuf_remain_len - 1) { 229 /* not enough space; bail out */ 230 errno = ENOSPC; 231 return (-1); 232 } 233 234 /* 235 * vsnprintf was successful; update pointers and counters 236 * as needed. If no bytes were written, treat it as a no-op 237 * and don't need to update anything. 238 */ 239 if (addlen >= 1) { 240 context->outbuf_remain_len -= addlen; 241 context->outbuf_p += addlen; 242 } 243 244 return (0); 245 } 246 247 248 /* 249 * pr_input_remaining - Check whether size bytes (or more) are remaining in 250 * the inbuf. 251 * returns 1 - there are enough bytes remaining 252 * 0 - not enough bytes left 253 */ 254 int 255 pr_input_remaining(pr_context_t *context, size_t size) 256 { 257 adr_t *adr = context->audit_adr; 258 259 /* no-op if not doing buf mode */ 260 if (context->data_mode != BUFMODE) 261 return (1); 262 263 if ((adr_count(adr) + size) > context->inbuf_totalsize) 264 return (0); 265 else 266 return (1); 267 } 268