xref: /onnv-gate/usr/src/lib/libadt_jni/common/adt_jni.c (revision 0:68f95e015346)
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