Gerald Sigmund, Advanced Database Systems, CO4705, 30.03.2009
CO4705
Gerald Sigmund
Word count: 2600
Gerald Sigmund, Advanced Database Systems, CO4705, 30.03.2009
Introduction .......................................................................................................................................... 3
Creating the tablespace ........................................................................................................................ 3
Creating the user STUDENT_ADMIN ................................................................................................ 3
Student_clerical .................................................................................................................................... 4 student_course_manager ...................................................................................................................... 5 student_module_leader ........................................................................................................................ 6
Student_student .................................................................................................................................... 7
Restricted access to the tables .............................................................................................................. 9
Conclusion ......................................................................................................................................... 10
OEM Screenshots ............................................................................................................................... 10
Tablespace ..................................................................................................................................... 10
Student_admin ............................................................................................................................... 11
Student_clerical ............................................................................................................................. 13
Student_course_manager ............................................................................................................... 14
Student_module_leader ................................................................................................................. 15
Student_student ............................................................................................................................. 16
Word count: 2600
The aim of this assignment was to create a database system with specific roles and ways of accessing the data. First I have used the oracle version 10g express and SQL Developer to connect to the database and create the tables, roles and users. Since 10g express doesn't have OEM installed
I have created all the work using SQL scripts. Later on in the course we got a virtual machine with oracle 11g installed and then I did the creation of the tables and roles on that database using the
OEM. I will illustrate screenshots of the OEM at the end of the report where you can see what I have done using OEM. I also used the fine grained access features of oracle in the 11g image since the express version hasn't enabled this feature.
First off all I had to create a new tablespace for the system. I connected to the database using the
SYS user.
With the following SQL statement I have created the new tablespace: create tablespace STUDENTS_GS
datafile '/home/gerald/oracle/students.dbf'
size 32m
autoextend on
next 32m maxsize 2048m
extent management local;
In that statement I defined the following values for the tablespace:
the location of the datafile
the initial size of the tablespace
the autoextend value is set to true, so if the system grows the file will automatically resized
I specified that the file will increase every time about 32 MB and has a maximum size of 2
GB
I specified the extend management to local since I specify the auto extend size
I found a detailed description of the create tablespace statement on the oracle home page
1
.
The next step was to create the user STUDENT_ADMIN which will be used as administrator to the student system.
I created the user using the SYS user. The default tablespace for this user should be STUDENT_GS
1 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7003.htm#S
QLRF01403 accessed 28.03.2009
and this user should have rights to create other users, and login to the oracle enterprise manager.
I have created the user using the following statement: create user STUDENT_ADMIN identified by pass default tablespace STUDENTS_GS; drop role OEM_MONITOR; create role OEM_MONITOR; grant connect to OEM_MONITOR; grant analyze any to OEM_MONITOR; grant create table to OEM_MONITOR; grant select_catalog_role to OEM_MONITOR; grant execute on dbms_rls to student_admin; grant OEM_MONITOR to student_admin; grant create role to student_admin; grant create user to student_admin; grant alter user to student_admin; grant create view to student_admin;
The admin user has the password “pass” and the default tablespace STUDENT_GS. To allow the user to login to the oracle enterprise manager I have created the role OEM_MONITOR. I found this role on an article of the oracle home page
2
. Another way to allow the user access to OEM is to grant him the dba right but than the user has access to the whole database.
I have found the syntax for creating a new user on the oracle page
3
.
The user got the rights to create other users, other roles and views. It also needs access to the package dbms_rls to create policy entries for fine grained access.
The next step was to login as the new user to the database and import the two SQL scripts to create the tables and insert the data.
I have opened the SQL files using the SQL Developer and pressed the “run script” button.
Now it was time to create all the roles for the database system. I created the following roles:
student_clerical
student_course_manager
student_course_leader
student_student
This user has insert, delete, select and update rights to all the tables in the system.
Here is the SQL statement I used:
2 http://download.oracle.com/docs/html/A88769_01/ch4.htm
accessed 28.03.2009
3 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_8003.htm
accessed 28.03.2009
create role student_clerical; grant connect to student_clerical; grant select, insert, delete, update on COURSE to student_clerical; grant select, insert, delete, update on MODULE to student_clerical; grant select, insert, delete, update on RESULT to student_clerical; grant select, insert, delete, update on STAFF to student_clerical; grant select, insert, delete, update on STUDENT to student_clerical;
First of all I created the role student_clerical. I granted the connect privilege to that role, so that it is possible for users of that role to connect to the database. After that I granted the select, insert, delete and update privilege to the role so that user of that role can modify and read all the tables of the system. I found a good article about granting privileges in oracle
4
.
The next step was to test the role.
I create a user called student_clc that has the role student_clerical. I tested selecting the table course, updating the table module, inserting an entry in table result and deleting a value of the table result.
The SQL statements where the following:
--create the user
Create user student_clc identified by pass default tablespace STUDENTS_GS; grant student_clerical to student_clc;
--login and run scripts select * from student_admin.course; update student_admin.module set examwt = 30, cwkwt = 70 where MCODE = 'CO2401'; insert into student_admin.result (netid, mcode, emark, cmark) values ('BHATTI_S', 'CO3801', 30,
70); select * From student_admin.result where netid = 'BHATTI_S' and mcode = 'CO3801'; delete from student_admin.result where netid = 'JUBAIL_A'; select * from student_admin.result where netid = 'JUBAIL_A
This role should have read access to all tables in the system. The should have update access to the module table since the are allowed to update the staff of the module. Here is the sql statement: create role student_course_manager; grant connect to student_course_manager;
4 http://www.dba-oracle.com/art_builder_grant_sec.htm
, accessed 28.03.2009
grant select on COURSE to student_course_manager; grant select on MODULE to student_course_manager; grant select on RESULT to student_course_manager; grant select on STAFF to student_course_manager; grant select on STUDENT to student_course_manager; grant update(MLECTURER) on MODULE to student_course_manager;
The SQL statement looks similar to the one of student_clerical but here we have a special grant update statement. Here I gave the user only an update right to one column. I found this way of granting rights in an article on the internet
5
.
I have tested the role by creating a user student_cm that has the role student_course_manager. I tested an update of a full row in table module and an update of only the column mlecturer.
The SQL statements:
--create the user create user student_cm identified by pass default tablespace STUDENTS_GS; grant student_course_manager to student_cm;
--login and run test update student_admin.module set examwt = 12 where mcode = 'CO2401'; update student_admin.module set mlecturer = 'John' where mcode = 'CO2401'; select * from student_admin.module where mcode = 'CO2401';
This role has read access to all tables but only update and insert rights on table result and can also change the weights for coursework and exam in table module. Here is the SQL statement: create role student_module_leader; grant connect to student_module_leader; grant select on COURSE to student_module_leader; grant select on MODULE to student_module_leader; grant select on RESULT to student_module_leader; grant select on STAFF to student_module_leader; grant select on STUDENT to student_module_leader; grant insert, update on RESULT to student_module_leader; grant update(examwt, cwkwt) on MODULE to student_module_leader;
5 http://www.dba-oracle.com/concepts/column_privileges.htm
accessed, 28.03.2009
This statement is quite similar to the the statement before. I granted read access to all tables, update and insert right to table result and a restricted update right to table module.
I have tested the insertion of a new row in table result. I have created a user student_ml with the role student_module_leader.
--create user create user student_ml identified by pass default tablespace STUDENTS_GS; grant student_module_leader to student_ml;
--login and run test insert into student_admin.result values('BHATTI_S', 'CO3801', 10, 90);
This role can read all data but is not allowed to read the phone number of the staff table.
Since oracle doesn't support a grant select only some columns this has to be done another way.
One way is the usage of views. It is possible to create a view v_staff that can the student select and so it is possible to let the student only view room number and staff id.
Here is the SQL code of creating the role and the view for the student: create role student_student; grant connect to student_student; grant select on COURSE to student_student; grant select on MODULE to student_student; grant select on RESULT to student_student; grant select on STUDENT to student_student; create view v_staff as
select staffid, room_no from staff; grant select on v_staff to student_student;
I have created the role student_student and grant it read access to all tables except table staff. To access this table the student user has to use the view v_staff.
The usage of views is not the only way of limiting the role student to only some rows of the table staff.
I found some articles about a technique that is called virtual private database or fine grained access
6
.
6 http://www.mdconsulting.de/PortalData/2/Resources/download_whitepaper_pdf/Virtual_Private_Database_in_Ora cle.pdf
This feature is available since oracle version 8i and since 10g it is possible to use it only on columns.
The technique works as follows. First you have to write a function that returns a where clause. The output of this function will be appended to your SQL statement.
Then you have to use the package dbms_rls to add a new policy to the database. You can define if the policy should work for a whole line of the table or only for some columns.
In my case I only needed the solution with some columns since I wanted to block the read access for the role student_student to the field phone of table staff.
First off all I wrote the function: create or replace function get_staff
(p_schema in varchar2, p_table in varchar2) return varchar2 as
l_retstr varchar2(2000);
l_netid varchar2(100); begin
select netid into l_netid from student where netid = user;
if (l_netid = null || l_netid = ‘’) then
l_retstr := null;
else
l_retstr := ‘ 1 = 0’;
end if; return l_retstr; end;
The function works the following way. I check if the current user is a student from table student. If not I append nothing to the where clause, but if yes I append ‘1 = 0’ which means that nothing will be listed to the user for the row phone.
Now I had to add the policy to the database. begin
sys.dbms_rls.add_policy (object_schema =>'STUDENT_ADMIN', object_name =>'STAFF',
policy_name => 'STAFF_POLICY', function_schema => 'STUDENT_ADMIN', policy_function => 'GET_STAFF',
statement_types => 'SELECT', update_check => TRUE, ENABLE => TRUE,
SEC_RELEVANT_COLS => 'PHONE',
SEC_RELEVANT_COLS_OPT => dbms_rls.ALL_ROWS ); end;
Here I added the policy to the database. I only set the column phone to be relevant so that my function will only affect the selection of this row.
I have tested this feature the following way. http://www.ordix.de/ORDIXNews/2_2007/Datenbanken/fine_grained_access_control.html
http://www.oracle.com/global/de/community/tipps/htmldb_vpd/index.html all accessed 28.03.2009
First of all I connected using the user student_ml and tried to select the whole table staff.
After that I created a new user 'BHATTI_S' as student_student and tried the same again.
Here is the listening of the SQL statements:
--login as user student_ml
Select * from student_admin.student;
--login as student_admin
Create user BHATTI_S identified by pass default tablespace STUDENT_GS;
Grant student_student to BHATTI_S;
--login as BHATTI_S
Select * from student_admin.staff;
This technique works pretty well but I prefer the usage of views. I think they are easier to maintain.
You don’t have to change a policy function or add other policies to the database. A view can easily created and it is easy to change them. If you have an error in your policy function it will be possible to access the data for more users than you wanted to. In a view you have to specify the select statement and that is for every user the same.
The question was how is it possible to let the module leader and student only see their own data.
I tried that solution by the usage of views. For the lecturer I created two views. One for tables modules and one for table result. I used the variable ‘user’ in the select statement to get the username of the current logged in user. For table module and staff it was quite simple since the name of the lecturer is stored in the field mlecturer and staffid. For the table result I had to use the reference to table module to verify if this result belongs to a module of the logged in user. create or replace view v_my_modules as
select * from module where mlecturer = user; create or replace view v_my_results as
select result.* from result, module where result.mcode = module.mcode and module.mlecturer = user; create or replace view v_my_staff as
select * from staff where staffid = user;
With that views it is also possible for the module leader to update the table result and table module since the view only returns the output of one table and not of all the connected ones. If the view returns values from more than one table a trigger has to be written which writes the correct insert and update statement.
For the role student_student it was nearly the same. I have added a view for table student, result and staff. For the first two tables it was only necessary to check the field netid against the current logged in user.
For table staff it was not so easy. I had to check if the specific staff is one of the lecturers of the modules of the student. So I had to go from table result to table module and staff.
--student stuff create or replace view v_my_student as
select * from student where netid = user; create or replace view v_my_result as
select * from result where netid = user; create or replace view v_my_staff as
select staff.room_no, staff.staffid from staff, result, module where result.mcode = module.mcode and staff.staffid = mlecturer and result.netid = user;
Instead of using views it would also be possible to use the policy feature of oracle. But I prefer the usage of view more so I haven’t used this feature.
Instead of making this restriction on the database it is also possible to let the application which queries the data filter it depending on the current user. For example the application queries table student and checks than which student is currently logged in to the application and shows only the rows that belong to that student.
The creation of the views or policies can be done using SQL or the OEM. The OEM has a menu point in the web interface where you can create, delete or change the stored policies. But you have to write the policy function using SQL.
In that assignment I learned a lot about oracles security features. Before I didn't know oracles fine grained access. I think it is an interesting way of implementing restrictions to tables but I prefer the usage of views. I prefered the usage of SQL Developer instead of OEM because I think it is more technical to work with a tool like that. In OEM you only have to click on the correct buttons and every thing works. It's a great tool to have a look at all the users the objects and other stuff.