Row level policy doesn't work on my table - sql

I have a table which I'm trying to apply a policy on, the setup looks something like this:
create role anonymous nologin;
create schema api;
create schema private;
create table private.mytable(
id serial primary key,
description text default ''
);
create view api.mytable as select * from private.mytable;
insert into api.mytable (description) values ('row 1'), ('row 2');
grant usage on schema api to anonymous;
grant select on api.mytable to anonymous;
alter table private.mytable enable row level security;
create policy mytable_policy on private.mytable
for select
using (null);
When I set the role to anonymous and select all records from mytable:
set role anonymous;
select * from api.mytable;
I excpect no rows to be returned since my expression in the using clause in the policy is null but I get everything.
I tried different postgresql versions (9.5, 9.6, 10.3) but they all have the same behaviour, am I doing something wrong here?

update
https://stackoverflow.com/a/33863371/5315974
RLS won't work with views like that. You can use RLS for views though it is limited.
what you can do is
alter view api.mytable owner to anonymous ;

Related

Restrict INSERT to specific value in given column for certain user

Is there a possibility, to restrict, that certain user can insert only specified value in some column?
For example table
test (id integer, value text)
and user 'restricted_user' could only INSERT 1 in column id (any in the other columns)
Sure, use Row Level Security:
ALTER TABLE test ENABLE ROW LEVEL SECURITY;
GRANT INSERT ON test TO restricted_user;
CREATE POLICY restr_ins ON test
FOR INSERT TO restricted_user
WITH CHECK (id = 1);
You'd have to add appropriate policies for other users that are supposed to work with the table, else they can do nothing with the table.
Row Level Security (as shown by Laurenz) is one option. Using a VIEW and with check option is another solution:
create view restricted_test
as
select *
from test
where id = 1
with check option;
Then disallow inserts into the table directly:
revoke insert,update on test from restricted_user;
And only allow to insert into the view:
grant insert,update on restricted_test to restricted_user;

Grant Select To Synonym For Specified Columns

I've been trying to restrict a user's select access to a synonym. Consider the following below:
CREATE USER Test_User WITHOUT LOGIN;
CREATE SYNONYM S_TEST FOR dbo.Items;
GRANT SELECT ON dbo.S_TEST (Id, [Name]) TO Test_User;
I get an error:
Msg 1020, Level 16, State 3, Line 4
Sub-entity lists (such as column or security expressions)
cannot be specified for entity-level permissions.
But if I change it to use dbo.Items directly then it works:
GRANT SELECT ON dbo.Items (Id, [Name]) TO Test_User;
How can I restrict the SELECT on a synonym for a specified user? Is this possible? If no, are there any alternatives?
"How can I restrict the SELECT on a synonym for a specified user? " You can't. A Synonym is just an alternative name for an object. The check to see if the object even exists is deferred till runtime when referencing the SYNONYM not when it's created. For example CREATE SYNONYM dbo.MySynonym FOR MadeUp.TableObject; will create the synonym even though the reference object doesn't exist.
CREATE SYNONYM dbo.MySynonym FOR MadeUp.TableObject;
GO
SELECT *
FROM dbo.MySynonym; --fails
GO
DROP SYNONYM dbo.MySynonym;
GO
All the permissions need to be set up the object that the Synonym references, not the synonym itself.

Avoid alter and drop command on a Table and SP in SQL Server

I have a table and a SP in SQL Server. I want to add Permissions on a table and SP that no one can change the Structure of table and Logic of SP. Is there any way to specify such type of Permissions. Any Trigger which avoids drop and alter commands, or any other way to do this.
Thanks in Advance.
You need to create and use a separate user that has only privileges that you explicitly allow it to (eg GRANT SELECT from table or GRANT EXECUTE on your stored procedure).
Rather than looking at it as disallowing certain actions you should consider what actions are allowed (see Principle of Least Privilege).
It is highly recommended that you manage the permissions on the objects. However, if you have no control over the permissions, consider setting up a database DDL trigger to at least log the events.
create table AuditTable
(
event_type varchar(max) not null
, tsql_command varchar(max) not null
, modified_by varchar(128) not null default (current_user)
, modified_time datetime not null default (getdate())
)
go
create trigger log_database_level_event
on database
for ddl_database_level_events
as
insert AuditTable
(
event_type
, tsql_command
)
values
(
eventdata().value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(max)')
, eventdata().value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'varchar(max)')
)
go
create user tester without login
go
execute as user = 'tester'
go
create proc test_proc
as
select ##version
go
alter proc test_proc
as
select 1
go
revert
go
select * from AuditTable
go
Yes, this is possible but not using constraint . Constraint is a bussiness rule kind of validation and here your question about Permission on Objects so now
this is clear that you need to define permission on object for specific user.If you want to
secure your Table and Stored Procedure then please follow this step.
Create one new User/Login with specific Database/Objects permission.
Give grant on your Secure table using - GRANT SELECT ON <TableName> TO <Username>
GIVE grant on your Secure Stored Procedure using - GRANT EXECUTE ON <SP Name> TO <Username>
for further regarding permission please do some search on Google .

Add a column SQL query in Oracle database

I am using Oracle Database (version is 9i) and I want to add a column to a current table in oracle database.
I want to add an integer column to keep track of invalid tries per user, so default value should be 5.
When I try to execute this query in Sql*Plus it gives an error table or view doesn't exist ( I have double checked table name is correct.
ALTER TABLE CustApps_user ADD VALID_TRIES INT DEFAULT 5 NOT NULL;
I guess the error you're getting is ORA-00942. This can mean a number of things, but basically it means the object does not exist in the current scope and context of what you're doing. So for instance it is the error thrown when we attempt to build a view on a table in another schema when we have been granted privileges through a role and not directly.
In your case it probably mean that the table is in another schema. You normally may be accessing it through a view or synonym. You can easily check this by querying the data dictionary:
select owner, object_type
from all_objects
where object_name = 'CUSTAPPS_USER'
alter table
table_name
add
(
column1_name column1_datatype column1_constraint,
column2_name column2_datatype column2_constraint,
column3_name column3_datatype column3_constraint
);
Here are some examples of Oracle "alter table" syntax to add data columns.
alter table
cust_table
add
cust_sex varchar2(1) NOT NULL;
Here is an example of Oracle "alter table" syntax to add multiple data columns.
ALTER TABLE
cust_table
ADD
(
cust_sex char(1) NOT NULL,
cust_credit_rating number
);
You have to add bracket in query:
ALTER TABLE CustApps_user ADD (VALID_TRIES INT DEFAULT 5 NOT NULL);
INT is legal, but it will be converted to NUMBER, so you can also use:
ALTER TABLE CustApps_user ADD (VALID_TRIES NUMBER(38,0) DEFAULT 5 NOT NULL);
or change (decrease) NUMBER precision.

triggers in different schemas

I am new to SQL Server.
I have to write a trigger for inserting and updating table in different schema in MS SQL.
Example:
TEMP1 table in one Schema
TEMP2 table in another Schema
How can this be done?
As long the SCHEMAs have the same owner (The AUTHORIZATION bit in CREATE SCHEMA) you'd simply refer to the objects using 2 part names.
See CREATE TRIGGER too
create trigger MyTrigger on Schema1.Table1
for insert
as
set nocount on
insert Schema2.Table2 (...)
select (..) from inserted
go
Not sure I understand the problem completely, but basic syntax would look like this:
create trigger MyTrigger on Schema1.Table1
after insert, update
as
insert Schema2.Table2 values(1, 'test', ...)
update Schema3.Table3
set Name = 'XX'
where Id = 1
go
You have to create multiple triggers to handle different events on different tables.
Refer to CREATE TRIGGER (Transact-SQL).