この章では、tsoluser(4) ユーザーデータベースと、tsolprof(4) プロファイルデータベースのエントリを読み取るプログラミングインタフェースについて説明します。エントリは、システム管理者がグラフィカルユーザーインタフェースのユーザーマネージャとプロファイルマネージャを使用して、ユーザーとプロファイルの設定を行う場合に、これらのデータベースに格納されます。
ユーザーデータベースには、システム内の全ユーザーのログイン、プロファイル、役割、ワークステーション、ラベル、認可上限、およびプロセスセキュリティ属性についての情報が入っています。
プロファイルデータベースには、CDE アクション、コマンド、承認についての情報が入っています。承認は、ユーザーや役割のプロファイル内でユーザーや役割に割り当てられています。
この章で説明しているプログラミングインタフェースを使用するには、次のヘッダーファイルが必要です。
#include <tsol/user.h>
#include <tsol/prof.h>
この章の例は、次のライブラリを使用してコンパイルしています。
-ltsoldb -lnsl -lcmd -ltsol
userent_t 構造体は、tsoluser(4) データベースのエントリ情報を含みます。このユーザーデータベースのエントリルーチンは、次の型の変数でデータを返します。
フィールド |
内容 |
char *name; |
当該エントリのユーザー名 |
char *lock; |
アカウントのロック状態 |
char *gen; |
パスワード生成の方法 |
char *profiles; |
使用されているユーザープロファイル |
char *roles; |
なることのできる役割 |
char *idletime; |
ワークステーションのアイドル時間 |
char *idlecmd; |
アイドル時間に達したときのコマンド |
char *labelview; |
内部または外部用のラベル表示 |
char *labeltrans; |
現在は未使用 |
char *labelmin; |
ユーザーの最下位ラベル |
char *labelmax; |
ユーザーの最上位ラベル (認可上限) |
char *usertype; |
一般ユーザー、一般の役割、管理役割のいずれか |
char *res1; |
将来使用のため予約 |
char *res2; |
将来使用のため予約 |
char *res3; |
将来使用のため予約 |
tsolprof(4) データベースエントリにアクセスするインタフェースには、2 種類あります。get*str() は、文字列に対する profstr_t 構造体のポインタでエントリを返します。get*ent() は、profent_t 構造体で情報を返します。この構造体では、コマンドとアクションの情報にリンクリストが使用されています。コマンドまたはアクションのリスト全体をステップ実行したい場合は、リンクリストを操作する方が簡単です。しかし、たとえばプロファイルの説明を確認するだけのように、データを詳しく確認する必要がない場合は、get*str() ルーチンの方が高速です。
profstr_t 構造体は、tsolprof データベースのエントリ情報を含みます。
フィールド |
内容 |
char *name; |
当該エントリのプロファイル名 |
char *desc; |
プロファイルの説明 |
char *auths; |
コンマで区切られた承認 ID |
char *actions; |
セミコロンで区切られた CDE アクションの説明 |
char *cmds; |
セミコロンで区切られたコマンドの説明 |
profent_t 構造は、tsolprof(4) データベースのエントリ情報を含みます。アクションとコマンドの情報は、リンクリストで返されます。
フィールド |
内容 |
char *name; |
当該エントリのプロファイル名 |
char *desc; |
プロファイルの説明 |
char *auths; |
コンマで区切られた承認 ID |
profact_t *actions; |
プロファイル内の CDE アクションのリンクリスト |
profcmd_t *cmds; |
プロファイル内のコマンドのリンクリスト |
profact_t 構造体は、アクションのリンクリストを含みます。
フィールド |
内容 |
char *actname |
アクション名 |
char *argclass |
引数のクラス |
char *argtype |
引数の種類 |
char *argmode |
引数のモード |
char *argcount |
引数の数 |
char *privs |
特権 |
char *euid |
実効ユーザー ID |
char *egid |
実効グループ ID |
char *min |
割り当てられたラベル範囲における最下位のラベル |
char *max |
割り当てられたラベル範囲における最上位のラベル |
profcmd_t 構造体は、コマンドのリンクリストを含みます。
フィールド |
内容 |
char *dir |
コマンドが常駐するディレクトリ |
char *file |
コマンドファイルの名前 |
char *privs |
特権 |
char *euid |
実効ユーザー ID |
char *egid |
実効グループ ID |
char *min |
割り当てられたラベル範囲における最下位のラベル |
char *max |
割り当てられたラベル範囲における最上位のラベル |
ライブラリルーチンを使用して、tsoluser(4) と tsolprof(4) データベース内のユーザー認可上限とプロファイルの情報にアクセスできます。この節の多くのインタフェースで使用される src パラメータ値は、データベース情報を取得する位置を示しています。
TSOL_DB_SRC_SWITCH - /etc/nsswitch.conf ファイルを使用して、データベース情報の情報元を確認する。このフラグは、もっともよく使用されます。
TSOL_DB_SRC_NISPLUS - tsoluser または tsolprof NIS+ データベースから読み取る
TSOL_DB_SRC_FILES - /etc/security/tsol/tsoluser または /etc/security/tsol/tsolprof ファイルから読み取る
次のルーチンは、ユーザーの名前またはユーザー ID を使用して、tsoluser データベース内のユーザーエントリを取得します。詳細は、getuserent(3) のマニュアルページを参照してください。
userent_t *getuserentbyname(char *user, int src); userent_t *getuserentbyuid(uid_t uid, int src);
次のルーチンは、tsoluser データベースの先頭に移動し、データベース全体を巡回します。詳細は、getuserent(3) マニュアルページを参照してください。
/* getuserent() に対する最初の呼び出しの前にこのルーチンを呼び出す */ void setuserent(int stayopen, int src); /* ユーザーのデータベースの最初のエントリを戻す。その後、 */ /* 呼び出しの都度、その次のエントリを戻す */ userent_t *getuserent(int src); /* 終了処理 */ void enduserent(int src);
次のルーチンは、再入可能なルーチン getuserentbyname(3)、 getuserentbyuid(3)、 getuserent(3) に割り当てられた記憶領域を解放します。詳細は、getuserent(3) マニュアルページを参照してください。
void free_userent(userent_t *userent);
次のルーチンは、プロファイル名を使用して tsolprof(4) データベース内のエントリを取得します。getprofentbyname(3) ルーチンは、リンクリスト内のアクションとコマンドの情報を返します。この情報は、getprofstrbyname(3) ルーチンが返す情報よりも詳しいものです。詳細は、getprofent(3) と getprofstr(3) マニュアルページを参照してください。
profstr_t *getprofstrbyname(char *name, int src); profent_t *getprofentbyname(char *name, int src);
次のルーチンは、tsolprof データベースの初めに移動し、データベース内を巡回します。詳細は、getprofent(3) と getprofstr(3) のマニュアルページを参照してください。
/* getprofent() に対する最初の呼び出しの前に呼び出す */ void setprofstr(int stayopen, int src); void setprofent(int stayopen, int src); /* ユーザーのデータベースの最初のエントリを戻す。その後、 */ /* 呼び出しの都度、その次のエントリを戻す */ profstr_t *getprofstr(int src); profent_t *getprofent(int src); /* 終了処理 */ void endprofstr(int src); void endprofent(int src);
次のルーチンは、再入可能なルーチン getprofentbyname(3)、 getprofent(3)、 getprofstrbyname(3)、getprofstr(3) に割り当てられた記憶領域を解放します。詳細は、getprofent(3) と getprofstr(3) マニュアルページを参照してください。
void free_profstr(profstr_t *profent); void free_profent(profent_t *profent);
次のコード例は、指定されたユーザーのユーザーエントリとプロファイルエントリを取得します。getuserentbyuid(3) ルーチンは getuserentbyname(3) ルーチンとほとんど変わらないため、示されていません。このコードセグメントのヘッダーファイルと宣言は、最初のプログラムに含まれています。
#include <tsol/user.h> #include <tsol/prof.h> main() { userent_t *uentry; profent_t *pentry; profstr_t *sentry; char *uname = "zelda"; char *pname = "All Authorizations"; uentry = getuserentbyname(uname, TSOL_DB_SRC_SWITCH); sentry = getprofstrbyname(pname, TSOL_DB_SRC_SWITCH); pentry = getprofentbyname(pname, TSOL_DB_SRC_SWITCH); /* ユーザーのデータベースのエントリを出力する */ printf("User name = %s¥n", uentry->name); printf(User lock = %s¥n", uentry->lock); printf(User password generation = %s¥n", uentry->gen); printf(User profiles = %s¥n", uentry->profiles); printf(User roles = %s¥n", uentry->roles); printf(User idletime = %s¥n", uentry->idletime); printf(User idlecmd = %s¥n", uentry->idlecmd); printf(Label view = %s¥n", uentry->labelview); printf(User label translation = %s¥n", uentry->labeltrans); printf(User minimum label = %s¥n", uentry->labelmin); printf(User maximum label = %s¥n", uentry->labelmax); printf(User type = %s¥n", uentry->usertype); /* プロファイルのデータベースのエントリを出力する */ printf("Profile name = %s¥n". sentry->name); printf("Description = %s¥n", sentry->desc); printf("Authorizations = %s¥n", sentry->auths); printf("Actions = %s¥n", sentry->actions); printf("Commands = %s ¥n", sentry->cmds); printf("Profile Name = %s¥n", pentry->name); printf("Description = %s¥n", pentry->desc); printf("Authorizations = %s¥n", pentry->auths); printf("Directory = %s¥n", pentry->cmds->dir); printf("File = %s¥n", pentry->cmds->dir); printf("Privs = %s¥n", pentry->cmds->privs); printf("EUID = %s¥n", pentry->cmds->euid); printf("GID = %s¥n", pentry->cmds->egid); printf("Min = %s¥n", pentry->cmds->min); printf("Max = %s¥n", pentry->cmds->max); printf("Actname = %s¥n", pentry->actions->actname); printf("Arg class = %s¥n", pentry->actions->argclass); free_userent(uentry); free_profstr(sentry); free_profent(pentry); }
printf(1) 文によって、ユーザーデータベースから次のように出力されます。最下位ラベルと最上位ラベルは、常に 16 進で返されます。この情報を別の形式にしたい場合は、第 6 章「ラベルのコード例」に挙げられている 16 進からバイナリ、バイナリから ASCII への変換ルーチンを使用してください。
User name = zelda User lock = open User password generation = manual User profiles = All Authorizations,All User roles = admin,oper,root,secadmin User idle time = 120 User idle command = lock user Label view = internal,showil,showsl User label translation = 0X0000 User Minimum label in hexadecimal = 0x00040c0000000000000000000000000000000000000000000003fffff fffffff0000 User Maximum label (clearance) in hexadecimal = 0x0006cc0000000000000000000000000000000000000000000003fffff fffffff0000 User type = utnorm |
コード例中の printf 文によって、まず getprofstrbyname(3) の結果が出力され、続いて getprofentbyname(3) の結果が出力されます。
getprofstrbyname(3) の printf(1) 文によって、次のように出力されます。
Profile name = All Authorizations Description = Grant all authorizations Authorizations = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36, 37,38,39,40,41,42,43,44,45 Actions = none;*;*;*;*;;;;; Commands = none;;;;;; |
getprofentbyname(3) の printf(1) 文によって、次のように出力されます。
Profile name = All Authorizations Description = Grant all authorizations Authorizations = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36, 37,38,39,40,41,42,43,44,45 |
Directory = none
File = none
Privs =
EUID =
GID =
Min =
Max =
Actname = none
Arg class = *
次の例は、tsoluser(4) データベースの先頭から開始し、エントリを 1 つずつ列挙する方法を示します。最後に、この列挙に割り当てられている資源と uentry (ユーザーエントリ) に割り当てられている記憶領域が解放されます。tsolprof(4) データベース内のエントリを列挙するコードはほとんどこのコードと変わらないため、示されていません。
#include <tsol/user.h> #include <tsol/prof.h> main() { userent_t *uentry; /* ユーザーのデータベースの先頭で列挙処理を設定する */ setuserent(0, TSOL_DB_SRC_SWITCH); while((uentry = getuserent(TSOL_DB_SRC_SWITCH)) != NULL) { /* ユーザーエントリをひとつずつ処理する */ } /* 列挙処理を終了し、資源を解放する */ enduserent(TSOL_DB_SRC_SWITCH); /* uentry に割り当てられた記憶領域を解放する */ free_userent(uentry); }