Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libbsm/auditxml
+++ new/usr/src/lib/libbsm/auditxml
1 1 #!/usr/perl5/bin/perl -w
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 #
23 23 # Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 # Use is subject to license terms.
25 25 #
26 26
27 27 # auditxml takes the audit record description (.xml file) and
28 28 # generates the files needed for the C audit api.
29 29
30 30 my $prog = $0; $prog =~ s|.*/||g;
31 31 my $usage = <<EOF;
32 32
33 33 Usage: $prog [options] <xml-input-file>
34 34 Options:
35 35 -d Enable debug output
36 36 -e pfx Internal event prefix (default: AUE)
37 37 -i pfx Interface prefix (default: adt)
38 38 External event prefix is uppercase version of this string.
39 39 -o dir Output directory (default: current dir)
40 40
41 41 EOF
42 42
43 43 use auditxml;
44 44 use Getopt::Std;
45 45 use strict;
46 46
47 47 our $debug = 0; # normal use is to set via the file being parsed.
48 48 # <debug set="on"/> or <debug set="off"/> or <debug/>
49 49 # if the set attribute is omitted, debug state is toggled
50 50 # Override with appDebug, but toggle won't do what you
51 51 # want.
52 52 my $appDebug = 0; # used after return from "new auditxml";
53 53
54 54 # Process command-line options
55 55 our ($opt_d, $opt_e, $opt_i, $opt_o);
56 56 $opt_e = "";
57 57 $opt_i = "";
58 58 $opt_o = "";
59 59 if (!getopts('de:i:o:') || $#ARGV != 0) {
60 60 die $usage;
61 61 }
62 62 my $outdir = $opt_o || ".";
63 63 my $pfx_adt = lc($opt_i) || "adt";
64 64 my $pfx_ADT = uc($pfx_adt);
65 65 my $pfx_AUE = uc($opt_e) || "AUE";
66 66
67 67 $appDebug = $opt_d;
68 68
69 69 my $uniLabel = "adr";
70 70 my $xlateUniLabelInc = 0;
71 71
72 72
73 73 # where everything comes from and where it goes:
74 74
75 75 my $xlateFile = "$outdir/${pfx_adt}_xlate.c";
76 76 my $headerFile = "$outdir/${pfx_adt}_event_N.h";
77 77
78 78 my $filename = $ARGV[0]; # input XML file
79 79 my $doc = new auditxml ($filename);
80 80 $filename =~ s|.*/||g;
81 81
82 82 $debug = $appDebug;
83 83
84 84 my $genNotice = "
85 85 DO NOT EDIT. This file is auto generated by the Solaris Audit
86 86 system from $filename.
87 87
88 88 See http://opensolaris.org/os/project/audit/
89 89 ";
90 90
91 91 # trim leading/trailing newlines
92 92 $genNotice =~ s/^\n//s;
93 93 $genNotice =~ s/\n$//s;
94 94
95 95 my %xlateEventTable = ();
96 96 my @xlateTypeList = ();
97 97 my %xlateTypeList = ();
98 98 my %eventAPI = ();
99 99 my %eventExtra = ();
100 100 my %headers = ();
101 101 my %externalIdNo = ();
102 102 my @outputState = ();
103 103 my %nameTranslation = ();
104 104 my @xlateDefaults = ();
105 105 my %xlateDefault = ();
106 106 my %msg_list = ();
107 107
108 108 my $event;
109 109 while ($event = $doc->getNextEvent()) {
110 110 my $eventId = $event->getId();
111 111 my $eventHeader = $event->getHeader();
112 112 my $idNo = $event->getIdNo();
113 113 $externalIdNo{$eventId} = $idNo;
114 114 addHeader($eventHeader) if defined ($eventHeader);
115 115 my $super;
116 116 my $omit = $event->getOmit();
117 117 my $eventType = '';
118 118 if ($super = $event->getSuperClass()) {
119 119 $event = $super;
120 120 $eventType = 'instance';
121 121 } else {
122 122 $eventType = $event->getType();
123 123 }
124 124
125 125 # header file for API use
126 126 generateAPIFile($event, $eventId, $eventType, $eventHeader, $idNo)
127 127 unless $omit eq 'always';
128 128
129 129 # c file table for translation
130 130 generateTableC($event, $eventId, $eventType, $eventHeader, $omit);
131 131 }
132 132
133 133 my $textList;
134 134 while ($textList = $doc->getNextMsgId()) {
135 135 generateMsgLists($textList); # enum -> text mappings
136 136 }
137 137
138 138 printTableC($xlateFile);
139 139 printAPIFile($headerFile, $doc);
140 140
141 141 exit 0;
142 142
143 143
144 144 sub printTableC {
145 145 my $file = shift;
146 146
147 147 unless (open(Cfile, ">$file")) {
148 148 print STDERR "can't open output file ($file): $!\n";
149 149 return;
150 150 }
151 151
152 152 my $notice = $genNotice;
153 153 $notice =~ s/\n/\n * /gs;
154 154 $notice =~ s/\s+\n/\n/gs;
155 155 print Cfile <<EOF;
156 156 /*
157 157 * $notice
158 158 */
159 159
160 160 #include <bsm/libbsm.h>
161 161 #include <adt_xlate.h>
162 162 #include <libintl.h>
163 163
164 164 EOF
165 165 print Cfile "#ifndef _PRAUDIT\n";
166 166 print Cfile "/* Internal data type definitions */\n\n";
167 167 my $extDef;
168 168 foreach $extDef (@xlateTypeList) {
169 169 print Cfile "static $extDef\n";
170 170 }
171 171 @xlateTypeList = ();
172 172
173 173 print Cfile "\n/* External event structure to internal event structure */\n\n";
174 174
175 175 my @pointers = ();
176 176
177 177 foreach my $eventId (sort keys %xlateEventTable) {
178 178 if ($xlateEventTable{$eventId}) {
179 179 my ($ref1, $eventType, $firstToken, $eventHeader) =
180 180 @{$xlateEventTable{$eventId}};
181 181 my @entries = @$ref1;
182 182 my $entry;
183 183 my $entries = $#entries;
184 184 my $count = $entries + 1;
185 185 my $externalName = $nameTranslation{$eventId};
186 186 my $externalRoot = $externalName;
187 187 $externalRoot =~ s/${pfx_AUE}_//;
188 188 my $structName = "XX_$externalRoot";
189 189 my $root = $eventId;
190 190 $root =~ s/${pfx_AUE}_//;
191 191 my $externalId = $eventId;
192 192 $externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
193 193
194 194 unless ($eventType eq 'generic') {
195 195 print Cfile "static struct entry $structName\[$count\] = {\n";
196 196 foreach $entry (@entries) {
197 197 if ($entries--) {
198 198 $entry =~ s/EOL/,/;
199 199 }
200 200 else {
201 201 $entry =~ s/EOL//;
202 202 }
203 203 $entry =~ s/selfReference/$structName/;
204 204 print Cfile "\t$entry\n";
205 205 }
206 206 print Cfile "};\n";
207 207
208 208 print Cfile "static struct translation X_$externalRoot = {\n";
209 209 push (@pointers, "X_$externalRoot");
210 210
211 211 print Cfile "\t0,\n"; # tx_offsetsCalculated = 0
212 212 print Cfile "\t$externalId,\n";
213 213 print Cfile "\t$externalName,\n";
214 214
215 215 print Cfile "\t$count,\n";
216 216 print Cfile "\t&XX_$externalRoot\[$firstToken\],\n";
217 217 print Cfile "\t&XX_$externalRoot\[0\]\n};\n";
218 218 }
219 219 } else {
220 220 print STDERR "expected entry for $eventId but none found\n";
221 221 }
222 222 }
223 223
224 224 my $count = $#pointers + 2;
225 225 print Cfile "adt_translation_t *${pfx_adt}_xlate_table[$count] = {\n";
226 226
227 227 my $firstEvent = 1;
228 228 foreach my $eventId (@pointers) {
229 229 if ($firstEvent) {
230 230 $firstEvent = 0;
231 231 }
232 232 else {
233 233 print Cfile ",\n";
234 234 }
235 235 print Cfile "\t&$eventId";
236 236 }
237 237 print Cfile ",\n\tNULL\n};\n";
238 238
239 239 # generate the Event preload() function
240 240
241 241 print Cfile <<EOF;
242 242
243 243 void
244 244 ${pfx_adt}_preload(au_event_t event_id, adt_event_data_t *event_data)
245 245 {
246 246 switch (event_id) {
247 247 EOF
248 248
249 249 foreach my $id (@xlateDefaults) {
250 250 my $adtID = $id;
251 251 $adtID =~ s/${pfx_AUE}/${pfx_ADT}/;
252 252
253 253 print Cfile <<EOF;
254 254 case $adtID:
255 255 EOF
256 256 my @preloads = @{$xlateDefault{$id}};
257 257 while (@preloads) {
258 258 my $fieldName = shift @preloads;
259 259 my $default = shift @preloads;
260 260 $id =~ s/${pfx_AUE}_/${pfx_adt}_/;
261 261
262 262 print Cfile <<EOF;
263 263 event_data->$id.$fieldName = $default;
264 264 EOF
265 265 }
266 266
267 267 print Cfile <<EOF;
268 268 break;
269 269 EOF
270 270 }
271 271
272 272 print Cfile <<EOF;
273 273 default:
274 274 break;
275 275 }
276 276 }
277 277 #endif
278 278
279 279 EOF
280 280
281 281 print Cfile "/* message lists */\n\n";
282 282 my $listName;
283 283 my @listName;
284 284 foreach $listName (sort keys %msg_list) {
285 285 my ($listRef, $headref) = @{$msg_list{$listName}};
286 286 my ($header, $start, $public, $deprecated) = @$headref;
287 287
288 288 my @listValue = @$listRef;
289 289 my $listValue;
290 290 my $listLength = $#listValue + 1;
291 291
292 292 $listName = 'NULL' if ($#listValue < 0);
293 293
294 294 push (@listName, [$listName, $listLength - 1, $start, $public]);
295 295
296 296 next if ($#listValue < 0);
297 297
298 298 print Cfile "/* Deprecated message list */\n" if ($deprecated);
299 299 print Cfile "static char *msg_$listName\[$listLength] = {\n";
300 300
301 301 my $ffirst = 1;
302 302 foreach $listValue (@listValue) {
303 303 print Cfile ",\n" unless $ffirst;
304 304 $ffirst = 0;
305 305 my ($id, $text) = split(/\s*::\s*/, $listValue);
306 306 if ($text) {
307 307 print Cfile "\t\"$text\"";
308 308 }
309 309 else {
310 310 print Cfile "\tNULL";
311 311 }
312 312 }
313 313 print Cfile "\n};\n";
314 314 }
315 315
316 316 if ($#listName >= 0) {
317 317 print Cfile "\nstruct msg_text ${pfx_adt}_msg_text[", $#listName + 1,
318 318 "] = {\n";
319 319 my $ffirst = 1;
320 320 foreach $listName (@listName) {
321 321 my ($name, $max, $start) = @$listName;
322 322 $start = -$start if $start;
323 323 print Cfile ",\n" unless $ffirst;
324 324 $ffirst = 0;
325 325 $name = "msg_$name" if ($name ne 'NULL');
326 326 print Cfile "\t{0, $max, $name, $start}";
327 327 }
328 328 print Cfile "\n};\n";
329 329 }
330 330
331 331 close Cfile;
332 332 }
333 333
334 334 sub printAPIFile {
335 335 my $file = shift;
336 336 my $xmlDoc = shift;
337 337
338 338 my @Hfile;
339 339 @Hfile = openHeaderFiles($file);
340 340
341 341 my $notice = $genNotice;
342 342 $notice =~ s/\n/\n * /gs;
343 343 $notice =~ s/\s+\n/\n/gs;
344 344
345 345 foreach my $header (keys %headers) {
346 346 next unless $Hfile[$header];
347 347 *Hfile = $Hfile[$header];
348 348 my $include = "adt.h";
349 349 my $adt_event_n = "_${pfx_ADT}_EVENT_H";
350 350 if ($header > 0) {
351 351 $include = "${pfx_adt}_event.h";
352 352 $adt_event_n = "_${pfx_ADT}_EVENT_".$header."_H";
353 353 }
354 354 print Hfile <<EOF;
355 355 /*
356 356 * $notice
357 357 */
358 358
359 359 #ifndef $adt_event_n
360 360 #define $adt_event_n
361 361
362 362 #include <bsm/$include>
363 363
364 364 #ifdef __cplusplus
365 365 extern "C" {
366 366 #endif
367 367
368 368 /*
369 369 * adt_put_event() status values. Positive values are for kernel-generated
370 370 * failure, -1 for user-space. For ADT_SUCCESS, the adt_put_event() return_val
371 371 * is not used; the convention is to set it to ADT_SUCCESS.
372 372 */
373 373 #define ADT_SUCCESS 0
374 374 #define ADT_FAILURE -1
375 375
376 376 EOF
377 377 }
378 378
379 379 foreach my $listName (sort keys %msg_list) {
380 380 my $shortName = uc $listName;
381 381 $shortName =~ s/_TEXT//;
382 382
383 383 my ($listRef, $headref) = @{$msg_list{$listName}};
384 384 my ($header, $start, $public, $deprecated) = @$headref;
385 385 next unless $Hfile[$header];
386 386 *Hfile = $Hfile[$header];
387 387
388 388 print Hfile "/* Deprecated message list */\n" if $deprecated;
389 389 print Hfile "#define\t${pfx_ADT}_$shortName\t$start\n" if $start;
390 390
391 391 my @listValue = @$listRef;
392 392 next unless ($#listValue >= 0);
393 393 print Hfile "enum\t${pfx_adt}_$listName", " {\n";
394 394
395 395 my $listValue;
396 396 my $i = 0;
397 397 my $j = $#listValue;
398 398 my $comma = ',';
399 399 foreach $listValue (@listValue) {
400 400 my ($id, $text) = split(/\s*::\s*/, $listValue);
401 401 $comma = '' if $i++ == $j;
402 402 if ($start) {
403 403 $start = " = $start$comma";
404 404 } else {
405 405 $start = "$comma\t";
406 406 }
407 407 $text = "(no token will be generated)" unless $text;
408 408 my $line = "\t${pfx_ADT}_$shortName"."_$id$start\t/* ";
409 409 # ensure whole line does not exceed 80 chars
410 410 my $eline = $line.$text;
411 411 #expand tabs
412 412 1 while $eline =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
413 413 if ((length($eline) > 77) && ($line =~ /\t\t/)) {
414 414 # 77 = 80 - length(" */")
415 415 # strip off double tab so that comment can be longer
416 416 $line =~ s/\t\t/\t/;
417 417 # shorten eline; don't mind where the spaces are removed, it is
418 418 # only $eline length which matters
419 419 $eline =~ s/ {8}//;
420 420 }
421 421 if (length($eline) > 77) { # 80 - length(" */")
422 422 # here we use negative length in substr to leave off from the
423 423 # right side; 74 = 77 - length("...")
424 424 $line .= substr($text, 0, 74 - length($eline));
425 425 # strip off part of last word (already cut)
426 426 $line =~ s/\s(\S+)$/ /;
427 427 $line .= "...";
428 428 } else {
429 429 $line .= $text;
430 430 }
431 431 print Hfile "$line */\n";
432 432 $start = '';
433 433 }
434 434 print Hfile "};\n";
435 435 }
436 436
437 437 # generate defines for external event names
438 438
439 439 foreach my $eventId (sort keys %eventAPI) {
440 440 my ($header, $idNo) = @{$eventExtra{$eventId}};
441 441 unless (defined ($header)) {
442 442 print STDERR "missing header selection for $eventId\n";
443 443 next;
444 444 }
445 445 *Hfile = $Hfile[$header];
446 446 next unless $Hfile[$header];
447 447
448 448 my $l = length($eventId) + 8; # label plus preceding #define\t
449 449 $l = 5 - int(($l + 8)/8);
450 450 $l = 1 if $l < 1;
451 451 my $tab = "\t" x $l;
452 452
453 453 print STDERR "missing id number for $eventId\n" unless $idNo;
454 454
455 455 $eventId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
456 456 print Hfile "#define\t$eventId$tab$idNo\n";
457 457 }
458 458
459 459
460 460 # generate per-event structures
461 461
462 462 foreach my $eventId (sort keys %eventAPI) {
463 463 my ($header, $idNo) = @{$eventExtra{$eventId}};
464 464 my $dataId = $eventId;
465 465 $dataId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
466 466 unless(defined ($header)) {
467 467 print STDERR "$eventId is missing the header assignment\n";
468 468 next;
469 469 }
470 470 *Hfile = $Hfile[$header];
471 471 next unless $Hfile[$header];
472 472
473 473 my $externalId = $eventId;
474 474 $externalId =~ s/${pfx_AUE}_/${pfx_ADT}_/;
475 475
476 476 print Hfile "\nstruct $dataId {\t/* $externalId */\n";
477 477
478 478 my @entries = @{$eventAPI{$eventId}};
479 479 my $entry;
480 480 if ($#entries < 0) {
481 481 print Hfile "\tint\tdummy;\t/* not used */\n";
482 482 } else {
483 483 foreach $entry (@entries) {
484 484 $entry =~ s/termid/adt_termid_t/;
485 485 print Hfile "\t$entry\n";
486 486 }
487 487 }
488 488 print Hfile "};\n";
489 489 $eventId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
490 490 print Hfile "typedef struct $dataId $eventId","_t;\n";
491 491 }
492 492
493 493 foreach my $header (sort keys %headers) {
494 494 $outputState[$header] = 0;
495 495 }
496 496
497 497 foreach my $eventId (sort keys %eventAPI) {
498 498 my ($header, $idNo) = @{$eventExtra{$eventId}};
499 499 unless(defined ($header)) {
500 500 # don't print duplicate error message
501 501 next;
502 502 }
503 503 *Hfile = $Hfile[$header];
504 504 next unless $Hfile[$header];
505 505 if ($outputState[$header] == 0) {
506 506 $outputState[$header] = 1;
507 507 my $suffix = '';
508 508 $suffix = "_$header" if $header;
509 509 print Hfile "\nunion adt_event_data$suffix {\n";
510 510 }
511 511 my $elementName = $eventId;
512 512 $elementName =~ s/^${pfx_AUE}_/${pfx_adt}_/;
513 513 $eventId =~ s/^${pfx_AUE}_/${pfx_adt}_/;
514 514 $elementName =~ s/_t$//;
515 515
516 516 print Hfile "\t\t$eventId","_t\t$elementName;\n";
517 517 }
518 518 foreach my $header (sort keys %headers) {
519 519 if ($outputState[$header]) {
520 520 *Hfile = $Hfile[$header];
521 521 next unless $Hfile[$header];
522 522 print Hfile "};\n";
523 523 }
524 524 }
525 525 foreach my $header (keys %headers) {
526 526 next unless $Hfile[$header];
527 527 *Hfile = $Hfile[$header];
528 528 my $adt_event_n = "_${pfx_ADT}_EVENT_H";
529 529 if ($header > 0) {
530 530 $adt_event_n = "_${pfx_ADT}_EVENT_".$header."_H";
531 531 }
532 532 print Hfile <<EOF;
533 533
534 534
535 535 #ifndef ${pfx_ADT}_PRIVATE
536 536 #define ${pfx_ADT}_PRIVATE
537 537
538 538 /*
539 539 * These interfaces are project private and will change without
540 540 * notice as needed for the Solaris Audit project.
541 541 */
542 542
543 543 extern void adt_get_auid(const adt_session_data_t *, au_id_t *);
544 544 extern void adt_set_auid(const adt_session_data_t *, const au_id_t);
545 545
546 546 extern void adt_get_mask(const adt_session_data_t *, au_mask_t *);
547 547 extern void adt_set_mask(const adt_session_data_t *, const au_mask_t *);
548 548
549 549 extern void adt_get_termid(const adt_session_data_t *, au_tid_addr_t *);
550 550 extern void adt_set_termid(const adt_session_data_t *,
551 551 const au_tid_addr_t *);
552 552
553 553 extern void adt_get_asid(const adt_session_data_t *, au_asid_t *);
554 554 extern void adt_set_asid(const adt_session_data_t *, const au_asid_t);
555 555 extern au_asid_t adt_get_unique_id(au_id_t);
556 556 extern void adt_load_table(const adt_session_data_t *, adt_translation_t **,
557 557 void (*preload)(au_event_t, adt_event_data_t *));
558 558
559 559 extern void ${pfx_adt}_preload(au_event_t, adt_event_data_t *);
560 560
561 561 extern adt_translation_t *${pfx_adt}_xlate_table[];
562 562
563 563 #endif
564 564
565 565 #ifdef __cplusplus
566 566 }
567 567 #endif
568 568
569 569 #endif /* $adt_event_n */
570 570 EOF
571 571 }
572 572 closeHeaderFiles(@Hfile);
573 573 }
574 574
575 575 sub generateTableC {
576 576 my $event = shift;
577 577 my $eventId = shift;
578 578 my $eventType = shift;
579 579 my $eventHeader = shift;
580 580 my $omit = shift;
581 581
582 582 my %tokenType = (
583 583 #
584 584 # tokenTypes are the ones that are actually defined
585 585 # for use in adt.xml audit records
586 586 #
587 587
588 588 # 'acl' => 'AUT_ACL', # not defined
589 589 # 'arbitrary' => 'AUT_ARBITRARY', # not defined
590 590 # 'arg' => 'AUT_ARG', # not defined
591 591 # 'attr' => 'AUT_ATTR',
592 592 'command' => 'AUT_CMD',
593 593 'command_alt' => 'ADT_CMD_ALT', # dummy token id
594 594 # 'date' => 'AUT_TEXT', # not used
595 595 # 'exec_args' => 'AUT_EXEC_ARGS', # not defined
596 596 # 'exec_env' => 'AUT_EXEC_ENV', # not defined
597 597 # 'exit' => 'AUT_EXIT', # not defined
598 598 'fmri' => 'AUT_FMRI',
599 599 # 'groups' => 'AUT_GROUPS', # not defined
600 600 # 'header' => 'AUT_HEADER', # not defined
601 601 'in_peer' => 'ADT_IN_PEER', # dummy token id
602 602 'in_remote' => 'ADT_IN_REMOTE', # dummy token id
603 603 # 'ipc' => 'AUT_IPC', # not defined
604 604 # 'ipc_perm' => 'AUT_IPC_PERM', # not defined
605 605 'iport' => 'AUT_IPORT',
↓ open down ↓ |
605 lines elided |
↑ open up ↑ |
606 606 'label' => 'AUT_LABEL',
607 607 'newgroups' => 'AUT_NEWGROUPS',
608 608 # 'opaque' => 'AUT_OPAQUE', # not defined
609 609 'path' => 'AUT_PATH',
610 610 'path_list' => '-AUT_PATH', # dummy token id
611 611 'process' => 'AUT_PROCESS',
612 612 'priv_effective' => 'ADT_AUT_PRIV_E', # dummy token id
613 613 'priv_limit' => 'ADT_AUT_PRIV_L', # dummy token id
614 614 'priv_inherit' => 'ADT_AUT_PRIV_I', # dummy token id
615 615 'return' => 'AUT_RETURN',
616 + 'secflags' => 'AUT_SECFLAGS',
616 617 # 'seq' => 'AUT_SEQ', # not defined
617 618 # 'socket' => 'AUT_SOCKET', # not defined
618 619 # 'socket-inet' => 'AUT_SOCKET_INET',
619 620 'subject' => 'AUT_SUBJECT',
620 621 'text' => 'AUT_TEXT',
621 622 'tid' => 'AUT_TID',
622 623 # 'trailer' => 'AUT_TRAILER', # not defined
623 624 'uauth' => 'AUT_UAUTH',
624 625 'user' => 'AUT_USER',
625 626 'zonename' => 'AUT_ZONENAME'
626 627 );
627 628
628 629 my @xlateEntryList = ();
629 630
630 631 my $external = $event->getExternal();
631 632 my $internal = $event->getInternal();
632 633
633 634 unless ($external) {
634 635 print STDERR "No external object captured for event $eventId\n";
635 636 return;
636 637 }
637 638 if ($eventType) {
638 639 $nameTranslation{$eventId} = $eventId;
639 640 } else {
640 641 $nameTranslation{$eventId} = $external->getInternalName();
641 642 }
642 643 unless ($internal) {
643 644 print STDERR "No internal object captured for event $eventId\n";
644 645 return;
645 646 }
646 647 my @entryRef = $internal->getEntries();
647 648 my $entryRef;
648 649 my @tokenOrder = ();
649 650 my $firstTokenIndex = 0; # djdj not used yet, djdj BUG!
650 651 # needs to be used by translate table
651 652
652 653 if ($internal->isReorder()) { # prescan the entry list to get the token order
653 654 my @inputOrder;
654 655 foreach $entryRef (@entryRef) {
655 656 my ($intEntry, $entry) = @$entryRef;
656 657 push (@inputOrder, $intEntry->getAttr('order'));
657 658 }
658 659
659 660 my $i; # walk down the inputOrder list once
660 661 my $k = 1; # discover next in line
661 662 my $l = 0; # who should point to next in line
662 663 for ($i = 0; $i <= $#inputOrder; $i++) {
663 664 my $j;
664 665 for ($j = 0; $j <= $#inputOrder; $j++) {
665 666 if ($k == $inputOrder[$j]) {
666 667 if ($k == 1) {
667 668 $firstTokenIndex = $j;
668 669 } else {
669 670 $tokenOrder[$l] = "&(selfReference[$j])";
670 671 }
671 672 $l = $j;
672 673 last;
673 674 }
674 675 }
675 676 $k++;
676 677 }
677 678 $tokenOrder[$l] = 'NULL';
678 679 }
679 680 else { # default order -- input order same as output
680 681 my $i;
681 682 my $j;
682 683 for ($i = 0; $i < $#entryRef; $i++) {
683 684 my $j = $i + 1;
684 685 $tokenOrder[$i] = "&(selfReference[$j])";
685 686 }
686 687 $tokenOrder[$#entryRef] = 'NULL';
687 688 }
688 689
689 690 my $sequence = 0;
690 691 foreach $entryRef (@entryRef) {
691 692 my ($intEntry, $entry) = @$entryRef;
692 693 my $entryId = $entry->getAttr('id');
693 694
694 695 my ($extEntry, $unusedEntry, $tokenId) =
695 696 $external->getEntry($entryId);
696 697 my $opt = $extEntry->getAttr('opt');
697 698
698 699 if ($opt eq 'none') {
699 700 if (defined ($doc->getToken($tokenId))) {
700 701 if (defined ($tokenType{$tokenId})) {
701 702 $tokenId = $tokenType{$tokenId};
702 703 }
703 704 else {
704 705 print STDERR "token id $tokenId not implemented\n";
705 706 }
706 707 }
707 708 else {
708 709 print STDERR "token = $tokenId is undefined\n";
709 710 $tokenId = 'error';
710 711 }
711 712 my ($xlate, $jni) =
712 713 formatTableEntry ('', $tokenId, $eventId, '', 0, 0,
713 714 $tokenOrder[$sequence], 'NULL', '', $omit);
714 715 push (@xlateEntryList, $xlate);
715 716 }
716 717 else {
717 718 my $dataType = $extEntry->getAttr('type');
718 719 $dataType =~ s/\s+//g; # remove blanks (char * => char*)
719 720
720 721 my $enumGroup = '';
721 722 if ($dataType =~ /^msg/i) {
722 723 $enumGroup = $dataType;
723 724 $enumGroup =~ s/^msg\s*//i;
724 725 $enumGroup = "${pfx_adt}_" . $enumGroup;
725 726 }
726 727 my $required = ($opt eq 'required') ? 1 : 0;
727 728 my $tsol = 0;
728 729 my $tokenId = $intEntry->getAttr('token');
729 730 my $token;
730 731 my $tokenName;
731 732 my $tokenFormat = $intEntry->getAttr('format');
732 733 if (defined ($tokenFormat)) {
733 734 $tokenFormat = "\"$tokenFormat\"";
734 735 }
735 736 else {
736 737 $tokenFormat = 'NULL';
737 738 }
738 739
739 740 if (defined ($token = $doc->getToken($tokenId))) {
740 741 $tsol = (lc $token->getUsage() eq 'tsol') ? 1 : 0;
741 742 if (defined ($tokenType{$tokenId})) {
742 743 $tokenName = $tokenType{$tokenId};
743 744 }
744 745 else {
745 746 print STDERR "token id $tokenId not implemented\n";
746 747 }
747 748 }
748 749 else {
749 750 print STDERR
750 751 "$tokenId is an unimplemented token ($entryId in $eventId)\n";
751 752 $tokenName = 'AUT_TEXT';
752 753 }
753 754 my ($xlate, $jni) =
754 755 formatTableEntry($entryId, $tokenName, $eventId, $dataType, $required,
755 756 $tsol, $tokenOrder[$sequence], $tokenFormat,
756 757 $enumGroup, $omit);
757 758 push (@xlateEntryList, $xlate);
758 759 }
759 760 $sequence++;
760 761 }
761 762 $xlateEventTable{$eventId} = [\@xlateEntryList, $eventType, $firstTokenIndex,
762 763 $eventHeader];
763 764 }
764 765
765 766 sub formatTableEntry {
766 767 my ($id, $token, $eventId, $type, $required, $tsol, $sequence, $format,
767 768 $enumGroup, $omitEntry) = @_;
768 769
769 770
770 771 # does this map belong in the xml source? (at least the defaults?)
771 772 # fill in the default value only if it is other than zero.
772 773 # base type adt name, default value
773 774 my %entryDef = ( 'au_asid_t' => ['ADT_UINT32', ''],
774 775 'uint_t' => ['ADT_UINT32', ''],
775 776 'int' => ['ADT_INT', ''],
776 777 'int32_t' => ['ADT_INT32', ''],
777 778 'uid_t' => ['ADT_UID', 'AU_NOAUDITID'],
778 779 'gid_t' => ['ADT_GID', 'AU_NOAUDITID'],
779 780 'uid_t*' => ['ADT_UIDSTAR', ''],
780 781 'gid_t*' => ['ADT_GIDSTAR', ''],
781 782 'char' => ['ADT_CHAR', ''],
782 783 'char*' => ['ADT_CHARSTAR', ''],
783 784 'char**' => ['ADT_CHAR2STAR', ''],
784 785 'long' => ['ADT_LONG', ''],
785 786 'pid_t' => ['ADT_PID', ''],
786 787 'priv_set_t*' => ['ADT_PRIVSTAR', ''],
787 788 'ulong_t' => ['ADT_ULONG', ''],
788 789 'uint16_t', => ['ADT_UINT16', ''],
789 790 'uint32_t' => ['ADT_UINT32', ''],
790 791 'uint32_t*' => ['ADT_UINT32STAR', ''],
791 792 'uint32_t[]' => ['ADT_UINT32ARRAY', ''],
792 793 'uint64_t' => ['ADT_UINT64', ''],
793 794 'uint64_t*' => ['ADT_UINT64STAR', ''],
794 795 'm_label_t*' => ['ADT_MLABELSTAR', ''],
795 796 'fd_t' => ['ADT_FD', '-1'],
796 797 );
797 798 my $xlateLabel = $uniLabel.$xlateUniLabelInc;
798 799 my $xlateLabelInc = 0;
799 800 my $xlateLine = '';
800 801 my @jniLine = ();
801 802
802 803 # the list handling should be a simple loop with a loop of one
803 804 # falling out naturally.
804 805
805 806 unless ($type =~ /,/) { # if list, then generate sequence of entries
806 807 my $dataType;
807 808 my $dataSize;
808 809 my $xlateLabelRef = '';
809 810
810 811 my $arraySize = '';
811 812 $arraySize = $1 if ($type =~ s/\[(\d+)\]/[]/);
812 813
813 814 my $entryType = ${$entryDef{$type}}[0];
814 815
815 816 my @xlateType = (); # for adt_xlate.c
816 817 my $typeCount = 1;
817 818
818 819 if ($entryType) {
819 820 $dataType = $entryType;
820 821 $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
821 822 $type =~ s/\[\]//;
822 823 $dataSize = "sizeof ($type)";
823 824 if ($arraySize) {
824 825 $dataSize = "$arraySize * " . $dataSize;
825 826 }
826 827 $xlateLine = "{{$dataType, $dataSize}}";
827 828 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
828 829 } elsif ($type eq '') {
829 830 $xlateLabelRef = 'NULL';
830 831 } elsif ($type =~ /^msg/i) {
831 832 $type =~ s/^msg//i;
832 833 $dataType = 'ADT_MSG';
833 834 my $dataEnum = 'ADT_LIST_' . uc $type;
834 835 $xlateLine = "{{$dataType, $dataEnum}}";
835 836 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
836 837 } elsif ($type =~ /time_t/i) {
837 838 $dataType = 'ADT_DATE';
838 839 $dataSize = "sizeof (time_t)";
839 840 $xlateLine = "{{$dataType, $dataSize}}";
840 841 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
841 842 } elsif ($type =~ /termid/i) {
842 843 $dataType = 'ADT_TERMIDSTAR';
843 844 $dataSize = "sizeof (au_tid_addr_t *)";
844 845 $xlateLine = "{{$dataType, $dataSize}}";
845 846 push (@jniLine, [$id, $dataType, $format, $enumGroup, $required]);
846 847 } elsif (uc $omitEntry eq 'JNI') {
847 848 $xlateLabelRef = 'NULL';
848 849 } else {
849 850 print STDERR "$type is not an implemented data type\n";
850 851 $xlateLabelRef = 'NULL';
851 852 }
852 853 if ($xlateLine && !($xlateTypeList{$xlateLine})) {
853 854 $xlateTypeList{$xlateLine} = $xlateLabel;
854 855 push (@xlateTypeList, "datadef\t$xlateLabel\[1\] =\t$xlateLine;");
855 856 $xlateLabelInc = 1;
856 857 } else {
857 858 $xlateLabel = $xlateTypeList{$xlateLine};
858 859 }
859 860 $xlateLabelRef = '&' . $xlateLabel . '[0]'
860 861 unless $xlateLabelRef eq 'NULL';
861 862
862 863 # "EOL" is where a comma should go unless end of list
863 864 $xlateLine = "{$token,\t1,\t$xlateLabelRef,\t$sequence,\n" .
864 865 "\t\t0,\t$required,\t$tsol,\t$format}EOL";
865 866
866 867 if (uc $omitEntry ne 'ALWAYS' && ${$entryDef{$type}}[1]) {
867 868 my @list = ();
868 869 if ($xlateDefault{$eventId}) {
869 870 @list = @{$xlateDefault{$eventId}};
870 871 } else {
871 872 push (@xlateDefaults, $eventId);
872 873 }
873 874 push (@list, $id, ${$entryDef{$type}}[1]);
874 875 $xlateDefault{$eventId} = \@list;
875 876 }
876 877 } else { # is a list
877 878 my @type = split(/,/, $type);
878 879 my @arraySize = ();
879 880 my @id = split(/,/, $id);
880 881 my @jniId = @id;
881 882 my $dataType;
882 883 my $typeCount = ($#type + 1);
883 884 my @xlateType = ();
884 885 my @default = ();
885 886
886 887 foreach my $dtype (@type) {
887 888 my $jniId = shift @jniId;
888 889 my $id = shift @id;
889 890 my $arraySize = '';
890 891 $arraySize = $1 if ($dtype =~ s/\[(\d+)\]/[]/);
891 892
892 893 my $entryType = ${$entryDef{$dtype}}[0];
893 894 if ($entryType) {
894 895 my $type = $dtype;
895 896 $type =~ s/([^*]+)\s*(\*+)/$1 $2/;
896 897 $type =~ s/\[\]//;
897 898
898 899 my $sizeString = "sizeof";
899 900 $sizeString = "$arraySize * " . $sizeString if $arraySize;
900 901 push (@xlateType, "\{$entryType, $sizeString ($type)\}");
901 902 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
902 903 } elsif ($type =~ /^msg/i) {
903 904 $type =~ s/^msg//i;
904 905 $dataType = 'ADT_MSG';
905 906 my $dataEnum = 'ADT_LIST_' . uc $type;
906 907 push (@xlateType, "\{$dataType, $dataEnum\}};");
907 908 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
908 909 } elsif ($type =~ /time_t/i) {
909 910 $dataType = 'ADT_DATE';
910 911 push (@xlateType, "\{$entryType, sizeof ($type)\}");
911 912 push (@jniLine, [$jniId, $entryType, $format, $enumGroup, $required]);
912 913 } elsif ($type =~ /termid/i) {
913 914 $dataType = 'ADT_TERMIDSTAR';
914 915 push (@xlateType, "\{$dataType, sizeof (au_tid_addr_t *)\}");
915 916 push (@jniLine, [$jniId, $dataType, $format, $enumGroup, $required]);
916 917 } elsif (uc $omitEntry eq 'JNI') {
917 918 # nothing to do.
918 919 } else {
919 920 print STDERR "$dtype is not an implemented data type\n";
920 921 }
921 922 if (uc $omitEntry ne 'ALWAYS' && ${$entryDef{$dtype}}[1]) {
922 923 push (@default, $id, ${$entryDef{$dtype}}[1]);
923 924 }
924 925 }
925 926 my $xlateArray = "\[$typeCount\] =\t{" . join(",\n\t\t\t\t", @xlateType) . "};";
926 927
927 928 unless ($xlateTypeList{$xlateArray}) {
928 929 $xlateTypeList{$xlateArray} = $xlateLabel;
929 930 $xlateArray = "datadef\t$xlateLabel" . $xlateArray;
930 931 push (@xlateTypeList, $xlateArray);
931 932 $xlateLabelInc = 1;
932 933 } else {
933 934 $xlateLabel = $xlateTypeList{$xlateArray};
934 935 }
935 936 $xlateLine =
936 937 "{$token,\t$typeCount,\t&$xlateLabel\[0\],\t$sequence,\n" .
937 938 "\t\t0,\t$required,\t$tsol,\t$format}EOL";
938 939 if (@default) {
939 940 my @list = ();
940 941 if ($xlateDefault{$eventId}) {
941 942 @list = @{$xlateDefault{$eventId}};
942 943 } else {
943 944 push (@xlateDefaults, $eventId);
944 945 }
945 946 push (@list, @default);
946 947 $xlateDefault{$eventId} = \@list;
947 948 }
948 949 }
949 950 $xlateUniLabelInc++ if $xlateLabelInc;
950 951 return ($xlateLine, \@jniLine);
951 952 }
952 953
953 954 sub generateAPIFile {
954 955 my $event = shift;
955 956 my $eventId = shift;
956 957 my $eventType = shift;
957 958 my $eventHeader = shift;
958 959 my $idNo = shift;
959 960
960 961 my @entryList = ();
961 962
962 963 my $external = $event->getExternal();
963 964
964 965 if ($eventType && $debug) {
965 966 print STDERR "event $eventId is of type $eventType\n";
966 967 }
967 968
968 969 return unless $external;
969 970
970 971 my ($extEntry, $entry, $tokenId, $format);
971 972 while (($extEntry, $entry, $tokenId, $format) = $external->getNextEntry()) {
972 973 last unless $entry;
973 974 my $entryId = $entry->getAttr('id');
974 975
975 976 unless (defined $entryId) {
976 977 print STDERR "undefined entry id for external $eventId\n";
977 978 next;
978 979 }
979 980 my $option = $extEntry->getAttr('opt');
980 981 next if ($option eq 'none');
981 982
982 983 if (defined (my $token = $doc->getToken($tokenId))) {
983 984 $option = 'Trusted Solaris only'
984 985 if (lc $token->getUsage() eq 'tsol') ? 1 : 0;
985 986 }
986 987 $option .= " (format: $format)" if $format;
987 988
988 989 my $dataType = $extEntry->getAttr('type');
989 990 unless (defined $dataType) {
990 991 print STDERR "no type defined for external tag for $eventId\n";
991 992 $dataType = "error";
992 993 }
993 994
994 995 my $comment = $entry->getContent();
995 996
996 997 if (($dataType =~ /,/) || ($entryId =~ /,/)) {
997 998 my @type = split(/\s*,\s*/, $dataType);
998 999 my @id = split(/\s*,\s*/, $entryId);
999 1000 if ($#type != $#id) {
1000 1001 print STDERR
1001 1002 "number of data types ($dataType) does not match number of ids ($entryId)",
1002 1003 " for event $eventId\n";
1003 1004 if ($#type < $#id) {
1004 1005 $#id = $#type;
1005 1006 }
1006 1007 else {
1007 1008 $#type = $#id;
1008 1009 }
1009 1010 }
1010 1011
1011 1012 my $i;
1012 1013 my $line = '';
1013 1014 $line = "/* $comment */\n\t" if defined $comment;
1014 1015 for ($i = 0; $i <= $#type; $i++) {
1015 1016 my ($primitive, $dereference) =
1016 1017 ($type[$i] =~ /([^\*]+)\s*(\**)/);
1017 1018 $id[$i] .= $1 if ($primitive =~ s/(\[\d+\])//);
1018 1019 $line .= "$primitive\t$dereference$id[$i];\t/* $option */";
1019 1020 push (@entryList, $line);
1020 1021 $line = '';
1021 1022 }
1022 1023 }
1023 1024 else {
1024 1025 my $line = '';
1025 1026 $line = "/* $comment */\n\t" if defined $comment;
1026 1027 if ($dataType =~ /^msg/i) {
1027 1028 $dataType =~ s/^msg\s*//i;
1028 1029 $line .= "enum ${pfx_adt}_$dataType" . "\t$entryId;\t/* $option */";
1029 1030 }
1030 1031 elsif ($dataType =~ /time_t/i) {
1031 1032 $line .= "time_t\t$entryId;\t/* $option */";
1032 1033 }
1033 1034 else {
1034 1035 my ($primitive, $dereference) =
1035 1036 ($dataType =~ /([^\*]+)\s*(\**)/);
1036 1037 $entryId .= $1 if ($primitive =~ s/(\[\d+\])//);
1037 1038 $line .= "$primitive\t$dereference$entryId;\t/* $option */";
1038 1039 }
1039 1040 push (@entryList, $line);
1040 1041 }
1041 1042 }
1042 1043 $eventExtra{$eventId} = [$eventHeader, $idNo];
1043 1044 $eventAPI{$eventId} = \@entryList;
1044 1045 }
1045 1046
1046 1047 sub generateMsgLists {
1047 1048 my $textList = shift;
1048 1049
1049 1050 my $textName = $textList->getId();
1050 1051 my $header = $textList->getHeader();
1051 1052 my $start = $textList->getMsgStart();
1052 1053 my $public = $textList->getMsgPublic();
1053 1054 my $deprecated = $textList->getDeprecated();
1054 1055
1055 1056 addHeader($header);
1056 1057 print "$textName starts at $start\n" if $debug;
1057 1058
1058 1059 my $entry;
1059 1060 my @entry;
1060 1061 while ($entry = $textList->getNextMsg()) {
1061 1062 if ($debug) {
1062 1063 my ($id, $text) = split(/\s*::\s*/, $entry);
1063 1064 print " $id = $text\n";
1064 1065 }
1065 1066 unshift (@entry, $entry);
1066 1067 }
1067 1068 $msg_list{$textName} =
1068 1069 [\@entry, [$header, $start, $public, $deprecated]];
1069 1070 }
1070 1071
1071 1072 sub addHeader {
1072 1073 my $header_index = shift;
1073 1074
1074 1075 die "invalid adt_event_N.h index: $header_index\n"
1075 1076 unless ($header_index =~ /^\d+$/);
1076 1077
1077 1078 $headers{$header_index} = $header_index;
1078 1079 }
1079 1080
1080 1081 # $header = 0 is a special case; it is for adt_event.h
1081 1082 # $header > 0 creates adt_event_N.h, where N = $header
1082 1083
1083 1084 sub openHeaderFiles {
1084 1085 my $outfile = shift; # path to an adt_event_N.h file
1085 1086
1086 1087 my $header;
1087 1088 my @Hfile = (); # potentially sparse array of file handles
1088 1089 my @HfileName = (); # parallel array to Hfile, file name (not path)
1089 1090 foreach $header (sort keys %headers) {
1090 1091 my $file = $outfile;
1091 1092 if ($header > 0) {
1092 1093 $file =~ s/_N/_$header/;
1093 1094 } else {
1094 1095 $file =~ s/_N//;
1095 1096 }
1096 1097 unless (open($Hfile[$header], ">$file")) {
1097 1098 print STDERR "can't open output ($file): $!\n";
1098 1099 $HfileName[$header] = '';
1099 1100 $Hfile[$header] = '';
1100 1101 } else {
1101 1102 my @tmp = split(/\//, $file);
1102 1103 $HfileName[$header] = $tmp[$#tmp];
1103 1104 }
1104 1105 }
1105 1106 return (@Hfile);
1106 1107 }
1107 1108
1108 1109 sub closeHeaderFiles {
1109 1110 my @Hfile = @_;
1110 1111
1111 1112 my $header;
1112 1113 foreach $header (sort keys %headers) {
1113 1114 close $Hfile[$header] if $Hfile[$header];
1114 1115 }
1115 1116 }
↓ open down ↓ |
490 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX