MSSQL Permissions not making sense in MSSQL2008 - sql-server

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.

Related

SQL Server - You do not have permission to use the bulk load statement

Using SQL Server 2016, I am trying to configure a user other than 'SA' to import a file. The code I am executing is as follows:
EXECUTE AS USER = 'DataImports';
SELECT CURRENT_USER;
EXEC xp_cmdshell 'TYPE myFileNameHere.txt'
BULK INSERT DataImports.staging_AddressBook
FROM 'myFileNameHere.txt'
WITH (DATAFILETYPE = 'char'
, FIRSTROW = 2
, FIELDTERMINATOR = ' '
, ROWTERMINATOR = '\n');
The error that I get is:
Msg 4834, Level 16, State 1, Line 20
You do not have permission to use the bulk load statement.
I have validated the following:
I do have access to the file as the user required - The cmdshell TYPE returns the rows expected. I do not appear to have a file access issue.
I have INSERT permission on the database in general.
I tested by using:
SELECT
[DatabaseUserName] = princ.[name],
[PermissionType] = perm.[permission_name],
[PermissionState] = perm.[state_desc]
FROM
sys.database_principals princ
LEFT JOIN
sys.database_permissions perm ON perm.[grantee_principal_id] = princ.[principal_id]
WHERE
princ.[name] = 'DataImports';`
I do have the bulk admin role
SELECT
r.name AS [RoleName],
m.name AS [MemberName],
CASE
WHEN m.name IS NOT NULL THEN 1 ELSE 0
END AS IsMember
FROM
sys.server_principals r
LEFT JOIN
sys.server_role_members rm ON (r.principal_id = rm.role_principal_id)
LEFT JOIN
sys.server_principals m ON (rm.member_principal_id = m.principal_id)
WHERE
r.type = 'R' AND m.name = 'Dataimports';
I have even configured the user to be a sys-admin (not part of the long term plan) but I'm still getting the error.
These are the main points that have been highlighted in the other SO tickets and general searches I have performed. I can import the table as SA but not as DataImports despite what appears to be correct configuration.
This is part of a job that is being run and currently we are having to give SA access just to read a file. Security wise this is less than ideal but I cannot work out what is missing.
Any suggestions of what else to check would be gratefully received - all the basics seem to be in place.
Any suggestions
of what else to check would be gratefully received - all the basics
seem to be in place.
Few things:
GRANT ADMINISTER BULK OPERATIONS TO Dataimports
If the destination table contains triggers or checks constraints
GRANT ALTER ON TABLE DataImports.staging_AddressBook TO Dataimports
And
ALTER DATABASE [yourDB] SET TRUSTWORTHY ON;
Because of:
For security considerations, the server-scoped permissions are
stripped down when you impersonate a database user unless the system
administrator has explicitly set SQL Server to trust the impersonated
context at the server-scope. In this case, a login with the control
server server-scoped permission has no permissions to access any
particular database. Therefore, the trigger module that is executed as
this login cannot run.

How to access IBM DB2 warehouse on cloud as administrator

I'm currently using a free DB2 warehouse on cloud provided by IBM. What I'm trying to do is to create a new table in the database. However, an error message pops up saying that
To resolve this, I open the web console and run the following command: create tablespace mytablespace pagesize 4096. Then, another error message pops up:
Based on what I have googled, it looks like I need to grant administrator role for the user "DASH******". So I do this by adding an optional parameter to the credentials:
But it doesn't work. Is there any way to workaround this?
EDIT1: I create the table using the following command:
Users are not allowed to create their own tablespaces in free DB2WoC systems, since they don't have the SYSCTRL or SYSADM authorities there. You have to use existing tablespaces where you are allowed to create your tables.
Run the following statement from your DASH*** user.
This statement returns all the tablespaces, where your user is allowed to create tables.
If it doesn't return any rows, then this means, that you should open a ticket to the IBM support. Support should create it for you and grant your user the USE privilege on this tablespace.
SELECT
T.DATATYPE
--, P.PRIVILEGE
--, P.OBJECTTYPE
--, P.OBJECTSCHEMA
, P.OBJECTNAME
, U.AUTHID, U.AUTHIDTYPE
FROM SYSIBMADM.PRIVILEGES P
CROSS JOIN TABLE(VALUES USER) A (AUTHID)
JOIN TABLE (
SELECT GROUP, 'G' FROM table(AUTH_LIST_GROUPS_FOR_AUTHID(A.AUTHID))
UNION ALL
select ROLENAME, 'R' from table(AUTH_LIST_ROLES_FOR_AUTHID(A.AUTHID, 'U'))
UNION ALL
SELECT * FROM TABLE(VALUES ('PUBLIC', 'G'), (A.AUTHID, 'U')) T (AUTHID, AUTHIDTYPE)
) U (AUTHID, AUTHIDTYPE) ON U.AUTHID=P.AUTHID AND U.AUTHIDTYPE=P.AUTHIDTYPE
JOIN SYSCAT.TABLESPACES T ON T.TBSPACE=P.OBJECTNAME
WHERE P.OBJECTTYPE='TABLESPACE' AND T.DATATYPE IN ('A', 'L')

Postgres permission denied for relation <table>

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.

What's difference between sp_addrolemember and alter user with default schema...?

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.

How can we restrict the other user to change the record which has been entered by particular user in MDS

I have created Product entity in MDS.
It's having the following values:
Bike 1 ABC
Car 2 XYZ
Cycle 3 RRR
owner XYZ can change the record of RRR. But if owner XYZ or any other owner in this entity tried to update the ABC's record, access should be denied. That means, no one should have the permission to change the records which are entered by ABC.
for this I have executed following :
CREATE TRIGGER mdm.product_readonly
ON mdm.tbl_1034_1215_en
AFTER UPDATE, INSERT AS
If exists (system_user!='ABC')
and EXISTS (SELECT * FROM deleted a, inserted b, mdm.vw_product c
WHERE a.code=c.code
or b.code=c.code
And c.owner = 'ABC')
BEGIN
ROLLBACK TRANSACTION
RAISERROR ('Attempt to change a read-only row', 16, 1)
RETURN
END
After executing this, If I trying to update the record as ABC owner I can update all the records. If I try to update as other than ABC owner I couldnt update the ABC record. But from MDS I couldnt update any of the record. It showing like Database error.
How can we achieve this. Please help me out in this regard.
Thanks!
Please have a look on how to set permissions for MDS.
http://msdn.microsoft.com/en-us/library/hh231026.aspx
You can set permissions for users and/or groups.
I would recommend to assign permissions using AD groups as this is much easier to mantain on the long run.
If you need a more complex permission concept which is row based you can set permissions using derived hierarchies.
Permission settings are also stored in tables of MDSDB database. If you need to set permissions for many users I would recommend using code to copy permissiond. I can provide some snippets if needed.

Resources