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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * adt_jni.c 23 * 24 * JNI wrapper for adt interface within libbsm 25 * 26 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 * 29 */ 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <bsm/adt.h> 33 #include "adt_jni.h" 34 #include <jni.h> 35 #include "../com/sun/audit/AuditSession.h" /* javah output */ 36 #include <assert.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <netdb.h> 40 41 /* 42 * local_throw -- throw an exception. 43 * "why" string must be i18n'd before calling here. 44 * 45 */ 46 47 void 48 local_throw(JNIEnv *env, const char *exception, const char *why) { 49 jobject jexception; 50 jclass exceptionclass; 51 jmethodID jexceptionnew; 52 53 jbyteArray jbarray; 54 55 jstring jmsg; 56 jclass strclass; 57 jmethodID jstrnew; 58 59 /* Get a String class and "new" method */ 60 strclass = (*env)->FindClass(env, "java/lang/String"); 61 jstrnew = (*env)->GetMethodID(env, strclass, "<init>", "([B)V"); 62 63 /* Create a Byte Array from message "why" */ 64 jbarray = (*env)->NewByteArray(env, (jsize)(strlen(why))); 65 (*env)->SetByteArrayRegion(env, jbarray, (jsize)0, 66 (jsize)(strlen(why)), (jbyte*) why); 67 68 /* Create string from byte array */ 69 jmsg = (*env)->NewObject(env, strclass, jstrnew, jbarray); 70 exceptionclass = (*env)->FindClass(env, exception); 71 jexceptionnew = (*env)->GetMethodID(env, exceptionclass, 72 "<init>", "(Ljava/lang/String;)V"); 73 74 jexception = (*env)->NewObject(env, exceptionclass, jexceptionnew, 75 jmsg); 76 (*env)->Throw(env, jexception); 77 } 78 79 /* 80 * i18n the strerror return. Input is errno. 81 * 82 */ 83 84 static char * 85 errno_to_i18n(int error_code) { 86 char *locale; 87 char *local_text; 88 89 locale = I18N_SETUP; 90 local_text = strerror(error_code); 91 (void) setlocale(LC_MESSAGES, locale); 92 return (local_text); 93 } 94 95 /* 96 * j2c_pointer 97 * 98 * convert java byte array into a C pointer 99 */ 100 int 101 j2c_pointer(JNIEnv *env, jbyteArray jpointer, caddr_t *cpointer) { 102 union { 103 caddr_t ptr; 104 jbyte buf[sizeof (uint64_t)]; 105 } u; 106 size_t jpointer_length; 107 char *locale; 108 109 (void) memset(u.buf, 0, sizeof (uint64_t)); 110 111 assert(jpointer != NULL); 112 113 jpointer_length = (*env)->GetArrayLength(env, jpointer); 114 if (jpointer_length != sizeof (uint64_t)) { 115 locale = I18N_SETUP; 116 local_throw(env, "java/lang/Error", 117 gettext("Bad session handle")); 118 (void) setlocale(LC_MESSAGES, locale); 119 return (-1); 120 } 121 (*env)->GetByteArrayRegion(env, jpointer, 0, jpointer_length, 122 &(u.buf[0])); 123 *cpointer = (caddr_t)u.ptr; 124 125 return (0); 126 } 127 128 /* 129 * c2j_pointer 130 * 131 * convert a C pointer into a java byte array 132 */ 133 void 134 c2j_pointer(JNIEnv *env, caddr_t cpointer, jbyteArray *jpointer) { 135 union { 136 caddr_t ptr; 137 jbyte buf[sizeof (uint64_t)]; 138 } u; 139 140 (void) memset(u.buf, 0, sizeof (uint64_t)); 141 u.ptr = cpointer; 142 143 *jpointer = (*env)->NewByteArray(env, sizeof (uint64_t)); 144 145 (*env)->SetByteArrayRegion(env, *jpointer, 0, sizeof (uint64_t), 146 &(u.buf[0])); 147 } 148 149 /* 150 * adt_start_session wrapper 151 * 152 */ 153 /*ARGSUSED*/ 154 JNIEXPORT jbyteArray JNICALL 155 Java_com_sun_audit_AuditSession_startSession(JNIEnv *env, jobject cls, 156 jbyteArray jimport, jlong flags) { 157 jbyteArray jstate; 158 adt_session_data_t *state; 159 jbyte *import; 160 size_t import_size; 161 int rc; 162 163 if (jimport == NULL) { 164 import = NULL; 165 } else { 166 import_size = (*env)->GetArrayLength(env, jimport); 167 import = (jbyte *)malloc(import_size * sizeof (jbyte)); 168 if (import == NULL) { 169 local_throw(env, "java/lang/Error", 170 errno_to_i18n(errno)); 171 return (NULL); 172 } 173 (*env)->GetByteArrayRegion(env, jimport, 0, import_size, 174 import); 175 } 176 rc = adt_start_session(&state, (adt_export_data_t *)import, flags); 177 178 if (import != NULL) 179 free(import); 180 181 if (rc) { 182 local_throw(env, "java/lang/Error", errno_to_i18n(errno)); 183 return (NULL); 184 } 185 c2j_pointer(env, (caddr_t)state, &jstate); 186 187 return (jstate); 188 } 189 190 /* 191 * adt_end_session wrapper 192 */ 193 194 /* ARGSUSED */ 195 JNIEXPORT void JNICALL 196 Java_com_sun_audit_AuditSession_endSession(JNIEnv *env, jobject cls, 197 jbyteArray jstate) { 198 adt_session_data_t *state; 199 char *locale; 200 201 if (j2c_pointer(env, jstate, (caddr_t *)&state)) 202 return; 203 204 if (state == NULL) 205 return; /* invalid session, nothing to free */ 206 207 /* presently, no errors defined, but what the heck? */ 208 if (adt_end_session(state)) { 209 locale = I18N_SETUP; 210 local_throw(env, "java/lang/Error", 211 gettext("Bad session handle")); 212 (void) setlocale(LC_MESSAGES, locale); 213 } 214 } 215 216 /* 217 * adt_dup_session wrapper 218 */ 219 220 /* ARGSUSED */ 221 JNIEXPORT jbyteArray JNICALL 222 Java_com_sun_audit_AuditSession_dupSession(JNIEnv *env, jobject cls, 223 jbyteArray jsource) { 224 jbyteArray jdest; 225 adt_session_data_t *source, *dest; 226 char *locale; 227 228 if (j2c_pointer(env, jsource, (caddr_t *)&source)) 229 return (NULL); 230 231 if (adt_dup_session(source, &dest)) { 232 locale = I18N_SETUP; 233 local_throw(env, "java/lang/Error", 234 gettext("Out of memory")); 235 (void) setlocale(LC_MESSAGES, locale); 236 } 237 238 c2j_pointer(env, (caddr_t)dest, &jdest); 239 240 return (jdest); 241 } 242 243 /* 244 * adt_get_session_id wrapper 245 * 246 */ 247 248 /* ARGSUSED */ 249 JNIEXPORT jstring JNICALL 250 Java_com_sun_audit_AuditSession_getSessionId(JNIEnv *env, jobject cls, 251 jbyteArray jstate) { 252 adt_session_data_t *state; 253 char *session_id; 254 jstring return_val; 255 256 if (j2c_pointer(env, jstate, (caddr_t *)&state)) 257 return (NULL); 258 259 if (adt_get_session_id(state, &session_id)) { 260 return_val = (*env)->NewStringUTF(env, session_id); 261 free(session_id); 262 return (return_val); 263 } else 264 return (NULL); 265 } 266 267 /* 268 * adt_get_session_id wrapper 269 */ 270 271 /* ARGSUSED */ 272 JNIEXPORT jbyteArray JNICALL 273 Java_com_sun_audit_AuditSession_exportSessionData 274 (JNIEnv *env, jobject cls, jbyteArray jstate) { 275 adt_session_data_t *state; 276 size_t length; 277 jbyte *buffer; 278 jbyteArray jbuf; 279 280 if (j2c_pointer(env, jstate, (caddr_t *)&state)) 281 return (NULL); 282 283 length = adt_export_session_data(state, (adt_export_data_t **)&buffer); 284 285 if ((jbuf = (*env)->NewByteArray(env, length)) == NULL) { 286 free(buffer); 287 return (NULL); 288 } 289 (*env)->SetByteArrayRegion(env, jbuf, 0, length, buffer); 290 free(buffer); 291 292 return (jbuf); 293 } 294 295 /* ARGSUSED */ 296 JNIEXPORT void JNICALL 297 Java_com_sun_audit_AuditSession_sessionAttr(JNIEnv *env, jobject cls, 298 jbyteArray jstate, 299 jint euid, jint egid, jint ruid, jint rgid, 300 jstring jhostname, jint context) { 301 adt_session_data_t *state; 302 const char *hostname; 303 adt_termid_t *termid; 304 305 if (j2c_pointer(env, jstate, (caddr_t *)&state)) 306 return; /* j2c_pointer threw exception */ 307 308 if (state == NULL) 309 return; /* invalid session */ 310 311 hostname = (*env)->GetStringUTFChars(env, jhostname, NULL); 312 313 if (adt_load_hostname(hostname, &termid)) { 314 local_throw(env, "java/lang/Error", errno_to_i18n(errno)); 315 } else if (adt_set_user(state, euid, egid, ruid, rgid, termid, 316 context)) { 317 free(termid); 318 local_throw(env, "java/lang/Error", errno_to_i18n(errno)); 319 } 320 (*env)->ReleaseStringUTFChars(env, jhostname, hostname); 321 free(termid); 322 } 323 324 /* ARGSUSED */ 325 JNIEXPORT jboolean JNICALL 326 Java_com_sun_audit_AuditSession_bsmAuditOn(JNIEnv *env, jobject cls) { 327 int condition; 328 329 if (auditon(A_GETCOND, (caddr_t)&condition, sizeof (condition))) 330 return (0); 331 332 return (1); 333 } 334