#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# auditxml takes the audit record description (.xml file) and
# generates the files needed for the C audit api.
my $usage = <<EOF;
Usage: $prog [options] <xml-input-file>
Options:
-d Enable debug output
-e pfx Internal event prefix (default: AUE)
-i pfx Interface prefix (default: adt)
External event prefix is uppercase version of this string.
-o dir Output directory (default: current dir)
EOF
use auditxml;
use strict;
# <debug set="on"/> or <debug set="off"/> or <debug/>
# if the set attribute is omitted, debug state is toggled
# Override with appDebug, but toggle won't do what you
# want.
# Process command-line options
$opt_e = "";
$opt_i = "";
$opt_o = "";
}
my $uniLabel = "adr";
my $xlateUniLabelInc = 0;
# where everything comes from and where it goes:
my $xlateFile = "$outdir/${pfx_adt}_xlate.c";
my $headerFile = "$outdir/${pfx_adt}_event_N.h";
$filename =~ s|.*/||g;
my $genNotice = "
DO NOT EDIT. This file is auto generated by the Solaris Audit
system from $filename.
";
$genNotice =~ s/^\n//s;
$genNotice =~ s/\n$//s;
my %xlateEventTable = ();
my @xlateTypeList = ();
my %xlateTypeList = ();
my %eventAPI = ();
my %eventExtra = ();
my %headers = ();
my %externalIdNo = ();
my @outputState = ();
my %nameTranslation = ();
my @xlateDefaults = ();
my %xlateDefault = ();
my %msg_list = ();
my $event;
my $super;
} else {
}
# header file for API use
# c file table for translation
}
my $textList;
}
exit 0;
sub printTableC {
my $file = shift;
return;
}
my $notice = $genNotice;
print Cfile <<EOF;
/*
* $notice
*/
#include <bsm/libbsm.h>
#include <adt_xlate.h>
#include <libintl.h>
EOF
my $extDef;
}
@{$xlateEventTable{$eventId}};
my $entry;
my $externalRoot = $externalName;
$externalRoot =~ s/${pfx_AUE}_//;
my $externalId = $eventId;
$externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
}
else {
}
$entry =~ s/selfReference/$structName/;
}
}
} else {
}
}
my $firstEvent = 1;
$firstEvent = 0;
}
else {
}
}
# generate the Event preload() function
print Cfile <<EOF;
void
${pfx_adt}_preload(au_event_t event_id, adt_event_data_t *event_data)
{
switch (event_id) {
EOF
print Cfile <<EOF;
case $adtID:
EOF
my @preloads = @{$xlateDefault{$id}};
my $fieldName = shift @preloads;
print Cfile <<EOF;
event_data->$id.$fieldName = $default;
EOF
}
print Cfile <<EOF;
break;
EOF
}
print Cfile <<EOF;
default:
break;
}
}
#endif
EOF
my $listName;
my @listName;
my $listValue;
my $listLength = $#listValue + 1;
my $ffirst = 1;
$ffirst = 0;
}
else {
}
}
}
"] = {\n";
my $ffirst = 1;
$ffirst = 0;
}
}
}
sub printAPIFile {
my $file = shift;
my $xmlDoc = shift;
my @Hfile;
my $notice = $genNotice;
}
print Hfile <<EOF;
/*
* $notice
*/
#ifndef $adt_event_n
#define $adt_event_n
#include <bsm/$include>
#ifdef __cplusplus
extern "C" {
#endif
/*
* adt_put_event() status values. Positive values are for kernel-generated
* failure, -1 for user-space. For ADT_SUCCESS, the adt_put_event() return_val
* is not used; the convention is to set it to ADT_SUCCESS.
*/
#define ADT_SUCCESS 0
#define ADT_FAILURE -1
EOF
}
my $shortName = uc $listName;
$shortName =~ s/_TEXT//;
my $listValue;
my $i = 0;
my $j = $#listValue;
} else {
}
# ensure whole line does not exceed 80 chars
#expand tabs
# 77 = 80 - length(" */")
# strip off double tab so that comment can be longer
$line =~ s/\t\t/\t/;
# shorten eline; don't mind where the spaces are removed, it is
# only $eline length which matters
$eline =~ s/ {8}//;
}
# here we use negative length in substr to leave off from the
# right side; 74 = 77 - length("...")
# strip off part of last word (already cut)
} else {
}
}
}
# generate defines for external event names
next;
}
$l = 5 - int(($l + 8)/8);
$l = 1 if $l < 1;
}
# generate per-event structures
next;
}
my $externalId = $eventId;
$externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
my $entry;
} else {
$entry =~ s/termid/adt_termid_t/;
}
}
}
$outputState[$header] = 0;
}
# don't print duplicate error message
next;
}
$outputState[$header] = 1;
}
my $elementName = $eventId;
$elementName =~ s/^${pfx_AUE}_/${pfx_adt}_/;
$elementName =~ s/_t$//;
}
}
}
}
print Hfile <<EOF;
#ifndef ${pfx_ADT}_PRIVATE
#define ${pfx_ADT}_PRIVATE
/*
* These interfaces are project private and will change without
* notice as needed for the Solaris Audit project.
*/
extern void adt_get_auid(const adt_session_data_t *, au_id_t *);
extern void adt_set_auid(const adt_session_data_t *, const au_id_t);
extern void adt_get_mask(const adt_session_data_t *, au_mask_t *);
extern void adt_set_mask(const adt_session_data_t *, const au_mask_t *);
extern void adt_get_termid(const adt_session_data_t *, au_tid_addr_t *);
extern void adt_set_termid(const adt_session_data_t *,
const au_tid_addr_t *);
extern void adt_get_asid(const adt_session_data_t *, au_asid_t *);
extern void adt_set_asid(const adt_session_data_t *, const au_asid_t);
extern au_asid_t adt_get_unique_id(au_id_t);
extern void adt_load_table(const adt_session_data_t *, adt_translation_t **,
void (*preload)(au_event_t, adt_event_data_t *));
extern void ${pfx_adt}_preload(au_event_t, adt_event_data_t *);
extern adt_translation_t *${pfx_adt}_xlate_table[];
#endif
#ifdef __cplusplus
}
#endif
#endif /* $adt_event_n */
EOF
}
}
sub generateTableC {
my $event = shift;
my $eventId = shift;
my $eventType = shift;
my $eventHeader = shift;
my $omit = shift;
my %tokenType = (
#
# tokenTypes are the ones that are actually defined
# for use in adt.xml audit records
#
# 'acl' => 'AUT_ACL', # not defined
# 'arbitrary' => 'AUT_ARBITRARY', # not defined
# 'arg' => 'AUT_ARG', # not defined
# 'attr' => 'AUT_ATTR',
'command' => 'AUT_CMD',
'command_alt' => 'ADT_CMD_ALT', # dummy token id
# 'date' => 'AUT_TEXT', # not used
# 'exec_args' => 'AUT_EXEC_ARGS', # not defined
# 'exec_env' => 'AUT_EXEC_ENV', # not defined
# 'exit' => 'AUT_EXIT', # not defined
'fmri' => 'AUT_FMRI',
# 'groups' => 'AUT_GROUPS', # not defined
# 'header' => 'AUT_HEADER', # not defined
'in_peer' => 'ADT_IN_PEER', # dummy token id
'in_remote' => 'ADT_IN_REMOTE', # dummy token id
# 'ipc' => 'AUT_IPC', # not defined
# 'ipc_perm' => 'AUT_IPC_PERM', # not defined
'iport' => 'AUT_IPORT',
'label' => 'AUT_LABEL',
'newgroups' => 'AUT_NEWGROUPS',
# 'opaque' => 'AUT_OPAQUE', # not defined
'path' => 'AUT_PATH',
'path_list' => '-AUT_PATH', # dummy token id
'process' => 'AUT_PROCESS',
'priv_effective' => 'ADT_AUT_PRIV_E', # dummy token id
'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id
'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id
'return' => 'AUT_RETURN',
'secflags' => 'AUT_SECFLAGS',
# 'seq' => 'AUT_SEQ', # not defined
# 'socket' => 'AUT_SOCKET', # not defined
# 'socket-inet' => 'AUT_SOCKET_INET',
'subject' => 'AUT_SUBJECT',
'text' => 'AUT_TEXT',
'tid' => 'AUT_TID',
# 'trailer' => 'AUT_TRAILER', # not defined
'uauth' => 'AUT_UAUTH',
'user' => 'AUT_USER',
'zonename' => 'AUT_ZONENAME'
);
return;
}
} else {
}
return;
}
my $entryRef;
my $firstTokenIndex = 0; # djdj not used yet, djdj BUG!
# needs to be used by translate table
my @inputOrder;
}
my $i; # walk down the inputOrder list once
my $k = 1; # discover next in line
my $l = 0; # who should point to next in line
my $j;
if ($k == 1) {
$firstTokenIndex = $j;
} else {
}
$l = $j;
last;
}
}
$k++;
}
}
else { # default order -- input order same as output
my $i;
my $j;
my $j = $i + 1;
}
}
my $sequence = 0;
}
else {
}
}
else {
}
}
else {
$dataType =~ s/\s+//g; # remove blanks (char * => char*)
$enumGroup =~ s/^msg\s*//i;
}
my $tsol = 0;
my $token;
my $tokenName;
}
else {
}
}
else {
}
}
else {
print STDERR
}
$enumGroup, $omit);
}
$sequence++;
}
}
sub formatTableEntry {
$enumGroup, $omitEntry) = @_;
# does this map belong in the xml source? (at least the defaults?)
# fill in the default value only if it is other than zero.
# base type adt name, default value
'uint_t' => ['ADT_UINT32', ''],
'int' => ['ADT_INT', ''],
'int32_t' => ['ADT_INT32', ''],
'uid_t' => ['ADT_UID', 'AU_NOAUDITID'],
'gid_t' => ['ADT_GID', 'AU_NOAUDITID'],
'uid_t*' => ['ADT_UIDSTAR', ''],
'gid_t*' => ['ADT_GIDSTAR', ''],
'char' => ['ADT_CHAR', ''],
'char*' => ['ADT_CHARSTAR', ''],
'char**' => ['ADT_CHAR2STAR', ''],
'long' => ['ADT_LONG', ''],
'pid_t' => ['ADT_PID', ''],
'priv_set_t*' => ['ADT_PRIVSTAR', ''],
'ulong_t' => ['ADT_ULONG', ''],
'uint16_t', => ['ADT_UINT16', ''],
'uint32_t' => ['ADT_UINT32', ''],
'uint32_t*' => ['ADT_UINT32STAR', ''],
'uint32_t[]' => ['ADT_UINT32ARRAY', ''],
'uint64_t' => ['ADT_UINT64', ''],
'uint64_t*' => ['ADT_UINT64STAR', ''],
'm_label_t*' => ['ADT_MLABELSTAR', ''],
'fd_t' => ['ADT_FD', '-1'],
);
my $xlateLabelInc = 0;
# the list handling should be a simple loop with a loop of one
# falling out naturally.
my $dataType;
my $dataSize;
my $entryType = ${$entryDef{$type}}[0];
my $typeCount = 1;
$type =~ s/\[\]//;
}
} else {
}
$xlateLabelInc = 1;
} else {
}
# "EOL" is where a comma should go unless end of list
@list = @{$xlateDefault{$eventId}};
} else {
}
$xlateDefault{$eventId} = \@list;
}
} else { # is a list
my $dataType;
my $entryType = ${$entryDef{$dtype}}[0];
$type =~ s/\[\]//;
# nothing to do.
} else {
}
}
}
$xlateLabelInc = 1;
} else {
}
@list = @{$xlateDefault{$eventId}};
} else {
}
$xlateDefault{$eventId} = \@list;
}
}
}
sub generateAPIFile {
my $event = shift;
my $eventId = shift;
my $eventType = shift;
my $eventHeader = shift;
my $idNo = shift;
}
next;
}
$option = 'Trusted Solaris only'
}
}
print STDERR
$#id = $#type;
}
else {
$#type = $#id;
}
}
my $i;
for ($i = 0; $i <= $#type; $i++) {
}
}
else {
}
}
else {
}
}
}
$eventExtra{$eventId} = [$eventHeader, $idNo];
}
sub generateMsgLists {
my $textList = shift;
my $entry;
my @entry;
}
}
[\@entry, [$header, $start, $public, $deprecated]];
}
sub addHeader {
my $header_index = shift;
die "invalid adt_event_N.h index: $header_index\n"
}
# $header = 0 is a special case; it is for adt_event.h
# $header > 0 creates adt_event_N.h, where N = $header
sub openHeaderFiles {
my $outfile = shift; # path to an adt_event_N.h file
my $header;
} else {
}
} else {
$HfileName[$header] = $tmp[$#tmp];
}
}
}
sub closeHeaderFiles {
my @Hfile = @_;
my $header;
}
}