1#!/usr/perl5/bin/perl -w 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance 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 2007 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26# ident "%Z%%M% %I% %E% SMI" 27# 28 29# auditxml_jni [-d] <xml input file> 30 31# auditxml takes the audit record description (.xml file) and 32# generates the files needed for the Java 33 34use auditxml; 35use Getopt::Std; 36use vars qw($opt_d); 37use strict; 38 39 40our $debug = 0; # normal use is to set via the file being parsed. 41 # <debug set="on"/> or <debug set="off"/> or <debug/> 42 # if the set attribute is omitted, debug state is toggled 43 # Override with appDebug, but toggle won't do what you 44 # want. 45my $appDebug = 0; # used after return from "new auditxml"; 46 47my $genNotice = " 48DO NOT EDIT. This file is auto generated by the Solaris Audit 49system from adt.xml. 50 51See http://opensolaris.org/os/project/audit/ 52"; 53 54# trim leading/trailing newlines 55$genNotice =~ s/^\n//s; 56$genNotice =~ s/\n$//s; 57my $prog = $0; $prog =~ s|.*/||g; 58my $usage = "usage: $prog [-d] file.xml\n"; 59 60getopts('d'); 61 62$appDebug = $opt_d; 63 64my $uniLabel = "adr"; 65my $xlateUniLabelInc = 0; 66 67die $usage if ($#ARGV < 0); 68 69# where everything comes from and where it goes: 70 71my $templatePath = './'; 72my $javaPath = $templatePath; 73my $bsmBuildPath = "../libbsm"; 74 75my $jniBuildPath = "$javaPath"; 76 77my $buildPathJ = "$jniBuildPath/com/sun/audit"; 78my $buildPathJNI = "$jniBuildPath/common"; 79 80my $auditEventJ = "$buildPathJ/AuditEvent.java"; 81my $jniC = "$buildPathJNI/adt_jni_event.c"; 82my $mapFile = "$jniBuildPath/common/mapfile-vers"; 83 84my $doc = new auditxml ($ARGV[0]); # input XML file 85 86$debug = $appDebug; 87 88my %jniEventTable = (); 89my %externalIdNo = (); 90my %msg_list = (); 91my %eventCode = (); 92 93readAuditEventFile("$bsmBuildPath/audit_event.txt"); 94 95my $event; 96while ($event = $doc->getNextEvent()) { 97 my $eventId = $event->getId(); 98 my $idNo = $event->getIdNo(); 99 $externalIdNo{$eventId} = $idNo; 100 my $super; 101 my $omit = $event->getOmit(); 102 my $eventType = ''; 103 if ($super = $event->getSuperClass()) { 104 $event = $super; 105 $eventType = 'instance'; 106 } else { 107 $eventType = $event->getType(); 108 } 109 110 # c file table for translation 111 generateTableC($event, $eventId, $eventType, undef, $omit); 112} 113 114while (my $textList = $doc->getNextMsgId()) { 115 generateMsgLists($textList); # enum -> text mappings 116} 117 118printJavaFiles($jniC, $auditEventJ, $buildPathJ, $mapFile); 119 120exit 0; 121 122 123 124sub printJavaFiles { 125 my $jniFile = shift; 126 my $javaFile = shift; 127 my $subclassPath = shift; 128 my $mapFile = shift; 129 130 # warning: time_t is equated to jlong since there is no 131 # way to use sys/types.h in Java code. 132 # java long is C long long, 64 bits. 133 # java int is 32 bits. 134 135 my %java_jni = ('ADT_DATE' => ['long', 'jlong'], 136 'ADT_UINT' => ['int', 'jint'], 137 'ADT_INT' => ['int', 'jint'], 138 'ADT_INT32' => ['int', 'jint'], 139 'ADT_UID' => ['int', 'jint'], 140 'ADT_GID' => ['int', 'jint'], 141 'ADT_UIDSTAR' => ['int[]', 'jintArray'], 142 'ADT_GIDSTAR' => ['int[]', 'jintArray'], 143 'ADT_CHAR' => ['String', 'jchar'], 144 'ADT_CHARSTAR' => ['String', 'jstring'], 145 'ADT_CHAR2STAR' => ['String[]', 'jstring'], 146 'ADT_MSG' => ['int', 'jint'], 147 'ADT_PID' => ['int', 'jint'], 148# ADT_PRIVSTAR omitted -- not implemented and the audit records that 149# use it must be coded to emit no java. We'll cross that bridge 150# when someone in Java land needs to generate a priv token. 151 'ADT_LONG' => ['int', 'jint'], 152 'ADT_TERMIDSTAR' => ['String', 'jstring'], # hostname -> termid 153 'ADT_ULONG' => ['int', 'jint'], 154 'ADT_UINT16' => ['int', 'jint'], 155 'ADT_UINT32' => ['int', 'jint'], 156 'ADT_UINT32STAR' => ['int[]', 'jintArray'], 157# ADT_UINT32ARRAY omitted; no Java implementation yet 158 'ADT_UINT64' => ['long', 'jlong'], 159 'ADT_UINT64STAR' => ['long[]', 'jlongArray'] 160 ); 161 my $noMemory = 'gettext("Out of memory")'; 162 163 # open output files 164 open (Cfile, ">$jniFile") or 165 die "can't open output file ($jniFile): $!\n"; 166 open (Jfile, ">$javaFile") or 167 die "can't open output file ($javaFile): $!\n"; 168 open (MapFile, ">$mapFile") or 169 die "can't open output file ($mapFile): $!\n"; 170 171 # write headers 172 my $notice = $genNotice; 173 $notice =~ s/\n/\n * /gs; 174 $notice =~ s/\s+\n/\n/gs; 175 print Cfile <<EOF; 176/* 177 * $notice 178 */ 179 180#include "../../libbsm/common/adt_xlate.h" 181#include <jni.h> 182#include "../com/sun/audit/AuditSession.h" /* javah output */ 183#include "adt_jni.h" 184#include <stdlib.h> 185#include <string.h> 186 187static char *except_class = "java/lang/Exception"; 188 189EOF 190 print Jfile <<EOF; 191/* 192 * $notice 193 */ 194 195package com.sun.audit; 196 197public class AuditEvent { 198 protected AuditSession sh; // associated session object 199 200 public AuditEvent(AuditSession auSession) 201 throws Error 202 { 203 204 sh = auSession; 205 } 206 207 // See the subclasses of AuditEvent for mapping message codes 208 // to events 209EOF 210 211 my $notice_map = $genNotice; 212 $notice_map =~ s/\n/\n# /gs; 213 $notice_map =~ s/\s+\n/\n/gs; 214 print MapFile <<EOF; 215# 216# $notice_map 217# 218 219SUNWprivate_1.1 { 220 global: 221 c2j_pointer; 222 j2c_pointer; 223 Java_com_sun_audit_AuditSession_bsmAuditOn; 224 Java_com_sun_audit_AuditSession_startSession; 225 Java_com_sun_audit_AuditSession_endSession; 226 Java_com_sun_audit_AuditSession_dupSession; 227 Java_com_sun_audit_AuditSession_getSessionId; 228 Java_com_sun_audit_AuditSession_exportSessionData; 229 230# One subclass of AuditEvent per audit record... 231EOF 232 233 # generate java final int classes to line up with string/enums 234 235 foreach my $listName (sort keys %msg_list) { 236 my $shortName = uc $listName; 237 $shortName =~ s/_TEXT//; 238 my ($listRef, $headref) = @{$msg_list{$listName}}; 239 my @listValue = @$listRef; 240 my ($header, $enumValue, $public, $deprecated) = @$headref; 241 my $listValue; 242 243 print Jfile "\n\t// adt_$listName" . "\n\n"; 244 print Jfile "\tpublic static final int ADT_$shortName", 245 " = $enumValue;\n" if $enumValue; 246 247 next unless ($#listValue >= 0); 248 print Jfile "\t// Deprecated message list\n" if $deprecated; 249 foreach $listValue (@listValue) { 250 my ($id, $text) = split(/\s*::\s*/, $listValue); 251 print Jfile "\t// $text\n"; 252 print Jfile "\tpublic static final int ADT_$shortName"; 253 print Jfile "_$id = $enumValue;\n"; 254 $enumValue++; 255 } 256 } 257 258 # generate event creation and access functions and event 259 # generation for both Java and JNI 260 # com.sun.audit.AuditEvent_xxx.java 261 foreach my $eventId (sort keys %jniEventTable) { 262 my ($ref1, $eventType, $allowedIds, $header) = @{$jniEventTable{$eventId}}; 263 $eventCode{$eventId} = -1 if ($eventType eq 'generic'); 264 my @entries = @$ref1; 265 my $entries = $#entries; 266 my $root = $eventId; 267 $root =~ s/AUE_//; 268 my $javaPutEvent = 'putEvent'; 269 my $putMethod = "_$root"; 270 $putMethod =~ s/_/_1/g; 271 272 my $jniPutEvent = "Java_com_sun_audit_AuditEvent$putMethod" . "_$javaPutEvent"; 273 274 # the subclass file template isn't used; it may be needed to get 275 # the right file header stuff in place. The subclassPath is 276 # the directory that contains 'em. 277 278 my $validSfile = 1; 279 unless (open(Sfile, ">$subclassPath/AuditEvent_$root.java")) { 280 print STDERR "can't open class file AuditEvent_$root.java: $!\n"; 281 $validSfile = 0; 282 } 283 if ($eventCode{"AUE_$root"}) { 284 if ($validSfile) { 285 print Sfile <<EOF; 286/* 287 * $notice 288 */ 289 290package com.sun.audit; 291 292// audit event: $eventId = $eventCode{"AUE_$root"} 293 294public class AuditEvent_$root extends AuditEvent { 295 296EOF 297 } 298 } else { 299 print STDERR "no event code for $eventId. Is audit_event current?\n"; 300 } 301 my $nativeParameterList = ''; 302 my $jniParameterList = ''; 303 my $specParameterList = ''; 304 my $jniStorageList = ''; 305 my $needCleanupTarget = 0; 306 my $jniFreeList = ''; 307 308 my $haveStringDef = 0; 309 my $haveCDef = 0; 310 my $haveLengthDef = 0; 311 my $haveStringArrayDef = 0; 312 my $cntTermidDef = 0; 313 my $jniDefine; 314 my $needLocaleDefined = 0; 315 my $jniADTalloc; 316 if (defined $header && ($header > 0) ) { 317 $jniDefine = "union union_of_events *event;\n" . 318 "\tadt_session_data_t *session;\n"; 319 $jniADTalloc = '(union union_of_events *)adt_alloc_event'; 320 } else { 321 $jniDefine = "adt_event_data_t *event;\n" . 322 "\tadt_session_data_t *session;\n"; 323 $jniADTalloc = 'adt_alloc_event'; 324 } 325 my $ref2; 326 foreach $ref2 (@entries) { 327 my ($id, $type) = @$ref2; 328 my $jniRoot = $root . $id; 329 $jniRoot =~ s/_/_1/g; # escape unicode "_" 330 331 my $p_event; 332 if (defined $header && ($header > 0) ) { 333 $p_event = "event->d$header.adt_$root.$id"; 334 } else { 335 $p_event = "event->adt_$root.$id"; 336 } 337 338 if ($type eq 'ADT_UINT32STAR') { # int array 339 $needLocaleDefined = 1; 340 341 342 $jniStorageList .= <<EOF; 343 /* $id */ 344 length = (*env)->GetArrayLength(env, $id); 345 $p_event = 346 (int *)malloc(length * sizeof (int)); 347 if ($p_event == NULL) { 348 locale = I18N_SETUP; 349 local_throw(env, except_class, 350 $noMemory); 351 (void) setlocale(LC_MESSAGES, locale); 352 goto cleanup; 353 } 354 (*env)->GetIntArrayRegion(env, $id, 0, length, 355 (int *)$p_event); 356EOF 357 358 359 $jniFreeList .= "\n\tif ($p_event != NULL)\n" . 360 "\t\tfree($p_event);\n"; 361 unless ($haveLengthDef) { 362 $haveLengthDef = 1; 363 $jniDefine .= "\tint\t\t\tlength;\n"; 364 } 365 $nativeParameterList .= ",\n\t int[]\t$id"; 366 $jniParameterList .= ",\n jintArray\t$id"; 367 $specParameterList .= ", jintArray"; 368 $needCleanupTarget = 1; 369 } elsif (($type eq 'ADT_UIDSTAR') || 370 ($type eq 'ADT_GIDSTAR')) { # gid_t array 371 my $cType = 'uid_t'; 372 $cType = 'gid_t' if ($type eq 'ADT_GIDSTAR'); 373 $needLocaleDefined = 1; 374 375 376 $jniStorageList .= <<EOF; 377 /* $id */ 378 length = (*env)->GetArrayLength(env, $id); 379 $p_event = 380 ($cType *)malloc(length * sizeof ($cType)); 381 if ($p_event == NULL) { 382 locale = I18N_SETUP; 383 local_throw(env, except_class, 384 $noMemory); 385 (void) setlocale(LC_MESSAGES, locale); 386 goto cleanup; 387 } 388 (*env)->GetIntArrayRegion(env, $id, 0, length, 389 (int *)$p_event); 390EOF 391 392 393 $jniFreeList .= 394 "\n\tif ($p_event != NULL)\n" . 395 "\t\tfree($p_event);\n"; 396 unless ($haveLengthDef) { 397 $haveLengthDef = 1; 398 $jniDefine .= "\tint\t\t\tlength;\n"; 399 } 400 $nativeParameterList .= ",\n\t int[]\t$id"; 401 $jniParameterList .= ",\n jintArray\t$id"; 402 $specParameterList .= ", jintArray"; 403 $needCleanupTarget = 1; 404 } elsif ($type eq 'ADT_UINT64STAR') { # long array 405 $needLocaleDefined = 1; 406 $jniStorageList .= <<EOF; 407 /* $id */ 408 length = (*env)->GetArrayLength(env, $id); 409 $p_event = 410 (long *)malloc(length * sizeof (long long)); 411 if ($p_event == NULL) { 412 locale = I18N_SETUP; 413 local_throw(env, except_class, 414 $noMemory); 415 (void) setlocale(LC_MESSAGES, locale); 416 goto cleanup; 417 } 418 (*env)->GetLongArrayRegion(env, $id, 0, length, 419 $p_event); 420EOF 421 $jniFreeList .= "\n\tif ($p_event != NULL)\n" . 422 "\t\tfree($p_event);\n"; 423 unless ($haveLengthDef) { 424 $haveLengthDef = 1; 425 $jniDefine .= "\tint\t\t\tlength;\n"; 426 } 427 $nativeParameterList .= ",\n\t long[]\t$id"; 428 $jniParameterList .= ",\n jlongArray\t$id"; 429 $specParameterList .= ", jlongArray"; 430 $needCleanupTarget = 1; 431 } elsif ($type eq 'ADT_CHAR') { # string in Java, char in C 432 $jniStorageList .= <<EOF; 433 434 /* $id */ 435 c = (char *)(*env)->GetStringUTFChars(env, $id, NULL); 436 if (c == NULL) 437 goto cleanup; /* exception thrown */ 438 $p_event = *c; 439 (*env)->ReleaseStringUTFChars(env, $id, c); 440EOF 441 # no need to free anything 442 unless ($haveCDef) { 443 $haveCDef = 1; 444 $jniDefine .= "\tchar\t\t\t*c\n"; 445 } 446 $nativeParameterList .= ",\n\t String\t$id"; 447 $jniParameterList .= ",\n jstring\t$id"; 448 $specParameterList .= ", jstring"; 449 } elsif ($type eq 'ADT_CHARSTAR') { 450 $needLocaleDefined = 1; 451 $jniStorageList .= <<EOF; 452 /* $id */ 453 if ($id != NULL) { 454 string = (char *)(*env)->GetStringUTFChars( 455 env, $id, NULL); 456 if (string == NULL) 457 goto cleanup; /* exception thrown */ 458 $p_event = strdup(string); 459 (*env)->ReleaseStringUTFChars(env, $id, string); 460 if ($p_event == NULL) { 461 locale = I18N_SETUP; 462 local_throw(env, except_class, 463 $noMemory); 464 (void) setlocale(LC_MESSAGES, locale); 465 goto cleanup; 466 } 467 } 468EOF 469 $jniFreeList .= "\n\tif ($p_event != NULL)\n" . 470 "\t\tfree($p_event);\n"; 471 unless ($haveStringDef) { 472 $haveStringDef = 1; 473 $jniDefine .= "\tchar\t\t\t*string;\n"; 474 } 475 $nativeParameterList .= ",\n\t String\t$id"; 476 $jniParameterList .= ",\n jstring\t$id"; 477 $specParameterList .= ", jstring"; 478 $needCleanupTarget = 1; 479 } elsif ($type eq 'ADT_CHAR2STAR') { # array of string 480 $needLocaleDefined = 1; 481 $jniStorageList .= <<EOF; 482 /* $id */ 483 length = (*env)->GetArrayLength(env, $id); 484 $p_event = (char **)malloc(length 485 * sizeof (char *)); 486 if ($p_event == NULL) { 487 locale = I18N_SETUP; 488 local_throw(env, except_class, 489 $noMemory); 490 (void) setlocale(LC_MESSAGES, locale); 491 goto cleanup; 492 } 493 p = $p_event; 494 for (i = 0; i < length; i++) { 495 jString = (*env)->GetObjectArrayElement(env, $id, i); 496 string = (char *)(*env)->GetStringUTFChars( 497 env, jString, NULL); 498 if (string == NULL) 499 goto cleanup; /* exception thrown */ 500 *p = strdup(string); 501 (*env)->ReleaseStringUTFChars(env, jString, string); 502 if (*p == NULL) { 503 locale = I18N_SETUP; 504 local_throw(env, except_class, 505 $noMemory); 506 (void) setlocale(LC_MESSAGES, locale); 507 while (p >= $p_event) 508 free(*p--); 509 goto cleanup; 510 } 511 p++; 512 } 513EOF 514 $jniFreeList .= 515 "\n\tif ($p_event != NULL)\n" . 516 "\t\tfree($p_event);\n"; 517 unless ($haveStringArrayDef) { 518 unless ($haveStringDef) { 519 $haveStringDef = 1; 520 $jniDefine .= <<EOF; 521 char *string; 522EOF 523 } 524 unless ($haveLengthDef) { 525 $haveLengthDef = 1; 526 $jniDefine .= <<EOF; 527 int length; 528EOF 529 } 530 $haveStringArrayDef = 1; 531 $jniDefine .= <<EOF; 532 int i; 533 char **p; 534 jstring jString; 535EOF 536 } 537 $nativeParameterList .= ",\n\t String[]\t$id"; 538 $jniParameterList .= ",\n jstring\t$id"; 539 $specParameterList .= ", jstring"; 540 $needCleanupTarget = 1; 541 } elsif ($type eq 'ADT_TERMIDSTAR') { 542 $needLocaleDefined = 1; 543 544 $jniStorageList .= <<EOF; 545 /* $id */ 546 hostname$cntTermidDef = (char *)(*env)->GetStringUTFChars(env, $id, NULL); 547 548 if (adt_load_hostname((const char *)hostname$cntTermidDef, &termid$cntTermidDef)) { 549 local_throw(env, except_class, 550 gettext("hostname lookup failed")); 551 } 552 $p_event = termid$cntTermidDef; 553 554 (*env)->ReleaseStringUTFChars(env, $id, hostname$cntTermidDef); 555EOF 556 557 $jniFreeList .= "\n\tif (hostname$cntTermidDef != NULL)\n" . 558 "\t\tfree(hostname$cntTermidDef);\n"; 559 $jniFreeList .= "\n\tif (termid$cntTermidDef != NULL)\n" . 560 "\t\tfree(termid$cntTermidDef);\n"; 561 562 $jniDefine .= "\tchar\t\t\t*hostname$cntTermidDef;\n"; 563 $jniDefine .= "\tadt_termid_t\t\t*termid$cntTermidDef;\n"; #djdj 564 565 $cntTermidDef++; 566 567 my ($nativeParameter, $jniParameter) = @{$java_jni{$type}}; 568 $nativeParameterList .= ",\n\t $nativeParameter\t$id"; 569 $jniParameterList .= ",\n $jniParameter\t$id"; 570 $specParameterList .= ", $jniParameter"; 571 $needCleanupTarget = 1; 572 } else { # all others are primitive types 573 $jniStorageList .= "\n\t$p_event = $id;\n"; 574 my ($nativeParameter, $jniParameter) = @{$java_jni{$type}}; 575 $nativeParameter = "$nativeParameter\t" 576 if length $nativeParameter < 4; # why? 577 $nativeParameterList .= ",\n\t $nativeParameter\t$id"; 578 $jniParameterList .= ",\n $jniParameter\t$id"; 579 $specParameterList .= ", $jniParameter"; 580 } 581 } 582 if ($needLocaleDefined) { 583 $jniDefine .= <<EOF 584 char *locale; 585EOF 586 } 587 my $genericOverride = ''; 588 my $idParameter = $eventId; 589 $idParameter =~ s/AUE_/ADT_/; 590 if ($eventType eq 'generic') { 591 $genericOverride = ', jint eventId'; 592 $idParameter = 'eventId'; 593 } 594 $jniFreeList = "\tcleanup:\n" . $jniFreeList if $needCleanupTarget; 595 596 print Cfile qq{/* ARGSUSED */ 597JNIEXPORT void JNICALL 598$jniPutEvent( 599 JNIEnv *env, 600 jobject self, 601 jbyteArray jsession$genericOverride, 602 jint status, 603 jint ret_val$jniParameterList) 604{ 605 $jniDefine 606 (void) j2c_pointer(env, jsession, (char **)&session); 607 608 event = $jniADTalloc(session, $idParameter); 609 610$jniStorageList 611 (void) adt_put_event((adt_event_data_t *)event, status, ret_val); 612 613$jniFreeList 614 adt_free_event((adt_event_data_t *)event); 615} 616}; 617 print MapFile qq{ 618 $jniPutEvent; }; 619 my $overrideParameter = ''; 620 if ($eventType eq 'generic') { 621 $overrideParameter = 'int eventId,'; 622 my @allowed = @$allowedIds; 623 if (@allowed) { 624 my $i; 625 if ($validSfile) { 626 print Sfile "\t// Allowed values for eventId in putEvent:\n"; 627 for ($i = 0; $i <= $#allowed; $i++) { 628 my $idNo = $externalIdNo{$allowed[$i]}; 629 $allowed[$i] =~ s/AUE_/ADT_/; 630 print Sfile "\tstatic final int $allowed[$i] = ", 631 "$idNo;\n"; 632 } 633 print Sfile "\n"; 634 } 635 } else { 636 print STDERR "Generic event with no allowed instances: $eventId\n"; 637 } 638 } 639 if ($validSfile) { 640 print Sfile <<EOF; 641 private native void $javaPutEvent(byte[]session, $overrideParameter 642 int status, int ret_val$nativeParameterList); 643 644 public AuditEvent_$root(AuditSession session) 645 throws Exception 646 { 647 super(session); 648 } 649 650EOF 651 my $javaParameterList = ''; 652 foreach $ref2 (@entries) { 653 my ($id, $type, $format, $jComment, $required) = @$ref2; 654 655 # generate java native method prototypes 656 # and the corresponding C method implementation 657 658 my $javaMethodName = "$id"; 659 my $javaStorageName = $javaMethodName . '_val'; 660 my $jniMethodName = $root . $id; 661 my $storage; 662 my $enumUsage = ''; 663 my $jParam = @{$java_jni{$type}}[0]; 664 my $comment = ''; 665 if ($required) { 666 if ($format ne 'NULL') { 667 $comment = "\t// (required) formatted: $format"; 668 } else { 669 $comment = "\t// required"; 670 } 671 } else { 672 if ($format ne 'NULL') { 673 $comment = "\t// (optional) formatted: $format"; 674 } else { 675 $comment = "\t// optional"; 676 } 677 } 678 if (($type eq 'ADT_UINT32STAR') || 679 ($type eq 'ADT_UIDSTAR') || 680 ($type eq 'ADT_GIDSTAR')) { # int array 681 $storage = "int[] $javaStorageName" . ($required ? 682 ' = {}' : ''); 683 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 684 } elsif ($type eq 'ADT_UINT64STAR') { # long array 685 $storage = "long[] $javaStorageName" . ($required ? 686 ' = {}' : ''); 687 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 688 } elsif (($type eq 'ADT_CHARSTAR') || 689 ($type eq 'ADT_CHAR')) { # string 690 $storage = "String $javaStorageName" . ($required ? 691 ' = ""' : ''); 692 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 693 } elsif ($type eq 'ADT_CHAR2STAR') { # array of string 694 $storage = "String[] $javaStorageName" . ($required ? 695 ' = {}' : ''); 696 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 697 } elsif ($type eq 'ADT_TERMIDSTAR') { # array of string 698 $storage = "String $javaStorageName" . ($required ? 699 ' = ""' : ''); 700 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 701 } else { # all others are primitive types 702 $storage = "$jParam $javaStorageName = 0"; 703 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 704 $enumUsage = "\n\t// See $jComment in AuditEvent.java for valid values" 705 if $jComment; 706 } 707 print Sfile <<EOF; 708$enumUsage 709 private $storage;$comment 710 public void $javaMethodName($jParam setTo) 711 { 712 $javaStorageName = setTo; 713 } 714EOF 715 } # end foreach (@entries) 716 if ($eventType eq 'generic') { 717 print Sfile <<EOF; 718 719 public void putEvent(int status, int ret_val, int eventId) 720 { 721 byte[] session = super.sh.getSession(); 722 723 if ((super.sh.AuditIsOn) && (super.sh.ValidSession)) 724 $javaPutEvent(session, eventId, 725 status, ret_val$javaParameterList); 726 } 727} 728EOF 729 } else { 730 print Sfile <<EOF; 731 732 public void putEvent(int status, int ret_val) 733 { 734 byte[] session = super.sh.getSession(); 735 736 if ((super.sh.AuditIsOn) && (super.sh.ValidSession)) 737 $javaPutEvent(session, status, ret_val$javaParameterList); 738 } 739} 740EOF 741 } 742 close Sfile; 743 } # end if ($validSfile); 744 } 745 746 # write trailers 747 print Jfile <<EOF; 748 749} 750EOF 751 print MapFile <<EOF; 752 753 local: 754 *; 755}; 756EOF 757 close Cfile; 758 close Jfile; 759 close MapFile; 760} 761 762sub generateTableC { 763 my $event = shift; 764 my $eventId = shift; 765 my $eventType = shift; 766 my $eventHeader = shift; 767 my $omit = shift; 768 769 my %tokenType = ( 770 'acl' => 'AUT_ACL', 771 'arbitrary' => 'AUT_ARBITRARY', 772 'arg' => 'AUT_ARG', 773 'attr' => 'AUT_ATTR', 774 'command' => 'AUT_CMD', 775 'command_1' => 'ADT_CMD_ALT', # dummy token id 776 'date' => 'AUT_TEXT', 777 'exec_args' => 'AUT_EXEC_ARGS', 778 'exec_env' => 'AUT_EXEC_ENV', 779 'exit' => 'AUT_EXIT', 780 'file' => 'AUT_FILE', 781 'fmri' => 'AUT_FMRI', 782 'groups' => 'AUT_GROUPS', 783 # 'header' => 'AUT_HEADER', # not used 784 'in_addr' => 'AUT_IN_ADDR', 785 'tid' => 'AUT_TID', 786 'ipc' => 'AUT_IPC', 787 'ipc_perm' => 'AUT_IPC_PERM', 788 'iport' => 'AUT_IPORT', 789 'label' => 'AUT_LABEL', 790 'newgroups' => 'AUT_NEWGROUPS', 791 'opaque' => 'AUT_OPAQUE', 792 'path' => 'AUT_PATH', 793 'path_list' => '-AUT_PATH', # dummy token id 794 'process' => 'AUT_PROCESS', 795 'priv_effective' => 'ADT_AUT_PRIV_E', # dummy token id 796 'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id 797 'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id 798 'return' => 'AUT_RETURN', 799 'seq' => 'AUT_SEQ', 800 'socket' => 'AUT_SOCKET', 801 'socket-inet' => 'AUT_SOCKET_INET', 802 'subject' => 'AUT_SUBJECT', 803 'text' => 'AUT_TEXT', 804 # 'trailer' => 'AUT_TRAILER', # not used 805 'uauth' => 'AUT_UAUTH', 806 'zonename' => 'AUT_ZONENAME' 807 ); 808 809 my @xlateEntryList = (); 810 my @jniEntryList = (); 811 812 my $external = $event->getExternal(); 813 my $internal = $event->getInternal(); 814 815 unless ($external) { 816 print STDERR "No external object captured for event $eventId\n"; 817 return; 818 } 819 unless ($internal) { 820 print STDERR "No internal object captured for event $eventId\n"; 821 return; 822 } 823 my @entryRef = $internal->getEntries(); 824 my $entryRef; 825 my @tokenOrder = (); 826 my $firstTokenIndex = 0; # djdj not used yet, djdj BUG! 827 # needs to be used by translate table 828 829 if ($internal->isReorder()) { # prescan the entry list to get the token order 830 my @inputOrder; 831 foreach $entryRef (@entryRef) { 832 my ($intEntry, $entry) = @$entryRef; 833 push (@inputOrder, $intEntry->getAttr('order')); 834 } 835 836 my $i; # walk down the inputOrder list once 837 my $k = 1; # discover next in line 838 my $l = 0; # who should point to next in line 839 for ($i = 0; $i <= $#inputOrder; $i++) { 840 my $j; 841 for ($j = 0; $j <= $#inputOrder; $j++) { 842 if ($k == $inputOrder[$j]) { 843 if ($k == 1) { 844 $firstTokenIndex = $j; 845 } else { 846 $tokenOrder[$l] = "&(selfReference[$j])"; 847 } 848 $l = $j; 849 last; 850 } 851 } 852 $k++; 853 } 854 $tokenOrder[$l] = 'NULL'; 855 } 856 else { # default order -- input order same as output 857 my $i; 858 my $j; 859 for ($i = 0; $i < $#entryRef; $i++) { 860 my $j = $i + 1; 861 $tokenOrder[$i] = "&(selfReference[$j])"; 862 } 863 $tokenOrder[$#entryRef] = 'NULL'; 864 } 865 866 my $sequence = 0; 867 foreach $entryRef (@entryRef) { 868 my ($intEntry, $entry) = @$entryRef; 869 my $entryId = $entry->getAttr('id'); 870 871 my ($extEntry, $unusedEntry, $tokenId) = 872 $external->getEntry($entryId); 873 my $opt = $extEntry->getAttr('opt'); 874 875 if ($opt eq 'none') { 876 if (defined ($doc->getToken($tokenId))) { 877 if (defined ($tokenType{$tokenId})) { 878 $tokenId = $tokenType{$tokenId}; 879 } 880 else { 881 print STDERR "token id $tokenId not implemented\n"; 882 } 883 } 884 else { 885 print STDERR "token = $tokenId is undefined\n"; 886 $tokenId = 'error'; 887 } 888 my ($xlate, $jni) = 889 formatTableEntry ('', $tokenId, $eventId, '', 0, 0, $tokenOrder[$sequence], 890 'NULL', ''); 891 push (@xlateEntryList, $xlate); 892 push (@jniEntryList, @$jni); 893 } 894 else { 895 my $dataType = $extEntry->getAttr('type'); 896 $dataType =~ s/\s+//g; # remove blanks (char * => char*) 897 898 my $enumGroup = ''; 899 if ($dataType =~ /^msg/i) { 900 $enumGroup = $dataType; 901 $enumGroup =~ s/^msg\s*//i; 902 $enumGroup = 'adt_' . $enumGroup; 903 } 904 my $required = ($opt eq 'required') ? 1 : 0; 905 my $tsol = 0; 906 my $tokenId = $intEntry->getAttr('token'); 907 my $token; 908 my $tokenName; 909 my $tokenFormat = $intEntry->getAttr('format'); 910 if (defined ($tokenFormat)) { 911 $tokenFormat = "\"$tokenFormat\""; 912 } 913 else { 914 $tokenFormat = 'NULL'; 915 } 916 917 if (defined ($token = $doc->getToken($tokenId))) { 918 $tsol = (lc $token->getUsage() eq 'tsol') ? 1 : 0; 919 if (defined ($tokenType{$tokenId})) { 920 $tokenName = $tokenType{$tokenId}; 921 } 922 else { 923 print STDERR "token id $tokenId not implemented\n"; 924 } 925 } 926 else { 927 print STDERR 928 "$tokenId is an unimplemented token ($entryId in $eventId)\n"; 929 $tokenName = 'AUT_TEXT'; 930 } 931 my ($xlate, $jni) = 932 formatTableEntry($entryId, $tokenName, $eventId, $dataType, $required, 933 $tsol, $tokenOrder[$sequence], $tokenFormat, 934 $enumGroup, (uc $omit eq 'JNI')); 935 push (@xlateEntryList, $xlate); 936 push (@jniEntryList, @$jni); 937 } 938 $sequence++; 939 } 940 $jniEventTable{$eventId} = [\@jniEntryList, $eventType, 941 $external->getAllowedTypes(), $eventHeader] 942 unless (uc $omit eq 'JNI') || ($omit eq 'always'); 943} 944 945sub formatTableEntry { 946 my ($id, $token, $eventId, $type, $required, $tsol, $sequence, $format, $enumGroup, 947 $omitJNI) = @_; 948 949 950 # does this map belong in the xml source? (at least the defaults?) 951 # fill in the default value only if it is other than zero. 952 # base type adt name, default value 953 my %entryDef = ( 'au_asid_t' => ['ADT_UINT32', ''], 954 'uint_t' => ['ADT_UINT32', ''], 955 'int' => ['ADT_INT', ''], 956 'int32_t' => ['ADT_INT32', ''], 957 'uid_t' => ['ADT_UID', 'AU_NOAUDITID'], 958 'gid_t' => ['ADT_GID', 'AU_NOAUDITID'], 959 'uid_t*' => ['ADT_UIDSTAR', ''], 960 'gid_t*' => ['ADT_GIDSTAR', ''], 961 'char' => ['ADT_CHAR', ''], 962 'char*' => ['ADT_CHARSTAR', ''], 963 'char**' => ['ADT_CHAR2STAR', ''], 964 'long' => ['ADT_LONG', ''], 965 'pid_t' => ['ADT_PID', ''], 966 'priv_set_t*' => ['ADT_PRIVSTAR', ''], 967 'ulong_t' => ['ADT_ULONG', ''], 968 'uint16_t', => ['ADT_UINT16', ''], 969 'uint32_t' => ['ADT_UINT32', ''], 970 'uint32_t*' => ['ADT_UINT32STAR', ''], 971 'uint32_t[]' => ['ADT_UINT32ARRAY', ''], 972 'uint64_t' => ['ADT_UINT64', ''], 973 'uint64_t*' => ['ADT_UINT64STAR', ''], 974 'm_label_t*' => ['ADT_MLABELSTAR', ''], 975 ); 976 my $xlateLabel = $uniLabel.$xlateUniLabelInc; 977 my $xlateLabelInc = 0; 978 my $xlateLine = ''; 979 my @jniLine = (); 980 981 # the list handling should be a simple loop with a loop of one 982 # falling out naturally. 983 984 unless ($type =~ /,/) { # if list, then generate sequence of entries 985 my $dataType; 986 my $dataSize; 987 my $xlateLabelRef = ''; 988 989 my $arraySize = ''; 990 $arraySize = $1 if ($type =~ s/\[(\d+)\]/[]/); 991 992 my $entryType = ${$entryDef{$type}}[0]; 993 994 my @xlateType = (); # for adt_xlate.c 995 my $typeCount = 1; 996 997 if ($entryType) { 998 $dataType = $entryType; 999 $type =~ s/([^*]+)\s*(\*+)/$1 $2/; 1000 $type =~ s/\[\]//; 1001 $dataSize = "sizeof ($type)"; 1002 if ($arraySize) { 1003 $dataSize = "$arraySize * " . $dataSize; 1004 } 1005 $xlateLine = "{{$dataType, $dataSize}}"; 1006 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1007 } elsif ($type eq '') { 1008 $xlateLabelRef = 'NULL'; 1009 } elsif ($type =~ /^msg/i) { 1010 $type =~ s/^msg//i; 1011 $dataType = 'ADT_MSG'; 1012 my $dataEnum = 'ADT_LIST_' . uc $type; 1013 $xlateLine = "{{$dataType, $dataEnum}}"; 1014 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1015 } elsif ($type =~ /time_t/i) { 1016 $dataType = 'ADT_DATE'; 1017 $dataSize = "sizeof (time_t)"; 1018 $xlateLine = "{{$dataType, $dataSize}}"; 1019 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1020 } elsif ($type =~ /termid/i) { 1021 $dataType = 'ADT_TERMIDSTAR'; 1022 $dataSize = "sizeof (au_tid_addr_t *)"; 1023 $xlateLine = "{{$dataType, $dataSize}}"; 1024 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1025 } elsif ($omitJNI) { 1026 $xlateLabelRef = 'NULL'; 1027 } else { 1028 print STDERR "$type is not an implemented data type\n"; 1029 $xlateLabelRef = 'NULL'; 1030 } 1031 $xlateLabelRef = '&' . $xlateLabel . '[0]' 1032 unless $xlateLabelRef eq 'NULL'; 1033 1034 # "EOL" is where a comma should go unless end of list 1035 $xlateLine = "{$token,\t1,\t$xlateLabelRef,\t$sequence,\n" . 1036 "\t\t0,\t$required,\t$tsol,\t$format}EOL"; 1037 1038 } else { # is a list 1039 my @type = split(/,/, $type); 1040 my @arraySize = (); 1041 my @id = split(/,/, $id); 1042 my @jniId = @id; 1043 my $dataType; 1044 my $typeCount = ($#type + 1); 1045 my @xlateType = (); 1046 my @default = (); 1047 1048 foreach my $dtype (@type) { 1049 my $jniId = shift @jniId; 1050 my $id = shift @id; 1051 my $arraySize = ''; 1052 $arraySize = $1 if ($dtype =~ s/\[(\d+)\]/[]/); 1053 1054 my $entryType = ${$entryDef{$dtype}}[0]; 1055 if ($entryType) { 1056 my $type = $dtype; 1057 $type =~ s/([^*]+)\s*(\*+)/$1 $2/; 1058 $type =~ s/\[\]//; 1059 1060 my $sizeString = "sizeof"; 1061 $sizeString = "$arraySize * " . $sizeString if $arraySize; 1062 push (@xlateType, "\{$entryType, $sizeString ($type)\}"); 1063 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]); 1064 } elsif ($type =~ /^msg/i) { 1065 $type =~ s/^msg//i; 1066 $dataType = 'ADT_MSG'; 1067 my $dataEnum = 'ADT_LIST_' . uc $type; 1068 push (@xlateType, "\{$dataType, $dataEnum\}};"); 1069 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]); 1070 } elsif ($type =~ /time_t/i) { 1071 $dataType = 'ADT_DATE'; 1072 push (@xlateType, "\{$entryType, sizeof ($type)\}"); 1073 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]); 1074 } elsif ($type =~ /termid/i) { 1075 $dataType = 'ADT_TERMIDSTAR'; 1076 push (@xlateType, "\{$dataType, sizeof (au_tid_addr_t *)\}"); 1077 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]); 1078 } elsif ($omitJNI) { 1079 # nothing to do. 1080 } else { 1081 print STDERR "$dtype is not an implemented data type\n"; 1082 } 1083 if (${$entryDef{$dtype}}[1]) { 1084 push (@default, $id, ${$entryDef{$dtype}}[1]); 1085 } 1086 } 1087 my $xlateArray = "\[$typeCount\] =\t{" . join(",\n\t\t\t\t", @xlateType) . "};"; 1088 1089 $xlateLine = 1090 "{$token,\t$typeCount,\t&$xlateLabel\[0\],\t$sequence,\n" . 1091 "\t\t0,\t$required,\t$tsol,\t$format}EOL"; 1092 } 1093 $xlateUniLabelInc++ if $xlateLabelInc; 1094 return ($xlateLine, \@jniLine); 1095} 1096 1097sub generateMsgLists { 1098 my $textList = shift; 1099 1100 my $textName = $textList->getId(); 1101 my $header = $textList->getHeader(); 1102 my $start = $textList->getMsgStart(); 1103 my $public = $textList->getMsgPublic(); 1104 my $deprecated = $textList->getDeprecated(); 1105 1106 print "$textName starts at $start\n" if $debug; 1107 1108 my $entry; 1109 my @entry; 1110 while ($entry = $textList->getNextMsg()) { 1111 if ($debug) { 1112 my ($id, $text) = split(/\s*::\s*/, $entry); 1113 print " $id = $text\n"; 1114 } 1115 unshift (@entry, $entry); 1116 } 1117 $msg_list{$textName} = 1118 [\@entry, [$header, $start, $public, $deprecated]]; 1119} 1120sub readAuditEventFile { 1121 my $eventListFile = shift; 1122 1123 open(Event, $eventListFile) 1124 or die "can't open $eventListFile: $!\n"; 1125 while(<Event>) { 1126 next if /^\s*#/; 1127 next if /^\s*$/; 1128 my ($value, $name) = split(/\s*:\s*/); 1129 next if $value < 6000; 1130 $eventCode{$name} = $value; 1131 } 1132 close Event; 1133} 1134 1135