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 Java_com_sun_audit_AuditSession_sessionAttr; 230 231# One subclass of AuditEvent per audit record... 232EOF 233 234 # generate java final int classes to line up with string/enums 235 236 foreach my $listName (sort keys %msg_list) { 237 my $shortName = uc $listName; 238 $shortName =~ s/_TEXT//; 239 my ($listRef, $headref) = @{$msg_list{$listName}}; 240 my @listValue = @$listRef; 241 my ($header, $enumValue, $public, $deprecated) = @$headref; 242 my $listValue; 243 244 print Jfile "\n\t// adt_$listName" . "\n\n"; 245 print Jfile "\tpublic static final int ADT_$shortName", 246 " = $enumValue;\n" if $enumValue; 247 248 next unless ($#listValue >= 0); 249 print Jfile "\t// Deprecated message list\n" if $deprecated; 250 foreach $listValue (@listValue) { 251 my ($id, $text) = split(/\s*::\s*/, $listValue); 252 print Jfile "\t// $text\n"; 253 print Jfile "\tpublic static final int ADT_$shortName"; 254 print Jfile "_$id = $enumValue;\n"; 255 $enumValue++; 256 } 257 } 258 259 # generate event creation and access functions and event 260 # generation for both Java and JNI 261 # com.sun.audit.AuditEvent_xxx.java 262 foreach my $eventId (sort keys %jniEventTable) { 263 my ($ref1, $eventType, $allowedIds, $header) = @{$jniEventTable{$eventId}}; 264 $eventCode{$eventId} = -1 if ($eventType eq 'generic'); 265 my @entries = @$ref1; 266 my $entries = $#entries; 267 my $root = $eventId; 268 $root =~ s/AUE_//; 269 my $javaPutEvent = 'putEvent'; 270 my $putMethod = "_$root"; 271 $putMethod =~ s/_/_1/g; 272 273 my $jniPutEvent = "Java_com_sun_audit_AuditEvent$putMethod" . "_$javaPutEvent"; 274 275 # the subclass file template isn't used; it may be needed to get 276 # the right file header stuff in place. The subclassPath is 277 # the directory that contains 'em. 278 279 my $validSfile = 1; 280 unless (open(Sfile, ">$subclassPath/AuditEvent_$root.java")) { 281 print STDERR "can't open class file AuditEvent_$root.java: $!\n"; 282 $validSfile = 0; 283 } 284 if ($eventCode{"AUE_$root"}) { 285 if ($validSfile) { 286 print Sfile <<EOF; 287/* 288 * $notice 289 */ 290 291package com.sun.audit; 292 293// audit event: $eventId = $eventCode{"AUE_$root"} 294 295public class AuditEvent_$root extends AuditEvent { 296 297EOF 298 } 299 } else { 300 print STDERR "no event code for $eventId. Is audit_event current?\n"; 301 } 302 my $nativeParameterList = ''; 303 my $jniParameterList = ''; 304 my $specParameterList = ''; 305 my $jniStorageList = ''; 306 my $needCleanupTarget = 0; 307 my $jniFreeList = ''; 308 309 my $haveStringDef = 0; 310 my $haveCDef = 0; 311 my $haveLengthDef = 0; 312 my $haveStringArrayDef = 0; 313 my $cntTermidDef = 0; 314 my $jniDefine; 315 my $needLocaleDefined = 0; 316 my $jniADTalloc; 317 if (defined $header && ($header > 0) ) { 318 $jniDefine = "union union_of_events *event;\n" . 319 "\tadt_session_data_t *session;\n"; 320 $jniADTalloc = '(union union_of_events *)adt_alloc_event'; 321 } else { 322 $jniDefine = "adt_event_data_t *event;\n" . 323 "\tadt_session_data_t *session;\n"; 324 $jniADTalloc = 'adt_alloc_event'; 325 } 326 my $ref2; 327 foreach $ref2 (@entries) { 328 my ($id, $type) = @$ref2; 329 my $jniRoot = $root . $id; 330 $jniRoot =~ s/_/_1/g; # escape unicode "_" 331 332 my $p_event; 333 if (defined $header && ($header > 0) ) { 334 $p_event = "event->d$header.adt_$root.$id"; 335 } else { 336 $p_event = "event->adt_$root.$id"; 337 } 338 339 if ($type eq 'ADT_UINT32STAR') { # int array 340 $needLocaleDefined = 1; 341 342 343 $jniStorageList .= <<EOF; 344 /* $id */ 345 length = (*env)->GetArrayLength(env, $id); 346 $p_event = 347 (int *)malloc(length * sizeof (int)); 348 if ($p_event == NULL) { 349 locale = I18N_SETUP; 350 local_throw(env, except_class, 351 $noMemory); 352 (void) setlocale(LC_MESSAGES, locale); 353 goto cleanup; 354 } 355 (*env)->GetIntArrayRegion(env, $id, 0, length, 356 (int *)$p_event); 357EOF 358 359 360 $jniFreeList .= "\n\tif ($p_event != NULL)\n" . 361 "\t\tfree($p_event);\n"; 362 unless ($haveLengthDef) { 363 $haveLengthDef = 1; 364 $jniDefine .= "\tint\t\t\tlength;\n"; 365 } 366 $nativeParameterList .= ",\n\t int[]\t$id"; 367 $jniParameterList .= ",\n jintArray\t$id"; 368 $specParameterList .= ", jintArray"; 369 $needCleanupTarget = 1; 370 } elsif (($type eq 'ADT_UIDSTAR') || 371 ($type eq 'ADT_GIDSTAR')) { # gid_t array 372 my $cType = 'uid_t'; 373 $cType = 'gid_t' if ($type eq 'ADT_GIDSTAR'); 374 $needLocaleDefined = 1; 375 376 377 $jniStorageList .= <<EOF; 378 /* $id */ 379 length = (*env)->GetArrayLength(env, $id); 380 $p_event = 381 ($cType *)malloc(length * sizeof ($cType)); 382 if ($p_event == NULL) { 383 locale = I18N_SETUP; 384 local_throw(env, except_class, 385 $noMemory); 386 (void) setlocale(LC_MESSAGES, locale); 387 goto cleanup; 388 } 389 (*env)->GetIntArrayRegion(env, $id, 0, length, 390 (int *)$p_event); 391EOF 392 393 394 $jniFreeList .= 395 "\n\tif ($p_event != NULL)\n" . 396 "\t\tfree($p_event);\n"; 397 unless ($haveLengthDef) { 398 $haveLengthDef = 1; 399 $jniDefine .= "\tint\t\t\tlength;\n"; 400 } 401 $nativeParameterList .= ",\n\t int[]\t$id"; 402 $jniParameterList .= ",\n jintArray\t$id"; 403 $specParameterList .= ", jintArray"; 404 $needCleanupTarget = 1; 405 } elsif ($type eq 'ADT_UINT64STAR') { # long array 406 $needLocaleDefined = 1; 407 $jniStorageList .= <<EOF; 408 /* $id */ 409 length = (*env)->GetArrayLength(env, $id); 410 $p_event = 411 (long *)malloc(length * sizeof (long long)); 412 if ($p_event == NULL) { 413 locale = I18N_SETUP; 414 local_throw(env, except_class, 415 $noMemory); 416 (void) setlocale(LC_MESSAGES, locale); 417 goto cleanup; 418 } 419 (*env)->GetLongArrayRegion(env, $id, 0, length, 420 $p_event); 421EOF 422 $jniFreeList .= "\n\tif ($p_event != NULL)\n" . 423 "\t\tfree($p_event);\n"; 424 unless ($haveLengthDef) { 425 $haveLengthDef = 1; 426 $jniDefine .= "\tint\t\t\tlength;\n"; 427 } 428 $nativeParameterList .= ",\n\t long[]\t$id"; 429 $jniParameterList .= ",\n jlongArray\t$id"; 430 $specParameterList .= ", jlongArray"; 431 $needCleanupTarget = 1; 432 } elsif ($type eq 'ADT_CHAR') { # string in Java, char in C 433 $jniStorageList .= <<EOF; 434 435 /* $id */ 436 c = (char *)(*env)->GetStringUTFChars(env, $id, NULL); 437 if (c == NULL) 438 goto cleanup; /* exception thrown */ 439 $p_event = *c; 440 (*env)->ReleaseStringUTFChars(env, $id, c); 441EOF 442 # no need to free anything 443 unless ($haveCDef) { 444 $haveCDef = 1; 445 $jniDefine .= "\tchar\t\t\t*c\n"; 446 } 447 $nativeParameterList .= ",\n\t String\t$id"; 448 $jniParameterList .= ",\n jstring\t$id"; 449 $specParameterList .= ", jstring"; 450 } elsif ($type eq 'ADT_CHARSTAR') { 451 $needLocaleDefined = 1; 452 $jniStorageList .= <<EOF; 453 /* $id */ 454 if ($id != NULL) { 455 string = (char *)(*env)->GetStringUTFChars( 456 env, $id, NULL); 457 if (string == NULL) 458 goto cleanup; /* exception thrown */ 459 $p_event = strdup(string); 460 (*env)->ReleaseStringUTFChars(env, $id, string); 461 if ($p_event == NULL) { 462 locale = I18N_SETUP; 463 local_throw(env, except_class, 464 $noMemory); 465 (void) setlocale(LC_MESSAGES, locale); 466 goto cleanup; 467 } 468 } 469EOF 470 $jniFreeList .= "\n\tif ($p_event != NULL)\n" . 471 "\t\tfree($p_event);\n"; 472 unless ($haveStringDef) { 473 $haveStringDef = 1; 474 $jniDefine .= "\tchar\t\t\t*string;\n"; 475 } 476 $nativeParameterList .= ",\n\t String\t$id"; 477 $jniParameterList .= ",\n jstring\t$id"; 478 $specParameterList .= ", jstring"; 479 $needCleanupTarget = 1; 480 } elsif ($type eq 'ADT_CHAR2STAR') { # array of string 481 $needLocaleDefined = 1; 482 $jniStorageList .= <<EOF; 483 /* $id */ 484 length = (*env)->GetArrayLength(env, $id); 485 $p_event = (char **)malloc(length 486 * sizeof (char *)); 487 if ($p_event == NULL) { 488 locale = I18N_SETUP; 489 local_throw(env, except_class, 490 $noMemory); 491 (void) setlocale(LC_MESSAGES, locale); 492 goto cleanup; 493 } 494 p = $p_event; 495 for (i = 0; i < length; i++) { 496 jString = (*env)->GetObjectArrayElement(env, $id, i); 497 string = (char *)(*env)->GetStringUTFChars( 498 env, jString, NULL); 499 if (string == NULL) 500 goto cleanup; /* exception thrown */ 501 *p = strdup(string); 502 (*env)->ReleaseStringUTFChars(env, jString, string); 503 if (*p == NULL) { 504 locale = I18N_SETUP; 505 local_throw(env, except_class, 506 $noMemory); 507 (void) setlocale(LC_MESSAGES, locale); 508 while (p >= $p_event) 509 free(*p--); 510 goto cleanup; 511 } 512 p++; 513 } 514EOF 515 $jniFreeList .= 516 "\n\tif ($p_event != NULL)\n" . 517 "\t\tfree($p_event);\n"; 518 unless ($haveStringArrayDef) { 519 unless ($haveStringDef) { 520 $haveStringDef = 1; 521 $jniDefine .= <<EOF; 522 char *string; 523EOF 524 } 525 unless ($haveLengthDef) { 526 $haveLengthDef = 1; 527 $jniDefine .= <<EOF; 528 int length; 529EOF 530 } 531 $haveStringArrayDef = 1; 532 $jniDefine .= <<EOF; 533 int i; 534 char **p; 535 jstring jString; 536EOF 537 } 538 $nativeParameterList .= ",\n\t String[]\t$id"; 539 $jniParameterList .= ",\n jstring\t$id"; 540 $specParameterList .= ", jstring"; 541 $needCleanupTarget = 1; 542 } elsif ($type eq 'ADT_TERMIDSTAR') { 543 $needLocaleDefined = 1; 544 545 $jniStorageList .= <<EOF; 546 /* $id */ 547 hostname$cntTermidDef = (char *)(*env)->GetStringUTFChars(env, $id, NULL); 548 549 if (adt_load_hostname((const char *)hostname$cntTermidDef, &termid$cntTermidDef)) { 550 local_throw(env, except_class, 551 gettext("hostname lookup failed")); 552 } 553 $p_event = termid$cntTermidDef; 554 555 (*env)->ReleaseStringUTFChars(env, $id, hostname$cntTermidDef); 556EOF 557 558 $jniFreeList .= "\n\tif (hostname$cntTermidDef != NULL)\n" . 559 "\t\tfree(hostname$cntTermidDef);\n"; 560 $jniFreeList .= "\n\tif (termid$cntTermidDef != NULL)\n" . 561 "\t\tfree(termid$cntTermidDef);\n"; 562 563 $jniDefine .= "\tchar\t\t\t*hostname$cntTermidDef;\n"; 564 $jniDefine .= "\tadt_termid_t\t\t*termid$cntTermidDef;\n"; #djdj 565 566 $cntTermidDef++; 567 568 my ($nativeParameter, $jniParameter) = @{$java_jni{$type}}; 569 $nativeParameterList .= ",\n\t $nativeParameter\t$id"; 570 $jniParameterList .= ",\n $jniParameter\t$id"; 571 $specParameterList .= ", $jniParameter"; 572 $needCleanupTarget = 1; 573 } else { # all others are primitive types 574 $jniStorageList .= "\n\t$p_event = $id;\n"; 575 my ($nativeParameter, $jniParameter) = @{$java_jni{$type}}; 576 $nativeParameter = "$nativeParameter\t" 577 if length $nativeParameter < 4; # why? 578 $nativeParameterList .= ",\n\t $nativeParameter\t$id"; 579 $jniParameterList .= ",\n $jniParameter\t$id"; 580 $specParameterList .= ", $jniParameter"; 581 } 582 } 583 if ($needLocaleDefined) { 584 $jniDefine .= <<EOF 585 char *locale; 586EOF 587 } 588 my $genericOverride = ''; 589 my $idParameter = $eventId; 590 $idParameter =~ s/AUE_/ADT_/; 591 if ($eventType eq 'generic') { 592 $genericOverride = ', jint eventId'; 593 $idParameter = 'eventId'; 594 } 595 $jniFreeList = "\tcleanup:\n" . $jniFreeList if $needCleanupTarget; 596 597 print Cfile qq{/* ARGSUSED */ 598JNIEXPORT void JNICALL 599$jniPutEvent( 600 JNIEnv *env, 601 jobject self, 602 jbyteArray jsession$genericOverride, 603 jint status, 604 jint ret_val$jniParameterList) 605{ 606 $jniDefine 607 (void) j2c_pointer(env, jsession, (char **)&session); 608 609 event = $jniADTalloc(session, $idParameter); 610 611$jniStorageList 612 (void) adt_put_event((adt_event_data_t *)event, status, ret_val); 613 614$jniFreeList 615 adt_free_event((adt_event_data_t *)event); 616} 617}; 618 print MapFile qq{ 619 $jniPutEvent; }; 620 my $overrideParameter = ''; 621 if ($eventType eq 'generic') { 622 $overrideParameter = 'int eventId,'; 623 my @allowed = @$allowedIds; 624 if (@allowed) { 625 my $i; 626 if ($validSfile) { 627 print Sfile "\t// Allowed values for eventId in putEvent:\n"; 628 for ($i = 0; $i <= $#allowed; $i++) { 629 my $idNo = $externalIdNo{$allowed[$i]}; 630 $allowed[$i] =~ s/AUE_/ADT_/; 631 print Sfile "\tstatic final int $allowed[$i] = ", 632 "$idNo;\n"; 633 } 634 print Sfile "\n"; 635 } 636 } else { 637 print STDERR "Generic event with no allowed instances: $eventId\n"; 638 } 639 } 640 if ($validSfile) { 641 print Sfile <<EOF; 642 private native void $javaPutEvent(byte[]session, $overrideParameter 643 int status, int ret_val$nativeParameterList); 644 645 public AuditEvent_$root(AuditSession session) 646 throws Exception 647 { 648 super(session); 649 } 650 651EOF 652 my $javaParameterList = ''; 653 foreach $ref2 (@entries) { 654 my ($id, $type, $format, $jComment, $required) = @$ref2; 655 656 # generate java native method prototypes 657 # and the corresponding C method implementation 658 659 my $javaMethodName = "$id"; 660 my $javaStorageName = $javaMethodName . '_val'; 661 my $jniMethodName = $root . $id; 662 my $storage; 663 my $enumUsage = ''; 664 my $jParam = @{$java_jni{$type}}[0]; 665 my $comment = ''; 666 if ($required) { 667 if ($format ne 'NULL') { 668 $comment = "\t// (required) formatted: $format"; 669 } else { 670 $comment = "\t// required"; 671 } 672 } else { 673 if ($format ne 'NULL') { 674 $comment = "\t// (optional) formatted: $format"; 675 } else { 676 $comment = "\t// optional"; 677 } 678 } 679 if (($type eq 'ADT_UINT32STAR') || 680 ($type eq 'ADT_UIDSTAR') || 681 ($type eq 'ADT_GIDSTAR')) { # int array 682 $storage = "int[] $javaStorageName" . ($required ? 683 ' = {}' : ''); 684 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 685 } elsif ($type eq 'ADT_UINT64STAR') { # long array 686 $storage = "long[] $javaStorageName" . ($required ? 687 ' = {}' : ''); 688 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 689 } elsif (($type eq 'ADT_CHARSTAR') || 690 ($type eq 'ADT_CHAR')) { # string 691 $storage = "String $javaStorageName" . ($required ? 692 ' = ""' : ''); 693 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 694 } elsif ($type eq 'ADT_CHAR2STAR') { # array of string 695 $storage = "String[] $javaStorageName" . ($required ? 696 ' = {}' : ''); 697 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 698 } elsif ($type eq 'ADT_TERMIDSTAR') { # array of string 699 $storage = "String $javaStorageName" . ($required ? 700 ' = ""' : ''); 701 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 702 } else { # all others are primitive types 703 $storage = "$jParam $javaStorageName = 0"; 704 $javaParameterList .= ",\n\t\t\t $javaStorageName"; 705 $enumUsage = "\n\t// See $jComment in AuditEvent.java for valid values" 706 if $jComment; 707 } 708 print Sfile <<EOF; 709$enumUsage 710 private $storage;$comment 711 public void $javaMethodName($jParam setTo) 712 { 713 $javaStorageName = setTo; 714 } 715EOF 716 } # end foreach (@entries) 717 if ($eventType eq 'generic') { 718 print Sfile <<EOF; 719 720 public void putEvent(int status, int ret_val, int eventId) 721 { 722 byte[] session = super.sh.getSession(); 723 724 if ((super.sh.AuditIsOn) && (super.sh.ValidSession)) 725 $javaPutEvent(session, eventId, 726 status, ret_val$javaParameterList); 727 } 728} 729EOF 730 } else { 731 print Sfile <<EOF; 732 733 public void putEvent(int status, int ret_val) 734 { 735 byte[] session = super.sh.getSession(); 736 737 if ((super.sh.AuditIsOn) && (super.sh.ValidSession)) 738 $javaPutEvent(session, status, ret_val$javaParameterList); 739 } 740} 741EOF 742 } 743 close Sfile; 744 } # end if ($validSfile); 745 } 746 747 # write trailers 748 print Jfile <<EOF; 749 750} 751EOF 752 print MapFile <<EOF; 753 754 local: 755 *; 756}; 757EOF 758 close Cfile; 759 close Jfile; 760 close MapFile; 761} 762 763sub generateTableC { 764 my $event = shift; 765 my $eventId = shift; 766 my $eventType = shift; 767 my $eventHeader = shift; 768 my $omit = shift; 769 770 my %tokenType = ( 771 'acl' => 'AUT_ACL', 772 'arbitrary' => 'AUT_ARBITRARY', 773 'arg' => 'AUT_ARG', 774 'attr' => 'AUT_ATTR', 775 'command' => 'AUT_CMD', 776 'command_1' => 'ADT_CMD_ALT', # dummy token id 777 'date' => 'AUT_TEXT', 778 'exec_args' => 'AUT_EXEC_ARGS', 779 'exec_env' => 'AUT_EXEC_ENV', 780 'exit' => 'AUT_EXIT', 781 'file' => 'AUT_FILE', 782 'fmri' => 'AUT_FMRI', 783 'groups' => 'AUT_GROUPS', 784 # 'header' => 'AUT_HEADER', # not used 785 'in_addr' => 'AUT_IN_ADDR', 786 'tid' => 'AUT_TID', 787 'ipc' => 'AUT_IPC', 788 'ipc_perm' => 'AUT_IPC_PERM', 789 'iport' => 'AUT_IPORT', 790 'label' => 'AUT_LABEL', 791 'newgroups' => 'AUT_NEWGROUPS', 792 'opaque' => 'AUT_OPAQUE', 793 'path' => 'AUT_PATH', 794 'path_list' => '-AUT_PATH', # dummy token id 795 'process' => 'AUT_PROCESS', 796 'priv_effective' => 'ADT_AUT_PRIV_E', # dummy token id 797 'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id 798 'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id 799 'return' => 'AUT_RETURN', 800 'seq' => 'AUT_SEQ', 801 'socket' => 'AUT_SOCKET', 802 'socket-inet' => 'AUT_SOCKET_INET', 803 'subject' => 'AUT_SUBJECT', 804 'text' => 'AUT_TEXT', 805 # 'trailer' => 'AUT_TRAILER', # not used 806 'uauth' => 'AUT_UAUTH', 807 'zonename' => 'AUT_ZONENAME' 808 ); 809 810 my @xlateEntryList = (); 811 my @jniEntryList = (); 812 813 my $external = $event->getExternal(); 814 my $internal = $event->getInternal(); 815 816 unless ($external) { 817 print STDERR "No external object captured for event $eventId\n"; 818 return; 819 } 820 unless ($internal) { 821 print STDERR "No internal object captured for event $eventId\n"; 822 return; 823 } 824 my @entryRef = $internal->getEntries(); 825 my $entryRef; 826 my @tokenOrder = (); 827 my $firstTokenIndex = 0; # djdj not used yet, djdj BUG! 828 # needs to be used by translate table 829 830 if ($internal->isReorder()) { # prescan the entry list to get the token order 831 my @inputOrder; 832 foreach $entryRef (@entryRef) { 833 my ($intEntry, $entry) = @$entryRef; 834 push (@inputOrder, $intEntry->getAttr('order')); 835 } 836 837 my $i; # walk down the inputOrder list once 838 my $k = 1; # discover next in line 839 my $l = 0; # who should point to next in line 840 for ($i = 0; $i <= $#inputOrder; $i++) { 841 my $j; 842 for ($j = 0; $j <= $#inputOrder; $j++) { 843 if ($k == $inputOrder[$j]) { 844 if ($k == 1) { 845 $firstTokenIndex = $j; 846 } else { 847 $tokenOrder[$l] = "&(selfReference[$j])"; 848 } 849 $l = $j; 850 last; 851 } 852 } 853 $k++; 854 } 855 $tokenOrder[$l] = 'NULL'; 856 } 857 else { # default order -- input order same as output 858 my $i; 859 my $j; 860 for ($i = 0; $i < $#entryRef; $i++) { 861 my $j = $i + 1; 862 $tokenOrder[$i] = "&(selfReference[$j])"; 863 } 864 $tokenOrder[$#entryRef] = 'NULL'; 865 } 866 867 my $sequence = 0; 868 foreach $entryRef (@entryRef) { 869 my ($intEntry, $entry) = @$entryRef; 870 my $entryId = $entry->getAttr('id'); 871 872 my ($extEntry, $unusedEntry, $tokenId) = 873 $external->getEntry($entryId); 874 my $opt = $extEntry->getAttr('opt'); 875 876 if ($opt eq 'none') { 877 if (defined ($doc->getToken($tokenId))) { 878 if (defined ($tokenType{$tokenId})) { 879 $tokenId = $tokenType{$tokenId}; 880 } 881 else { 882 print STDERR "token id $tokenId not implemented\n"; 883 } 884 } 885 else { 886 print STDERR "token = $tokenId is undefined\n"; 887 $tokenId = 'error'; 888 } 889 my ($xlate, $jni) = 890 formatTableEntry ('', $tokenId, $eventId, '', 0, 0, $tokenOrder[$sequence], 891 'NULL', ''); 892 push (@xlateEntryList, $xlate); 893 push (@jniEntryList, @$jni); 894 } 895 else { 896 my $dataType = $extEntry->getAttr('type'); 897 $dataType =~ s/\s+//g; # remove blanks (char * => char*) 898 899 my $enumGroup = ''; 900 if ($dataType =~ /^msg/i) { 901 $enumGroup = $dataType; 902 $enumGroup =~ s/^msg\s*//i; 903 $enumGroup = 'adt_' . $enumGroup; 904 } 905 my $required = ($opt eq 'required') ? 1 : 0; 906 my $tsol = 0; 907 my $tokenId = $intEntry->getAttr('token'); 908 my $token; 909 my $tokenName; 910 my $tokenFormat = $intEntry->getAttr('format'); 911 if (defined ($tokenFormat)) { 912 $tokenFormat = "\"$tokenFormat\""; 913 } 914 else { 915 $tokenFormat = 'NULL'; 916 } 917 918 if (defined ($token = $doc->getToken($tokenId))) { 919 $tsol = (lc $token->getUsage() eq 'tsol') ? 1 : 0; 920 if (defined ($tokenType{$tokenId})) { 921 $tokenName = $tokenType{$tokenId}; 922 } 923 else { 924 print STDERR "token id $tokenId not implemented\n"; 925 } 926 } 927 else { 928 print STDERR 929 "$tokenId is an unimplemented token ($entryId in $eventId)\n"; 930 $tokenName = 'AUT_TEXT'; 931 } 932 my ($xlate, $jni) = 933 formatTableEntry($entryId, $tokenName, $eventId, $dataType, $required, 934 $tsol, $tokenOrder[$sequence], $tokenFormat, 935 $enumGroup, (uc $omit eq 'JNI')); 936 push (@xlateEntryList, $xlate); 937 push (@jniEntryList, @$jni); 938 } 939 $sequence++; 940 } 941 $jniEventTable{$eventId} = [\@jniEntryList, $eventType, 942 $external->getAllowedTypes(), $eventHeader] 943 unless (uc $omit eq 'JNI') || ($omit eq 'always'); 944} 945 946sub formatTableEntry { 947 my ($id, $token, $eventId, $type, $required, $tsol, $sequence, $format, $enumGroup, 948 $omitJNI) = @_; 949 950 951 # does this map belong in the xml source? (at least the defaults?) 952 # fill in the default value only if it is other than zero. 953 # base type adt name, default value 954 my %entryDef = ( 'au_asid_t' => ['ADT_UINT32', ''], 955 'uint_t' => ['ADT_UINT32', ''], 956 'int' => ['ADT_INT', ''], 957 'int32_t' => ['ADT_INT32', ''], 958 'uid_t' => ['ADT_UID', 'AU_NOAUDITID'], 959 'gid_t' => ['ADT_GID', 'AU_NOAUDITID'], 960 'uid_t*' => ['ADT_UIDSTAR', ''], 961 'gid_t*' => ['ADT_GIDSTAR', ''], 962 'char' => ['ADT_CHAR', ''], 963 'char*' => ['ADT_CHARSTAR', ''], 964 'char**' => ['ADT_CHAR2STAR', ''], 965 'long' => ['ADT_LONG', ''], 966 'pid_t' => ['ADT_PID', ''], 967 'priv_set_t*' => ['ADT_PRIVSTAR', ''], 968 'ulong_t' => ['ADT_ULONG', ''], 969 'uint16_t', => ['ADT_UINT16', ''], 970 'uint32_t' => ['ADT_UINT32', ''], 971 'uint32_t*' => ['ADT_UINT32STAR', ''], 972 'uint32_t[]' => ['ADT_UINT32ARRAY', ''], 973 'uint64_t' => ['ADT_UINT64', ''], 974 'uint64_t*' => ['ADT_UINT64STAR', ''], 975 'm_label_t*' => ['ADT_MLABELSTAR', ''], 976 ); 977 my $xlateLabel = $uniLabel.$xlateUniLabelInc; 978 my $xlateLabelInc = 0; 979 my $xlateLine = ''; 980 my @jniLine = (); 981 982 # the list handling should be a simple loop with a loop of one 983 # falling out naturally. 984 985 unless ($type =~ /,/) { # if list, then generate sequence of entries 986 my $dataType; 987 my $dataSize; 988 my $xlateLabelRef = ''; 989 990 my $arraySize = ''; 991 $arraySize = $1 if ($type =~ s/\[(\d+)\]/[]/); 992 993 my $entryType = ${$entryDef{$type}}[0]; 994 995 my @xlateType = (); # for adt_xlate.c 996 my $typeCount = 1; 997 998 if ($entryType) { 999 $dataType = $entryType; 1000 $type =~ s/([^*]+)\s*(\*+)/$1 $2/; 1001 $type =~ s/\[\]//; 1002 $dataSize = "sizeof ($type)"; 1003 if ($arraySize) { 1004 $dataSize = "$arraySize * " . $dataSize; 1005 } 1006 $xlateLine = "{{$dataType, $dataSize}}"; 1007 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1008 } elsif ($type eq '') { 1009 $xlateLabelRef = 'NULL'; 1010 } elsif ($type =~ /^msg/i) { 1011 $type =~ s/^msg//i; 1012 $dataType = 'ADT_MSG'; 1013 my $dataEnum = 'ADT_LIST_' . uc $type; 1014 $xlateLine = "{{$dataType, $dataEnum}}"; 1015 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1016 } elsif ($type =~ /time_t/i) { 1017 $dataType = 'ADT_DATE'; 1018 $dataSize = "sizeof (time_t)"; 1019 $xlateLine = "{{$dataType, $dataSize}}"; 1020 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1021 } elsif ($type =~ /termid/i) { 1022 $dataType = 'ADT_TERMIDSTAR'; 1023 $dataSize = "sizeof (au_tid_addr_t *)"; 1024 $xlateLine = "{{$dataType, $dataSize}}"; 1025 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]); 1026 } elsif ($omitJNI) { 1027 $xlateLabelRef = 'NULL'; 1028 } else { 1029 print STDERR "$type is not an implemented data type\n"; 1030 $xlateLabelRef = 'NULL'; 1031 } 1032 $xlateLabelRef = '&' . $xlateLabel . '[0]' 1033 unless $xlateLabelRef eq 'NULL'; 1034 1035 # "EOL" is where a comma should go unless end of list 1036 $xlateLine = "{$token,\t1,\t$xlateLabelRef,\t$sequence,\n" . 1037 "\t\t0,\t$required,\t$tsol,\t$format}EOL"; 1038 1039 } else { # is a list 1040 my @type = split(/,/, $type); 1041 my @arraySize = (); 1042 my @id = split(/,/, $id); 1043 my @jniId = @id; 1044 my $dataType; 1045 my $typeCount = ($#type + 1); 1046 my @xlateType = (); 1047 my @default = (); 1048 1049 foreach my $dtype (@type) { 1050 my $jniId = shift @jniId; 1051 my $id = shift @id; 1052 my $arraySize = ''; 1053 $arraySize = $1 if ($dtype =~ s/\[(\d+)\]/[]/); 1054 1055 my $entryType = ${$entryDef{$dtype}}[0]; 1056 if ($entryType) { 1057 my $type = $dtype; 1058 $type =~ s/([^*]+)\s*(\*+)/$1 $2/; 1059 $type =~ s/\[\]//; 1060 1061 my $sizeString = "sizeof"; 1062 $sizeString = "$arraySize * " . $sizeString if $arraySize; 1063 push (@xlateType, "\{$entryType, $sizeString ($type)\}"); 1064 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]); 1065 } elsif ($type =~ /^msg/i) { 1066 $type =~ s/^msg//i; 1067 $dataType = 'ADT_MSG'; 1068 my $dataEnum = 'ADT_LIST_' . uc $type; 1069 push (@xlateType, "\{$dataType, $dataEnum\}};"); 1070 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]); 1071 } elsif ($type =~ /time_t/i) { 1072 $dataType = 'ADT_DATE'; 1073 push (@xlateType, "\{$entryType, sizeof ($type)\}"); 1074 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]); 1075 } elsif ($type =~ /termid/i) { 1076 $dataType = 'ADT_TERMIDSTAR'; 1077 push (@xlateType, "\{$dataType, sizeof (au_tid_addr_t *)\}"); 1078 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]); 1079 } elsif ($omitJNI) { 1080 # nothing to do. 1081 } else { 1082 print STDERR "$dtype is not an implemented data type\n"; 1083 } 1084 if (${$entryDef{$dtype}}[1]) { 1085 push (@default, $id, ${$entryDef{$dtype}}[1]); 1086 } 1087 } 1088 my $xlateArray = "\[$typeCount\] =\t{" . join(",\n\t\t\t\t", @xlateType) . "};"; 1089 1090 $xlateLine = 1091 "{$token,\t$typeCount,\t&$xlateLabel\[0\],\t$sequence,\n" . 1092 "\t\t0,\t$required,\t$tsol,\t$format}EOL"; 1093 } 1094 $xlateUniLabelInc++ if $xlateLabelInc; 1095 return ($xlateLine, \@jniLine); 1096} 1097 1098sub generateMsgLists { 1099 my $textList = shift; 1100 1101 my $textName = $textList->getId(); 1102 my $header = $textList->getHeader(); 1103 my $start = $textList->getMsgStart(); 1104 my $public = $textList->getMsgPublic(); 1105 my $deprecated = $textList->getDeprecated(); 1106 1107 print "$textName starts at $start\n" if $debug; 1108 1109 my $entry; 1110 my @entry; 1111 while ($entry = $textList->getNextMsg()) { 1112 if ($debug) { 1113 my ($id, $text) = split(/\s*::\s*/, $entry); 1114 print " $id = $text\n"; 1115 } 1116 unshift (@entry, $entry); 1117 } 1118 $msg_list{$textName} = 1119 [\@entry, [$header, $start, $public, $deprecated]]; 1120} 1121sub readAuditEventFile { 1122 my $eventListFile = shift; 1123 1124 open(Event, $eventListFile) 1125 or die "can't open $eventListFile: $!\n"; 1126 while(<Event>) { 1127 next if /^\s*#/; 1128 next if /^\s*$/; 1129 my ($value, $name) = split(/\s*:\s*/); 1130 next if $value < 6000; 1131 $eventCode{$name} = $value; 1132 } 1133 close Event; 1134} 1135 1136