I am trying to understand the securables of SQL Server, I am not sure on what is the exact use of OwnedSchema. Can someone help me on this, where it plays a significant role?
The dialog on the picture enlist you all database's schemas and marks some schemas as "checked" if current database principal is the owner of these schemas.
So it shows you the result of this query (that you can catch using Profiler):
SELECT
s.name AS [Name],
s.schema_id AS [ID],
ISNULL(dp1.name, N'') AS [Owner],
CAST(
case when s.name in ('dbo','guest','INFORMATION_SCHEMA','sys','db_owner','db_accessadmin','db_securityadmin','db_ddladmin','db_backupoperator','db_datareader','db_datawriter','db_denydatareader', 'db_denydatawriter') then 1 else 0 end AS bit) AS [IsSystemObject]
FROM
sys.schemas AS s
LEFT OUTER JOIN sys.database_principals AS dp1
ON dp1.principal_id = s.principal_id
Using this dialog you can change the owner of the schema to current user, i.e. execute the following code:
ALTER AUTHORIZATION ON SCHEMA::[this_schema] TO [this_user]
This link is also useful to understand Ownership and User-Schema Separation in SQL Server.
Schema Owners and Permissions
Schemas can be owned by any database principal, and a single principal
can own multiple schemas. You can apply security rules to a schema,
which are inherited by all objects in the schema. Once you set up
access permissions for a schema, those permissions are automatically
applied as new objects are added to the schema. Users can be assigned
a default schema, and multiple database users can share the same
schema. By default, when developers create objects in a schema, the
objects are owned by the security principal that owns the schema, not
the developer. Object ownership can be transferred with ALTER
AUTHORIZATION Transact-SQL statement. A schema can also contain
objects that are owned by different users and have more granular
permissions than those assigned to the schema, although this is not
recommended because it adds complexity to managing permissions.
Objects can be moved between schemas, and schema ownership can be
transferred between principals. Database users can be dropped without
affecting schemas.
Related
I already posted a similar question to the Power Bi forum, but probably it's too short-sighted to search the solution on Power Bi side.
We have a postgres schema and a postgres user that has the following rights: granted connect to db and schema, revoked create on schema, granted select privilege on all tables in schema. Nothing more. The user works in the db client, can only read from the tables in the schema, cannot create, insert, read, update, delete anything.
When we import the schema in Power Bi with our Read Only User, the relations between the tables is not displayed. The postgres documentation writes the following:
"The view table_constraints contains all constraints belonging to tables that the current user owns or has some privilege other than SELECT on."
This would mean, our Read Only User must have granted insert, delete or update permissions to make Power Bi able to display the table relations?! Our postgres db shall work as a datawarehouse and give customers the possibility to connect from their local Power Bi Desktop or their companies Power Bi instance, so we don't have too much influence on Power Bi side at all.
Is there a permission we can give the Read Only User that keeps him read only but allows to resolve the table relations in Power Bi?
Thanks and kind regards!
We tried giving the user a insert privilege on all tables, that made Power Bi resolve the table relations but is conflicting with our Read Only behave.
We read documentation and tried to find out, if there are other possibilities than the above.
That is really unfortunate, but the SQL standard explicitly requires that (e.g. in ISO/IEC 9075-11:2003, 5.58):
5.58 TABLE_CONSTRAINTS view
Function
Identify the table constraints defined on tables in this catalog that are accessible to a given user or role.
Definition
CREATE VIEW TABLE_CONSTRAINTS AS
SELECT CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME,
TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,
CONSTRAINT_TYPE, IS_DEFERRABLE, INITIALLY_DEFERRED
FROM DEFINITION_SCHEMA.TABLE_CONSTRAINTS
WHERE ( TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME ) IN
( SELECT TP.TABLE_CATALOG, TP.TABLE_SCHEMA, TP.TABLE_NAME
FROM DEFINITION_SCHEMA.TABLE_PRIVILEGES AS TP
WHERE TP.PRIVILEGE_TYPE <> 'SELECT'
[...]
So really this is a shortcoming of Power BI, if it is supposed to work with a read-only user. On the other hand, if they want to be database agnostic, they have little choice but to use the information_schema.
But interesting as that may be, you are looking for a solution or a workaround. If you look at the view definition of information_schema.table_constraints, you will see that visibility is determined by this condition:
pg_has_role(r.relowner, 'USAGE'::text) OR
has_table_privilege(r.oid, 'INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER'::text) OR
has_any_column_privilege(r.oid, 'INSERT, UPDATE, REFERENCES'::text)
I'd say that the most promising privilege here is REFERENCES, which allows a user to create a foreign key pointing to the table. If the user doesn't have the CREATE privilege on any schema, they cannot create a table that references the table, so the privilege is effectively useless. Still, if you grant the user REFERENCES on all tables, the constraints will become visible. It is hacky, but it should be good enough.
When collaborating with colleagues I need to change the schema name every time I receive a SQL script (Postgres).
I am only an ordinary user of a corporate database (no permissions to change anything). Also, we are not allowed to create tables in PUBLIC schema. However, we can use (read-only) all the tables from BASE schema.
It is cumbersome for the team of users, where everybody is creating SQL scripts (mostly only for creating tables), which need to be shared amongst others. Every user has its own schema.
Is it possible to change the script below, where I will share the script to another user without the need for the other user to find/replace the schema, in this case, user1?
DROP TABLE IF EXISTS user1.table1;
CREATE TABLE user1.table1 AS
SELECT * FROM base.table1;
You can set the default schema at the start of the script (similar to what pg_dump generates):
set search_path = user1;
DROP TABLE IF EXISTS table1;
CREATE TABLE table1 AS
SELECT * FROM base.table1;
Because the search path was change to contain user1 as the first schema, tables will be searched in that schema when dropping and creating. And because the search path does not include any other schema, no other schema will be consulted.
If you
However the default search_path is "$user", public which means that any unqualified table will be searched or created in a schema with the same name as the current user.
Caution
Note that a DROP TABLE will drop the table in the first schema found in that case. So if table1 doesn't exist in the user's schema, but in the public schema, it would be dropped from the public schema. So for your use-case setting the path to exactly one schema might be more secure.
I am an Oracle DBA, new to PostgreSQL. I have a requirement to separate some modules data, so that one module will not have access to read the data of another module.
I read about the use of schemas in PostgreSql which is somewhat different than the use of it in Oracle. However seems like it is recommended to use the method of different schemas for separation and management - just like in Oracle.
However, when I create 2 schemas - connected to the same database and same user - I can do a select from the other schema's table.
That is, for example, if I have schema A owning table a, and schema B owning table b, when I set the search path to schema B I can do a select on schema’s A table a without any problem.
I couldn't find a way to revoke this privilege from schema B.
The only I could find then to separate access to data, is using different roles, that is to create role A with schema A, and role B with schema B. then I can grant and revoke access from user B in order for it to see what I want from role's A tables.
Is this correct? Am I missing something?
if I have schema A owning table a
A schema does not "own" a table in Postgres - a user does. This is the same as in Oracle - the difference (and maybe where your confusion arises) is that in Oracle in a regular user can't create tables outside of a schema that has the same name as the user account.
So if user arthur creates a table in schema_a and one in schema_b, both tables are owned by arthur - not "the schema".
If you used different schemas/users in Oracle to separate data and to prevent access to the other user's tables, then you need two users and two schemas in Postgres as well.
The default search_path in Postgres is setup in a way, that (unqualified) tables are always first searched (and created) in a schema with the same name as the user running the statement.
So if you create two users and a schema with the user's name for each user, you pretty much have the same setup as in Oracle:
create user arthur with password 'foobar';
create schema arthur authorization arthur; --<< this is what Oracle does "automatically"
create user bob with password 'verysecret';
create schema bob authorization bob;
Now, if bob creates a table, that table is created in the schema bob and is owned by the user bob. User arthur has not privileges to access that table.
If you never need to share data between those users (or schemas), then you can create two databases, create two users and let both users create everything in the public schema of "their" database.
I am working around a workaround to a "feature" in IBM DB2.
This fancy database has a "feature" in it which if I try to use a CREATE TABLE statement and it doesn't find the schema, it will create this schema for me, even if I don't want it to. This bug has caused me a lot of hours in debugging, because my code right now exists with the expectation that it won't create the schema if it doesn't exist
My question is -- how do I change the permissions of a particular schema (or even during the create schema phase) which a particular user does not have access to view?
I checked out this doc..
It seems with GRANT, there are the following three permissions:
ALTERIN
Grants the privilege to alter or comment on all objects in the
schema. The owner of an explicitly created schema automatically
receives ALTERIN privilege.
CREATEIN
Grants the privilege to create
objects in the schema. Other authorities or privileges required to
create the object (such as CREATETAB) are still required. The owner of
an explicitly created schema automatically receives CREATEIN
privilege. An implicitly created schema has CREATEIN privilege
automatically granted to PUBLIC.
DROPIN
Grants the privilege to drop
all objects in the schema. The owner of an explicitly created schema
automatically receives DROPIN privilege
With only ALTERIN, CREATEIN, and DROPIN, I don't see anything relevant to view access permissions :/
EDIT:
I checked out our Dash DB database for this particular table which has these special permissions for particular users using the following SQL:
SELECT * FROM SYSIBMADM.PRIVILEGES WHERE OBJECTSCHEMA = 'FAKE_SCRATCH';
This is the result:
EDIT 2:
I tried the following to emulate Dash DB's permissions for that user for that schema:
GRANT ALTERIN, CREATEIN, DROPIN ON SCHEMA FAKE_SCRATCH TO USER TEST_USER;
Still doesn't work :/
The following SQL query executed in DB2 fixed the problem:
REVOKE IMPLICIT_SCHEMA ON DATABASE FROM PUBLIC
I have access to some schema in different database and as part of some migration work, I am comparing 2 schema.
I am using Syscat to compare the 2 schema. However in one of the schema, I get an error saying
"user does not have select privilege on "
I would like to know , how can I see what and all access permissions have been set up in a particular schema (basically all users who have access and the type of access for a gievn schema). The database is db2.
Please note that I am not using any tool like schema crawler etc. Instead I am writing a JDBC application which uses the Syscat to query the details like select * from syscat.tables where tabSchema = <schemaName>
Using a tool etc is a long process in terms to getting approval , justification etc (and I personally think that JDBC program should be good to start with the analysis).
In DB2 privileges granted on a schema do not give you any privileges on objects belonging to that schema (unless you created those objects yourself). You have to be granted explicit object privileges or certain database level privileges, such as DATAACCESS.
The actual DB2 error message should contain the name of the object that generates the error. Try printing the String representation of the SQLException object.
A schema is a logical group of objects. These objects can be views, tables, indexes, sequences, functions, sotred procedures, etc. Each of these objects has a different set of privileges: table has select, insert, delete and others; stored procedure has the execution and others; etc. It means that every single object has different types of privileges, and you cannot get "all privilegesfor a given schema", you have to give the type of object.
For example, in order to get the privileges on tables for a given schema, you can execute
db2 "
select substr(GRANTEE,1,16),GRANTEETYPE,substr(tabschema || '.' || tabname,1,64),
CONTROLAUTH, ALTERAUTH, DELETEAUTH, INDEXAUTH, INSERTAUTH, REFAUTH, SELECTAUTH, UPDATEAUTH
from syscat.TABAUTH
where tabschema like 'MYSCHEMA%'"
Each kind of object that a table in syscat schema that contains the privileges for that kind of object. You just have to query the table.
In a similar way, you can create the appropiated sentences in order to grant or revoke privileges on an object
select 'grant select on ' || trim(tabschema) || '.' || trim(tabname) ' to user johndoe'
from syscat.tables
where tabschema like 'MYSCHE%'
Finally, there are not only privileges (grants) on db2, there are also database level authorities, and some of them have privileges on all objects.