3    認証データベース

この章では,次の内容について説明しています。

3.1    認証データベースの概要

認証データベースは,エンハンスト・セキュリティが使用可能になっているときに,Tru64 UNIX のセキュリティ情報をすべて格納する一連のデータベースです。認証データベースは,次のデータベースから構成されています。

エンハンスト・セキュリティが使用可能なシステム用に特別に作成されたトラステッド・プログラム (つまり,セキュリティ・ルールを破ることができる立場にあるプログラム) は,これらのデータベース内の情報を使用する必要があります。特別な場合を除き,システム管理者は Tru64 UNIX 管理インタフェースを使ってこれらのデータベースを保守します。このため,ユーザのプログラムでは通常,これらのデータベースの読み取りのみを行います。

以下の節では,認証データベースについて説明します。ファイル形式についての一般的な説明は, authcap(4) のリファレンス・ページを参照してください。

3.1.1    デバイス割り当てデータベース (devassign)

デバイス割り当てデータベースには,システム上のデバイスのデバイス属性が格納されています。 現在のところ,devassign データベースに入っているデバイスは,次の 2 種類です。

デバイス関連コマンドには,デバイス・エントリの名前を使用します。この名前は,デバイスを表すデバイス・ファイルとは関係ありません。

システム管理者は,デバイス割り当てデータベースを保守します。ユーザのプログラムでは,このデータベースの内容を変更してはなりません。

このデータベースの論理エントリのサイズは,動的に変わります (自己内蔵型ではありません)。このため,そのエントリを含む構造体の作業用コピーを作るには,copyesdvent() ルーチンを使わなければなりません。詳細については, getesdvent(3) のリファレンス・ページを参照してください。

テキスト・ファイル /etc/auth/system/devassign には,デバイス割り当てデータベース全体が格納されています。

3.1.2    ファイル制御データベース

ファイル制御データベースは,機密ファイルの保護属性 (所有者,モード・ビットなど) が正しいか確認するのに役立ちます。このデータベースには,各ファイル (またはディレクトリ) の絶対パス名と正しい属性が保存されています。これらの属性には,次の項目の任意の組合せが入っています。

ユーザのプログラムでは,create_file_securely() インタフェースを介して新しく作成されたファイルに対してファイル制御データベースのエントリを使用する以外は,ファイル制御データベースからの読み取りまたはファイル制御データベースへの書き込みを行ってはなりません。ただし, すべての新しい機密ファイルと機密ディレクトリをデータベースに追加する必要があります。変化しない属性をすべて含めます。これにより,これらの属性が定期的にチェックされ修正されるようになります。

create_file_securely() ルーチンを使って,ファイル制御データベース内に指定された属性でファイルを作成することができます。このルーチンを使用できるのは,新しいファイルを作成する場合だけです。新しいバージョンのファイルを,別のファイルに作成する必要があります。( Tru64 UNIX の表記法により,ファイルの新しい内容を表す :t をパス名に追加します)。次に,新しいファイルの名前を既存のファイル名に変更します (rename() システム・コールを使用)。

ファイル制御データベースは,テキスト・ファイル /etc/auth/system/files です。このファイルのフォーマットの定義は, files(4) のリファレンス・ページを参照してください。システム管理者は,edauth -df コマンドを使って,データベースへエントリを追加したり,データベースからエントリを削除することができます。詳細については, edauth(8) のリファレンス・ページを参照してください。

3.1.3    システム省略時設定データベース (default)

システム省略時設定データベース /etc/auth/system/default は,対応するフィールドが他のデータベースで未定義のままのときに使用されるフィールドが格納されたテキスト・ファイルです。つまり,このデータベースには,エンハンスト (保護) パスワード,デバイス割り当て,および端末制御データベースの省略時の情報が入っています。(各認証データベース内のフィールドはどれも未定義にできますが,すべてのフィールドに省略時の値があるわけではありません)。

システム省略時設定データベースには,システムのその他のパラメータのフィールドもあります。 ユーザのプログラムには,その他の情報は必要ありません。

システム管理者がこのデータベースを保守するため,ユーザのプログラムでこのデータベースを変更することはありません。他のデータベースのアクセス・ルーチンも,システム省略時設定を戻します。システム省略時設定データベースの情報にアクセスし,使用する方法の例は,3.1.5 項を参照してください。

システム省略時設定データベース全体には,エントリが 1 つだけあります (default エントリ)。

3.1.4    エンハンスト (保護) パスワード・データベース

エンハンスト・パスワード・データベース (/tcb/files/auth.db および /var/tcb/files/auth.db) は,一連のユーザ認証プロファイルが格納された dbm ファイルです。ユーザ認証プロファイルは,NIS prpasswd マップを使って,Tru64 UNIX システム間で配布することもできます。各 認証プロファイル・エントリには,ユーザ名 (ログイン時にユーザが使う名前) で名前が付けられています。認証プロファイルには,ユーザのログイン・セッションを管理するフィールドが多数あります。これらのフィールドについての詳細は,第 4 章を参照してください。

認証プロファイルは,従来の /etc/passwd ファイルまたは NIS passwd マップの 1 行で存在が示されるアカウントに対応しています。 暗号化されたパスワードは,/etc/passwd ファイルから認証プロファイルに移動されました。

システムは,/etc/passwd データベース内のその他のフィールドを,従来通りの意味で扱います。/etc/passwd 内の各エントリは,保護パスワード・データベース内でユーザ ID と名前が同じ認証プロファイルと正確に 1 対 1 で対応しています (有効なアカウントとしてみなすには,両方が必要)。/etc/passwd エントリには,ダミーの暗号化パスワード・フィールドがあります。認証プロファイルには,本当のパスワード・フィールドがあります。

/etc/passwd ファイルを照会する従来の UNIX インタフェースは,getpwent() です。インタフェースの機能に違いはなく,情報は必ず /etc/passwd ファイルまたは NIS マップから取り出されます。ただし,戻される暗号化パスワードはダミーの値であることに注意してください (このルーチンに対して,認証プロファイルから暗号化パスワードを取り出すような変更は行われていません)。

ユーザのプログラムでは,エンハンスト (保護) パスワード・データベースを変更してはなりません。ただし,多くのトラステッド・プログラムでは,ユーザ認証プロファイルから情報を読み取る必要があります。

3.1.5    端末制御データベース

端末制御データベース (/etc/auth/system/ttys.db) は,主にログイン時に使用され,ログインしているユーザに対してではなく,ログイン端末に対して適用されるフィールドが格納された dbm ファイルです。このデータベースは,ユーザがログインできる各端末 (X 端末を含む) のエントリで構成されています。

データベース内の各エントリには,端末の名前があります。この名前は,ログイン・ポートを指定するために使用されるファイル (/etc/inittab) 内の名前に対応しています。 デバイス割り当てデータベースのエントリは,端末制御データベースの各エントリと対応します。対応するエントリがデバイス割り当てデータベースにない場合,ほとんどのトラステッド・プログラム (たとえば,login) はサービスを提供しません。

各端末制御データベースのエントリには,次のフィールドがあります。

Tru64 UNIX のログイン・プログラムでは多数のフィールドを変更しますが,このデータベースのエントリを保守するのはシステム管理者です。ユーザのプログラムは通常,このデータベースを変更しません。あまりないことですが,トラステッド・プログラムでは,このデータベースを読み取らなくてはならないこともあります。

/etc/auth/system/ttys.db ファイルには,端末制御データベース全体が格納されています。

3.2    認証データベースの構成要素

各データベースは,名前付きのエントリ群で構成されています。 プログラムでは,データベース内のエントリを順次検索することもできますが,主にエントリの名前を使ってデータベースから特定のエントリを取り出します。

各エントリには,一連のフィールドが含まれています。各フィールドには,フィールドと値にアクセスするための識別子があります。 各データベースでは,そのエントリに使用可能なフィールドが決まっています。個々のフィールドは省略可能で,エントリから省略することができます。フィールドの種類には,文字列,整数,論理値があります。

エントリの一般的な形式を次に示します。

entry_name:string_field=value:integer_field#value:\
:boolean_field_true:boolean_field_false@:chkent:
 

ライブラリ・ルーチンは通常,1 つのエントリ全体を読み取ったり書き込んだりします。C の構造体には,指定されたデータベース・エントリが持つ可能性のあるフィールドすべてが確保されています。この構造体には必ず,フラグ構造体が付いています。このフラグ構造体は,読み取ったり書き込んだりするフィールドを示すマスクを持っています。

フィールドが未定義の場合,ユーザのプログラムは適切な動作を行う必要があります。多くの場合,未定義フィールドはシステム省略時設定データベースから取り出されます。 これについては 3.2.1 項 で説明します。各データベースの構造体には,そのデータベース用のシステム省略時設定フィールドとフラグがあります。このため,システム省略時設定は個々のエントリの値が格納されている構造体と同じ構造体から利用でき,特定のフィールドに関連するシステム省略時設定の値を簡単に取り出すことができます。

3.2.1    データベースの形式

通常は,認証データベースの物理的フォーマットを意識する必要はありません。すべてのデータベースの論理的フォーマットは同じで,アクセス・ライブラリも似ています。 たとえば,端末制御データベースは,各制御対象端末用のエントリで構成されています。 次の ttys ファイルの例は,tty01 の物理的フォーマットのエントリを示しています。また,次の表は,データベース・ファイルのフォーマットを示しています。

tty01:t_devname=tty01:t_uid#44:t_logtime#772479074:\
	:t_login_timeout#20:t_failures#3:t_lock@:\
	:chkent:

意味 フィールド 説明
名前 t_devname tty01 端末 1
最後にログインしたユーザ t_uid 44 UID が 44
最後にログインした日時 t_logtime 772479074 Fri Jun 24 13:31:13 EDT 1994
ログイン・タイムアウト t_login_timeout#20 20 ログイン・タイムアウト (秒)
最後にログインした後の失敗回数 t_failures#3 3 最後に正常にログインした後にログインに失敗した回数
アカウントの状態 t_lock @ アンロック (偽)
チェック・エントリ :chkent:<EOL> chkent エントリの最後

次の C の構造体は,ttys データベースからエントリを取り出すために使用します (インクルード・ファイル <prot.h> を参照)。

struct es_term  {
    struct estc_field  *ufld;     /* fields for this entry */
    struct estc_flag   *uflg;     /* flags for this entry */
    struct estc_field  *sfld;     /* system default fields */
    struct estc_flag   *sflg;     /* system default flags */
};

estc_field は,エントリのフィールドのデータを保持しています。estc_flag は,estc_field 内に存在する (つまり設定されている) フィールドを示すフラグを保持しています。次に,estc_field 構造体を示します。

struct estc_field  {
    char    *fd_devname;      /* terminal name */
    uid_t   fd_uid;           /* uid of last successful login */
    time_t  fd_slogin;        /* time of last successful login*/
    ushort  fd_nlogins;       /* consecutive failed attempts */
    char    fd_lock;          /* terminal lock status */
    ushort  fd_login_timeout; /* login timeout value */
};

struct estc_flag  {
unsigned short
    fg_devname        :1,     /* name present? */
*/ fg_uid            :1,     /* uid present? */
*/ fg_slogin         :1,     /* time present? */
*/ fg_nlogins        :1,     /* failed attempts present? */
*/ fg_lock           :1,     /* lock status present? */
*/ fg_login_timeout  :1      /* login timeout present? */
 
 
};

getestcent(3) のリファレンス・ページでは,端末制御データベースにアクセスするために使用できるライブラリ・ルーチンが定義されています。このアクセス・ルーチンは,特定のエントリ ufld および uflg のフィールドや,システム省略時設定 (sfld および sflg) のフィールドを取り出したり,設定したりします。システム省略時設定があるフィールドを持つデータベースの場合,エントリに対応するフィールドの他,システム省略時設定も戻されます。

3.2.2    データベースの読み取りと書き込み

各データベースは,ユーザおよびグループが所有しています。 ユーザのプログラムは,このユーザおよびグループへ自由にアクセスできなければなりません。プログラムは,2 つの方法でインストールすることができます。

ライブラリ・ルーチンは,1 つのデータベースへの書き込みプロセスを,一時点では 1 つに自動的に制限します。ただし, データベースがロックされるのは,書き換えが行われている間だけです。取り出し操作と書き込みの操作にまたがってエントリをロックする方法はありません。書き込みは,できるだけ早く完了させる必要があります。

3.2.2.1    バッファ管理

データベース・エントリの取り出し,置き換え,追加を行うプログラムを適切にコーディングするには,システムがどのようにデータベース・エントリのバッファを割り当てて返すかを知っておかなければなりません。すべてのデータベース・ルーチンは,getpwent() ルーチンを見本にして作成されています。このルーチンは,各呼び出しで再使用される静的記憶域へのポインタを戻します。別のエントリを取り出してから前のエントリを再度参照する必要がある場合,または既存エントリを再度書き込むか新しいエントリを追加する必要がある場合は,バッファの内容を保存しなければなりません。データベース・エントリを読み取り,1 つ以上のフィールドとフラグの値を変更して,データベースを変更するルーチンへ同じバッファを渡すことはできません。

いくつかのデータベース・フィールドの論理的な形式は,自己内蔵型です。この他のフィールドには,可変長データへのポインタが入っています。

devassign データベースの論理的な形式には,可変長データへのポインタであるフィールドがあります。 getesdvent(3) のリファレンス・ページでは,copyesdvent() ルーチンについて説明しています。このルーチンは,デバイス割り当てのデータベース・エントリを持つ構造体を割り当て,その中に,getesdvent() または getesdvnam() から戻されたバッファの内容をコピーします。

自己内蔵型データベースのエントリは,次のように,構造体の簡単な代入で保存することができます。

struct es_passwd *pr;       /* returned value */
struct es_passwd *pwcopy;   /* buffer for saved values */
 
/* Retrieve john's protected password database entry */
 
pr = getesnam("john");
 
/* store values of john's entry to a local buffer */
 
pwcopy = copyespwent(pr);
if (!pwcopy) abort();
 
/* Change the password minimum change time to two weeks */
 
pwcopy->uflg->fg_min = 1;
pwcopy->ufld->fd_min = 14 * 24 * 60 * 60;
 
/* Rewrite john's protected password database entry */
 
if (!putespwnam("john", pwcopy))
    errmsg("Could not write protected password entry\n");
free(pwcopy);

3.2.2.2    名前または ID でのエントリの読み取り

データベース・エントリを読み取るには,エントリの名前を指定します。一部のデータベースでは,名前以外の識別値を指定して読み取ることもできます。たとえば,エンハンスト (保護) パスワード・データベースからエントリ名 (ユーザの名前) またはユーザ ID でエントリを取り出すことができます。次のコードは,端末制御データベースから,名前が tty44 のエントリを読み取ります。

 .
 .
 .
struct es_term   *entry;
 .
 .
 .
if ((entry = getestcnam("tty44")) == NULL)
            errmsg ("Entry not found");

getestcnam() は,戻されるエントリ用のデータ構造体を割り当てます。つまり,entry は,es_term 構造体へのポインタです。この構造体は,次回,prtc() または estc() ルーチンが呼び出されたときに再度使用されます。

3.2.2.3    エントリの順次読み取り

次に示すコードのようにして,データベース・エントリを順次読み取ることもできます。

 .
 .
 .
struct es_term   *entry;
 .
 .
 .
setprtcent();                            /* rewind the database*/
while ((entry = getestcent()) != NULL){  /* read next entry   */
 .                                       /* process the entry */
 .
 .
}
endprtcent ();                           /* close */

getestcent() もまた,エントリのデータ構造体を割り当てることに注意してください。setprtcent() を使用すると,先頭から検索を再度開始することができます。

3.2.2.4    システム省略時設定の使用

システム省略時設定のフィールドは,エントリ内の対応するフィールドが定義されていないときに使用されます。システム省略時設定データベースには,他のデータベースの省略時の値が入っています。次のデータベースには,システム省略時設定の情報が入っています。

省略時設定があるのは,これらのデータベース内の一部のフィールドだけです。

プログラムが論理エントリを読み取った場合,ライブラリ・ルーチンは,そのエントリのフィールド (ufld および uflg) とシステム省略時設定 (sfld および sflg) の両方を戻します。要求したフィールドがエントリにない場合,システム省略時設定を使用します。システム省略時設定も未定義の場合は,プログラムは監査データを生成し,エラーを報告して障害処理を実行する必要があります。それ以外の場合は,省略時の値を安全に定義することができます。

たとえば,端末 tty14 のタイムアウト値を調べる必要がある場合,コードは次のようになります。

struct es_term  *entry;        /* the entry for the terminal */
ushort          time_out;      /* final timeout value */
  .
  .
  .
 
/*--- fetch the entry by name ---*/
 
if ((entry = getestcnam ("tty14")) == NULL)
      errmsg ("Entry not found");
 
/*--- if defined for the terminal, use it ---*/
 
if (entry->uflg->fg_login_timeout)
      time_out = entry->ufld->fd_login_timeout;
 
/*--- else if system default is defined, use it ---*/
 
else if (entry->sflg->fg_login_timeout)
      time_out = entry->sfld->fd_login_timeout;
 
/*--- otherwise, assume a value of 0 ---*/
 
else time_out = 0;

3.2.2.5    エントリの書き込み

ユーザのプログラムでデータベースを変更することは,めったにありません。またそれ以上に,ユーザのプログラムでシステム省略時設定を変更することはまずありません。ただし,この変更が必要な場合は,新しいフィールドを ufld に置き,対応するフラグを uflg に設定してから,適切なライブラリ・ルーチンを呼び出します。 たとえば,端末 tty14 の新しいタイムアウト値に 20 を設定するコードは,次のようになります。

struct es_term  *entry, *ecopy;
 .
 .
 .
 
/*--- fetch the entry by name ---*/
 
if ((entry = getestcnam("tty14")) == NULL)
      errmsg ("Entry not found");
 
/*--- change the desired field(s) ---*/
 
ecopy = copyestcent(entry); if (! ecopy) abort():
ecopy->ufld->fd_login_timeout = 20;  /* set timeout value */
ecopy->uflg->fg_login_timeout =  1;  /* set flag to show the
                                          field has been set */
/*--- update the database ---*/
 
if (!putestcnam("tty14", ecopy))
      errmsg ("Could not update database");
free(ecopy);

注意

後で使用するためにデータを保存するには,適切な copyes*() ルーチンを呼び出さなければなりません。

copyes*() ルーチンは,malloc() 記憶域へのポインタを戻します。この記憶域は,呼び出し側が解放しなければなりません。

システムの省略時の値を設定できるのは,システム省略時設定データベース用の putesdfnam() インタフェースを使用する方法だけです。たとえば,es_term エントリ内のフィールド sfldsflg を設定してから,putestcnam() を呼び出してシステム省略時設定値を設定することはできません。

3.3    認証データベースのアクセス

Tru64 UNIX には,各データベースへアクセスするライブラリ・ルーチンが一式あります。次に示すリファレンス・ページでは,これらのデータベースの形式と使用方法について説明しています。この章とこれらのリファレンス・ページを合わせて参照してください。

名前 データベース リファレンス・ページ
デバイス割り当て devassign getesdvent(3)
ファイル制御 file getesfient(3)
システム省略時設定 default getesdfent(3)
保護パスワード auth.db/prpasswd (NIS) getespwent(3)
端末制御 ttys.db getestcent(3)

これらのリファレンス・ページで定義されているライブラリ・ルーチンは,データベースの実際のファイル形式を隠しています。トラステッド・プログラムでは,この形式を意識する必要はありません。これらのライブラリ・ルーチンを使用するだけで済みます。