Subject | View Privileges |
---|---|
Author | Bambang P |
Post date | 2006-01-26T16:44:21Z |
For a view, it is suffice for a user/role to have privileges only to
the view. The user does not have to get privileges to the underlying
table.
However, I found this is not the case for the table specified in view
columns, like this view:
CREATE VIEW VIEW_PRESENCE
( PRESENCE_ID,
EMPLOYEE_ID,
WORKDATE,
PRESENCE_STATUS
)
AS
SELECT P.ID,
P.PRESENCE_ID_EMPLOYEE,
P.WORKDATE,
CASE
WHEN PRESENCE=1 THEN 'Presence'
WHEN EXISTS( SELECT 1 FROM LEAVES L
WHERE P.PRESENCE_ID_EMPLOYEE= L.LEAVES_ID_EMPLOYEE
AND P.WORKDATE BETWEEN L.LEAVE_FROM AND L.LEAVE_UNTIL) THEN 'Leaves'
ELSE 'Absent'
END
FROM PRESENCE P;
The view is granted SELECT privilege on PRESENCE and LEAVES table.
However, an USER who has SELECT privilege on the view but doesn't have
SELECT privilege on the LEAVES table will fail to query the view.
To reproduce the case, first please create an user named BAMBANG with
password xxx, and then run this script in isql.exe:
--- Begin Quote ---
CREATE DATABASE 'DBTEST.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
CREATE TABLE PRESENCE
(ID INTEGER NOT NULL PRIMARY KEY,
PRESENCE_ID_EMPLOYEE INTEGER NOT NULL,
WORKDATE DATE,
PRESENCE SMALLINT
);
COMMIT;
INSERT INTO PRESENCE VALUES (1,1,'2006-01-01',1);
INSERT INTO PRESENCE VALUES (2,1,'2006-01-02',0);
INSERT INTO PRESENCE VALUES (3,1,'2006-01-03',0);
INSERT INTO PRESENCE VALUES (4,1,'2006-01-04',1);
COMMIT;
CREATE TABLE LEAVES
(
ID INTEGER NOT NULL PRIMARY KEY,
LEAVES_ID_EMPLOYEE INTEGER NOT NULL,
LEAVE_FROM DATE NOT NULL,
LEAVE_UNTIL DATE NOT NULL
);
COMMIT;
INSERT INTO LEAVES VALUES (1,1,'2006-01-02','2006-01-02');
COMMIT;
SET TERM ^ ;
CREATE VIEW VIEW_PRESENCE
( PRESENCE_ID,
EMPLOYEE_ID,
WORKDATE,
PRESENCE_STATUS
)
AS
SELECT P.ID,
P.PRESENCE_ID_EMPLOYEE,
P.WORKDATE,
CASE
WHEN PRESENCE=1 THEN 'Presence'
WHEN EXISTS( SELECT 1 FROM LEAVES L
WHERE P.PRESENCE_ID_EMPLOYEE= L.LEAVES_ID_EMPLOYEE
AND P.WORKDATE BETWEEN L.LEAVE_FROM AND L.LEAVE_UNTIL) THEN 'Leaves'
ELSE 'Absent'
END
FROM PRESENCE P;
^
SET TERM ; ^
COMMIT;
-- Is it necessary to grant SELECT on table PRESENCE?
GRANT SELECT ON PRESENCE TO VIEW VIEW_PRESENCE;
COMMIT;
--
GRANT SELECT ON LEAVES TO VIEW VIEW_PRESENCE;
COMMIT;
--
GRANT SELECT ON VIEW_PRESENCE TO BAMBANG;
COMMIT;
-- Now Connect as user BAMBANG
CONNECT DBTEST.FDB USER BAMBANG PASSWORD xxx;
-- This fails because BAMBANG doesn't have privilege on table LEAVES
SELECT * FROM VIEW_PRESENCE;
COMMIT;
--- End Quote---
Is it the expected behaviour?
Any enlightment will be much appreciated. Thanks
--
Bambang P.
the view. The user does not have to get privileges to the underlying
table.
However, I found this is not the case for the table specified in view
columns, like this view:
CREATE VIEW VIEW_PRESENCE
( PRESENCE_ID,
EMPLOYEE_ID,
WORKDATE,
PRESENCE_STATUS
)
AS
SELECT P.ID,
P.PRESENCE_ID_EMPLOYEE,
P.WORKDATE,
CASE
WHEN PRESENCE=1 THEN 'Presence'
WHEN EXISTS( SELECT 1 FROM LEAVES L
WHERE P.PRESENCE_ID_EMPLOYEE= L.LEAVES_ID_EMPLOYEE
AND P.WORKDATE BETWEEN L.LEAVE_FROM AND L.LEAVE_UNTIL) THEN 'Leaves'
ELSE 'Absent'
END
FROM PRESENCE P;
The view is granted SELECT privilege on PRESENCE and LEAVES table.
However, an USER who has SELECT privilege on the view but doesn't have
SELECT privilege on the LEAVES table will fail to query the view.
To reproduce the case, first please create an user named BAMBANG with
password xxx, and then run this script in isql.exe:
--- Begin Quote ---
CREATE DATABASE 'DBTEST.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
CREATE TABLE PRESENCE
(ID INTEGER NOT NULL PRIMARY KEY,
PRESENCE_ID_EMPLOYEE INTEGER NOT NULL,
WORKDATE DATE,
PRESENCE SMALLINT
);
COMMIT;
INSERT INTO PRESENCE VALUES (1,1,'2006-01-01',1);
INSERT INTO PRESENCE VALUES (2,1,'2006-01-02',0);
INSERT INTO PRESENCE VALUES (3,1,'2006-01-03',0);
INSERT INTO PRESENCE VALUES (4,1,'2006-01-04',1);
COMMIT;
CREATE TABLE LEAVES
(
ID INTEGER NOT NULL PRIMARY KEY,
LEAVES_ID_EMPLOYEE INTEGER NOT NULL,
LEAVE_FROM DATE NOT NULL,
LEAVE_UNTIL DATE NOT NULL
);
COMMIT;
INSERT INTO LEAVES VALUES (1,1,'2006-01-02','2006-01-02');
COMMIT;
SET TERM ^ ;
CREATE VIEW VIEW_PRESENCE
( PRESENCE_ID,
EMPLOYEE_ID,
WORKDATE,
PRESENCE_STATUS
)
AS
SELECT P.ID,
P.PRESENCE_ID_EMPLOYEE,
P.WORKDATE,
CASE
WHEN PRESENCE=1 THEN 'Presence'
WHEN EXISTS( SELECT 1 FROM LEAVES L
WHERE P.PRESENCE_ID_EMPLOYEE= L.LEAVES_ID_EMPLOYEE
AND P.WORKDATE BETWEEN L.LEAVE_FROM AND L.LEAVE_UNTIL) THEN 'Leaves'
ELSE 'Absent'
END
FROM PRESENCE P;
^
SET TERM ; ^
COMMIT;
-- Is it necessary to grant SELECT on table PRESENCE?
GRANT SELECT ON PRESENCE TO VIEW VIEW_PRESENCE;
COMMIT;
--
GRANT SELECT ON LEAVES TO VIEW VIEW_PRESENCE;
COMMIT;
--
GRANT SELECT ON VIEW_PRESENCE TO BAMBANG;
COMMIT;
-- Now Connect as user BAMBANG
CONNECT DBTEST.FDB USER BAMBANG PASSWORD xxx;
-- This fails because BAMBANG doesn't have privilege on table LEAVES
SELECT * FROM VIEW_PRESENCE;
COMMIT;
--- End Quote---
Is it the expected behaviour?
Any enlightment will be much appreciated. Thanks
--
Bambang P.