So, Im using Informix DB engine to create my database. I have noticed something peculiar I cannot find information about in the official IBM page.
If you check the definition of my table, there is a line at the end saying :
revoke all on "gabriel.barrios".proveedores from "public" as "gabriel.barrios";
I did not write that, I simply defined the table attributes. But it seems as the engine itself is adding that.
Is this the case?
And if it is, how can I cahnge this default behaviour.
Additionally, could someone clarify ths line's output :
{ TABLE "gabriel.barrios".proveedores row size = 110 number of columns = 4 index size = 9 }
[gabriel.barrios#informix1 ~]$ dbschema -d practico_matias_barrios -t Proveedores
DBSCHEMA Schema Utility INFORMIX-SQL Version 11.70.UC8W1
{ TABLE "gabriel.barrios".proveedores row size = 110 number of columns = 4 index size = 9 }
create table "gabriel.barrios".proveedores
(
id serial not null ,
nombre varchar(50) not null constraint "gabriel.barrios".proveedor_nombre_vacio,
situacion integer not null constraint "gabriel.barrios".proveedor_situacion_vacio,
ciudad varchar(50) not null constraint "gabriel.barrios".proveedor_ciudad_vacio,
primary key (id) constraint "gabriel.barrios".proveedor_clave_primaria
);
revoke all on "gabriel.barrios".proveedores from "public" as "gabriel.barrios";
Informix default behavior is to grant privileges to the PUBLIC role.
As per the documentation (Table-level privileges) :
In an ANSI-compliant database, only the table owner has any
privileges. In other databases, the database server, as part of
creating a table, automatically grants to PUBLIC all table privileges
except Alter and References, unless the NODEFDAC environment variable
has been set to 'yes' to withhold all table privileges from PUBLIC.
When you allow the database server to automatically grant all table
privileges to PUBLIC, a newly created table is accessible to any user
with the Connect privilege. If this is not what you want (if users
exist with the Connect privilege who should not be able to access this
table), you must revoke all privileges on the table from PUBLIC after
you create the table.
What your are seeing is dbschema always revoking privileges from PUBLIC on the create table output and then adding them back on the privileges output.
$ dbschema -d mydatabase -t default_privileges
DBSCHEMA Schema Utility INFORMIX-SQL Version 12.10.FC12
{ TABLE "myuser".default_privileges row size = 4 number of columns = 1 index size = 0 }
create table "myuser".default_privileges
(
id integer
);
revoke all on "myuser".default_privileges from "public" as "myuser";
Using dbschema privileges output and filtering by table default_privileges :
$ dbschema -d mydatabase -p all | grep default_privileges
grant select on "myuser".default_privileges to "public" as "myuser";
grant update on "myuser".default_privileges to "public" as "myuser";
grant insert on "myuser".default_privileges to "public" as "myuser";
grant delete on "myuser".default_privileges to "public" as "myuser";
grant index on "myuser".default_privileges to "public" as "myuser";
Related
I'm currently doing a comparision between Stambia and Talend. For this, I wanted to use the same data. So I tried to use the data available for Stambia tutorials. These are coming from an HSQL Database.
For this, I made a HSQLDB Sever with simples proprieties :
server.database.0 = file:hsqldb/demodb
server.dbname.0 = testdb
After that, I added the script whose coming from Stambia into my new database "demodb" :
SET DATABASE UNIQUE NAME HSQLDB2467A82B33
SET DATABASE GC 0
SET DATABASE DEFAULT RESULT MEMORY ROWS 0
SET DATABASE EVENT LOG LEVEL 0
SET DATABASE SQL NAMES FALSE
SET DATABASE SQL REFERENCES FALSE
SET DATABASE SQL SIZE FALSE
SET DATABASE SQL TYPES FALSE
SET DATABASE SQL TDC DELETE TRUE
SET DATABASE SQL TDC UPDATE TRUE
SET DATABASE SQL TRANSLATE TTI TYPES TRUE
SET DATABASE SQL CONCAT NULLS TRUE
SET DATABASE SQL UNIQUE NULLS TRUE
SET DATABASE SQL CONVERT TRUNCATE TRUE
SET DATABASE SQL AVG SCALE 0
SET DATABASE SQL DOUBLE NAN TRUE
SET DATABASE TRANSACTION CONTROL LOCKS
SET DATABASE DEFAULT ISOLATION LEVEL READ COMMITTED
SET DATABASE TRANSACTION ROLLBACK ON CONFLICT TRUE
SET DATABASE TEXT TABLE DEFAULTS ''
SET FILES WRITE DELAY 10
SET FILES BACKUP INCREMENT TRUE
SET FILES CACHE SIZE 10000
SET FILES CACHE ROWS 50000
SET FILES SCALE 1
SET FILES LOB SCALE 32
SET FILES DEFRAG 0
SET FILES NIO TRUE
SET FILES NIO SIZE 256
SET FILES LOG TRUE
SET FILES LOG SIZE 200
CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e'
CREATE SCHEMA PUBLIC AUTHORIZATION DBA
CREATE SCHEMA DATAMART AUTHORIZATION DBA
CREATE SCHEMA HOTEL_DATAMART AUTHORIZATION DBA
SET SCHEMA DATAMART
CREATE MEMORY TABLE DATAMART.DIM_CUSTOMER(CUS_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,CUS_ID INTEGER NOT NULL,CUS_TITLE CHARACTER(32),CUS_NAME CHARACTER(50) NOT NULL,CUS_FORNAME VARCHAR(25),CUS_COMPANY VARCHAR(100),GEO_KEY_ID INTEGER,UPDATE_DATE TIMESTAMP,CONSTRAINT PK_DIM_CUSTOMER PRIMARY KEY(CUS_KEY_ID))
ALTER TABLE DATAMART.DIM_CUSTOMER ALTER COLUMN CUS_KEY_ID RESTART WITH 300
CREATE INDEX CUSTOMER_ID ON DATAMART.DIM_CUSTOMER(CUS_ID)
CREATE MEMORY TABLE DATAMART.DIM_GEOGRAPHY(GEO_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,GEO_ZIP_CODE VARCHAR(6),GEO_CITY VARCHAR(50),GEO_DISTRICT_CODE VARCHAR(3),GEO_DISTRICT VARCHAR(50),GEO_REGION VARCHAR(50),CONSTRAINT PK_DIM_GEOGRAPHY PRIMARY KEY(GEO_KEY_ID))
ALTER TABLE DATAMART.DIM_GEOGRAPHY ALTER COLUMN GEO_KEY_ID RESTART WITH 2
CREATE UNIQUE INDEX I_DIM_GEOGRAPHY ON DATAMART.DIM_GEOGRAPHY(GEO_ZIP_CODE,GEO_CITY)
CREATE MEMORY TABLE DATAMART.DIM_TIME(TIME_KEY_DAY VARCHAR(10) NOT NULL,TIME_DATE TIMESTAMP,TIME_MONTH_DAY NUMERIC(2),TIME_WEEK_DAY NUMERIC(1),TIME_DAY_NAME VARCHAR(15),TIME_MONTH NUMERIC(2),TIME_MONTH_NAME VARCHAR(15),TIME_QUARTER NUMERIC(1),TIME_YEAR NUMERIC(4),CONSTRAINT PK_DIM_TIME PRIMARY KEY(TIME_KEY_DAY))
CREATE INDEX TIME_DAY ON DATAMART.DIM_TIME(TIME_DATE)
CREATE MEMORY TABLE DATAMART.DIM_DISCOUNT(DIS_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,DIS_RANGE VARCHAR(35),DIS_MIN NUMERIC(3),DIS_MAX NUMERIC(3),CONSTRAINT PK_DIM_DISCOUNT PRIMARY KEY(DIS_KEY_ID))
ALTER TABLE DATAMART.DIM_DISCOUNT ALTER COLUMN DIS_KEY_ID RESTART WITH 19
CREATE MEMORY TABLE DATAMART.DIM_PAYMENT_TYPES(PMT_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,PMT_CODE VARCHAR(10),PMT_NAME VARCHAR(35),CONSTRAINT PK_DIM_PAYMENT_TYPES PRIMARY KEY(PMT_KEY_ID))
ALTER TABLE DATAMART.DIM_PAYMENT_TYPES ALTER COLUMN PMT_KEY_ID RESTART WITH 9
CREATE MEMORY TABLE DATAMART.DIM_CHAMBER(CHB_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,CHB_ID NUMERIC(10),CHB_NUMBER NUMERIC(4),CHB_FLOOR NUMERIC(2),CHB_BATH NUMERIC(1),CHB_SHOWER NUMERIC(1),CHB_WC NUMERIC(1),CHB_BED_NUMBER NUMERIC(2),CHB_PHONE_NUMBER CHARACTER(3),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_DIM_CHAMBER PRIMARY KEY(CHB_KEY_ID))
ALTER TABLE DATAMART.DIM_CHAMBER ALTER COLUMN CHB_KEY_ID RESTART WITH 60
CREATE INDEX CHAMBER_ID ON DATAMART.DIM_CHAMBER(CHB_ID)
CREATE MEMORY TABLE DATAMART.FACT_BILLING(BIL_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,BIL_ID NUMERIC(10,2),CUS_KEY_ID INTEGER,TIME_KEY_DAY VARCHAR(10),DIS_KEY_ID INTEGER,PMT_KEY_ID INTEGER,BIL_MONTANT NUMERIC(10,2),BIL_QTE NUMERIC(10),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_FACT_BILLING PRIMARY KEY(BIL_KEY_ID),CONSTRAINT FK_FACT_BILLING_CUS FOREIGN KEY(CUS_KEY_ID) REFERENCES DATAMART.DIM_CUSTOMER(CUS_KEY_ID),CONSTRAINT FK_FACT_BILLING_DIS FOREIGN KEY(DIS_KEY_ID) REFERENCES DATAMART.DIM_DISCOUNT(DIS_KEY_ID),CONSTRAINT FK_FACT_BILLING_PMT FOREIGN KEY(PMT_KEY_ID) REFERENCES DATAMART.DIM_PAYMENT_TYPES(PMT_KEY_ID),CONSTRAINT FK_FACT_BILLING_TIME FOREIGN KEY(TIME_KEY_DAY) REFERENCES DATAMART.DIM_TIME(TIME_KEY_DAY))
ALTER TABLE DATAMART.FACT_BILLING ALTER COLUMN BIL_KEY_ID RESTART WITH 8532
CREATE MEMORY TABLE DATAMART.FACT_BOOKING(BOK_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL,CUS_KEY_ID INTEGER,TIME_KEY_DAY VARCHAR(10),CHB_KEY_ID INTEGER,BOK_NP_PEOPLE NUMERIC(10),BOK_BOOKED NUMERIC(1),BOK_OCCUPIED NUMERIC(1),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_FACT_BOOKING PRIMARY KEY(BOK_KEY_ID),CONSTRAINT FK_FACT_BOOKING_CHB FOREIGN KEY(CHB_KEY_ID) REFERENCES DATAMART.DIM_CHAMBER(CHB_KEY_ID),CONSTRAINT FK_FACT_BOOKING_CUS FOREIGN KEY(CUS_KEY_ID) REFERENCES DATAMART.DIM_CUSTOMER(CUS_KEY_ID),CONSTRAINT FK_FACT_BOOKING_TIME FOREIGN KEY(TIME_KEY_DAY) REFERENCES DATAMART.DIM_TIME(TIME_KEY_DAY))
ALTER TABLE DATAMART.FACT_BOOKING ALTER COLUMN BOK_KEY_ID RESTART WITH 43686
CREATE INDEX BOOK_CUS ON DATAMART.FACT_BOOKING(CUS_KEY_ID)
CREATE INDEX BOOK_TIM ON DATAMART.FACT_BOOKING(TIME_KEY_DAY)
SET SCHEMA HOTEL_DATAMART
CREATE SEQUENCE HOTEL_DATAMART.SEQ_GEO_KEY_ID AS INTEGER START WITH 1000
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_BEDROOM(BDR_ID NUMERIC(10),BDR_NUMBER NUMERIC(4),BDR_FLOOR NUMERIC(2),BDR_BATH NUMERIC(1),BDR_SHOWER NUMERIC(1),BDR_BAR NUMERIC(1),BDR_BED_COUNT NUMERIC(2),BDR_PHONE_NUMBER VARCHAR(3),BDR_TYPE VARCHAR(30),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_DIM_BEDROOM PRIMARY KEY(BDR_ID))
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_DISCOUNT(DIS_RANGE VARCHAR(35),DIS_MIN NUMERIC(3),DIS_MAX NUMERIC(3),CONSTRAINT PK_DIM_DISCOUNT PRIMARY KEY(DIS_RANGE))
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_GEOGRAPHY(GEO_KEY_ID NUMERIC(10),GEO_ZIP_CODE VARCHAR(6),GEO_CITY VARCHAR(50),GEO_STATE_CODE VARCHAR(3),GEO_STATE VARCHAR(50),CONSTRAINT PK_DIM_GEOGRAPHY PRIMARY KEY(GEO_KEY_ID))
CREATE INDEX IDX_GEO_ZIP_CODE ON HOTEL_DATAMART.DIM_GEOGRAPHY(GEO_ZIP_CODE)
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_BIL_TYPE(BIL_TYPE_CODE VARCHAR(4),BIL_TYPE_NAME VARCHAR(35),CONSTRAINT PK_DIM_BIL_TYPE PRIMARY KEY(BIL_TYPE_CODE))
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_PAYMENT_TYPE(PMT_CODE VARCHAR(4),PMT_NAME VARCHAR(35),PMT_DESCRIPTION VARCHAR(35),CONSTRAINT PK_DIM_PAYMENT_TYPE PRIMARY KEY(PMT_CODE))
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_TIME(TIME_KEY_DAY VARCHAR(10) NOT NULL,TIME_DATE TIMESTAMP,TIME_MONTH_DAY NUMERIC(2),TIME_WEEK_DAY NUMERIC(1),TIME_DAY_NAME VARCHAR(15),TIME_MONTH NUMERIC(2),TIME_MONTH_NAME VARCHAR(15),TIME_QUARTER NUMERIC(1),TIME_YEAR NUMERIC(4),CONSTRAINT PK_DIM_TIME PRIMARY KEY(TIME_KEY_DAY))
CREATE INDEX IX_TIME_DATE ON HOTEL_DATAMART.DIM_TIME(TIME_DATE)
CREATE MEMORY TABLE HOTEL_DATAMART.DIM_CUSTOMER(CUS_ID INTEGER NOT NULL,CUS_TITLE VARCHAR(32),CUS_NAME VARCHAR(100) NOT NULL,CUS_COMPANY VARCHAR(100),GEO_KEY_ID NUMERIC(10),CUS_VIP NUMERIC(1),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_DIM_CUSTOMER PRIMARY KEY(CUS_ID),CONSTRAINT FK_DIM_CUSTOMER_GEO FOREIGN KEY(GEO_KEY_ID) REFERENCES HOTEL_DATAMART.DIM_GEOGRAPHY(GEO_KEY_ID))
CREATE INDEX IDX_CUS_GEO_KEY_ID ON HOTEL_DATAMART.DIM_CUSTOMER(GEO_KEY_ID)
CREATE MEMORY TABLE HOTEL_DATAMART.FACT_BILLING(BIL_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL,BIL_ID INTEGER,CUS_ID INTEGER,TIME_KEY_DAY VARCHAR(10),DIS_RANGE VARCHAR(35),PMT_CODE VARCHAR(4),BIL_AMOUNT NUMERIC(10,2),BIL_QTY NUMERIC(10,2),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_FACT_BILLING PRIMARY KEY(BIL_KEY_ID),CONSTRAINT FK_FACT_BILLING_DIS FOREIGN KEY(DIS_RANGE) REFERENCES HOTEL_DATAMART.DIM_DISCOUNT(DIS_RANGE),CONSTRAINT FK_FACT_BILLING_CUS FOREIGN KEY(CUS_ID) REFERENCES HOTEL_DATAMART.DIM_CUSTOMER(CUS_ID),CONSTRAINT FK_FACT_BILLING_PMT FOREIGN KEY(PMT_CODE) REFERENCES HOTEL_DATAMART.DIM_PAYMENT_TYPE(PMT_CODE),CONSTRAINT FK_FACT_BILLING_TIME FOREIGN KEY(TIME_KEY_DAY) REFERENCES HOTEL_DATAMART.DIM_TIME(TIME_KEY_DAY))
ALTER TABLE HOTEL_DATAMART.FACT_BILLING ALTER COLUMN BIL_KEY_ID RESTART WITH 1
CREATE INDEX IDX_BIL_CUS_ID ON HOTEL_DATAMART.FACT_BILLING(CUS_ID)
CREATE INDEX IDX_BIL_DIS_RANGE ON HOTEL_DATAMART.FACT_BILLING(DIS_RANGE)
CREATE INDEX IDX_BIL_PMT_CODE ON HOTEL_DATAMART.FACT_BILLING(PMT_CODE)
CREATE INDEX IDX_BIL_TIME_KEY_DAY ON HOTEL_DATAMART.FACT_BILLING(TIME_KEY_DAY)
CREATE INDEX IDX_RANGE_AND_ID ON HOTEL_DATAMART.FACT_BILLING(BIL_ID,DIS_RANGE)
CREATE MEMORY TABLE HOTEL_DATAMART.FACT_BOOKING(BOK_KEY_ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL,CUS_ID INTEGER,TIME_KEY_DAY VARCHAR(10),BDR_ID NUMERIC(10),BOK_PEOPLE NUMERIC(10),BOK_BOOKED NUMERIC(1),UPDATE_DATE TIMESTAMP,CONSTRAINT PK_FACT_BOOKING PRIMARY KEY(BOK_KEY_ID),CONSTRAINT FK_FACT_BOOKING_BDR FOREIGN KEY(BDR_ID) REFERENCES HOTEL_DATAMART.DIM_BEDROOM(BDR_ID),CONSTRAINT FK_FACT_BOOKING_CUS FOREIGN KEY(CUS_ID) REFERENCES HOTEL_DATAMART.DIM_CUSTOMER(CUS_ID),CONSTRAINT FK_FACT_BOOKING_TIME FOREIGN KEY(TIME_KEY_DAY) REFERENCES HOTEL_DATAMART.DIM_TIME(TIME_KEY_DAY))
ALTER TABLE HOTEL_DATAMART.FACT_BOOKING ALTER COLUMN BOK_KEY_ID RESTART WITH 1
CREATE INDEX IDX_BOK_BDR_ID ON HOTEL_DATAMART.FACT_BOOKING(BDR_ID)
CREATE INDEX IDX_BOK_TIME_KEY_DAY ON HOTEL_DATAMART.FACT_BOOKING(TIME_KEY_DAY)
CREATE MEMORY TABLE HOTEL_DATAMART.L1_DIM_TIME(L1_TIME_KEY_DAY VARCHAR(10),L2_TIME_DATE TIMESTAMP,L3_TIME_MONTH_DAY NUMERIC(2),L4_TIME_WEEK_DAY NUMERIC(1),L5_TIME_DAY_NAME VARCHAR(15),L6_TIME_MONTH NUMERIC(2),L7_TIME_MONTH_NAME VARCHAR(15),L8_TIME_QUARTER NUMERIC(1),L9_TIME_YEAR NUMERIC(4))
ALTER TABLE DATAMART.DIM_CUSTOMER ADD CONSTRAINT FK_DIM_CUSTOMER_GEO FOREIGN KEY(GEO_KEY_ID) REFERENCES DATAMART.DIM_GEOGRAPHY(GEO_KEY_ID)
ALTER SEQUENCE SYSTEM_LOBS.LOB_ID RESTART WITH 1
ALTER SEQUENCE HOTEL_DATAMART.SEQ_GEO_KEY_ID RESTART WITH 209465
SET DATABASE DEFAULT INITIAL SCHEMA PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.SQL_IDENTIFIER TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.YES_OR_NO TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.TIME_STAMP TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CARDINAL_NUMBER TO PUBLIC
GRANT USAGE ON DOMAIN INFORMATION_SCHEMA.CHARACTER_DATA TO PUBLIC
GRANT DBA TO SA
SET SCHEMA SYSTEM_LOBS
INSERT INTO BLOCKS VALUES(0,2147483647,0)
SET SCHEMA DATAMART
INSERT INTO DIM_CUSTOMER VALUES(200,1,'Monsieur','DUPONT ','Alain',NULL,1,'2013-06-04 11:43:21.211000')
INSERT INTO DIM_CUSTOMER VALUES(201,2,'Monsieur','MARTIN ','Marc','Transports MARTIN & fils',1,'2013-06-04 11:43:21.211000')
Now, I made an HSQLDB connection in Talend and I retrieve schema, so I have every tables of base_datamart in Talend.
I created a job with a source (delimited file) to charge my DIM_Discount table through a tMap.
But when I run the job, I get the error : Exception in component tHSQLDbOutput_1 (Load_DIM_DISCOUNT)
java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: DIM_DISCOUNT
I made research for about 2 days but I didn't find any solutions... if someone ever faced this problem, or has any idea for this, I would be really pleased.
Have a good day, thanks.
I'm trying to learn Postgres and Ive made two basic tables and I can't join them together.
here is my list Of relations:
Schema | Name | Type | Owner
--------+--------------+----------+----------
public | login | table | postgres
public | login_id_seq | sequence | postgres
public | users | table | test
(3 rows)
When I use the command
SELECT * FROM users JOIN login ON users.name = login.name;
I get
ERROR: permission denied for relation login
I have no idea what to do or what I did wrong.
You should grant the SELECT permission to user test:
GRANT SELECT ON login TO test;
If if might allow test to modify login, you should grant other permissions as well:
GRANT SELECT, INSERT, UPDATE, DELETE ON login TO test;
You should execute these statements as database owner or as user postgres. In general, you can use
psql -Upostgres -dtest
if you're running this command on the same machine where the Postgres server is running.
You may also change the ownership of login to test:
ALTER TABLE login OWNER TO test;
ALTER SEQUENCE login_id_seq OWNER TO test;
But have to execute this as user postgres as well.
Edit: You can try to change the user with
SET ROLE 'postgres';
as suggested by #lat long.
So this is what I did to finally get it to work...I basically just went into the login properties on pgAdmin4, found the owner and switched it to test and ran:
SELECT * FROM users JOIN login ON users.name = login.name;
and finally got what I was looking for. Surprisingly a simple fix.
The "test" user doesn't have permission to login and use the related tables. Run the query with the "postgres" user:
SET ROLE 'postgres';
Then run your query.
Was wanting to add full access for a developer to a database.
I wanted them to be able to have full control over it...including deleting it if they wanted.
Somehow I stumbled upon two ways. Are these the right ways??
What's the difference of between access/permissions between the both commands?
What is the correct command to accomplish what I want?
Thanks.
Command 1
USE [testdb1]
GO
ALTER USER [john] WITH DEFAULT_SCHEMA=[dbo]
GO
Command 2
USE [testdb1]
GO
EXEC sp_addrolemember N'db_owner', N'john'
GO
According to the latest sp_addrolemember documentation, sp_addrolemember should be avoided and ALTER ROLE should be used instead.
This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature. Use ALTER ROLE instead.
There is no difference between the two as of SQL Server 2012.
alter role [RoleName] add member [MemberName];
is equivalent to
exec sp_addrolemember N'RoleName', N'MemberName';
References:
https://msdn.microsoft.com/en-us/library/ms189775.aspx
https://msdn.microsoft.com/en-us/library/ms187750.aspx
MSDN is a great source for answering that:
sp_addrolemember
Adds a database user, database role, Windows login, or Windows group
to a database role in the current database.
ALTER USER
Renames a database user or changes its default schema.
Note also the syntax:
sp_addrolemember [ #rolename = ] 'role',
[ #membername = ] 'security_account'
-- SQL Server Syntax
ALTER USER userName
WITH <set_item> [ ,...n ]
[;]
<set_item> ::=
NAME = newUserName
| DEFAULT_SCHEMA = { schemaName | NULL }
| LOGIN = loginName
| PASSWORD = 'password' [ OLD_PASSWORD = 'oldpassword' ]
| DEFAULT_LANGUAGE = { NONE | <lcid> | <language name> | <language alias> }
| ALLOW_ENCRYPTED_VALUE_MODIFICATIONS = [ ON | OFF ]
In other words, using sp_addrolemember, you could only add database user, database role, Windows login, or Windows group in the current database.
But using ALTER USER, you could alter its name, its default schema, its login name, its password, etc... which certain is unable to be done by using sp_addrolemember.
Check the two MSDN links. They are great source for info using SQL Server
As for your case, you probably want to use sp_addrolemember, provided that you already have a role which could give the user the access that they need (most probably db_owner).
USE [testdb1]
GO
EXEC sp_addrolemember N'db_owner', N'john'
GO
When you alter default schema of a user, it does not mean that they get new role - but they get new default schema, and the accessibility will depend on the security rules in the new schema for the existing user role. It could give you what you want, depends on the security rules for the user in the default schema it has.
I built a database with the entity user and permission
user (id, email, password, permission)
permission (id, create_user, delete_user, user_fk)
create_user and delete_user is BOOLEAN.
Relationship: One-One
Now every user can have it's own permissions.
My question is: How can I use shiro to read the permissions from the database?
If you really only wish to assign permissions on user level, you can "fake" the roles table to make Shiro happy.
As Wouter mentioned, use the JdbcRealm and specify the 3 queries for your table setup.
You should modify your permission table to have this structure:
permission (id, permissionname, user_fk)
Then you insert rows for the create_user/delete_user rights as needed.
This way it's very simple to add another permission (reset_password for example) to your setup, without the need to modify the db schema.
In the shiro.ini (or how you call the your shiro config file):
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
For the queries use then this:
jdbcRealm.authenticationQuery = select password from user where email=?
jdbcRealm.userRolesQuery = select id from user where email=?
jdbcRealm.authenticationQuery = select permissionname from permission where user_fk=?
The small trick in your setup is: you don't have roles at all, so we just return the id of the user as the role name.
When the lookup in the permission table is done, it then uses the role name (=user pk) and returns the associated permissions.
You should configure a JdbcReam in your .ini file:
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
If you change your schema to adhere to the shiro queries, no extra config is needed. You need tables users, user_roles and roles_permissions.
See the source code how the exact column names should be:
https://svn.apache.org/repos/asf/shiro/trunk/core/src/main/java/org/apache/shiro/realm/jdbc/JdbcRealm.java
Alternatively you can configure your own queries to match your schema in the .ini file like so:
jdbcRealm.authenticationQuery=<your password select statement>
jdbcRealm.userRolesQuery=<your role names for username select statement>
jdbcRealm.authenticationQuery=<your permissions for role name select statement>
I create the database in Management Studio. Added a SQL authenticated user to the list of users for the DB.
I set up (granted) the permissions like so:
use DjangoDB;
grant select,insert,update,alter,delete,references to django;
select
a.*,
b.name
from sys.database_permissions a
inner join sys.database_principals b
on a.grantee_principal_id = b.principal_id
and b.name = 'django'
The output of this command is:
class class_desc major_id minor_id grantee_principal_id grantor_principal_id type permission_name state state_desc name
0 DATABASE 0 0 5 1 AL ALTER G GRANT django
0 DATABASE 0 0 5 1 CO CONNECT G GRANT django
0 DATABASE 0 0 5 1 DL DELETE G GRANT django
0 DATABASE 0 0 5 1 IN INSERT G GRANT django
0 DATABASE 0 0 5 1 RF REFERENCES G GRANT django
0 DATABASE 0 0 5 1 SL SELECT G GRANT django
0 DATABASE 0 0 5 1 UP UPDATE G GRANT django
So the user appears to have the permissions (especially select which it will later claim is not a permission this user has)
Then I run python manage.py syncdb
Syncing...
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
...
and I (sometimes) get an error like:
File "E:\python\cloudbox\.cloudbox\lib\site-packages\sqlserver_ado\dbapi.py", line 99, in standardErrorHandler
raise errorclass(errorvalue)
DatabaseError: (-2147352567, 'Exception occurred.', (0, u'Microsoft OLE DB Provider for SQL Server', u"User 'django' does not have permission to run DBCC checkconstraints for database 'DjangoDB'.", None, 0, -2147217900), None)
Command:
DBCC CHECKCONSTRAINTS
Parameters:
[]
When I look up this error, it says:
Requires membership in the sysadmin fixed server role or the db_owner fixed database role.
I can find a whole list of roles to put this user into, but none of them are sysadmin. Where is this role hidden?
If I immediately rerun syncdb without changing anything, I get a different error though:
sqlserver_ado.dbapi.DatabaseError: (-2147352567, 'Exception occurred.', (0, u'Microsoft OLE DB Provider for SQL Server', u"The SELECT permission was denied on the object 'django_content_type', database 'DjangoDB', schema 'dbo'.", None, 0, -2147217911), None)
Command:
SELECT [django_content_type].[id], [django_content_type].[name], [django_content_type].[app_label], [django_content_type].[model] FROM [django_content_type] WHERE ([django_content_type].[model] = ? AND [django_content_type].[app_label] = ? )
Parameters:
[Name: p0, Dir.: Input, Type: adBSTR, Size: 10, Value: "permission", Precision: 0, NumericScale: 0, Name: p1, Dir.: Input, Type: adBSTR, Size: 4, Value: "auth", Precision: 0, NumericScale: 0]
Now it says the user doesn't have the SELECT privilege? But above it shows it DOES have the select privilege?
Is there some magic to granting the select privilege?
So, now the plot thickens. I make the sql user 'django' OWN the database. Now, everything will work, everything creates, no errors, south migration works.....
But I don't want my webserver user being the "owner" of the db. I want it to be able to do things like select,insert,update,alter,delete,references. But it seems like I can't just give it a limited set of permissions so it can fulfill that role. This seems a lot like running XP as administrator, something that does NOT make sense.
What am I doing wrong on permissions? Why does the webserver db user have to OWN this db?
Some Answers:
1) sysadmin is a Server Role, and not a database role like db_owner. It is much more powerful than making your user the database owner, so you definitely do not want to give it out.
2) For reasons that are something of a mystery, object-access permissions effectively must be granted to both the database (DjangoDB) and the schema (dbo). You already did the database, now you have to do the same for the schema. Here is what these commands might be in T-SQL:
GRANT DELETE ON SCHEMA::[dbo] TO [django]
GRANT EXECUTE ON SCHEMA::[dbo] TO [django]
GRANT INSERT ON SCHEMA::[dbo] TO [django]
GRANT REFERENCES ON SCHEMA::[dbo] TO [django]
GRANT SELECT ON SCHEMA::[dbo] TO [django]
GRANT UPDATE ON SCHEMA::[dbo] TO [django]
GRANT VIEW DEFINITION ON SCHEMA::[dbo] TO [django]
3) As for DBCC, it is a very powerful utility command, consequently, it requires powerful permissions. You may be able to grant your user the db_owner role instead of making them the owner of the database, but really that's not much better. Ideally, either your syncdb should only be executed by an admin instead of your app's users, or you should make a stored procedure to do the DBCC authorizing the proc with EXECUTE As OWNER, then authorize the user to that stored proc (already done if they are authorized to the schema, as above), and finally have syncdb changed to call that procedure instead of doing the DBCC directly.
sysadm is a server role.
The second error is occurring against a database called Amegy
You should not use the same user for both deployments and running the application code. They are different roles with different permission requirements.
Django's syncdb command requires the ability to enable/disable constraints and is part of its database API.