Oracle® Label Security Administrator's Guide 10g Release 2 (10.2) Part Number B14267-01 |
|
|
View PDF |
This appendix covers topics of interest to advanced users of Oracle Label Security. It contains these sections:
This section describes relationships between labels. It contains these topics:
The relationship between two labels can be described in terms of dominance. A user's ability to access an object depends on whether the user's label dominates the label of the object. If a user's label does not dominate the object's label, then the user is not allowed to access the object.
Label dominance is analyzed in terms of all its components: levels, compartments, and groups.
Table A-1 Dominance in the Comparison of Labels
Factor | Criteria for Dominance |
---|---|
Level | For label1 to dominate label2, the level of label1 must be greater than or equal to that of label2. |
Compartment | For label1 to dominate label2, the compartments of label1 must contain all the compartments of label2. |
Group | For label1 to dominate label2, label1 must contain at least one of the groups of label2. |
One label dominates another label if all of its components dominate the components of the other label. For example, the label HIGHLY_SENSITIVE:FINANCE,OPERATIONS dominates the label HIGHLY_SENSITIVE:FINANCE. Similarly, the label HIGHLY_SENSITIVE::WR_AP dominates the label HIGHLY_SENSITIVE::WR_AP, WR_AR.
The relationship between two labels cannot always be defined by dominance. Two labels are non-comparable if neither label dominates the other. If any compartments differ between the two labels (as with HS:A and HS:B), then they are non-comparable. Similarly, the labels HS:A and S:B are non-comparable.
You can use dominance functions to specify ranges in queries. The following functions enable you to indicate dominance relationships between specified labels.
Table A-2 Functions to Determine Dominance
Note that there are two types of dominance function. While the SA_UTL dominance functions return BOOLEAN values, the standalone dominance functions return integers.
The DOMINATES (DOM) function returns 1 (TRUE) if label1 dominates label2, or 0 (FALSE) if it does not.
Syntax:
FUNCTION DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
The STRICTLY_DOMINATES (SDOM) function returns 1 (TRUE) if label1 dominates label2 and is not equal to it.
Syntax:
FUNCTION STRICTLY_DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
The DOMINATED_BY (DOM_BY) function returns 1 (TRUE) if label1 is dominated by label2.
Syntax:
FUNCTION DOMINATED_BY ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
The STRICTLY_DOMINATED_BY (SDOM_BY) function returns 1 (TRUE) if label1 is dominated by label2 and is not equal to it.
Syntax:
FUNCTION STRICTLY_DOMINATED_BY ( label1 IN NUMBER, label2 IN NUMBER) RETURN INTEGER;
The SA_UTL.DOMINATES function returns TRUE if label1 dominates label2.
Syntax:
FUNCTION DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN BOOLEAN;
The SA_UTL.STRICTLY_DOMINATES function returns TRUE if label1 dominates label2 and is not equal to it.
Syntax:
FUNCTION STRICTLY_DOMINATES ( label1 IN NUMBER, label2 IN NUMBER) RETURN BOOLEAN;
The SA_UTL.DOMINATED_BY function returns TRUE if label1 is dominated by label2.
Syntax:
FUNCTION DOMINATED_BY ( label1 IN NUMBER, label2 IN NUMBER) RETURN BOOLEAN;
When using Oracle Call Interface (OCI) to connect, the policy's SYS_CONTEXT variables can be used to initialize the session label and the row label. The variables are set using the OCIAttrSet function to initialize externally initialized SYS_CONTEXT variables. These are available in Release 8.1.7 only when Oracle Label Security is installed.
Each policy has a SYS_CONTEXT named SA$policy_name_X. There are two variables that can be set, INITIAL_LABEL and INITIAL_ROW_LABEL.
When set to valid labels within the user's authorizations, the new values will be used instead of the default values stored for the user. This is the same mechanism used for remote connections
Additional attributes are defined for OCIAttrSet to insert context. Use OCI_ATTR_APPCTX_SIZE to initialize the context array size with the desired number of context attributes:
OCIAttrSet(session, OCI_HTYPE_SESSION, (dvoid *)&size, (ub4)0, OCI_ATTR_APPCTX_SIZE, error_handle);
Note that size is ub4 type.
Then call OCIAttrGet with OCI_ATTR_APPCTX_LIST to get a handle on the application context list descriptor for the session:
OCIAttrGet(session, OCI_HTYPE_SESSION, (dvoid *)&ctxl_desc, (ub4)0, OCI_ATTR_APPCTX_LIST, error_handle);
Note that ctxl_desc is (OCIParam *) type.
Then use the application context list descriptor to obtain an individual descriptor for the i-th application context:
OCIParamGet(ctxl_desc, OCI_DTYPE_PARAM, error_handle,(dvoid **)&ctx_desc, i);
Note that ctx_desc is (OCIParam *) type.
Set the proper values in the application context by using the three new attributes OCI_ATTR_APPCTX_NAME, OCI_ATTR_APPCTX_ATTR, and 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);
Note that only character type is supported, because application context operations are based on the VARCHAR2 type.
The following example shows how to use externalized SYS_CONTEXT with 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 */