トラステッド・プログラムは,以下の理由から独自の監査レコードを生成することがあります。
アプリケーション・レベルの監査を行うことによって,システム・レベルの監査レコードが大量に生成されるのを防ぐ。
監査レポートを確認するときに,システム・レベルの監査レコードからだけでユーザの意図を推量するのは難しい。
トラステッド・プログラムは,audgen()
システム・コール,audgenl()
ライブラリ・ルーチン,または
audgen
コマンドを使って監査レコードを生成できます。audgenl()
は,audgen()
のフロント・エンドです。このプログラムは引数として,監査イベントと,その後に監査データ (監査トークンと値からなる) を渡します。
次のコードでは,ブート認証をチェックするプログラムから
audgenl()
を呼び出して認証の失敗を監査する方法を示しています。
if(audgenl(AUTH_EVENT, [1] AUD_T_LOGIN, pr->ufld.fd_name, [2] AUD_T_UID, pr->ufld.fd_uid, AUD_T_CHARP, "boot authentication failed"),0)== -1) perror("audgenl");
注:
AUTH_EVENT
は,レコードのイベント名です。
[例に戻る]
AUD_T_LOGIN
,AUD_T_UID
,および
AUD_T_CHARP
は,トークンです。それぞれ,対応する値を持っています。
[例に戻る]
<sys/audit.h>
に定義されています。イベントとトークンの説明は,5.2 節および
5.3 節を参照してください。
各監査レコードには,それに対応する監査イベントがあります。システムは,システム・コールの監査レコードを生成するときに,自動的にイベントを追加します。自己監査アプリケーション・プログラムは,監査レコードを生成するときに,イベントを
audgen()
または
audgenl()
に引数として渡します。アプリケーション・プログラムで利用できる監査イベントには,2 つのタイプがあります。
トラステッド・イベント。MIN_TRUSTED_EVENT
〜
(MIN_TRUSTED_EVENT + N_TRUSTED_EVENTS -1)
の値で,<sys/audit.h>
に定義されているイベントです。たとえば,LOGIN
イベントです。
サイト定義イベント。MIN_SITE_EVENT
〜 1048576 の値で,/etc/sec/audit_events
に定義されています。サイト定義イベントの省略時の範囲は 64 です。サイト・イベントの定義については,5.8 節を参照してください。
監査サブシステムでは,固定レコード・タイプは使用しません。監査レコードは,タプル (2 つ以上の構成要素があるデータ・オブジェクト) が連続しています。各タプルは,監査トークンとそれに対応する値で構成されます。トークンのタイプによっては,タプルに長さフィールドが存在することもあります。
以降の項では,2 つのタイプのトークン (パブリック・トークン
と
プライベート・トークン
) について説明しています。アプリケーション・プログラムでは,パブリック・トークンを使います。
5.3.1 パブリック・トークン
audgen()
および
audgenl()
を使って監査レコードを生成するアプリケーション・プログラムでは,パブリック・トークンを利用できます。パブリック・トークンは,<sys/audit.h>
に定義されており,AUD_T_
で始まります。たとえば,AUD_T_CHARP
です。
パブリック・トークンには 3 つの基本タイプがあります。
ポインタとしてデータ文字列または構造体を表現するために使います。AUD_T_CHARP
(文字列) と
AUD_T_HOMEDIR
(ホーム・ディレクトリ) はどちらも,ポインタ・タイプのトークンです。
データを
iovec
フォーマットのデータとして表現するために使います。AUD_T_OPAQUE
と
AUD_T_INTARRAY
はどちらも,iovec タイプのトークンです。<sys/audit.h>
内の
iovec
のコメントを参照してください。iovec
構造体は,<sys/uio.h>
に定義されています。iovec
についての詳細は,
readv
(2)writev
(2)
データを 32 ビットまたは 64 ビットの量として表現するために使います (AUD_T_RESULT と AUD_TP_LONG は,64 ビットです。その他は,32 ビットです)。ほとんどのトークンでは,固定長データを使います。AUD_T_AUID
(監査 ID),AUD_T_UID
(ユーザ ID),および
AUD_T_PID
(プロセス ID) は,固定長トークンの例です。
次の例では,iovec
フォーマットのデータを使って監査レコードを生成します。
#define AUD_COMPAT #include <sys/audit.h> #include <sys/uio.h> main() { char buf[100]; int i; struct iovec iov; for (i = 0; i < sizeof(buf); i++) buf[i] = i; iov.iov_len = sizeof(buf); iov.iov_base = buf; if (audgenl (AUDGEN8, AUD_T_CHARP, "opaque data test", AUD_T_OPAQUE, &iov, 0 ) == -1 ) perror ("audgenl"); }
プライベート・トークンは,カーネルが使います。アプリケーション・プログラムでは,このトークンは使用できません。audgen()
システム・コールは,プライベート・トークンを持つレコードにアプリケーション・プログラムが書き込もうとすると拒否します。プライベート・トークンは,<sys/audit.h>
に定義されており,AUD_TP_
で始まります。たとえば,AUD_TP_AUID
です。
カーネルは,監査レコードを作成するときにプライベート・トークンを使います。たとえばカーネルは,各監査レコードを
AUD_TP_LENGTH
タプル (値がその監査レコードの長さを示す) でカプセル化します。別の例としては,audgen()
または
audgenl()
の引数
event
があります。カーネルはこの引数から,AUD_TP_EVENT
タプルを作成します。
5.4 監査フラグとマスク
監査イベントによって実際に監査レコードが生成されるかどうかは,次のフラグとマスクの設定で決まります。
プロセス監査制御フラグ
プロセス監査マスク
システム監査マスク
プロセス監査制御フラグには,4 つの排他的な状態があります。
システム監査マスクとプロセス監査マスクのいずれかで監査が必要と示されたイベントの場合,監査レコードが生成されます。
システム監査マスクとプロセス監査マスクの両方で監査が必要と示されたイベントの場合,監査レコードが生成されます。
現プロセスに対して監査レコードは生成されません。
プロセス監査マスクで監査が必要と示されたイベントの場合,監査レコードが生成されます。
また,プロセス監査制御フラグには,排他的でない状態が 2 つあります。
プロセスに対するシステム・コールのレコード生成をオフにします。
システム・マスクでシステム・コールがオフになっていても,プロセスのユーザ・マスク内のハビタット・システム・コールをオンにします。ハビタット・システム・コールには,System V -
unlink()
と
open()
,real time -
memlk()
,memunlk()
,psx4_time_drift()
,rt_setprio()
があります。これらのハビタット・システム・コールは,グループとしてオン,オフされます。ハビタット・イベントについては,付録 Bを参照してください。
システム管理者は,管理者が適切と判断するレベルで個々のユーザを監査する機能を残したまま,ユーザに対して省略時の監査レベルを指定することができます (監査サブシステムの構成と管理については『セキュリティ管理ガイド』を参照してください)。
プログラマから見ると,特権プロセスがその監査レベル (監査対象の指定) を設定できます。この監査レベルは,絶対マスクとして設定するか,システム監査マスクとの関連で設定します。プロセスの監査マスクの設定方法を示す例は,5.6 節
を参照してください。詳細については,
audcntl
(2)auditmask
(8)5.5 現プロセスのシステム・コール監査の無効化
どのイベントを監査するかを制御することは,監査データ収集の量を適切にチューニングするための重要なステップです。システム・コールは,大量の監査データを生成する可能性があります。しかし,このデータは,必ずしも役立つ情報とは限りません。一般的に,セキュリティ関連のデータベース内のフィールドの変更を積極的に監査したり,特定のセキュリティ関連アクションを監査すると,多数のシステム・コール監査レコードから得られる情報よりも,役立つ情報を入手できます。たとえば,ログイン・プロセスはたくさんのシステム・コールを実行しますが,ログイン・プロセスが情報として書き込む 1 つの監査レコードの方が,使用するシステム・リソースが少なく,簡単に理解することができます。
アプリケーション・プログラムは,トラステッド・イベントの監査を許可したまま,システム・コール監査を無効にすることができます。次のコードでは,audcntl()
システム・コールを使って
AUDIT_SYSCALL_OFF
を設定する方法を示しています。
/* OR the AUDIT_SYSCALL_OFF bit into the audcntl flag */ if ((cntlflag = audcntl(GET_PROC_ACNTL, NULL, 0, 0, 0, 0)) == -1) perror("audcntl"); else audcntl(SET_PROC_ACNTL, NULL, 0, cntlflag|AUDIT_SYSCALL_OFF, 0, 0);
プロセスは,ターゲット・プロセスの
auditmask
フラグと
audcntl
フラグを変更することによって,プロセス自身または別のプロセスに対して何を監査するかを制御できます。次のように,現プロセスの監査マスクを変更できます。
/* ex. set the process's auditmask to audit only LOGIN events and successful setgroups calls */ #include <sys/audit.h> #include <sys/syscall.h> char buf[AUDIT_MASK_LEN];
.
.
.
bzero (buf, sizeof(buf)); A_PROCMASK_SET (buf, LOGIN, 1, 1); A_PROCMASK_SET (buf, SYS_setgroups, 1, 0); if (audcntl (SET_PROC_AMASK, buf, AUDIT_MASK_LEN, 0, 0, 0) == -1) perror ("audcntl");
<sys/audit.h>
に定義されている A_PROCMASK_SET マクロは,次の引数を取ります。
マスクが設定されているバッファです。
ヘッダ・ファイル
<sys/audit.h>
には,トラステッド・イベント名があります。ヘッダ・ファイル
<sys/*syscall.h>
には,システム・コール名があります。
成功を監査するかどうかを示します。1
は,イベントの成功を監査することを意味します。
失敗を監査するかどうかを示します。1
は,イベントの失敗を監査することを意味します。
詳細については,
audcntl
(2)5.7 アプリケーション固有の監査レコード
アプリケーション・プログラムは,アプリケーション固有の監査データを
audgen()
または
audgenl()
への引数として渡します。
次のコードは,指定された
event
が発生したときに,監査レコードをカーネルに送信します。event
は,<sys/audit.h>
からのトラステッド・イベントか,/etc/sec/site_events
からのサイト定義イベントです。(カーネルが監査レコードを監査ログに実際に書き込むかどうかは,このプロセスで監査されているイベントによります)。
/* If bad_thing occurs, generate an event of type event_num, * with string "bad thing happened", and a result of 66. */ #include <sys/audit.h> if (bad_thing) { if (audgenl (event_num, AUD_T_CHARP, "bad thing happened", AUD_T_RESULT, 66, 0 ) == -1) perror ("audgenl"); }
通常,アプリケーションが生成する監査レコードには,表 5-1
に示すトークンのデータを入れる必要はありません。カーネルは,この情報を各監査レコードに自動的に追加します。ただし監査サブシステムは,監査レコードにパブリック・トークンのタプルが追加されるのを妨げません。たとえば,システムが後から
AUD_TP_AUID
を監査レコードに追加する場合でも,AUD_T_AUID
タプルを監査レコードに追加できます。このような場合は両方のタプルが監査ログに書き込まれます。
5.8 サイト定義イベント
サイトでは,独自の監査イベントの設定 (サイト定義イベント) を,ローカルに作成され保守されるファイル
/etc/sec/site_events
で定義できます。このファイル内には,各サイト・イベントに対するエントリが 1 つあります。
使用可能なサイト・イベント番号は,MIN_SITE_EVENT
(<sys/audit.h>
に定義されている) 〜 1048576 です。省略時の範囲は,64 です。この値を変更するには,/etc/sysconfigtab
内の
audit-site-events
を設定してから,リブートします。たとえば,サイト定義イベントを最大 128 個にするには,次のように設定します。
sec: audit-site-events=128
各サイト・イベント・エントリは,INT_MAX
個までのサブイベントを持つことができます。サブイベントには,省略時の範囲は定義されていません。
イベントまたはサブイベントの名前の最大長は,<sys/audit.h>
に定義されている
AUD_MAXEVENT_LEN
です。
アプリケーション・プログラムは,サイト定義イベントと,<sys/audit.h>
に定義されているトラステッド・イベント (MIN_TRUSTED_EVENT
〜
MAX_TRUSTED_EVENT
) の両方を持つレコードを生成できます。
auditmask
ユーティリティは,サイト定義イベントの事前選択をサポートしています。また,audit_tool
ユーティリティは,サイト定義イベントとサブイベントの事後選択をサポートしています。
5.8.1 サンプルの site_events ファイル
サイト定義監査イベント・エントリの構文は次のとおりです。
[イベント名 イベント番号 [ , サブイベント名 サブイベント番号 ... ] ;
]
サンプルの
/etc/sec/site_events
ファイルの次のエントリは,サイト定義イベントおよびサブイベントの作成方法を示しています。
essence 2048, [1] ess_read 0, [2] ess_write 1; [3] rdb 2049, rdb_open 0, rdb_close 1, rdb_read 2, rdb_write 3; decinspect 2050;
注:
essence
はイベントです。2048 はイベント番号です。2048 は
MIN_SITE_EVENT
で,サイト定義イベントに使用できる最小値です。
[例に戻る]
ess_read
は 1 番目のサブイベントです。0 は 1 番目のサブイベント番号です。
[例に戻る]
ess_write
は 2 番目のサブイベントです。1 は 2 番目のサブイベント番号です。
[例に戻る]
サイト定義イベントについての詳細は,
aud_sitevent
(3)5.8.2 例: サイト定義監査イベントの監査レコードの生成
次のコードは,audgenl()
を使って,rdb_close
イベントの監査データを生成します。
int event_num, subevent_num; /* translate event name(s) into event numbers */ if (aud_sitevent_num ("rdb", "rdb_close", &event_num, &subevent_num )) printf ("aud_sitevent_num failed"); /* generate audit data */ else if (audgenl (event_num, AUD_T_SUBEVENT, subevent_num, AUD_T_CHARP, "Trusted RDB V1.0 Close", 0) == -1) perror ("audgenl");
サイト定義イベントのレコードを生成する場合は,audgenl()
に
AUD_T_CHARP,
event name
という引数を含めてください。これにより,ローカルの
site_events
ファイルのコピーを持たないシステムで監査データを解析する作業が簡単になります。
詳細については,
aud_sitevent
(3)audgenl
(3)5.9 独自の監査ログの作成
audgen()
システム・コールを使って,独自の監査ログを作成できます。audgen
() への引数
size
がゼロ以外の値の場合,監査データは,システム監査ログに書き込まれるのではなく,audgen()
で指定した
userbuff
へコピーされます。この後,トラステッド・アプリケーションは,userbuff
のデータを固有のログ・ファイルに書き込むことができます。詳細については,
audgen
(2)
audit_tool
ユーティリティを使って,新しい監査ログを読み取ることができます。5.10 節の説明を参考に,ログから詳しい情報を読み取ることができます。
5.10 監査ログの解析
多くの人が,audit_tool
または
dxaudit
を使用して監査ログを参照します。audit_tool
ユーティリティは洗練されたプログラムで,監査データを役立つ情報に変換したり,出力をフォーマットしたり,複数の監査ログ・ファイルにまたがる監査レコードを処理します。audit_tool
は,監査ログを最初に読み取ったとき,そのログに対応する
.hdr
ファイルを作成して,状態情報を保守します。この状態情報により,その後の監査ログの読み取りに必要な時間が短縮されます。また,監査レコードが複数のログにまたがる場合は,audit_tool
が両方のログ・ファイルをオープンし,ヘッダ・ファイル内に完全なレコードを作成します。
以降の項では,監査ログのフォーマットと構造について,次のような情報を説明しています。
監査ログの説明と,すべての監査レコードにある一般的なトークン・タイプのリスト
バイナリ・レコードのフォーマットと,レコードの 8 進ダンプおよびそのフォーマットされた出力を示す例
パブリック・トークンおよびプライベート・トークンのデータ・タイプおよびフォーマットをリストした,トークンおよびタプルのバイト記述についての表
タプル解析のためのサンプル・マクロ
以降の項では,audit_tool
のようなプログラムを作成するために必要な,設計に関する情報は説明していません。監査ログを解析してレコードとタプルに分解するために必要な基本情報について説明しています。
5.10.1 監査ログのフォーマットの概要と共通タプルのリスト
監査ログは,通常の UNIX データ・ファイルで,監査レコードが格納されています。監査レコードは,フォーマットが
token:value
または
token:length:value
のどちらかの,連続したタプルで構成されています。各レコードは,AUD_TP_LENGTH
タプルで始まり,AUD_TP_LENGTH
タプルで終わります。audit_tool
ユーティリティは,監査レコードが有効かどうかを判断するのに
AUD_TP_LENGTH
を使います。レコードの実際の長さが
AUD_TP_LENGTH
の値と一致しない場合は,audit_tool
がレコードを破棄し,警告を出力します。表 5-1
は,監査レコードで広く使われている省略時のタプルを示しています。
表 5-1: 大半の監査レコードに共通する省略時のタプル
タプル | コメント | タプル | コメント |
AUD_TP_LENGTH | AUD_TP_VERSION | ||
AUD_TP_AUID | AUD_TP_RUID | ||
AUD_TP_HOSTADDR | AUD_TP_EVENTP | ハビタットの場合 | |
AUD_TP_HABITAT | ハビタットの場合 | AUD_TP_EVENT | |
AUD_TP_UID | AUD_TP_PID | ||
AUD_TP_PPID | AUD_TP_DEV | デバイスがプロセスに対応している場合 | |
AUD_TP_NCPU | AUD_TP_TV_USEC | ||
AUD_TP_SET_UIDS | uid の変更の場合 | AUD_TP_TID | AUDIT_USR フラグが設定されている場合 |
表 5-2
は,パブリック・トークンとプライベート・トークンを,8 進値と一緒に示しています。各タプルの 3 番目の欄は,カーネルが監査ログに書き込むタプル・データのシーケンスを示しています。トークンは 1 バイト,長さは 4 バイトです。サンプルの解析マクロは,audit_tool
がタプルを解析するために使うマクロを示しています。参考として,これらのマクロを5.10.3 項に記載します。
表 5-2: トークンおよびタプルのバイト記述
トークン | 8 進値 | タプルのフォーマットとサンプルの解析マクロ |
AUD_T_CHARP | 001 | トークン:長さ:ヌル終了する ASCII 文字列。PARSE_DEF3 |
AUD_T_SOCK | 003 | トークン:長さ:struct sockaddr (4.3 スタイル (u_short)。family > UCHAR_MAX の場合は 4.4 スタイルの sockaddr となり,「長さ」(バイト) の後に family (バイト) が続く)。PARSE_DEF3 |
AUD_T_LOGIN | 004 | トークン:長さ:ヌル終了する ASCII 文字列。PARSE_DEF3 |
AUD_T_HOMEDIR | 005 | トークン:長さ:ヌル終了する ASCII 文字列。PARSE_DEF3 |
AUD_T_SHELL | 006 | トークン:長さ:ヌル終了する ASCII 文字列。PARSE_DEF3 |
AUD_T_DEVNAME | 007 | トークン:長さ:ヌル終了する ASCII 文字列。PARSE_DEF3 |
AUD_T_SERVICE | 010 | トークン:長さ:ヌル終了する ASCII 文字列。(将来の使用のために予約済み) |
AUD_T_HOSTNAME | 011 | トークン:長さ:ヌル終了する ASCII 文字列。PARSE_DEF3 |
AUD_T_INTP | 012 | トークン:長さ:int (1 番目の要素は配列内の要素の数。監査レコードの生成時には,AUD_T_INTARRAY の方が適切なタプルである。PARSE_DEF3 |
AUD_T_LSOCK | 016 | |
AUD_T_RSOCK | 017 | |
AUD_T_LHOSTNAME | 020 | |
AUD_T_OPAQUE | 030 | トークン:長さ:値 (proplist または本当の opaque。proplist の名前と値の組をチェックし,なければ 16 進でダンプ)。PARSE_DEF6 |
AUD_T_INTARRAY | 031 | トークン:長さ:int。PARSE_DEF3 |
AUD_T_GIDSET | 032 | トークン:長さ:int1, int2, ... (境界合わせなし)。PARSE_DEF3 |
AUD_T_XDATA | 033 | トークン:struct aud_xdata (<sys/audit.h>
を参照)。PARSE_DEF8 |
AUD_T_AUID | 040 | トークン:int。PARSE_DEF2 |
AUD_T_RUID | 041 | トークン:int。PARSE_DEF2 |
AUD_T_UID | 042 | トークン:int。PARSE_DEF2 |
AUD_T_PID | 043 | トークン:int。PARSE_DEF2 |
AUD_T_PPID | 044 | トークン:int。PARSE_DEF2 |
AUD_T_GID | 045 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_EVENT | 046 | トークン:int。PARSE_DEF2 |
AUD_T_SUBEVENT | 047 | トークン:int。PARSE_DEF2 |
AUD_T_DEV | 050 | トークン:int (<sys/types.h>
のマクロ
major () および
minor () を使って解析する)。PARSE_DEF2 |
AUD_T_ERRNO | 051 | トークン:int。PARSE_DEF1 |
AUD_T_RESULT | 052 | トークン:long。PARSE_DEF4 |
AUD_T_MODE | 053 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_HOSTADDR | 054 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_INT | 055 | トークン:int。PARSE_DEF2 |
AUD_T_DESCRIP | 056 | トークン:int (ファイル記述子)。PARSE_DEF2 |
AUD_T_HOSTID | 057 | トークン:int。PARSE_DEF1 |
AUD_T_X_ATOM | 060 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_X_CLIENT | 061 | トークン:int。PARSE_DEF2 |
AUD_T_X_PROPERTY | 062 | トークン:int。PARSE_DEF2 |
AUD_T_X_RES_CLASS | 063 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_X_RES_TYPE | 064 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_X_RES_ID | 065 | トークン:unsigned int。PARSE_DEF2 |
AUD_T_LHOSTNAME | 066 | |
AUD_T_SECEVENT | 177 | トークン:int。PARSE_DEF2 |
AUD_TP_ACCRGHT | 201 | トークン:長さ:cmsg_data (fd1, fd2, ...
。<sys/socket.h>
を参照)。PARSE_DEF3 |
AUD_TP_MSGHDR | 202 | トークン:長さ:msghdr->msg_name (<sys/socket.h>
を参照)。PARSE_DEF3 |
AUD_TP_EVENTP | 203 | トークン:長さ:string。PARSE_DEF3 |
AUD_TP_HABITAT | 204 | トークン:長さ:string。PARSE_DEF3 |
AUD_TP_ADDRVEC | 205 | トークン:長さ:struct sockaddr (socket.h
を参照)。PARSE_DEF3 |
AUD_TP_INTP | 206 | トークン:長さ:int。PARSE_DEF3 |
AUD_TP_AUID | 241 | トークン:int。PARSE_DEF1 |
AUD_TP_RUID | 0242 | トークン:int。PARSE_DEF1 |
AUD_TP_UID | 0243 | トークン:int。PARSE_DEF1 |
AUD_TP_PID | 0244 | トークン:int。PARSE_DEF1 |
AUD_TP_PPID | 0245 | トークン:int。PARSE_DEF1 |
AUD_TP_HOSTADDR | 246 | トークン:unsigned int。PARSE_DEF1 |
AUD_TP_EVENT | 247 | トークン:int。PARSE_DEF1 |
AUD_TP_SUBEVENT | 250 | トークン:int (将来の使用のために予約済み)。PARSE_DEF1 |
AUD_TP_NCPU | 251 | トークン:int。PARSE_DEF1 |
AUD_TP_DEV | 252 | トークン:int (sys/types.h
のマクロ
major () および
minor () を使って解析する)。PARSE_DEF1 |
AUD_TP_LENGTH | 253 | トークン:int。PARSE_DEF1 |
AUD_TP_IPC_GID | 254 | トークン:unsigned int (ipc|msg|shm_perm.gid)。PARSE_DEF2 |
AUD_TP_IPC_MODE | 255 | トークン:unsigned int (ipc|msg|shm_perm.mode)。PARSE_DEF2 |
AUD_TP_IPC_UID | 256 | トークン:int (ipc|msg|shm_perm.uid)。PARSE_DEF2 |
AUD_TP_TV_SEC | 257 | トークン:timeval.tv_sec (<sys/time.h>
を参照)。PARSE_DEF1 |
AUD_TP_TV_USEC | 260 | トークン:timeval.tv_usec (<sys/time.h>
を参照)。PARSE_DEF1 |
AUD_TP_SHORT | 261 | トークン:short。PARSE_DEF2 |
AUD_TP_LONG | 262 | トークン:long。PARSE_DEF5 |
AUD_TP_VNODE_DEV | 263 | トークン:int。PARSE_DEF2 |
AUD_TP_VNODE_ID | 264 | トークン:unsigned int。PARSE_DEF2 |
AUD_TP_VNODE_MODE | 265 | トークン:unsigned int。PARSE_DEF2 |
AUD_TP_VERSION | 266 | トークン:unsigned int。(<sys/audit.h>
を参照)。(AUD_VERSION | AUD_VERS_LONG) PARSE_DEF1 |
AUD_TP_SET_UIDS | 267 | トークン:int。PARSE_DEF2 |
AUD_TP_CONT | 270 | トークン:unsigned int (レコードの各構成要素に固有の int)。PARSE_DEF1 |
AUD_TP_TID | 271 | トークン:long。PARSE_DEF4 |
AUD_TP_PRIV | 272 | トークン:unsigned short。PARSE_DEF1 |
監査レコードのストリームを読み取るアルゴリズムは次のとおりです。
監査ログをオープンします。
最初の監査レコードを見つけます (AUD_TP_LENGTH
タプルで始まり,AUD_TP_LENGTH
タプルで終わります)。
レコード長が
AUD_TP_LENGTH
タプルの値と一致するかチェックします (長さが一致しない場合は,レコードを破棄します)。
AUD_TP_LENGTH
タプルに続く最初のタプルを取り出します。
タプルが可変長の場合は,データのサイズを調べます。
データを抽出します。
次のタプルを取り出し,必要に応じて長さをチェックします。そして,データを抽出します。
レコードがなくなるまで繰り返します。
監査ログをクローズします。
次のマクロは,audit_tool
がどのようにタプルを解析するかを示しています。これらのマクロは,参考として記載しているだけで,1 つの手段を示しているに過ぎません。indx
の値は,audit_tool
が保守し,使用します。この値は,監査レコードのタプルの一部ではありません。
/* fixed length scalar value */ #define PARSE_DEF1(tokentype,field) \ bcopy (&rec_ptr[i+sizeof token], &field, sizeof(field)); \ i += (sizeof token + sizeof(field)); \ break; /* fixed length field in array */ #define PARSE_DEF2(tokentype,field,indx) \ if (indx < AUD_NPARAM) \ bcopy (&rec_ptr[i+sizeof token], &field[indx++], sizeof(field[0])); \ i += (sizeof token + sizeof(field[0])); \ break; /* array of strings */ #define PARSE_DEF3(tokentype,len,field,indx) \ bcopy (&rec_ptr[i+sizeof token], &j, sizeof(int)); \ if (j >= rec_len) j = 0; \ if (indx < AUD_NPARAM) { \ len[indx] = j; \ field[indx++] = (char *)&rec_ptr[i+(sizeof token)+(sizeof *intp)]; \ } \ i += (sizeof token + sizeof *intp + j); \ break; /* fixed length scalar value whose size is h/w dependent (32 or 64-bit) */ #define PARSE_DEF4(tokentype,field) \ bzero (field.val, sizeof(field.val)); \ j = af->version & AUD_VERS_LONG ? sizeof(int)*2 : sizeof(int); \ bcopy (&rec_ptr[i+sizeof token], field.val, j); \ i += (sizeof token + j); \ break; /* fixed length field in array whose size is h/w dependent (32 or 64-bit) */ #define PARSE_DEF5(tokentype,field,indx) \ bzero (field[indx].val, sizeof(field[indx].val)); \ j = af->version & AUD_VERS_LONG ? sizeof(int)*2 : sizeof(int); \ if (indx < AUD_NPARAM) \ bcopy (&rec_ptr[i+sizeof token], field[indx++].val, j); \ i += (sizeof token + j); \ break; /* array of opaque data streams */ #define PARSE_DEF6 PARSE_DEF3 /* iovec element in array */ #define PARSE_DEF7(tokentype,field,indx) \ j = sizeof(field[0]); \ if (indx < AUD_NPARAM) { \ bcopy (&rec_ptr[i+sizeof token], &j, sizeof(int)); \ if (j > rec_len ) j = 0; \ bcopy (&rec_ptr[i+sizeof token+sizeof(int)], &field[indx++], j); \ } \ i += (sizeof token + sizeof(int) + j); \ break; /* array of iovec elements with variable length components */ #define PARSE_DEF8(tokentype,field,ptr,indx) \ j = sizeof(field[0]); \ if (indx < AUD_NPARAM) { \ bcopy (&rec_ptr[i+sizeof token], &j, sizeof(int)); \ if (j > rec_len) j = 0; \ bcopy (&rec_ptr[i+sizeof token+sizeof(int)], &field[indx], j); \ ptr[indx++] = ((struct aud_xdata *) \ &rec_ptr[i+sizeof token+sizeof(int)])->xdata; \ } \ i += (sizeof token + sizeof(int) + j); \ break;