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