Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / audit / audit.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #ifdef AFS_AIX32_ENV
16 #include <sys/audit.h>
17 #else
18 #define AUDIT_OK 0
19 #define AUDIT_FAIL 1
20 #define AUDIT_FAIL_AUTH 2
21 #define AUDIT_FAIL_ACCESS 3
22 #define AUDIT_FAIL_PRIV 4
23 #endif /* AFS_AIX32_ENV */
24
25 #include <afs/opr.h>
26 #include "afs/afsint.h"
27 #include "afs/butc.h"
28 #include <rx/rx.h>
29 #include <rx/rxkad.h>
30 #include "audit.h"
31 #include "audit-api.h"
32 #include "lock.h"
33
34 #include <afs/afsutil.h>
35
36 extern struct osi_audit_ops audit_file_ops;
37 #ifdef HAVE_SYS_IPC_H
38 extern struct osi_audit_ops audit_sysvmq_ops;
39 #endif
40
41 static struct {
42 void *rock;
43 int (*islocal)(void *rock, char *name, char *inst, char *cell);
44 } audit_user_check = { NULL, NULL };
45
46 static struct {
47 const char *name;
48 const struct osi_audit_ops *ops;
49 } audit_interfaces[] = {
50
51 { "file", &audit_file_ops },
52 #ifdef HAVE_SYS_IPC_H
53 { "sysvmq", &audit_sysvmq_ops },
54 #endif
55 };
56
57 #define N_INTERFACES (sizeof(audit_interfaces) / sizeof(audit_interfaces[0]))
58
59 /* default to `file' audit interface */
60 static const struct osi_audit_ops *audit_ops = &audit_file_ops;
61
62 static int osi_audit_all = (-1); /* Not determined yet */
63 static int osi_echo_trail = (-1);
64
65 static int auditout_open = 0;
66
67 static int osi_audit_check(void);
68
69 #ifdef AFS_AIX32_ENV
70 static char *bufferPtr;
71 static int bufferLen;
72
73 static void
74 audmakebuf(char *audEvent, va_list vaList)
75 {
76 int code;
77 int vaEntry;
78 int vaInt;
79 afs_int32 vaLong;
80 char *vaStr;
81 struct AFSFid *vaFid;
82
83 vaEntry = va_arg(vaList, int);
84 while (vaEntry != AUD_END) {
85 switch (vaEntry) {
86 case AUD_STR: /* String */
87 case AUD_NAME: /* Name */
88 case AUD_ACL: /* ACL */
89 vaStr = (char *)va_arg(vaList, char *);
90 if (vaStr) {
91 strcpy(bufferPtr, vaStr);
92 bufferPtr += strlen(vaStr) + 1;
93 } else {
94 strcpy(bufferPtr, "");
95 bufferPtr++;
96 }
97 break;
98 case AUD_INT: /* Integer */
99 case AUD_ID: /* ViceId */
100 vaInt = va_arg(vaList, int);
101 *(int *)bufferPtr = vaInt;
102 bufferPtr += sizeof(vaInt);
103 break;
104 case AUD_DATE: /* Date */
105 case AUD_HOST: /* Host ID */
106 case AUD_LONG: /* long */
107 vaLong = va_arg(vaList, afs_int32);
108 *(afs_int32 *) bufferPtr = vaLong;
109 bufferPtr += sizeof(vaLong);
110 break;
111 case AUD_FID: /* AFSFid - contains 3 entries */
112 vaFid = (struct AFSFid *)va_arg(vaList, struct AFSFid *);
113 if (vaFid) {
114 memcpy(bufferPtr, vaFid, sizeof(struct AFSFid));
115 } else {
116 memset(bufferPtr, 0, sizeof(struct AFSFid));
117 }
118 bufferPtr += sizeof(struct AFSFid);
119 break;
120
121 /* Whole array of fids-- don't know how to handle variable length audit
122 * data with AIX audit package, so for now we just store the first fid.
123 * Better one than none. */
124 case AUD_FIDS:
125 {
126 struct AFSCBFids *Fids;
127
128 Fids = (struct AFSCBFids *)va_arg(vaList, struct AFSCBFids *);
129 if (Fids && Fids->AFSCBFids_len) {
130 *((u_int *) bufferPtr) = Fids->AFSCBFids_len;
131 bufferPtr += sizeof(u_int);
132 memcpy(bufferPtr, Fids->AFSCBFids_val,
133 sizeof(struct AFSFid));
134 } else {
135 *((u_int *) bufferPtr) = 0;
136 bufferPtr += sizeof(u_int);
137 memset(bufferPtr, 0, sizeof(struct AFSFid));
138 }
139 bufferPtr += sizeof(struct AFSFid);
140 break;
141 }
142 /* butc tape label */
143 case AUD_TLBL:
144 {
145 struct tc_tapeLabel *label;
146
147 label = (struct tc_tapeLabel *)va_arg(vaList,
148 struct tc_tapeLabel *);
149 if (label)
150 memcpy(bufferPtr, label, sizeof(*label));
151 else
152 memset(bufferPtr, 0, sizeof(*label));
153 bufferPtr += sizeof(label);
154 break;
155 }
156 /* butc dump interface */
157 case AUD_TDI:
158 {
159 struct tc_dumpInterface *di;
160
161 di = (struct tc_dumpInterface *)
162 va_arg(vaList, struct tc_dumpInterface *);
163 if (di)
164 memcpy(bufferPtr, di, sizeof(*di));
165 else
166 memset(bufferPtr, 0, sizeof(*di));
167 bufferPtr += sizeof(*di);
168 break;
169 }
170 /*
171 * butc dump array
172 * An array of dump descriptions, but the AIX audit package assumes fixed
173 * length, so we can only do the first one for now.
174 */
175 case AUD_TDA:
176 {
177 struct tc_dumpArray *da;
178
179 da = (struct tc_dumpArray *)
180 va_arg(vaList, struct tc_dumpArray *);
181 if (da && da->tc_dumpArray_len) {
182 memcpy(bufferPtr, &da->tc_dumpArray_len, sizeof(u_int));
183 bufferPtr += sizeof(u_int);
184 memcpy(bufferPtr, da->tc_dumpArray_val,
185 sizeof(da->tc_dumpArray_val[0]));
186 } else {
187 memset(bufferPtr, 0, sizeof(u_int));
188 bufferPtr += sizeof(u_int);
189 memset(bufferPtr, 0, sizeof(da->tc_dumpArray_val[0]));
190 }
191 bufferPtr += sizeof(da->tc_dumpArray_val[0]);
192 break;
193 }
194 /*
195 * butc restore array
196 * An array of restore descriptions, but the AIX audit package assumes
197 * fixed length, so we can only do the first one for now.
198 */
199 case AUD_TRA:
200 {
201 struct tc_restoreArray *ra;
202
203 ra = (struct tc_restoreArray *)
204 va_arg(vaList, struct tc_restoreArray *);
205 if (ra && ra->tc_restoreArray_len) {
206 memcpy(bufferPtr, &ra->tc_restoreArray_len, sizeof(u_int));
207 bufferPtr += sizeof(u_int);
208 memcpy(bufferPtr, ra->tc_restoreArray_val,
209 sizeof(ra->tc_restoreArray_val[0]));
210 } else {
211 memset(bufferPtr, 0, sizeof(u_int));
212 bufferPtr += sizeof(u_int);
213 memset(bufferPtr, 0, sizeof(ra->tc_restoreArray_val[0]));
214 }
215 bufferPtr += sizeof(ra->tc_restoreArray_val[0]);
216 break;
217 }
218 /* butc tape controller status */
219 {
220 struct tciStatusS *status;
221
222 status = (struct tciStatusS *)va_arg(vaList,
223 struct tciStatusS *);
224 if (status)
225 memcpy(bufferPtr, status, sizeof(*status));
226 else
227 memset(bufferPtr, 0, sizeof(*status));
228 bufferPtr += sizeof(*status);
229 break;
230 }
231 default:
232 #ifdef AFS_AIX32_ENV
233 code =
234 auditlog("AFS_Aud_EINVAL", (-1), audEvent,
235 (strlen(audEvent) + 1));
236 #endif
237 return;
238 break;
239 } /* end switch */
240
241 vaEntry = va_arg(vaList, int);
242 } /* end while */
243 }
244 #endif
245
246 static void
247 printbuf(int rec, char *audEvent, char *afsName, afs_int32 hostId,
248 afs_int32 errCode, va_list vaList)
249 {
250 int vaEntry;
251 int vaInt;
252 afs_int32 vaLong;
253 char *vaStr;
254 struct AFSFid *vaFid;
255 struct AFSCBFids *vaFids;
256 struct tc_tapeLabel *vaLabel;
257 struct tc_dumpInterface *vaDI;
258 struct tc_dumpArray *vaDA;
259 struct tc_restoreArray *vaRA;
260 struct tciStatusS *vaTCstatus;
261 int num = LogThreadNum();
262 struct in_addr hostAddr;
263 time_t currenttime;
264 char tbuffer[26];
265 struct tm tm;
266
267 /* Don't print the timestamp or thread id if we recursed */
268 if (rec == 0) {
269 currenttime = time(0);
270 if (strftime(tbuffer, sizeof(tbuffer), "%a %b %d %H:%M:%S %Y ",
271 localtime_r(&currenttime, &tm)) !=0)
272 audit_ops->append_msg(tbuffer);
273
274 if (num > -1)
275 audit_ops->append_msg("[%d] ", num);
276 }
277
278 audit_ops->append_msg("EVENT %s CODE %d ", audEvent, errCode);
279
280 if (afsName) {
281 hostAddr.s_addr = hostId;
282 audit_ops->append_msg("NAME %s HOST %s ", afsName, inet_ntoa(hostAddr));
283 }
284
285 vaEntry = va_arg(vaList, int);
286 while (vaEntry != AUD_END) {
287 switch (vaEntry) {
288 case AUD_STR: /* String */
289 vaStr = (char *)va_arg(vaList, char *);
290 if (vaStr)
291 audit_ops->append_msg("STR %s ", vaStr);
292 else
293 audit_ops->append_msg("STR <null>");
294 break;
295 case AUD_NAME: /* Name */
296 vaStr = (char *)va_arg(vaList, char *);
297 if (vaStr)
298 audit_ops->append_msg("NAME %s ", vaStr);
299 else
300 audit_ops->append_msg("NAME <null>");
301 break;
302 case AUD_ACL: /* ACL */
303 vaStr = (char *)va_arg(vaList, char *);
304 if (vaStr)
305 audit_ops->append_msg("ACL %s ", vaStr);
306 else
307 audit_ops->append_msg("ACL <null>");
308 break;
309 case AUD_INT: /* Integer */
310 vaInt = va_arg(vaList, int);
311 audit_ops->append_msg("INT %d ", vaInt);
312 break;
313 case AUD_ID: /* ViceId */
314 vaInt = va_arg(vaList, int);
315 audit_ops->append_msg("ID %d ", vaInt);
316 break;
317 case AUD_DATE: /* Date */
318 vaLong = va_arg(vaList, afs_int32);
319 audit_ops->append_msg("DATE %u ", vaLong);
320 break;
321 case AUD_HOST: /* Host ID */
322 vaLong = va_arg(vaList, afs_int32);
323 hostAddr.s_addr = vaLong;
324 audit_ops->append_msg("HOST %s ", inet_ntoa(hostAddr));
325 break;
326 case AUD_LONG: /* afs_int32 */
327 vaLong = va_arg(vaList, afs_int32);
328 audit_ops->append_msg("LONG %d ", vaLong);
329 break;
330 case AUD_FID: /* AFSFid - contains 3 entries */
331 vaFid = va_arg(vaList, struct AFSFid *);
332 if (vaFid)
333 audit_ops->append_msg("FID %u:%u:%u ", vaFid->Volume, vaFid->Vnode,
334 vaFid->Unique);
335 else
336 audit_ops->append_msg("FID %u:%u:%u ", 0, 0, 0);
337 break;
338 case AUD_FIDS: /* array of Fids */
339 vaFids = va_arg(vaList, struct AFSCBFids *);
340
341 if (vaFids) {
342 unsigned int i;
343
344 vaFid = vaFids->AFSCBFids_val;
345
346 if (vaFid) {
347 audit_ops->append_msg("FIDS %u ", vaFids->AFSCBFids_len);
348 for ( i = 1; i <= vaFids->AFSCBFids_len; i++, vaFid++ )
349 audit_ops->append_msg("FID %u:%u:%u ", vaFid->Volume,
350 vaFid->Vnode, vaFid->Unique);
351 } else
352 audit_ops->append_msg("FIDS 0 FID 0:0:0 ");
353
354 }
355 break;
356 case AUD_TLBL: /* butc tape label */
357 vaLabel = va_arg(vaList, struct tc_tapeLabel *);
358
359 if (vaLabel) {
360 audit_ops->append_msg("TAPELABEL %d:%.*s:%.*s:%u ",
361 vaLabel->size,
362 TC_MAXTAPELEN, vaLabel->afsname,
363 TC_MAXTAPELEN, vaLabel->pname,
364 vaLabel->tapeId);
365 } else {
366 audit_ops->append_msg("TAPELABEL <null>");
367 }
368 break;
369 case AUD_TDI:
370 vaDI = va_arg(vaList, struct tc_dumpInterface *);
371
372 if (vaDI) {
373 audit_ops->append_msg(
374 "TCDUMPINTERFACE %.*s:%.*s:%.*s:%d:%d:%d:%d:%.*s:%.*s:%d:%d:%d:%d:%d ",
375 TC_MAXDUMPPATH, vaDI->dumpPath, TC_MAXNAMELEN, vaDI->volumeSetName,
376 TC_MAXNAMELEN, vaDI->dumpName, vaDI->parentDumpId, vaDI->dumpLevel,
377 vaDI->doAppend,
378 vaDI->tapeSet.id, TC_MAXHOSTLEN, vaDI->tapeSet.tapeServer,
379 TC_MAXFORMATLEN, vaDI->tapeSet.format, vaDI->tapeSet.maxTapes,
380 vaDI->tapeSet.a, vaDI->tapeSet.b, vaDI->tapeSet.expDate,
381 vaDI->tapeSet.expType);
382 } else {
383 audit_ops->append_msg("TCDUMPINTERFACE <null>");
384 }
385 break;
386 case AUD_TDA:
387 vaDA = va_arg(vaList, struct tc_dumpArray *);
388
389 if (vaDA) {
390 u_int i;
391 struct tc_dumpDesc *desc;
392 struct in_addr hostAddr;
393
394 desc = vaDA->tc_dumpArray_val;
395 if (desc) {
396 audit_ops->append_msg("DUMPS %d ", vaDA->tc_dumpArray_len);
397 for (i = 0; i < vaDA->tc_dumpArray_len; i++, desc++) {
398 hostAddr.s_addr = desc->hostAddr;
399 audit_ops->append_msg("DUMP %d:%d:%.*s:%d:%d:%d:%s ",
400 desc->vid, desc->vtype, TC_MAXNAMELEN, desc->name,
401 desc->partition, desc->date, desc->cloneDate,
402 inet_ntoa(hostAddr));
403 }
404 } else {
405 audit_ops->append_msg("DUMPS 0 DUMP 0:0::0:0:0:0.0.0.0");
406 }
407 }
408 break;
409 case AUD_TRA:
410 vaRA = va_arg(vaList, struct tc_restoreArray *);
411
412 if (vaRA) {
413 u_int i;
414 struct tc_restoreDesc *desc;
415 struct in_addr hostAddr;
416
417 desc = vaRA->tc_restoreArray_val;
418 if (desc) {
419 audit_ops->append_msg("RESTORES %d ",
420 vaRA->tc_restoreArray_len);
421 for(i = 0; i < vaRA->tc_restoreArray_len; i++, desc++) {
422 hostAddr.s_addr = desc->hostAddr;
423 audit_ops->append_msg(
424 "RESTORE %d:%.*s:%d:%d:%d:%d:%d:%d:%d:%s:%.*s:%.*s ",
425 desc->flags, TC_MAXTAPELEN, desc->tapeName,
426 desc->dbDumpId, desc->initialDumpId,
427 desc->position, desc->origVid, desc->vid,
428 desc->partition, desc->dumpLevel,
429 inet_ntoa(hostAddr), TC_MAXNAMELEN,
430 desc->oldName, TC_MAXNAMELEN, desc->newName);
431 }
432 } else {
433 audit_ops->append_msg(
434 "RESTORES 0 RESTORE 0::0:0:0:0:0:0:0:0.0.0.0::: ");
435 }
436 }
437 break;
438 case AUD_TSTT:
439 vaTCstatus = va_arg(vaList, struct tciStatusS *);
440
441 if (vaTCstatus)
442 audit_ops->append_msg("TCSTATUS %.*s:%d:%d:%d:%d:%.*s:%d:%d ",
443 TC_MAXNAMELEN, vaTCstatus->taskName,
444 vaTCstatus->taskId, vaTCstatus->flags,
445 vaTCstatus->dbDumpId, vaTCstatus->nKBytes,
446 TC_MAXNAMELEN, vaTCstatus->volumeName,
447 vaTCstatus->volsFailed,
448 vaTCstatus->lastPolled);
449 else
450 audit_ops->append_msg("TCSTATUS <null>");
451 break;
452 default:
453 audit_ops->append_msg("--badval-- ");
454 break;
455 } /* end switch */
456 vaEntry = va_arg(vaList, int);
457 } /* end while */
458
459 audit_ops->send_msg();
460 }
461
462 #ifdef AFS_PTHREAD_ENV
463 static pthread_mutex_t audit_lock;
464 static volatile afs_int32 audit_lock_initialized = 0;
465 static pthread_once_t audit_lock_once = PTHREAD_ONCE_INIT;
466
467 static void
468 osi_audit_init_lock(void)
469 {
470 MUTEX_INIT(&audit_lock, "audit", MUTEX_DEFAULT, 0);
471 audit_lock_initialized = 1;
472 }
473 #endif
474
475 void
476 osi_audit_init(void)
477 {
478 #ifdef AFS_PTHREAD_ENV
479 if (!audit_lock_initialized) {
480 pthread_once(&audit_lock_once, osi_audit_init_lock);
481 }
482 #endif /* AFS_PTHREAD_ENV */
483 }
484
485 /* ************************************************************************** */
486 /* The routine that acually does the audit call.
487 * ************************************************************************** */
488 static int
489 osi_audit_internal(char *audEvent, /* Event name (15 chars or less) */
490 afs_int32 errCode, /* The error code */
491 char *afsName,
492 afs_int32 hostId,
493 va_list vaList)
494 {
495 #ifdef AFS_AIX32_ENV
496 afs_int32 code;
497 afs_int32 err;
498 static char BUFFER[32768];
499 int result;
500 #endif
501
502 #ifdef AFS_PTHREAD_ENV
503 /* i'm pretty sure all the server apps now call osi_audit_init(),
504 * but to be extra careful we'll leave this assert in here for a
505 * while to make sure */
506 opr_Assert(audit_lock_initialized);
507 #endif /* AFS_PTHREAD_ENV */
508
509 if ((osi_audit_all < 0) || (osi_echo_trail < 0))
510 osi_audit_check();
511 if (!osi_audit_all && !auditout_open)
512 return 0;
513
514 #ifdef AFS_AIX32_ENV
515 switch (errCode) {
516 case 0:
517 result = AUDIT_OK;
518 break;
519 case KANOAUTH: /* kautils.h */
520 case RXKADNOAUTH: /* rxkad.h */
521 result = AUDIT_FAIL_AUTH;
522 break;
523 case EPERM: /* errno.h */
524 case EACCES: /* errno.h */
525 case PRPERM: /* pterror.h */
526 result = AUDIT_FAIL_ACCESS;
527 break;
528 case VL_PERM: /* vlserver.h */
529 case BUDB_NOTPERMITTED: /* budb_errs.h */
530 case BZACCESS: /* bnode.h */
531 case VOLSERBAD_ACCESS: /* volser.h */
532 result = AUDIT_FAIL_PRIV;
533 break;
534 default:
535 result = AUDIT_FAIL;
536 break;
537 }
538 #endif
539
540 MUTEX_ENTER(&audit_lock);
541 #ifdef AFS_AIX32_ENV
542 bufferPtr = BUFFER;
543
544 /* Put the error code into the buffer list */
545 *(int *)bufferPtr = errCode;
546 bufferPtr += sizeof(errCode);
547
548 audmakebuf(audEvent, vaList);
549 #endif
550
551 #ifdef AFS_AIX32_ENV
552 bufferLen = (int)((afs_int32) bufferPtr - (afs_int32) & BUFFER[0]);
553 code = auditlog(audEvent, result, BUFFER, bufferLen);
554 #else
555 if (auditout_open) {
556 printbuf(0, audEvent, afsName, hostId, errCode, vaList);
557 }
558 #endif
559 MUTEX_EXIT(&audit_lock);
560
561 return 0;
562 }
563 int
564 osi_audit(char *audEvent, /* Event name (15 chars or less) */
565 afs_int32 errCode, /* The error code */
566 ...)
567 {
568 va_list vaList;
569
570 if ((osi_audit_all < 0) || (osi_echo_trail < 0))
571 osi_audit_check();
572 if (!osi_audit_all && !auditout_open)
573 return 0;
574
575 va_start(vaList, errCode);
576 osi_audit_internal(audEvent, errCode, NULL, 0, vaList);
577 va_end(vaList);
578
579 return 0;
580 }
581
582 /* ************************************************************************** */
583 /* Given a RPC call structure, this routine extracts the name and host id from the
584 * call and includes it within the audit information.
585 * ************************************************************************** */
586 int
587 osi_auditU(struct rx_call *call, char *audEvent, int errCode, ...)
588 {
589 struct rx_connection *conn;
590 struct rx_peer *peer;
591 afs_int32 secClass;
592 afs_int32 code;
593 char afsName[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
594 afs_int32 hostId;
595 va_list vaList;
596
597 if (osi_audit_all < 0)
598 osi_audit_check();
599 if (!osi_audit_all && !auditout_open)
600 return 0;
601
602 strcpy(afsName, "--Unknown--");
603 hostId = 0;
604
605 if (call) {
606 conn = rx_ConnectionOf(call); /* call -> conn) */
607 if (conn) {
608 secClass = rx_SecurityClassOf(conn); /* conn -> securityIndex */
609 if (secClass == RX_SECIDX_NULL) { /* unauthenticated */
610 osi_audit("AFS_Aud_Unauth", (-1), AUD_STR, audEvent, AUD_END);
611 strcpy(afsName, "--UnAuth--");
612 } else if (secClass == RX_SECIDX_KAD || secClass == RX_SECIDX_KAE) {
613 /* authenticated with rxkad */
614 char tcell[MAXKTCREALMLEN];
615 char name[MAXKTCNAMELEN];
616 char inst[MAXKTCNAMELEN];
617
618 code =
619 rxkad_GetServerInfo(conn, NULL, NULL, name, inst, tcell,
620 NULL);
621 if (code) {
622 osi_audit("AFS_Aud_NoAFSId", (-1), AUD_STR, audEvent, AUD_END);
623 strcpy(afsName, "--NoName--");
624 } else {
625 afs_int32 islocal = 0;
626 if (audit_user_check.islocal) {
627 islocal =
628 audit_user_check.islocal(audit_user_check.rock,
629 name, inst, tcell);
630 }
631 strlcpy(afsName, name, sizeof(afsName));
632 if (inst[0]) {
633 strlcat(afsName, ".", sizeof(afsName));
634 strlcat(afsName, inst, sizeof(afsName));
635 }
636 if (tcell[0] && !islocal) {
637 strlcat(afsName, "@", sizeof(afsName));
638 strlcat(afsName, tcell, sizeof(afsName));
639 }
640 }
641 } else { /* Unauthenticated and/or unknown */
642 osi_audit("AFS_Aud_UnknSec", (-1), AUD_STR, audEvent, AUD_END);
643 strcpy(afsName, "--Unknown--");
644 }
645 peer = rx_PeerOf(conn); /* conn -> peer */
646 if (peer)
647 hostId = rx_HostOf(peer); /* peer -> host */
648 else
649 osi_audit("AFS_Aud_NoHost", (-1), AUD_STR, audEvent, AUD_END);
650 } else { /* null conn */
651 osi_audit("AFS_Aud_NoConn", (-1), AUD_STR, audEvent, AUD_END);
652 }
653 } else { /* null call */
654 osi_audit("AFS_Aud_NoCall", (-1), AUD_STR, audEvent, AUD_END);
655 }
656 va_start(vaList, errCode);
657 osi_audit_internal(audEvent, errCode, afsName, hostId, vaList);
658 va_end(vaList);
659 return 0;
660 }
661
662 /* ************************************************************************** */
663 /* Determines whether auditing is on or off by looking at the Audit file.
664 * If the string AFS_AUDIT_AllEvents is defined in the file, then auditing will be
665 * enabled.
666 * ************************************************************************** */
667
668 int
669 osi_audit_check(void)
670 {
671 FILE *fds;
672 int onoff;
673 char event[257];
674
675 osi_audit_all = 1; /* say we made check (>= 0) */
676 /* and assume audit all events (for now) */
677 onoff = 0; /* assume we will turn auditing off */
678 osi_echo_trail = 0; /* assume no echoing */
679
680 fds = fopen(AFSDIR_SERVER_AUDIT_FILEPATH, "r");
681 if (fds) {
682 while (fscanf(fds, "%256s", event) > 0) {
683 if (strcmp(event, "AFS_AUDIT_AllEvents") == 0)
684 onoff = 1;
685
686 if (strcmp(event, "Echo_Trail") == 0)
687 osi_echo_trail = 1;
688 }
689 fclose(fds);
690 }
691
692 /* Audit this event all of the time */
693 if (onoff)
694 osi_audit("AFS_Aud_On", 0, AUD_END);
695 else
696 osi_audit("AFS_Aud_Off", 0, AUD_END);
697
698 /* Now set whether we audit all events from here on out */
699 osi_audit_all = onoff;
700
701 return 0;
702 }
703
704 int
705 osi_audit_file(const char *fileName)
706 {
707 if(!audit_ops->open_file(fileName)) {
708 auditout_open = 1;
709 return 0;
710 }
711 return 1;
712 }
713
714 int
715 osi_audit_interface(const char *interface)
716 {
717 int i;
718 for (i = 0; i < N_INTERFACES; ++i) {
719 if (strcmp(interface, audit_interfaces[i].name) == 0) {
720 audit_ops = audit_interfaces[i].ops;
721 return 0;
722 }
723 }
724
725 return 1;
726 }
727
728 void
729 osi_audit_set_user_check(void *rock,
730 int (*islocal) (void *rock, char *name, char *inst,
731 char *cell))
732 {
733 audit_user_check.rock = rock;
734 audit_user_check.islocal = islocal;
735 }
736
737 void
738 audit_PrintStats(FILE *out)
739 {
740 audit_ops->print_interface_stats(out);
741 }