この付録は、Oracle Label Securityの高度なユーザーを対象としています。 この付録の内容は、次のとおりです。
この項では、ラベル間の関係について説明します。 この項の内容は、次のとおりです。
ラベル間の関係は、支配という用語で説明できます。 ユーザーがオブジェクトにアクセスできるかどうかは、そのユーザーのラベルがオブジェクトのラベルを支配しているかどうかによって決定されます。ユーザーのラベルがオブジェクトのラベルを支配していない場合、ユーザーはそのオブジェクトへのアクセスを許可されません。
ラベルの支配関係は、そのすべてのコンポーネント、つまり、レベル、区分およびグループについて分析されます。
表A-1 ラベルの比較における支配関係
| 要因 | 支配関係の基準 |
|---|---|
|
レベル |
label1がlabel2を支配するには、label1のレベルがlabel2のレベル以上である必要があります。 |
|
区分 |
label1がlabel2を支配するには、label1の区分がlabel2のすべての区分を含んでいる必要があります。 |
|
グループ |
label1がlabel2を支配するには、label1がlabel2のグループを1つ以上含んでいる必要があります。 |
あるラベルが別のラベルを支配するのは、そのすべてのコンポーネントが別のラベルのコンポーネントを支配している場合です。たとえば、ラベルHIGHLY_SENSITIVE:FINANCE,OPERATIONSは、ラベルHIGHLY_SENSITIVE:FINANCEを支配します。同様に、ラベルHIGHLY_SENSITIVE::WR_APは、ラベルHIGHLY_SENSITIVE::WR_AP, WR_ARを支配します。
2つのラベル間の関係は、常に支配という用語で定義できるとはかぎりません。どちらのラベルも他方を支配していない場合、2つのラベルは比較できません。2つのラベル間で区分が異なる場合(HS:AやHS:Bなど)、両者は比較できません。同様に、ラベルHS:AおよびS:Bは比較できません。
支配ファンクションを使用すると、問合せで範囲を指定できます。次のファンクションを使用すると、指定したラベル間の支配関係を指定できます。
表A-2 支配関係を決定するファンクション
| ファンクション | 意味 |
|---|---|
|
label1の値によりlabel2の値が支配され、両者は等しくありません。 |
|
|
label1の値によりlabel2の値が支配されるか、等しくなります。 |
|
|
label1の値はlabel2の値に支配されます。 |
|
|
label1の値はlabel2の値に支配され、両者は等しくありません。 |
支配ファンクションには2つのタイプがあることに注意してください。SA_UTLの支配ファンクションはブール値を戻しますが、スタンドアロンの支配ファンクションは整数を戻します。
DOMINATES (DOM)ファンクションは、label1がlabel2を支配している場合は1(TRUE)、それ以外の場合は0(FALSE)を戻します。
構文:
FUNCTION DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
STRICTLY_DOMINATES (SDOM)ファンクションは、label1がlabel2を支配していて、両者が等しくない場合は1(TRUE)を戻します。
構文:
FUNCTION STRICTLY_DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
DOMINATED_BY (DOM_BY)ファンクションは、label1がlabel2に支配されている場合は1(TRUE)を戻します。
構文:
FUNCTION DOMINATED_BY ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
STRICTLY_DOMINATED_BY (SDOM_BY)ファンクションは、label1がlabel2に支配されていて、両者が等しくない場合は1(TRUE)を戻します。
構文:
FUNCTION STRICTLY_DOMINATED_BY ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
SA_UTL.DOMINATESファンクションは、label1がlabel2を支配している場合にTRUEを戻します。
構文:
FUNCTION DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN BOOLEAN;
SA_UTL.STRICTLY_DOMINATESファンクションは、label1がlabel2を支配していて、両者が等しくない場合にTRUEを戻します。
構文:
FUNCTION STRICTLY_DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN BOOLEAN;
SA_UTL.DOMINATED_BYファンクションは、label1がlabel2に支配されている場合にTRUEを戻します。
構文:
FUNCTION DOMINATED_BY ( label1 IN NUMBER, label2 IN NUMBER) RETURN BOOLEAN;
Oracle Call Interface(OCI)を使用して接続する場合は、ポリシーのSYS_CONTEXT変数を使用してセッション・ラベルと行ラベルを初期化できます。 各変数は、OCIAttrSetファンクションを使用して設定し、外部で初期化されたSYS_CONTEXT変数を初期化します。リリース8.1.7でこれらを使用できるのは、Oracle Label Securityがインストールされている場合のみです。
各ポリシーには、SA$policy_name_XというSYS_CONTEXTがあります。また、2つの変数INITIAL_LABELおよびINITIAL_ROW_LABELを設定できます。
新規の値をユーザーの認証の範囲内で有効なラベルに設定すると、ユーザー用に格納されているデフォルト値のかわりにその値が使用されます。これは、リモート接続に使用されるのと同じメカニズムです。
コンテキスト挿入用に、OCIAttrSetには追加の属性が定義されます。 OCI_ATTR_APPCTX_SIZEを使用して必要な数のコンテキスト属性を指定し、コンテキストの配列サイズを初期化します。
OCIAttrSet(session, OCI_HTYPE_SESSION,
(dvoid *)&size, (ub4)0, OCI_ATTR_APPCTX_SIZE, error_handle);
サイズはub4型であることに注意してください。
OCI_ATTR_APPCTX_LISTを指定してOCIAttrGetをコールし、セッション用のアプリケーション・コンテキスト・リスト記述子のハンドルを取得します。
OCIAttrGet(session, OCI_HTYPE_SESSION,
(dvoid *)&ctxl_desc, (ub4)0, OCI_ATTR_APPCTX_LIST, error_handle);
ctxl_descが(OCIParam *)型であることに注意してください。
アプリケーション・コンテキスト・リスト記述子を使用して、i番目のアプリケーション・コンテキストの個別記述子を取得します。
OCIParamGet(ctxl_desc, OCI_DTYPE_PARAM, error_handle,(dvoid **)&ctx_desc, i);
ctx_descが(OCIParam *)型であることに注意してください。
3つの新規属性OCI_ATTR_APPCTX_NAME、OCI_ATTR_APPCTX_ATTRおよびOCI_ATTR_APPCTX_VALUEを使用して、アプリケーション・コンテキスト内で適切な値を設定します。
OCIAttrSet(ctx_desc, OCI_DTYPE_PARAM, (dvoid *)ctx_name, sizeof(ctx_name), OCI_ATTR_APPCTX_NAME, error_handle); OCIAttrSet(ctx_desc, OCI_DTYPE_PARAM, (dvoid *)attr_name, sizeof(attr_name), OCI_ATTR_APPCTX_ATTR, error_handle); OCIAttrSet(ctx_desc, OCI_DTYPE_PARAM, (dvoid *)value, sizeof(value), OCI_ATTR_APPCTX_VALUE, error_handle);
アプリケーション・コンテキストの操作はVARCHAR2型に基づいているため、サポートされるのは文字型のみであることに注意してください。
次の例に、外部化されたSYS_CONTEXTをOracle Label Securityで使用する方法を示します。
#ifdef RCSID static char *RCSid = "$Header: ext_mls.c 09-may-00.10:07:08 jdoe Exp $ "; #endif /* RCSID */ /* Copyright (c) Oracle Corporation 1999, 2000. All Rights Reserved. */ /* NAME
ext_mls.c - externalized SYS_CONTEXT with Label Security
DESCRIPTION
Run olsdemo.sql script before executing this example. Usage: <executable obtained with .c file> <user_name> <password> <session-initial-label Example: avg_sal sa_demo sa_demo L3:M,E:D10
PUBLIC FUNCTION(S)
<list of external functions declared/defined - with one-line descriptions>
PRIVATE FUNCTION(S)
<list of static functions defined in .c file - with one-line descriptions>
RETURNS
The average salary in the EMP table of the SA_DEMO schema querying as the specified user with the specified session label.
NOTES
<other useful comments, qualifications, and so on>
MODIFIED (MM/DD/YY)
jlev 09/18/03 - cleanup jdoe 05/09/00 - cleanup
jdoe 10/13/99 - standalone OCI program to test MLS SYS_CONTEXT
jdoe 10/13/99 - Creation
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>
static OCIEnv *envhp;
static OCIError *errhp;
int main(/*_ int argc, char *argv[] _*/);
/* get and print error */
static void checkerr(/*_OCIError *errhp, sword status _*/);
/* print error */
static void printerr(char *call);
static sword status;
/* return the average of employees' salary */
static CONST text *const selectstmt = (text *)
"select avg(sal) from sa_demo.emp";
int main(argc, argv)
int argc;
char *argv[];
{
OCISession *authp = (OCISession *) 0;
OCIServer *srvhp;
OCISvcCtx *svchp;
OCIDefine *defnp = (OCIDefine *) 0;
dvoid *parmdp;
ub4 ctxsize;
OCIParam *ctxldesc;
OCIParam *ctxedesc;
OCIStmt *stmtp = (OCIStmt *) 0;
ub4 avg_sal = 0;
sword status;
if (OCIInitialize((ub4) OCI_DEFAULT, (dvoid *) 0,
(dvoid * (*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t)) 0,
(void (*)(dvoid *, dvoid *)) 0))
printerr("OCIInitialize");
if (OCIEnvInit((OCIEnv **) &envhp, OCI_DEFAULT, (size_t) 0, (dvoid **) 0))
printerr("OCIEnvInit");
if (OCIHandleAlloc((dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,
(size_t) 0, (dvoid **) 0))
printerr("OCIHandleAlloc:OCI_HTYPE_ERROR");
if (OCIHandleAlloc((dvoid *) envhp, (dvoid **) &srvhp, OCI_HTYPE_SERVER,
(size_t) 0, (dvoid **) 0))
printerr("OCIHandleAlloc:OCI_HTYPE_SERVER");
if (OCIHandleAlloc((dvoid *) envhp, (dvoid **) &svchp, OCI_HTYPE_SVCCTX,
(size_t) 0, (dvoid **) 0))
printerr("OCIHandleAlloc:OCI_HTYPE_SVCCTX");
if (OCIServerAttach(srvhp, errhp, (text *) "", strlen(""), 0))
printerr("OCIServerAttach");
/* set attribute server context in the service context */
if (OCIAttrSet((dvoid *) svchp, OCI_HTYPE_SVCCTX, (dvoid *) srvhp,
(ub4) 0, OCI_ATTR_SERVER, (OCIError *) errhp))
printerr("OCIAttrSet:OCI_HTYPE_SVCCTX");
if (OCIHandleAlloc((dvoid *) envhp, (dvoid **) &authp,
(ub4) OCI_HTYPE_SESSION, (size_t) 0, (dvoid **) 0))
printerr("OCIHandleAlloc:OCI_HTYPE_SESSION");
/* set application context to 1 */
ctxsize = 1;
/* set up app ctx buffer */
if (OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) &ctxsize,
(ub4) 0, (ub4) OCI_ATTR_APPCTX_SIZE, errhp))
printerr("OCIAttrSet:OCI_ATTR_APPCTX_SIZE");
/* retrieve the list descriptor */
if (OCIAttrGet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION,
(dvoid *) &ctxldesc, 0, OCI_ATTR_APPCTX_LIST, errhp))
printerr("OCIAttrGet:OCI_ATTR_APPCTX_LIST");
if (status = OCIParamGet(ctxldesc, OCI_DTYPE_PARAM, errhp,
(dvoid **) &ctxedesc, 1))
{
if (status == OCI_NO_DATA)
{
printf("No Data found!\n");
exit(1);
}
}
/* set context namespace to SA$<pol_name>_X */
if (OCIAttrSet((dvoid *) ctxedesc, (ub4) OCI_DTYPE_PARAM,
(dvoid *) "SA$HUMAN_RESOURCES_X",
(ub4) strlen((char *) "SA$HUMAN_RESOURCES_X"),
(ub4) OCI_ATTR_APPCTX_NAME, errhp))
printerr("OCIAttrSet:OCI_ATTR_APPCTX_NAME:SA$HUMAN_RESOURCES_X");
/* set context attribute to INITIAL_LABEL */
if (OCIAttrSet((dvoid *) ctxedesc, (ub4) OCI_DTYPE_PARAM,
(dvoid *) "INITIAL_LABEL",
(ub4) strlen((char *) "INITIAL_LABEL"),
(ub4) OCI_ATTR_APPCTX_ATTR, errhp))
printerr("OCIAttrSet:OCI_DTYPE_PARAM:INITIAL_LABEL");
/* set context value to argv[3] - initial label */
if (OCIAttrSet((dvoid *) ctxedesc, (ub4) OCI_DTYPE_PARAM,
(dvoid *) argv[3],
(ub4) strlen((char *) argv[3]),
(ub4) OCI_ATTR_APPCTX_VALUE, errhp))
printerr("OCIAttrSet:argv[3]");
/* username first command line argument */
if (OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) argv[1],
(ub4) strlen((char *) argv[1]), (ub4) OCI_ATTR_USERNAME,
errhp))
printerr("OCIAttrSet:username");
/* password second command line argument */
if (OCIAttrSet((dvoid *) authp, (ub4) OCI_HTYPE_SESSION, (dvoid *) argv[2],
(ub4) strlen((char *) argv[2]), (ub4) OCI_ATTR_PASSWORD,
errhp))
printerr("OCIAttrSet:password");
if (OCISessionBegin(svchp, errhp, authp, OCI_CRED_RDBMS, (ub4) OCI_DEFAULT))
printerr("OCISessionBegin");
if (OCIAttrSet((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX, (dvoid *) authp,
(ub4) 0, (ub4) OCI_ATTR_SESSION, errhp))
printerr("OCIAttrSet:OCI_ATTR_SESSION");
if (OCIHandleAlloc((dvoid *) envhp, (dvoid **) &stmtp, OCI_HTYPE_STMT,
0, 0))
printerr("OCIHandleAlloc:OCI_HTYPE_STMT");
if (OCIStmtPrepare(stmtp, errhp, (CONST OraText *) selectstmt,
(ub4) strlen((const char *) selectstmt),
(ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT))
printerr("OCIStmtPrepare");
if (OCIDefineByPos(stmtp, &defnp, errhp, (ub4) 1, (dvoid *) &avg_sal,
(sb4) sizeof(avg_sal), SQLT_INT, 0, 0, 0, OCI_DEFAULT))
printerr("OCIDefineByPos");
if (status = OCIStmtExecute(svchp, stmtp, errhp, 1, 0, NULL, NULL,
OCI_DEFAULT))
{
if (status == OCI_NO_DATA)
{
printf("No Data found!\n");
exit(1);
}
}
if (OCISessionEnd(svchp, errhp, authp, OCI_DEFAULT))
printerr("OCISessionEnd");
printf("average salary is: %d\n", avg_sal);
}
void checkerr(errhp, status)
OCIError *errhp;
sword status;
{
text errbuf[512];
sb4 errcode = 0;
switch (status)
{
case OCI_ERROR:
(void) OCIErrorGet((dvoid *) errhp, 1, NULL, &errcode, errbuf,
(ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
printf("Error - %.*s\n", 512, errbuf);
break;
default:
break;
}
}
void printerr(call)
char *call;
{
printf("Error: %s\n", call);
}
/* end of file ext_mls.c */