How to mask a column in Redshift? - sql

I've a requirement to keep a user table for granting access to an application where there's a password field which has to be masked.
How to go about it?
Example: If you query select * from PG_USER; in Redshift, you'd see, the password column values are shown as *****. How to do exactly that for my custom table?

If there is a column in a table that you do not wish particular users to see, then:
Do not grant them permission to use the table
Use CREATE VIEW to select all columns you do wish them to be able to view
Grant them permission to use the view
Tell them to use the view instead of the table (they operate identically)
Or, create a table without the offending column and grant them permission to use that table.

Following post shows how to implment encryption UDF in Redshift with some data protection best practices.
https://techsboot.com/blogs/redshift/encrypt_decrypt_udf_using_pyaes/

Related

PostgreSQL : I want to Provide Schema-wise access to users where user should not be able to see other schema names, how can it be achieved?

I have situation where I have to give schema wise access to users where the user should not even be able to see other schema names as well as its contents like tables. I have tried below queries :
create user potter with password 'potter';
create schema if not exists potter AUTHORIZATION potter;
set search_path to 'potter';
create table pottertable(id numeric);
grant SELECT, UPDATE, INSERT ON potter.pottertable to potter;
In this case when connected to the server (PostgreSQL 9.6 localhost) as new user using pgAdmin 4, the user is not able to SELECT other schema data but able to see other schema names as well as the tables inside it, which is what I am looking to prevent. Any help is appreciated.

ORA-00942 error is generating while creating a view

I have created a new view named CONS_INTERRUPTED_DATA for the main user hfdora and the view has been created successfully. But when I am trying to create the same view for another user (cis) of the same database after giving all the privileges to the user (cis) I am getting the below error,
*oms_consumer
ERROR at line 13:
ORA-00942: table or view does not exist
Both the user hfdora and cis are the part of same database and this oms_consumer table is present at the database
I have granted the following privileges for the user cis before creating the view
grant select on energization_info to cis;
grant select on trigger_info to cis;
grant select on oms_source to cis;
grant select on oms_consumer to cis;
grant connect,resource,dba to cis;
My sql query to create the view,
>CREATE OR REPLACE VIEW CONS_INTERRUPTED_DATA AS
SELECT
trigger_info_A.b1 AS FDR_RMU_OFF_B1, trigger_info_A.b2 AS FDR_RMU_OFF_B2,
trigger_info_A.B3TEXT AS FDR_RMU_OFF_B3TEXT, trigger_info_A.elem AS FDR_RMU_OFF_ELEM,
trigger_info_B.b1 AS FDR_RMU_RESTORE_B1, trigger_info_B.b2 AS FDR_RMU_RESTORE_B2,
trigger_info_B.B3TEXT AS FDR_RMU_RESTORE_B3TEXT,
trigger_info_B.elem AS FDR_RMU_RESTORE_ELEM,
oms_consumer.consumer_code, energization_info.b1 AS AFFECTED_B1,
energization_info.b2 AS AFFECTED_B2, energization_info.b3text AS AFFECTED_B3TEXT,
to_char(energization_info.deenergized_date, 'DD-MM-YYYY Hh24:MI:SS') AS DEENERGIZED_DATE,
to_char(energization_info.energized_date, 'DD-MM-YYYY Hh24:MI:SS') AS ENERGIZED_DATE,
trigger_info_A.comments AS KEY
FROM
energization_info,
trigger_info trigger_info_A,
trigger_info trigger_info_B,
oms_consumer
WHERE
(energization_info.trigger_number = trigger_info_A.trigger_number)
AND (energization_info.ENERGIZED_TRIGGER_NUMBER = trigger_info_B.trigger_number)
AND (energization_info.b1 = oms_consumer.B1NAME
AND energization_info.b2 = oms_consumer.B2NAME
AND energization_info.b3 = oms_consumer.B3NAME)
WITH READ ONLY;
The first step in diagnosing a problem when creating a view is to try the select part on its own. In this case you would still get the ORA-00942 error, but the problem is now just a query and access issue and not to do with the view specifically.
When you get ORA-00942: table or view does not exist, it's because either:
The table or view name that you typed really doesn't exist.
Check the spelling - maybe there is a typo.
Are you connected to a database where it exists? Perhaps you are on a test system that doesn't have it.
Query dba_objects to see whether the table exists in another schema. (If you don't have privileges to query dba_objects, all_objects lists everything you have permission to view, which may be some help.)
It really does exist, but it's in another schema.
In that case, there are two possible issues:
You don't have permission to query it. The table's owner needs to grant read on xyz (substitute the actual table name for xyz) to either
you
public (if you want everyone to be able to see the data, not always advisable)
a role that you have (but roles aren't used by stored PL/SQL or views, though, so it's possible that you can query a table in another schema thanks to a role that you have, but still not be able to create a view or a procedure that uses it.)
You need to specify the schema. Say you want to query the REGIONS table in HR but you are connected as SCOTT. If you just select * from regions it will look for SCOTT.REGIONS, which doesn't exist. To fix that, do one of the following:
use hr.regions explicitly in your query.
in your schema, create or replace synonym regions for hr.regions;
Now whenever you refer to regions, the database will automatically redirect to hr.regions.
in any schema with permission to create public synonyms:
create or replace public synonym regions for hr.regions;
Now everyone connecting to the database will have any references to regions redirected to hr.regions, which isn't always a good idea, but it's one option anyway.
alter session set current_schema = hr;
Now the default schema for resolving names of objects is HR and not the one you logged into. For applications that always log in as a different user than the one that owns the tables, you can create an after logon trigger so this is always set. Then they can just refer to regions etc without needing to specify any schema and without any synonyms.
My issue has been resolved. :-)
I have made the following changes,
FROM
hfdora.energization_info,
hfdora.trigger_info trigger_info_A,
hfdora.trigger_info trigger_info_B,
hfdora.oms_consumer
Now the same view is created for the user cis.

DBA readonly account

I had a schema in one oracle DB as ui_prod. I asked my DBA team guys to create exactly same schema like ui_prod but as read only and name it ui_prod_readonly. Usually I will use Oracle SQL developer to connect a DB and query directly with table name like below.
--Connect to ui_prod
select * from table
but why I requested to put owner name infront when query for readonly schema they created for me, as without putting it, I get error table not exist.
--Connect to ui_prod_readonly
select * from ui_prod.table
I have project files which hardcode the sql query with only table names and adding owner name in front will cause many changes and effort. Can anyone explain me on this? or provide me any document/link to read. Thanks
You should look into synonyms, apparently the user you are connecting to the database as is not the owner of the objects. So to view the object you have to prepend the names with the schema name (the owner of the object themselves).
http://www.techonthenet.com/oracle/synonyms.php
CREATE OR REPLACE SYNONYM ui_prod_readonly.synonym_name
FOR ui_prod.object_name
It seems to me that your dbas have not created another set of tables but just granted the existing tables to the user ui_prod_readonly.
When you log in to Oracle, the current schema is the name of the user you used to log in. So if you log in with ui_prod_readonly Oracle checks that schema for the table if you do not qualify it with the owner (=schema).
If you want to change the current schema so that you don't need to fully qualify the tables, you can do that with ALTER SESSION
alter session set current_schema = ui_prod;
Once you have done that, you don't need to fully qualify the table with the owner (=schema).
if you need a user to read the data only
its simple to create new user and grant it only select privilege
you can create user and grant select privilege using
CREATE USER [user] IDENTIFIED BY [your_password];
grant select on table to [user]

make an insert action in a table without having the access right postgresql

i need to create a function that insert data rows in a table and make it executable for a user without giving the user the right to do any other action in the table ( no select or directly insert).
i tried with an insertion on a different table and trigger to move rows to the right table but it doesn't work !
You can create a function with SECURITY DEFINER modifier. It will use grants of a user that created this function. then grant an execution rights to the limited user.
Details here: http://www.postgresql.org/docs/current/static/sql-createfunction.html

Oracle: control access to data through views?

I have a problem with controling access to data in a database. The data is a mix of price-data from my company and price-data bought from a data-provider and since they charge per user who can access their data I need to be able to limit the access to data.
I have a scheme "DATA" which holds all price-data. I am thinking having 2 additional schemes (example: LIM_ACCESS and FULL_ACCESS) with VIEWS that is build on the DATA-scheme. example:
CREATE VIEW LIM_ACCESS.V_PRICES AS<br>
SELECT [] FROM DATA.PRICES<br>
WHERE SOURCE = [MyCompany]
CREATE VIEW FULL_ACCESS.V_PRICES AS<br>
SELECT [] FROM DATA.PRICES
But to my experience then the LIM_ACCESS- and FULL_ACCESS-schemes has to have select-privelige on the DATA-tables to create the views and then I am back to square 1.
Being a novice in databases I feel there must be a relative simple solution to this so any advice or hint(if this question has been asked and answered before) is appreciated :-)
Kind Regards,
Svend
You can put all the views in your DATA schema. Then GRANT SELECT on them to other schemas as necessary, ideally via database roles as Woot4Moo suggested.
The use of a view will not prevent a subset of users from accessing the data. What you need to do is implement row level security.
Another approach is to use some form of role based permissions, that enable only the specific group of users you want to access the "paid" information. This can be done fairly trivially example follows.
create user foo
identified by password;
--no permissions
create role paid_data;
--grant privileges here for the paid_data role
grant paid_data to foo
User foo will now have the permissions that the paid_data role has. The advantage of using roles like this is that you can quickly revoke everyone's access that is in that group / add more accesses as they need to be incorporated.
As GriffeyDog suggested, this is the best way to do it. First create two views in your schema and then grant select on those views to the two users.
CREATE VIEW LIM_ACCESS_V_PRICES AS<br>
SELECT [] FROM DATA.PRICES<br>
WHERE SOURCE = [MyCompany];
GRANT SELECT ON LIM_ACCESS_V_PRICES TO LIM_ACCESS;
CREATE VIEW FULL_ACCESS_V_PRICES AS<br>
SELECT [] FROM DATA.PRICES;
GRANT SELECT ON FULL_ACCESS_V_PRICES TO FULL_ACCESS;
Another approach is to use Oracle Row Level Security otherwise known as Oracle Label Security. I've used this to greatly simplify my application design while ensuring users only see the data they're allowed to see.