2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <sys/audit.h>
19 #endif /* AFS_AIX32_ENV */
22 #include "afs/afsint.h"
28 #include <sys/audit.h>
30 #include <afs/afsutil.h>
34 int osi_audit_all = (-1); /* Not determined yet */
35 int osi_echo_trail = (-1);
37 #ifdef AFS_AIX_ENV /** all these functions are only defined for AIX */
41 * These variadic functions work under AIX, and not all systems (osf1)
43 /* ************************************************************************** */
44 /* AIX requires a buffer filled with values to record with each audit event.
45 * aixmakebuf creates that buffer from the variable list of values we are given.
46 * ************************************************************************** */
47 static aixmakebuf (audEvent, vaList)
60 vaEntry = va_arg(vaList, int);
61 while ( vaEntry != AUD_END )
65 case AUD_STR : /* String */
66 vaStr = (char *) va_arg(vaList, int);
69 strcpy (bufferPtr, vaStr);
70 bufferPtr += strlen(vaStr) + 1;
74 strcpy (bufferPtr, "");
78 case AUD_INT : /* Integer */
79 vaInt = va_arg(vaList, int);
80 *(int *)bufferPtr = vaInt;
81 bufferPtr += sizeof(vaInt);
83 case AUD_DATE : /* Date */
84 case AUD_HOST : /* Host ID */
85 case AUD_LONG : /* long */
86 vaLong = va_arg(vaList, afs_int32);
87 *(afs_int32 *)bufferPtr = vaLong;
88 bufferPtr += sizeof(vaLong);
90 case AUD_LST : /* Ptr to another list */
91 vaLst = (char *) va_arg(vaList, int);
92 aixmakebuf(audEvent, vaLst);
94 case AUD_FID : /* AFSFid - contains 3 entries */
95 vaFid = (struct AFSFid *) va_arg(vaList, int);
97 memcpy(bufferPtr, vaFid, sizeof(struct AFSFid));
100 memset(bufferPtr, 0, sizeof(struct AFSFid));
102 bufferPtr += sizeof(struct AFSFid);
105 /* Whole array of fids-- don't know how to handle variable length audit
106 * data with AIX audit package, so for now we just store the first fid.
107 * Better one than none. */
110 struct AFSCBFids *Fids;
112 Fids = (struct AFSCBFids *) va_arg(vaList, int);
113 if (Fids && Fids->AFSCBFids_len) {
114 *((u_int *)bufferPtr) = Fids->AFSCBFids_len;
115 bufferPtr += sizeof(u_int);
116 memcpy(bufferPtr, Fids->AFSCBFids_val, sizeof(struct AFSFid));
120 *((u_int *)bufferPtr) = 0;
121 bufferPtr += sizeof(u_int);
122 memset(bufferPtr, 0, sizeof(struct AFSFid));
124 bufferPtr += sizeof(struct AFSFid);
129 code = auditlog("AFS_Aud_EINVAL", (-1), audEvent, (strlen(audEvent)+1));
135 vaEntry = va_arg(vaList, int);
139 static printbuf (audEvent, errCode, vaList)
150 struct AFSFid *vaFid;
151 struct AFSCBFids *vaFids;
153 if ( osi_echo_trail < 0 ) osi_audit_check();
154 if ( ! osi_echo_trail ) return;
156 if ( strcmp(audEvent,"VALST") != 0 )
157 printf ("%s %d ", audEvent, errCode);
159 vaEntry = va_arg(vaList, int);
160 while ( vaEntry != AUD_END )
164 case AUD_STR : /* String */
165 vaStr = (char *) va_arg(vaList, int);
166 if ( vaStr ) printf("%s ", vaStr);
167 else printf("<null>", vaStr);
169 case AUD_INT : /* Integer */
170 vaInt = va_arg(vaList, int);
171 printf("%d ", vaInt);
173 case AUD_DATE : /* Date */
174 case AUD_HOST : /* Host ID */
175 vaLong = va_arg(vaList, afs_int32);
176 printf("%u ", vaLong);
178 case AUD_LONG : /* afs_int32 */
179 vaLong = va_arg(vaList, afs_int32);
180 printf("%d ", vaLong);
182 case AUD_LST : /* Ptr to another list */
183 vaLst = (char *) va_arg(vaList, int);
184 printbuf("VALST", 0, vaLst);
186 case AUD_FID : /* AFSFid - contains 3 entries */
187 vaFid = (struct AFSFid *) va_arg(vaList, int);
188 if (vaFid) printf ("%u:%u:%u ", vaFid->Volume, vaFid->Vnode, vaFid->Unique);
189 else printf ("%u:%u:%u ", 0, 0, 0);
191 case AUD_FIDS : /* array of Fids */
192 vaFids = (struct AFSCBFids *) va_arg(vaList, int);
196 vaFid = vaFids->AFSCBFids_val;
198 printf ("%u %u:%u:%u ", vaFids->AFSCBFids_len, vaFid->Volume,
199 vaFid->Vnode, vaFid->Unique);
200 else printf ("0 0:0:0 ");
203 printf ("--badval-- ");
206 vaEntry = va_arg(vaList, int);
209 if ( strcmp(audEvent,"VALST") != 0 )
213 static aixmakebuf (audEvent, vaList)
220 static printbuf (audEvent, errCode, vaList)
231 /* ************************************************************************** */
232 /* The routine that acually does the audit call.
233 * ************************************************************************** */
234 int osi_audit (char *audEvent, /* Event name (15 chars or less) */
235 afs_int32 errCode, /* The error code */
244 static struct Lock audbuflock = {0,0,0,0,
245 #ifdef AFS_PTHREAD_ENV
246 PTHREAD_MUTEX_INITIALIZER,
247 PTHREAD_COND_INITIALIZER,
248 PTHREAD_COND_INITIALIZER
249 #endif /* AFS_PTHREAD_ENV */
251 static char BUFFER[32768];
253 if ( osi_audit_all < 0 ) osi_audit_check();
254 if ( ! osi_audit_all ) return;
261 case KANOAUTH : /* kautils.h */
262 case RXKADNOAUTH : /* rxkad.h */
263 result = AUDIT_FAIL_AUTH;
265 case EPERM : /* errno.h */
266 case EACCES : /* errno.h */
267 case PRPERM : /* pterror.h */
268 result = AUDIT_FAIL_ACCESS;
270 case VL_PERM : /* vlserver.h */
271 case BUDB_NOTPERMITTED : /* budb_errs.h */
272 /* case KRB_RD_AP_UNAUTHOR : */
273 case BZACCESS : /* bnode.h */
274 case VOLSERBAD_ACCESS : /* volser.h */
275 result = AUDIT_FAIL_PRIV;
282 ObtainWriteLock(&audbuflock);
285 /* Put the error code into the buffer list */
286 *(int *)bufferPtr = errCode;
287 bufferPtr += sizeof(errCode);
289 va_start(vaList, errCode);
290 aixmakebuf(audEvent, vaList);
292 va_start(vaList, errCode);
293 printbuf(audEvent, errCode, vaList);
295 bufferLen = (int)((afs_int32)bufferPtr - (afs_int32)&BUFFER[0]);
296 code = auditlog (audEvent, result, BUFFER, bufferLen);
301 code = auditlog ("AFS_Aud_Fail", result, &err, sizeof(err));
303 printf("Error while writing audit entry: %d.\n", errno);
306 ReleaseWriteLock(&audbuflock);
310 /* ************************************************************************** */
311 /* Given a RPC call structure, this routine extracts the name and host id from the
312 * call and includes it within the audit information.
313 * ************************************************************************** */
314 int osi_auditU (struct rx_call *call,
319 struct rx_connection *conn;
320 struct rx_peer *peer;
323 char afsName[MAXKTCNAMELEN];
328 if ( osi_audit_all < 0 ) osi_audit_check();
329 if ( !osi_audit_all ) return;
331 strcpy (afsName, "--Unknown--");
336 conn = rx_ConnectionOf(call); /* call -> conn) */
339 secClass = rx_SecurityClassOf(conn); /* conn -> securityIndex */
340 if (secClass == 0) /* unauthenticated */
342 osi_audit ("AFS_Aud_Unauth", (-1), AUD_STR, audEvent, AUD_END);
343 strcpy (afsName, "--UnAuth--");
345 else if (secClass == 2) /* authenticated */
347 code = rxkad_GetServerInfo(conn, NULL, NULL, afsName,
351 osi_audit ("AFS_Aud_NoAFSId", (-1), AUD_STR, audEvent, AUD_END);
352 strcpy (afsName, "--NoName--");
355 else /* Unauthenticated & unknown */
357 osi_audit ("AFS_Aud_UnknSec", (-1), AUD_STR, audEvent, AUD_END);
360 peer = rx_PeerOf(conn); /* conn -> peer */
362 hostId = rx_HostOf(peer); /* peer -> host */
364 osi_audit ("AFS_Aud_NoHost", (-1), AUD_STR, audEvent, AUD_END);
368 osi_audit ("AFS_Aud_NoConn", (-1), AUD_STR, audEvent, AUD_END);
373 osi_audit ("AFS_Aud_NoCall", (-1), AUD_STR, audEvent, AUD_END);
376 va_start(vaList, errCode);
377 osi_audit (audEvent, errCode, AUD_STR, afsName,
383 /* ************************************************************************** */
384 /* Determines whether auditing is on or off by looking at the Audit file.
385 * If the string AFS_AUDIT_AllEvents is defined in the file, then auditing will be
387 * ************************************************************************** */
389 int osi_audit_check ()
395 osi_audit_all = 1; /* say we made check (>= 0) */
396 /* and assume audit all events (for now) */
397 onoff = 0; /* assume we will turn auditing off */
398 osi_echo_trail = 0; /* assume no echoing */
400 fds = fopen(AFSDIR_SERVER_AUDIT_FILEPATH, "r");
403 while ( fscanf(fds, "%256s", event) > 0)
405 if ( strcmp(event,"AFS_AUDIT_AllEvents") == 0 )
408 if ( strcmp(event,"Echo_Trail") == 0 )
414 /* Audit this event all of the time */
415 if (onoff) osi_audit("AFS_Aud_On", 0, AUD_END);
416 else osi_audit("AFS_Aud_Off", 0, AUD_END);
418 /* Now set whether we audit all events from here on out */
419 osi_audit_all = onoff;
423 #else /* ! AFS_AIX_ENV */
425 int osi_audit (char *audEvent, afs_int32 errCode, ...)
428 int osi_auditU (struct rx_call *call, char *audEvent, int errCode, ...)