AuditSession.java revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* ident "%Z%%M% %I% %E% SMI"
*/
package com.sun.audit;
import java.util.Stack;
import java.io.Serializable;
public class AuditSession implements Serializable
{
// LD_LIBRARY_PATH determines directory for libadt_jni.so.
// When you get an UnsatisfiedLinkError, and have determined
// the path is right, the problem is probably in the library
// itself, but Java doesn't say what it is. Set up a cc
// command to link the library to see what the actual error
// is.
static private boolean library_loaded = false;
static {
try {
System.loadLibrary("adt_jni");
library_loaded = true;
} catch (Exception ex) {
library_loaded = false;
} catch (java.lang.UnsatisfiedLinkError ul) {
library_loaded = false;
}
}
private native boolean bsmAuditOn();
private native byte[] startSession(
byte[] context, long flags)
throws Error;
private native byte[] dupSession(
byte[] source)
throws Error;
private native void endSession(byte[] sessionHandle)
throws Error;
private native String getSessionId(byte[] sessionHandle)
throws Error;
private native byte[] exportSessionData(byte[] sessionHandle)
throws Error;
private native void sessionAttr(byte[] sessionHandle,
int euid, int egid, int ruid, int rgid,
String hostname, int context)
throws Error;
//TSOL only
// private native void setSL(byte[] sessionHandle, String label);
//end TSOL
private byte[] sh; // current session handle
private Stack stateStack = new Stack(); // for push/pop
boolean AuditIsOn = true; // Underlying BSM state
boolean ValidSession = true; // Session object state
// Create an audit session.
// The fixed length of 8 corresponds to a 64 bit pointer;
// valid overkill on 32 bit systems.
// Even if bsmAuditOn returns false, need to create a session.
public AuditSession(byte[] context) {
if (!library_loaded) {
ValidSession = false;
AuditIsOn = false;
sh = new byte[8]; // NULL pointer in C
return;
}
AuditIsOn = bsmAuditOn();
try {
sh = startSession(context, 0);
}
catch (java.lang.Exception e) {
ValidSession = false;
sh = new byte[8];
}
catch (java.lang.Error e) {
ValidSession = false;
sh = new byte[8];
throw e;
}
}
// getSession() is for use by AuditEvent, not much use to caller of
// AuditSession "package protected" == not public
//
// If you think you need this C pointer (sh), see
// exportSession() and the "context" parameter to
// startSession() for a way to pass an audit thread from one
// process to another or from one language to another.
byte[] getSession() {
return sh;
}
public String getSessionId() throws Exception {
String sessionId;
if (ValidSession) {
try {
sessionId = getSessionId(sh);
}
catch (Exception e) {
sessionId = null;
throw e;
}
catch (Error e) {
sessionId = null;
throw e;
}
} else {
sessionId = null;
}
return sessionId;
}
// auditOn: The return value does not reveal whether or
// auditing is on, but whether or not the current audit
// session was created ok.
public boolean auditOn() {
return (ValidSession);
}
public void finalize() {
byte[] state;
while (!stateStack.empty()) {
state = (byte[])stateStack.pop();
endSession(state);
}
endSession(sh);
}
// Returns export data even if auditing is off. If the
// session is invalid (no jni library, memory error in
// startSession), returns null.
//
// If you use exportSession(), it is important that you first
// call setUser() even when auditOn() returns false; otherwise
// the exported session will result in remote processes being
// unable to generate an valid audit trail.
public byte[] exportSession() throws Exception {
byte[] exportedData;
if (ValidSession) {
try {
exportedData = exportSessionData(sh);
}
catch (java.lang.Exception e) {
throw e;
}
} else {
exportedData = null;
}
return exportedData;
}
// ADT_NEW, ADT_UPDATE and ADT_USER are the only valid values
// for the context input to setUser(). If the user has
// completed initial authentication, use ADT_NEW; if the user
// is to change ids, such as to a role or to root, use
// ADT_UPDATE. If the process audit context is already set,
// use ADT_USER.
// If a uid or gid is unknown (e.g., unrecognized login id)
// then use ADT_NO_ATTRIB for the uid/gid.
//
// For ADT_UPDATE only, use ADT_NO_CHANGE for any uid or gid
// that you don't wish to change.
public static final int ADT_NEW = 0;
public static final int ADT_UPDATE = 1;
public static final int ADT_USER = 2;
public static final int ADT_NO_ATTRIB = -1;
public static final int ADT_NO_CHANGE = -2;
public void setUser(int euid, int egid, int ruid, int rgid,
String hostname, int context) {
if (ValidSession) {
try {
sessionAttr(sh, euid, egid, ruid, rgid,
hostname, context);
}
catch (java.lang.Error e) {
throw e;
}
}
}
// pushState duplicates the session handle, puts the source
// handle on a stack, and makes the duplicate the current
// handle dupSession throws an out of memory error to be
// caught higher up.
public void pushState() throws Exception {
byte[] copy;
int i;
copy = dupSession(sh);
stateStack.push(sh);
sh = copy;
}
// popState frees the current handle and pops a handle off a
// stack to become the new current handle.
// As with pushState, it lets the caller deal with any exceptions.
public void popState() throws Exception {
endSession(sh);
sh = (byte[])stateStack.pop();
}
//TSOL -- stub for base Solaris; should be called even if auditOn is
//false.
public void setLabel(String label) throws Exception {
// if (ValidSession)
// setSL(sh, label);
}
//end TSOL
}