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