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 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * ident "%Z%%M% %I% %E% SMI" 27 */ 28 package com.sun.audit; 29 30 import java.util.Stack; 31 import java.io.Serializable; 32 33 public class AuditSession implements Serializable 34 { 35 // LD_LIBRARY_PATH determines directory for libadt_jni.so. 36 // When you get an UnsatisfiedLinkError, and have determined 37 // the path is right, the problem is probably in the library 38 // itself, but Java doesn't say what it is. Set up a cc 39 // command to link the library to see what the actual error 40 // is. 41 42 static private boolean library_loaded = false; 43 static { 44 try { 45 System.loadLibrary("adt_jni"); 46 library_loaded = true; 47 } catch (Exception ex) { 48 library_loaded = false; 49 } catch (java.lang.UnsatisfiedLinkError ul) { 50 library_loaded = false; 51 } 52 } 53 private native boolean bsmAuditOn(); 54 private native byte[] startSession( 55 byte[] context, long flags) 56 throws Error; 57 private native byte[] dupSession( 58 byte[] source) 59 throws Error; 60 private native void endSession(byte[] sessionHandle) 61 throws Error; 62 private native String getSessionId(byte[] sessionHandle) 63 throws Error; 64 private native byte[] exportSessionData(byte[] sessionHandle) 65 throws Error; 66 private native void sessionAttr(byte[] sessionHandle, 67 int euid, int egid, int ruid, int rgid, 68 String hostname, int context) 69 throws Error; 70 //TSOL only 71 // private native void setSL(byte[] sessionHandle, String label); 72 //end TSOL 73 74 private byte[] sh; // current session handle 75 76 private Stack stateStack = new Stack(); // for push/pop 77 78 boolean AuditIsOn = true; // Underlying BSM state 79 boolean ValidSession = true; // Session object state 80 81 // Create an audit session. 82 // The fixed length of 8 corresponds to a 64 bit pointer; 83 // valid overkill on 32 bit systems. 84 // Even if bsmAuditOn returns false, need to create a session. 85 86 public AuditSession(byte[] context) { 87 88 if (!library_loaded) { 89 ValidSession = false; 90 AuditIsOn = false; 91 sh = new byte[8]; // NULL pointer in C 92 return; 93 } 94 AuditIsOn = bsmAuditOn(); 95 try { 96 sh = startSession(context, 0); 97 } 98 catch (java.lang.Exception e) { 99 ValidSession = false; 100 sh = new byte[8]; 101 } 102 catch (java.lang.Error e) { 103 ValidSession = false; 104 sh = new byte[8]; 105 throw e; 106 } 107 } 108 109 // getSession() is for use by AuditEvent, not much use to caller of 110 // AuditSession "package protected" == not public 111 // 112 // If you think you need this C pointer (sh), see 113 // exportSession() and the "context" parameter to 114 // startSession() for a way to pass an audit thread from one 115 // process to another or from one language to another. 116 117 byte[] getSession() { 118 return sh; 119 } 120 121 public String getSessionId() throws Exception { 122 String sessionId; 123 124 if (ValidSession) { 125 try { 126 sessionId = getSessionId(sh); 127 } 128 catch (Exception e) { 129 sessionId = null; 130 throw e; 131 } 132 catch (Error e) { 133 sessionId = null; 134 throw e; 135 } 136 } else { 137 sessionId = null; 138 } 139 return sessionId; 140 } 141 142 // auditOn: The return value does not reveal whether or 143 // auditing is on, but whether or not the current audit 144 // session was created ok. 145 146 public boolean auditOn() { 147 return (ValidSession); 148 } 149 150 public void finalize() { 151 byte[] state; 152 153 while (!stateStack.empty()) { 154 state = (byte[])stateStack.pop(); 155 endSession(state); 156 } 157 endSession(sh); 158 } 159 160 // Returns export data even if auditing is off. If the 161 // session is invalid (no jni library, memory error in 162 // startSession), returns null. 163 // 164 // If you use exportSession(), it is important that you first 165 // call setUser() even when auditOn() returns false; otherwise 166 // the exported session will result in remote processes being 167 // unable to generate an valid audit trail. 168 169 public byte[] exportSession() throws Exception { 170 byte[] exportedData; 171 172 if (ValidSession) { 173 try { 174 exportedData = exportSessionData(sh); 175 } 176 catch (java.lang.Exception e) { 177 throw e; 178 } 179 } else { 180 exportedData = null; 181 } 182 return exportedData; 183 } 184 185 // ADT_NEW, ADT_UPDATE and ADT_USER are the only valid values 186 // for the context input to setUser(). If the user has 187 // completed initial authentication, use ADT_NEW; if the user 188 // is to change ids, such as to a role or to root, use 189 // ADT_UPDATE. If the process audit context is already set, 190 // use ADT_USER. 191 192 // If a uid or gid is unknown (e.g., unrecognized login id) 193 // then use ADT_NO_ATTRIB for the uid/gid. 194 // 195 // For ADT_UPDATE only, use ADT_NO_CHANGE for any uid or gid 196 // that you don't wish to change. 197 198 public static final int ADT_NEW = 0; 199 public static final int ADT_UPDATE = 1; 200 public static final int ADT_USER = 2; 201 public static final int ADT_NO_ATTRIB = -1; 202 public static final int ADT_NO_CHANGE = -2; 203 204 public void setUser(int euid, int egid, int ruid, int rgid, 205 String hostname, int context) { 206 207 if (ValidSession) { 208 try { 209 sessionAttr(sh, euid, egid, ruid, rgid, 210 hostname, context); 211 } 212 catch (java.lang.Error e) { 213 throw e; 214 } 215 } 216 } 217 218 // pushState duplicates the session handle, puts the source 219 // handle on a stack, and makes the duplicate the current 220 // handle dupSession throws an out of memory error to be 221 // caught higher up. 222 223 public void pushState() throws Exception { 224 byte[] copy; 225 int i; 226 227 copy = dupSession(sh); 228 stateStack.push(sh); 229 sh = copy; 230 } 231 232 // popState frees the current handle and pops a handle off a 233 // stack to become the new current handle. 234 // As with pushState, it lets the caller deal with any exceptions. 235 236 public void popState() throws Exception { 237 238 endSession(sh); 239 sh = (byte[])stateStack.pop(); 240 } 241 //TSOL -- stub for base Solaris; should be called even if auditOn is 242 //false. 243 public void setLabel(String label) throws Exception { 244 // if (ValidSession) 245 // setSL(sh, label); 246 } 247 //end TSOL 248 } 249