----------------------------------------------------------------------------- -- (c) Copyright IBM Corp. 2007 All rights reserved. -- -- The following sample of source code ("Sample") is owned by International -- Business Machines Corporation or one of its subsidiaries ("IBM") and is -- copyrighted and licensed, not sold. You may use, copy, modify, and -- distribute the Sample in any form without payment to IBM, for the purpose of -- assisting you in the development of your applications. -- -- The Sample code is provided to you on an "AS IS" basis, without warranty of -- any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR -- IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Some jurisdictions do -- not allow for the exclusion or limitation of implied warranties, so the above -- limitations or exclusions may not apply to you. IBM shall not be liable for -- any damages you suffer as a result of using, copying, modifying or -- distributing the Sample, even if IBM has been advised of the possibility of -- such damages. ----------------------------------------------------------------------------- -- -- SOURCE FILE NAME: lbac.db2 -- -- SAMPLE: How to take advantage of DB2 LBAC (Label Based Access Control) -- feature -- -- PREREQUISITES FOR RUNNING THE SAMPLE: -- The sample assumes the existance of the following users along with -- the specified passwords -- secadm with password "secadm123" -- joe with password "joe123" -- bob with password "bob123" -- pat with password "pat123" -- -- SQL STATEMENTS USED: -- CONNECT -- CREATE SECURITY LABEL -- CREATE SECURITY POLICY -- CREATE TABLE -- DELETE -- DROP SECURITY LABEL -- DROP TABLE -- GRANT SECURITY LABEL -- GRANT EXEMPTION -- REVOKE SECURITY LABEL -- REVOKE EXEMPTION -- INSERT -- UPDATE -- SELECT -- -- ----------------------------------------------------------------------------- -- -- For more information about the command line processor (CLP) scripts, -- see the README file. -- -- For information on using SQL statements, see the SQL Reference. -- -- For the latest information on programming, building, and running DB2 -- applications, visit the DB2 Information Center: -- http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/index.jsp ----------------------------------------------------------------------------- -- Disconnect from any existing database connection. CONNECT RESET; -- This example shows how to take advantage of the DB2 LBAC feature. -- It shows LBAC being used in a hypothetical government setting. -- Grant SECADM authority to a user secadm -- An user with SYSADM authority can grant SECADM authority to a user CONNECT TO sample; GRANT SECADM ON DATABASE TO USER secadm; -- Connect as the user with SECADM authority CONNECT TO sample USER secadm USING secadm123; -- First, a user with SECADM authority creates the security label components -- that will be part of the security policy. This sample uses three security -- label components: level, departments, and groups. -- The level component is of type ARRAY and has these elements: -- -- TOP SECRET (Highest) -- SECRET -- CONFIDENTIAL -- UNCLASSIFIED (Lowest) -- -- This statement creates the level component: CREATE SECURITY LABEL COMPONENT level ARRAY ['TOP SECRET', 'SECRET', 'CONFIDENTIAL', 'UNCLASSIFIED']; -- The departments component is of type SET and has these elements: -- -- ALPHA, SIGMA, and DELTA -- -- This statement creates the departments component: CREATE SECURITY LABEL COMPONENT departments SET {'ALPHA', 'DELTA', 'SIGMA'}; -- The groups component is of type TREE and has these elements: -- -- G1 (ROOT) -- +--+--+ -- | | -- G2 G3 -- +--+--+ -- | | -- G4 G5 -- -- This statement creates the groups component: CREATE SECURITY LABEL COMPONENT groups TREE ('G1' ROOT, 'G2' UNDER 'G1', 'G3' UNDER 'G1', 'G4' UNDER 'G3', 'G5' UNDER 'G3'); -- Next, a user with SECADM authority executes this statement to -- create a security policy named secpolicy that has the three -- components previously created and uses the DB2LBACRULES rule set. CREATE SECURITY POLICY secpolicy COMPONENTS level, departments, groups WITH DB2LBACRULES; -- Now the user with SECADM authority can execute the following -- statements to create some security labels that are part of the -- security policy secpolicy. -- For the purposes of this example the security label names end with -- a number that indicates the relative "strength" of the label. -- In other words seclabel1 is blocked by seclabel2 and seclabel2 is -- blocked by seclabel3 but not by seclabel1, etc. This is only to make -- the example easier to follow. CREATE SECURITY LABEL secpolicy.seclabel1 COMPONENT level 'UNCLASSIFIED', COMPONENT departments 'ALPHA', 'DELTA', COMPONENT groups 'G4'; CREATE SECURITY LABEL secpolicy.seclabel2 COMPONENT level 'CONFIDENTIAL', COMPONENT departments 'ALPHA', 'DELTA', COMPONENT groups 'G4'; CREATE SECURITY LABEL secpolicy.seclabel3 COMPONENT level 'SECRET', COMPONENT departments 'ALPHA', 'DELTA', COMPONENT groups 'G4'; CREATE SECURITY LABEL secpolicy.seclabel4 COMPONENT level 'TOP SECRET', COMPONENT departments 'ALPHA', 'DELTA', COMPONENT groups 'G4'; -- Granting seclabel2 to user joe in order to create a column -- secured with seclabel2 GRANT SECURITY LABEL secpolicy.seclabel2 TO USER joe; CONNECT TO sample USER joe USING joe123; -- The user with SECADM authority now creates a protected table -- and attaches the security policy to the table. The table includes -- a column named rowseclabel that will hold the security labels -- protecting the rows. It also has a column named payrank that is -- protected by the security label seclabel2. The payrank column has -- a default value of 0. -- This is the statement that creates a protected table: CREATE TABLE joe.employee_lbac ( empno int, lastname char(10), deptno int, payrank int SECURED WITH seclabel2 DEFAULT 0, rowseclabel DB2SECURITYLABEL ) SECURITY POLICY secpolicy; -- The protected table is now ready for use. -- The user with SECADM authority grants security label seclabel1 to user joe CONNECT TO sample USER secadm USING secadm123; REVOKE SECURITY LABEL secpolicy.seclabel2 FROM USER joe; GRANT SECURITY LABEL secpolicy.seclabel1 TO USER joe; -- Joe now holds the security label seclabel1 for both read and write access. -- turn off echo Current Command option to suppress printing of echo command UPDATE COMMAND OPTIONS USING v OFF; !echo ---------------------------------------------------------------------; !echo -- INSERTING INTO A PROTECTED TABLE ---; !echo ---------------------------------------------------------------------; -- turn on the Echo Current Command option UPDATE COMMAND OPTIONS USING v ON; -- Joe tries to insert a row to the table by specifying a value for every -- column except rowseclabel: CONNECT TO sample USER joe USING joe123; INSERT INTO joe.employee_lbac (empno, lastname, deptno, payrank) VALUES (1, 'Smith', 11, 3); -- The insert fails because the column 'payrank' is protected by the -- security label seclabel2 and joe holds security label seclabel1. The security -- label seclabel1 cannot read from or write to security label seclabel2. -- Joe removes the column payrank from the INSERT statement. This time the insert -- is successful because the column payrank has a default value and therefore it -- is not necessary that an explicit value be given for it. INSERT INTO joe.employee_lbac (empno, lastname, deptno) VALUES (1, 'Smith', 11); -- Because no value is given for the column rowseclabel, the security label that -- the user holds for writing is inserted by default. In the case of user joe -- that is seclabel1. -- The rows in table employee_lbac now look like this: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- 1 Smith 11 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- Now the user with SECADM authority revokes seclabel1 from joe and grants -- him seclabel2 instead, by executing these statements: CONNECT TO sample USER secadm USING secadm123; REVOKE SECURITY LABEL secpolicy.seclabel1 FROM USER joe; GRANT SECURITY LABEL secpolicy.seclabel2 TO USER joe; -- Joe now holds the security label seclabel2 for both read and write access. -- He no longer holds the security label seclabel1. -- Joe inserts another row as he did before: CONNECT TO sample USER joe USING joe123; INSERT INTO joe.employee_lbac (empno, lastname, deptno) VALUES (2, 'Haas', 11); -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(rowseclabel AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- The values in the rowseclabel column are shown in a character representation -- of the internal format. This is the default. Joe wants to read them in -- security label string format so he executes the select again, this time using -- the SECLABEL_TO_CHAR built-in function to convert the security labels as below: -- CAST to VARCHAR(30) is done on rowseclabel column only to make the output fit -- the screen and is not otherwise required. -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- Joe wants the next row he writes to be protected by seclabel1 rather than the -- security label he currently holds. He uses the SECLABEL_BY_NAME built-in -- function to provide seclabel1 for insert. INSERT INTO joe.employee_lbac (empno, lastname, deptno, rowseclabel) VALUES (3, 'Miller', 11, SECLABEL_BY_NAME('SECPOLICY', 'SECLABEL1')); -- The statement does not give joe the results he wants. When you provide an -- explicit security label to protect a row you must be able to write to data -- protected by that security label, otherwise it cannot be used. You cannot -- insert a row that you would be unable to write to. -- The reason that seclabel2 cannot write to seclabel1 is the rule DB2LBACWRITEARRAY. -- That rule prevents writing to any security label that has an element for an ARRAY -- type component that is different than the element for the same component in your -- security label. The security label seclabel1 has a value of 'UNCLASSIFIED' for -- the level component while seclabel2 has a value of 'CONFIDENTIAL' for that component. -- What happens when you try to insert a security label that you cannot write to -- depends on whether or not the security policy was created with the -- RESTRICT NOT AUTHORIZED WRITE SECURITY LABEL option. It the option was used -- then the statement fails and an error is returned. If it was not used then no -- error is given but the provided security label is ignored and the user's -- security label for write access is used instead. -- The security policy secpolicy was created without -- the RESTRICT NOT AUTHORIZED WRITE SECURITY LABEL option, so no error is given -- and joe's current security label is used instead. -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- A user with SECADM authority now grants joe an exemption to the part of -- the DB2LBACWRITEARRAY rule that prevents writing to elements that are lower -- than yours (the write-down portion): CONNECT TO sample USER secadm USING secadm123; GRANT EXEMPTION ON RULE DB2LBACWRITEARRAY WRITEDOWN FOR secpolicy TO USER joe; -- Joe again tries to insert a row protected by seclabel1: CONNECT TO sample USER joe USING joe123; INSERT INTO joe.employee_lbac (empno, lastname, deptno, rowseclabel) VALUES (4, 'Barberra', 11, SECLABEL_BY_NAME('SECPOLICY', 'SECLABEL1')); -- This insert does what joe expects because joe can now write to data -- protected by seclabel1 -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- The next row that joe needs to insert must be protected by a security label in -- which level = UNCLASSIFIED, departments = ALPHA, and groups = G4. There is no -- named security label with those values so joe must use the SECLABEL built-in -- function. The SECLABEL function creates a security label based on a list of -- element values. INSERT INTO joe.employee_lbac (empno, lastname, deptno, rowseclabel) VALUES (5, 'Kubrick', 11, SECLABEL('SECPOLICY', 'UNCLASSIFIED:ALPHA:G4')); -- Joe is able to write to data protected by a security label with the -- values 'UNCLASSIFIED:ALPHA:G4' so the insert takes place and the -- supplied security label is used. -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- Joe must now insert a row that includes a payrank of 2 and is to be protected -- by seclabel2. Joe currently holds security label seclabel2 for write access. -- This means that he is able to write to the column payrank, which is protected -- by seclabel2. It also means that when he does not explicitly provide a security -- label for the column rowseclabel, the security label seclabel2 will be used. -- Joe executes this insert statement, which executes without error: INSERT INTO joe.employee_lbac (empno, lastname, deptno, payrank) VALUES (6, 'Little', 11, 2); -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- Joe has one last row to insert. This one must be protected by seclabel4 and -- must have a payrank of 5. Security labels seclabel2 and seclabel4 both have -- the same values for the departments and groups components. They are only -- different in the level component. So, if Joe is granted an exemption to the -- rule DB2WRITEARRAY for write-up he will be able to write to data protected -- by seclabel4 and will therefore be able to insert seclabel4 into the column. -- Note: Granting an exemption is a somewhat drastic solution to this problem -- and is only being done here for demonstration purposes. -- A user with SECADM authority grants joe an exemption to the write-up portion -- of the DB2WRITEARRAY rule by executing this statement: CONNECT TO sample USER secadm USING secadm123; GRANT EXEMPTION ON RULE DB2LBACWRITEARRAY WRITEUP FOR secpolicy TO USER joe; -- Joe now does an insert with security label seclabel4 CONNECT TO sample USER joe USING joe123; INSERT INTO joe.employee_lbac (empno, lastname, deptno, payrank, rowseclabel) VALUES (7, 'Addams', 22, 5, SECLABEL_BY_NAME('SECPOLICY', 'SECLABEL4')); -- The rows in table employee_lbac now look like this: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- ----------- ---------- ----------- ----------- ------------------------------ -- 1 Smith 11 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 2 Haas 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 3 Miller 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 4 Barberra 11 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 5 Kubrick 11 0 UNCLASSIFIED:ALPHA:G4 -- 6 Little 11 2 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 7 Addams 22 5 TOP SECRET:(ALPHA,DELTA):G4 -- turn off echo Current Command option to suppress printing of echo command UPDATE COMMAND OPTIONS USING v OFF; !echo ---------------------------------------------------------------------; !echo -- READING FROM A PROTECTED TABLE ---; !echo ---------------------------------------------------------------------; -- turn on the Echo Current Command option UPDATE COMMAND OPTIONS USING v ON; -- Just after finishing the previous inserts. Joe wants to make sure that all of -- the data is in the table so he executes this SELECT statement to count the rows: SELECT COUNT(*) AS count FROM joe.employee_lbac; -- The statement returns a count of 6. There seems to be a row missing. -- Joe executes this statement to view the rows: -- Select the rows in the table employee_lbac SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- The reason is that joe holds only seclabel2 for read access and has been granted -- no exemptions to the rules for read access. He cannot read the last row because -- his LBAC credentials prevent it. -- To allow joe to view the entire table, a user with SECADM authority revokes -- seclabel2 from joe and grants seclabel4 to him: CONNECT TO sample USER secadm USING secadm123; REVOKE SECURITY LABEL secpolicy.seclabel2 FROM USER joe; GRANT SECURITY LABEL secpolicy.seclabel4 TO USER joe; -- Select the rows in the table employee_lbac CONNECT TO sample USER joe USING joe123; SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- Joe is now done with the inserts so the user with SECADM authority revokes -- all of joe's exemptions and sets his security label back to seclabel1 with -- these statements: CONNECT TO sample USER secadm USING secadm123; REVOKE EXEMPTION ON RULE ALL FOR secpolicy FROM USER joe; REVOKE SECURITY LABEL secpolicy.seclabel4 FROM USER joe; GRANT SECURITY LABEL secpolicy.seclabel1 TO USER joe; -- Joe now tries to count the rows again. This time the count is 3 because with -- a security label of seclabel1 he is only able to read 3 of the rows. CONNECT TO sample USER joe USING joe123; SELECT COUNT(*) AS count FROM joe.employee_lbac; -- Joe tries to view the rows with this statement but because the -- asterisk (*) includes the column payrank in the select the -- statement fails. Joe no longer has read access to the column payrank. SELECT * FROM joe.employee_lbac; -- Joe changes the statement to exclude the payrank column and also to convert -- the security labels to a security label string format, then executes it: SELECT empno, lastname, deptno, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- turn off echo Current Command option to suppress printing of echo command UPDATE COMMAND OPTIONS USING v OFF; !echo ---------------------------------------------------------------------; !echo -- UPDATING A PROTECTED TABLE ---; !echo ---------------------------------------------------------------------; -- turn on the Echo Current Command option UPDATE COMMAND OPTIONS USING v ON; -- These rows are in table employee_lbac: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- ----------- ---------- ----------- ----------- ------------------------------ -- 1 Smith 11 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 2 Haas 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 3 Miller 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 4 Barberra 11 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 5 Kubrick 11 0 UNCLASSIFIED:ALPHA:G4 -- 6 Little 11 2 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 7 Addams 22 5 TOP SECRET:(ALPHA,DELTA):G4 -- User bob needs to make some updates to the employee_lbac table. A user -- with SECADM authority grants him security label seclabel1 with this statement: CONNECT TO sample USER secadm USING secadm123; GRANT SECURITY LABEL secpolicy.seclabel1 TO USER bob; -- Grant select, insert, update, delete privileges on employee_lbac -- table to bob, pat. This can be done by joe using the below statement CONNECT TO sample user joe USING joe123; GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE joe.employee_lbac TO USER bob, pat; -- Bob issues the following update statement: CONNECT TO sample USER bob USING bob123; UPDATE joe.employee_lbac SET deptno = 0; -- The update executes without error but rows to which bob does not have -- read access are not affected. Also, because the update does not explicitly -- set the column rowseclabel it is automatically set to the security label -- that bob holds for write access (seclabel1). -- After the statement, the rows in the table look like this: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- ----------- ---------- ----------- ----------- ------------------------------ -- 1 Smith 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 2 Haas 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 3 Miller 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 4 Barberra 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 5 Kubrick 0 0 UNCLASSIFIED:ALPHA:G4 -- 6 Little 11 2 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 7 Addams 22 5 TOP SECRET:(ALPHA,DELTA):G4 -- Now bob tries to change all payranks greater than 0 to 1. He executes this -- statement but the statement fails because he does not have write access or -- read access to the column payrank: UPDATE joe.employee_lbac SET payrank = 1 WHERE payrank > 0; -- A user with SECADM authority changes bob's security label to seclabel3 -- Connect as the SECADM user CONNECT TO sample USER secadm USING secadm123; REVOKE SECURITY LABEL secpolicy.seclabel1 FROM USER bob; GRANT SECURITY LABEL secpolicy.seclabel3 TO USER bob; -- Bob tries the update again. This time it fails because seclabel3, which bob -- holds for write access, has a value of 'SECRET' for the component level -- and the security label protecting the row has a value of 'CONFIDENTIAL' for -- that component. Writing to the row would violate the write-down part of the -- DB2LBACWRITEARRAY rule. To allow bob to make the update, a user with SECADM -- could either grant the security label seclabel2 to him or grant him an exemption -- on the write-down portion of the DB2LBACWRITEARRAY rule. Granting a new security -- label is by far the safest way to grant access, but for demonstration purposes -- assume the user with SECADM authority grants the exemption: GRANT EXEMPTION ON RULE DB2LBACWRITEARRAY WRITEDOWN FOR secpolicy TO USER bob; -- Bob executes the update again. This time it executes with no error because bob has -- both read and write access to the column payrank and also to the row. The update -- does not affect the row where empno = 7, however because bob is not able to read that -- row. Also, the security label protecting the updated row is changed to the security -- label that bob holds for write access, namely seclabel3. CONNECT TO sample USER bob USING bob123; UPDATE joe.employee_lbac SET payrank = 1 WHERE payrank > 0; -- After the statement, the rows in the table look like this: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- ----------- ---------- ----------- ----------- ------------------------------ -- 1 Smith 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 2 Haas 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 3 Miller 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 4 Barberra 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 5 Kubrick 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 6 Little 11 1 SECRET:(ALPHA,DELTA):G4 -- 7 Addams 22 5 TOP SECRET:(ALPHA,DELTA):G4 -- To check his work, bob selects the rows of the table. He uses the SECLABEL_TO_CHAR -- built-in function to convert the security labels to a more readable form. SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- Bob needs to change the row where empno = 6 so that it it protected by seclabel2 -- instead of seclabel3. Because he already holds an exemption to the write-down portion -- of the DB2LBACWRITEARRAY rule he can write to seclabel2 and can therefore explicitly -- use it in his update: UPDATE joe.employee_lbac SET rowseclabel = SECLABEL_BY_NAME('SECPOLICY', 'SECLABEL2') WHERE empno = 6; -- After the statement, the rows in the table look like this: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- ----------- ---------- ----------- ----------- ------------------------------ -- 1 Smith 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 2 Haas 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 3 Miller 11 0 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 4 Barberra 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 5 Kubrick 0 0 UNCLASSIFIED:(ALPHA,DELTA):G4 -- 6 Little 11 1 CONFIDENTIAL:(ALPHA,DELTA):G4 -- 7 Addams 22 5 TOP SECRET:(ALPHA,DELTA):G4 -- Bob is finished with his updates. The user with SECADM authority revokes all -- exemptions from him and also changes his security label back to seclabel1 CONNECT TO sample USER secadm USING secadm123; REVOKE EXEMPTION ON RULE ALL FOR secpolicy FROM USER bob; REVOKE SECURITY LABEL secpolicy.seclabel3 FROM USER bob; GRANT SECURITY LABEL secpolicy.seclabel1 TO USER bob; -- turn off echo Current Command option to suppress printing of echo command UPDATE COMMAND OPTIONS USING v OFF; !echo ---------------------------------------------------------------------; !echo -- DELETING FROM A PROTECTED TABLE ---; !echo ---------------------------------------------------------------------; -- turn on the Echo Current Command option UPDATE COMMAND OPTIONS USING v ON; -- User pat needs to delete some rows from the table employee_lbac. A user -- with SECADM authority grants her security label seclabel1 with this statement: GRANT SECURITY LABEL secpolicy.seclabel1 TO USER pat; -- Pat issues the following SQL statement. It fails because she has neither -- read access nor write access to the column payrank. CONNECT TO sample USER pat USING pat123; DELETE FROM joe.employee_lbac WHERE EMPNO >= 1; -- A user with SECADM authority grants security label seclabel2 to pat: CONNECT TO sample USER secadm USING secadm123; REVOKE SECURITY LABEL secpolicy.seclabel1 FROM USER pat; GRANT SECURITY LABEL secpolicy.seclabel2 TO USER pat; -- Pat tries the delete again. CONNECT TO sample USER pat USING pat123; DELETE FROM joe.employee_lbac WHERE EMPNO >= 1; -- This time the delete gives an error because some of the rows selected for deletion -- are protected by security labels that pat cannot write to. For example the row in -- which empno = 1 is protected by the security label seclabel1. Pat is able to read -- that row but is unable to write to it because that would violate the write-down -- portion of the DB2LBACWRITEARRAY rule. -- No rows are affected by the statement. -- A user with SECADM authority grants pat an exemption to both the write-up and the -- write-down portions of the DB2LBACWRITEARRAY rule: CONNECT TO sample USER secadm USING secadm123; GRANT EXEMPTION ON RULE DB2LBACWRITEARRAY WRITEUP FOR secpolicy TO USER pat; GRANT EXEMPTION ON RULE DB2LBACWRITEARRAY WRITEDOWN FOR secpolicy TO USER pat; -- Components of type ARRAY will have no effect when pat is writing. -- Pat tries the delete again. This time it executes without error because pat is able -- to write to all of the rows she is able to read. The rows that she is unable to -- read, however, are unaffected by the delete: CONNECT TO sample USER pat USING pat123; DELETE FROM joe.employee_lbac WHERE EMPNO >= 1; -- After the statement, there is only one row in the table: -- EMPNO LASTNAME DEPTNO PAYRANK ROWSECLABEL -- 7 Addams 22 5 TOP SECRET:(ALPHA,DELTA):G4 -- If pat executes a select on the table, however, she will see no rows because she -- is unable to read the row that is there. SELECT empno, lastname, deptno, payrank, CAST(SECLABEL_TO_CHAR('SECPOLICY', rowseclabel) AS VARCHAR(30)) AS rowseclabel FROM joe.employee_lbac; -- No rows are returned. -- The user with SECADM authority revokes all exemptions from pat and -- grants her security label seclabel1: CONNECT TO sample USER secadm USING secadm123; REVOKE EXEMPTION ON RULE ALL FOR secpolicy FROM USER pat; REVOKE SECURITY LABEL secpolicy.seclabel2 FROM USER pat; GRANT SECURITY LABEL secpolicy.seclabel1 TO USER pat; -- turn off echo Current Command option to suppress printing of echo command UPDATE COMMAND OPTIONS USING v OFF; !echo ---------------------------------------------------------------------; !echo -- REVOKING SECURITY LABELS FROM USERS. ----; !echo -- DROPPING SECURITY LABELS, SECURITY POLICY, PROTECTED TABLE ----; !echo -- SECURITY LABEL COMPONENTS. ----; !echo ---------------------------------------------------------------------; -- turn on the Echo Current Command option UPDATE COMMAND OPTIONS USING v ON; -- Revoke the security labels from joe, bob and pat REVOKE SECURITY LABEL secpolicy.seclabel1 FROM USER joe; REVOKE SECURITY LABEL secpolicy.seclabel1 FROM USER bob; REVOKE SECURITY LABEL secpolicy.seclabel1 FROM USER pat; -- Drop the protected table 'employee_lbac' CONNECT TO sample USER joe USING joe123; DROP TABLE joe.employee_lbac; -- Drop the security labels created CONNECT TO sample USER secadm USING secadm123; DROP SECURITY LABEL secpolicy.seclabel1; DROP SECURITY LABEL secpolicy.seclabel2; DROP SECURITY LABEL secpolicy.seclabel3; DROP SECURITY LABEL secpolicy.seclabel4; -- Drop the security policy 'secpolicy' DROP SECURITY POLICY secpolicy; -- Drop the security label components DROP SECURITY LABEL COMPONENT level; DROP SECURITY LABEL COMPONENT departments; DROP SECURITY LABEL COMPONENT groups; -- Disconnect from the database CONNECT RESET;