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 <afs/param.h>
14 #include <sys/audit.h>
15 #endif /* AFS_AIX32_ENV */
18 #include "afs/afsint.h"
24 #include <sys/audit.h>
26 #include <afs/afsutil.h>
30 int osi_audit_all = (-1); /* Not determined yet */
31 int osi_echo_trail = (-1);
33 #ifdef AFS_AIX_ENV /** all these functions are only defined for AIX */
37 * These variadic functions work under AIX, and not all systems (osf1)
39 /* ************************************************************************** */
40 /* AIX requires a buffer filled with values to record with each audit event.
41 * aixmakebuf creates that buffer from the variable list of values we are given.
42 * ************************************************************************** */
43 static aixmakebuf (audEvent, vaList)
56 vaEntry = va_arg(vaList, int);
57 while ( vaEntry != AUD_END )
61 case AUD_STR : /* String */
62 vaStr = (char *) va_arg(vaList, int);
65 strcpy (bufferPtr, vaStr);
66 bufferPtr += strlen(vaStr) + 1;
70 strcpy (bufferPtr, "");
74 case AUD_INT : /* Integer */
75 vaInt = va_arg(vaList, int);
76 *(int *)bufferPtr = vaInt;
77 bufferPtr += sizeof(vaInt);
79 case AUD_DATE : /* Date */
80 case AUD_HOST : /* Host ID */
81 case AUD_LONG : /* long */
82 vaLong = va_arg(vaList, afs_int32);
83 *(afs_int32 *)bufferPtr = vaLong;
84 bufferPtr += sizeof(vaLong);
86 case AUD_LST : /* Ptr to another list */
87 vaLst = (char *) va_arg(vaList, int);
88 aixmakebuf(audEvent, vaLst);
90 case AUD_FID : /* AFSFid - contains 3 entries */
91 vaFid = (struct AFSFid *) va_arg(vaList, int);
93 bcopy(vaFid, bufferPtr, sizeof(struct AFSFid));
96 bzero (bufferPtr, sizeof(struct AFSFid));
98 bufferPtr += sizeof(struct AFSFid);
101 /* Whole array of fids-- don't know how to handle variable length audit
102 * data with AIX audit package, so for now we just store the first fid.
103 * Better one than none. */
106 struct AFSCBFids *Fids;
108 Fids = (struct AFSCBFids *) va_arg(vaList, int);
109 if (Fids && Fids->AFSCBFids_len) {
110 *((u_int *)bufferPtr) = Fids->AFSCBFids_len;
111 bufferPtr += sizeof(u_int);
112 bcopy(Fids->AFSCBFids_val, bufferPtr, sizeof(struct AFSFid));
116 *((u_int *)bufferPtr) = 0;
117 bufferPtr += sizeof(u_int);
118 bzero (bufferPtr, sizeof(struct AFSFid));
120 bufferPtr += sizeof(struct AFSFid);
125 code = auditlog("AFS_Aud_EINVAL", (-1), audEvent, (strlen(audEvent)+1));
131 vaEntry = va_arg(vaList, int);
135 static printbuf (audEvent, errCode, vaList)
146 struct AFSFid *vaFid;
147 struct AFSCBFids *vaFids;
149 if ( osi_echo_trail < 0 ) osi_audit_check();
150 if ( ! osi_echo_trail ) return;
152 if ( strcmp(audEvent,"VALST") != 0 )
153 printf ("%s %d ", audEvent, errCode);
155 vaEntry = va_arg(vaList, int);
156 while ( vaEntry != AUD_END )
160 case AUD_STR : /* String */
161 vaStr = (char *) va_arg(vaList, int);
162 if ( vaStr ) printf("%s ", vaStr);
163 else printf("<null>", vaStr);
165 case AUD_INT : /* Integer */
166 vaInt = va_arg(vaList, int);
167 printf("%d ", vaInt);
169 case AUD_DATE : /* Date */
170 case AUD_HOST : /* Host ID */
171 vaLong = va_arg(vaList, afs_int32);
172 printf("%u ", vaLong);
174 case AUD_LONG : /* afs_int32 */
175 vaLong = va_arg(vaList, afs_int32);
176 printf("%d ", vaLong);
178 case AUD_LST : /* Ptr to another list */
179 vaLst = (char *) va_arg(vaList, int);
180 printbuf("VALST", 0, vaLst);
182 case AUD_FID : /* AFSFid - contains 3 entries */
183 vaFid = (struct AFSFid *) va_arg(vaList, int);
184 if (vaFid) printf ("%u:%u:%u ", vaFid->Volume, vaFid->Vnode, vaFid->Unique);
185 else printf ("%u:%u:%u ", 0, 0, 0);
187 case AUD_FIDS : /* array of Fids */
188 vaFids = (struct AFSCBFids *) va_arg(vaList, int);
192 vaFid = vaFids->AFSCBFids_val;
194 printf ("%u %u:%u:%u ", vaFids->AFSCBFids_len, vaFid->Volume,
195 vaFid->Vnode, vaFid->Unique);
196 else printf ("0 0:0:0 ");
199 printf ("--badval-- ");
202 vaEntry = va_arg(vaList, int);
205 if ( strcmp(audEvent,"VALST") != 0 )
209 static aixmakebuf (audEvent, vaList)
216 static printbuf (audEvent, errCode, vaList)
227 /* ************************************************************************** */
228 /* The routine that acually does the audit call.
229 * ************************************************************************** */
230 int osi_audit (char *audEvent, /* Event name (15 chars or less) */
231 afs_int32 errCode, /* The error code */
240 static struct Lock audbuflock = {0,0,0,0,
241 #ifdef AFS_PTHREAD_ENV
242 PTHREAD_MUTEX_INITIALIZER,
243 PTHREAD_COND_INITIALIZER,
244 PTHREAD_COND_INITIALIZER
245 #endif /* AFS_PTHREAD_ENV */
247 static char BUFFER[32768];
249 if ( osi_audit_all < 0 ) osi_audit_check();
250 if ( ! osi_audit_all ) return;
257 case KANOAUTH : /* kautils.h */
258 case RXKADNOAUTH : /* rxkad.h */
259 result = AUDIT_FAIL_AUTH;
261 case EPERM : /* errno.h */
262 case EACCES : /* errno.h */
263 case PRPERM : /* pterror.h */
264 result = AUDIT_FAIL_ACCESS;
266 case VL_PERM : /* vlserver.h */
267 case BUDB_NOTPERMITTED : /* budb_errs.h */
268 /* case KRB_RD_AP_UNAUTHOR : */
269 case BZACCESS : /* bnode.h */
270 case VOLSERBAD_ACCESS : /* volser.h */
271 result = AUDIT_FAIL_PRIV;
278 ObtainWriteLock(&audbuflock);
281 /* Put the error code into the buffer list */
282 *(int *)bufferPtr = errCode;
283 bufferPtr += sizeof(errCode);
285 va_start(vaList, errCode);
286 aixmakebuf(audEvent, vaList);
288 va_start(vaList, errCode);
289 printbuf(audEvent, errCode, vaList);
291 bufferLen = (int)((afs_int32)bufferPtr - (afs_int32)&BUFFER[0]);
292 code = auditlog (audEvent, result, BUFFER, bufferLen);
297 code = auditlog ("AFS_Aud_Fail", result, &err, sizeof(err));
299 printf("Error while writing audit entry: %d.\n", errno);
302 ReleaseWriteLock(&audbuflock);
306 /* ************************************************************************** */
307 /* Given a RPC call structure, this routine extracts the name and host id from the
308 * call and includes it within the audit information.
309 * ************************************************************************** */
310 int osi_auditU (struct rx_call *call,
315 struct rx_connection *conn;
316 struct rx_peer *peer;
319 char afsName[MAXKTCNAMELEN];
324 if ( osi_audit_all < 0 ) osi_audit_check();
325 if ( !osi_audit_all ) return;
327 strcpy (afsName, "--Unknown--");
332 conn = rx_ConnectionOf(call); /* call -> conn) */
335 secClass = rx_SecurityClassOf(conn); /* conn -> securityIndex */
336 if (secClass == 0) /* unauthenticated */
338 osi_audit ("AFS_Aud_Unauth", (-1), AUD_STR, audEvent, AUD_END);
339 strcpy (afsName, "--UnAuth--");
341 else if (secClass == 2) /* authenticated */
343 code = rxkad_GetServerInfo(conn, (char *)0, (char *)0, afsName,
344 (char *)0, (char *)0, (char *)0);
347 osi_audit ("AFS_Aud_NoAFSId", (-1), AUD_STR, audEvent, AUD_END);
348 strcpy (afsName, "--NoName--");
351 else /* Unauthenticated & unknown */
353 osi_audit ("AFS_Aud_UnknSec", (-1), AUD_STR, audEvent, AUD_END);
356 peer = rx_PeerOf(conn); /* conn -> peer */
358 hostId = rx_HostOf(peer); /* peer -> host */
360 osi_audit ("AFS_Aud_NoHost", (-1), AUD_STR, audEvent, AUD_END);
364 osi_audit ("AFS_Aud_NoConn", (-1), AUD_STR, audEvent, AUD_END);
369 osi_audit ("AFS_Aud_NoCall", (-1), AUD_STR, audEvent, AUD_END);
372 va_start(vaList, errCode);
373 osi_audit (audEvent, errCode, AUD_STR, afsName,
379 /* ************************************************************************** */
380 /* Determines whether auditing is on or off by looking at the Audit file.
381 * If the string AFS_AUDIT_AllEvents is defined in the file, then auditing will be
383 * ************************************************************************** */
385 int osi_audit_check ()
391 osi_audit_all = 1; /* say we made check (>= 0) */
392 /* and assume audit all events (for now) */
393 onoff = 0; /* assume we will turn auditing off */
394 osi_echo_trail = 0; /* assume no echoing */
396 fds = fopen(AFSDIR_SERVER_AUDIT_FILEPATH, "r");
399 while ( fscanf(fds, "%256s", event) > 0)
401 if ( strcmp(event,"AFS_AUDIT_AllEvents") == 0 )
404 if ( strcmp(event,"Echo_Trail") == 0 )
410 /* Audit this event all of the time */
411 if (onoff) osi_audit("AFS_Aud_On", 0, AUD_END);
412 else osi_audit("AFS_Aud_Off", 0, AUD_END);
414 /* Now set whether we audit all events from here on out */
415 osi_audit_all = onoff;
419 #else /* ! AFS_AIX_ENV */
421 int osi_audit (char *audEvent, afs_int32 errCode, ...)
424 int osi_auditU (struct rx_call *call, char *audEvent, int errCode, ...)