I'm working with a legacy system that attempts to execute schema changes in SQL for specific users by first querying sysobjects as that user to determine if the object exists. If it does it creates an ALTER VIEW statement otherwise it creates a CREATE VIEW statement. In this case the view exists, but the query continues to fail to list the object.
For example:
setuser 'APPLICATION_DEV'
Select * from sysobjects o, sysusers u
where u.uid = o.uid
and u.name = N'APPLICATION_DEV'
The problem is that certain accounts in this database can run this query without error and it returns all of the objects owned by that user. Other accounts however get no records returned by this query. If I setuser to SA and run the query all of that users objects appear. The affected user is the owner of the schema and has create view permissions on the schema. I cannot find any differences in permissions between a working user and a non-working user account.
Is there a permission that I am missing that would restrict a user from querying their own objects in sysobjects?
Yes, I know sysobjects is obsolete, but I have no control over the actual code here and instead have to fix the database so their code will work as expected.
EDIT: Additional findings.
To complicate matters I can run this succesfully:
setuser 'APPLICATION_DEV'
Select * from sysusers
Where name = 'APPLICATION_DEV'
I can also execute this succesfully:
setuser 'APPLICATION_DEV'
Select * from sysobjects
Where uid = 308 --308 is the uid of the APPLICATION_DEV user
However, when I use a join either in the where clause or via INNER JOIN I then get no records. What would restrict my access to records purely based on the join? Index permissions?? I'm baffled.
For the particular user in user mapping check whether you have checked all the checkboxes apart from db_denydatareader and db_denydatawriter.
also check this
The SELECT permission was denied on the object 'sysobjects', database 'mssqlsystemresource', schema 'sys'
http://social.msdn.microsoft.com/Forums/en/sqlsecurity/thread/a2befd20-2a9b-4a60-95a9-3a80a1a99ea1
Related
I'm trying to figure out why a particular SQL Server database user that has db_datareader and db_datawriter membership, can't run a select statement that gets some check constraints on a particular table.
I run the select statement in my code, but it doesn't return any data. I thought maybe that in order to get constraint information, you might need different permissions. I've tried going out to look at some of the roles, and what they mean, but it's not clear what exactly the db_reader role can do.
string constraintCommand = #"SELECT tc.CONSTRAINT_NAME, CC.CHECK_CLAUSE
FROM[INFORMATION_SCHEMA].[CHECK_CONSTRAINTS as cc
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc ON cc.CONSTRAINT_NAME = tc.CONSTRAINT_NAME AND cc.CONSTRAINT_SCHEMA = tc.TABLE_SCHEMA
WHERE tc.TABLE_NAME = 'VideoSources'";
This is in C#. I run the SQL statement in SSMS as me (db_owner), and the SQL statement returns the data I need. I'm wondering if it's a permission problem of some sort.
To run a stored procedure the role needs Execute permissions.
I believe that permission Grant or Deny overrides the role membership. You may have to specifically Grant Select permission in the table.
I am in the process of configuring database users for some new developers and I am running into some difficulties as I am reading lots of articles and it's not working out too well for me. I have tried various configurations manually and with T-SQL but I need a more efficient method.
My objective:
Some TSQL I can launch to give a database user the following permissions:
Grant permission to execute all Stored Procedures within the Database
Deny permission to View Definition of all of these stored procedures
Grant permission to SELECT, UPDATE, INSERT, DELETE from all tables within the database
Deny permission to View Definition of all of the tables in the database (I don't want them to view the data)
What I have tried:
I have achieved this manually but I have 200+ stored procedures and 100+ tables so I don't want to do it manually. From the T-SQL aspect I have managed to get the following to work:
USE database_name;
GRANT EXECUTE TO [security_account];
This works and allows the users to run the stored procedures but they cannot view the actual query code. I need the same logic for the tables as described above.
Thank you for your help.
I am not quite sure if this is a viable solution to your problem. But maybe it will get you at least closer to what you want. So, here is the setup I'd propose:
Do not grant anybody any permissions on any table.
Use stored procedures for DML.
Grant execute on all these stored procedures to public.
Setup one table in your database which lists all users which have access to your database including their login (suser_sname()) and their permissions (for example MayAlterTableUsers).
Implement into all stored procedures a check similar to this
if (
select isnull(MayAlterTableUsers, 0)
from tblUsers
where LoginName = suser_sname()
) > 0
begin
select N'Implementing the requested changes to tblUsers.'
end
else
begin
select N'You don''t have the required permission.'
end
Setup you views similar and grant select on all views to public
create view vShowAllUsers as
select *
from dbo.tblUsers
cross apply (
select MaySeeAllUsers
from dbo.tblUsers
where LoginName = suser_sname()
) as p
where p.MaySeeAllUsers = 1
In the end all views and all stored procedures will be publicly available but the handling of permission will be within each one of them. All permissions themselves will be within this table tblUsers. Since nobody has the possibility to alter this table tblUsers unless (of course) they are in this table with the appropriate permission, this DB setup is self-contained.
I'm trying to drop all the logins from SQL server except the default built-in SQL server logins but I'm unable to drop the <domain>\administrator account. It gives me following error:
Server principal '<domain>\administrator' has granted one or more
permission(s). Revoke the permission(s) before dropping the server
principal.
I tried checking the permission assigned to this user using this query :
Select *
from sys.server_permissions
where grantor_principal_id =
(Select principal_id
from sys.server_principals
where name = N'<domain>\administrator')
This query returns only one record corresponding to an end-point as below:
class class_desc major_id minor_id grantee_principal_id grantor_principal_id type permission_name state state_desc
105 ENDPOINT 65536 0 269 259 CO CONNECT G GRANT
But when I try to check the rights assigned to this user on all of the existing end-points, I find none have any kind of permissions for the user I'm trying to delete.
I'm not sure what is happening and where to look for to drop this user.
I was able to solve this issue. There were following issues which were not allowing me to drop the <Domain>\administrator login from SQL server:
Owner of ReportServer and ReportServerDB databases was <Domain>\administrator user
Owner of ConfigMgrEndPoint end-point was also <Domain>\administrator user.
I changed the ownership of all the above mentioned SQL objects. I made sa user as their new owner. Then I was successfully able to drop the <Domain>\administrator user. I also got following expert comment from one of my colleagues who was helping me with this issue :
Keeping [sa] as a default owner for most sql objects is a standard
practice. Making a domain user as owner of SQL objects can affect the
working later on if that user no longer exists or is disabled in the Active Directory at any point of time
to find out what are the permissions that are preventing the dropping of the login
I am using this script:
SELECT ##SERVERNAME,##SERVICENAME
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #GrantorName nvarchar(4000)
SET #GrantorName = 'xxx\the_login' /* Login in Question */
SELECT b.name as Grantor
, c.name as Grantee
, a.state_desc as PermissionState
, a.class_desc as PermissionClass
, a.type as PermissionType
, a.permission_name as PermissionName
, a.major_id as SecurableID
FROM sys.server_permissions a
JOIN sys.server_principals b
ON a.grantor_principal_id = b.principal_id
JOIN sys.server_principals c
ON a.grantee_principal_id = c.principal_id
WHERE grantor_principal_id =
(
SELECT principal_id
FROM sys.server_principals
WHERE name = #GrantorName
)
and sometimes this one:
--Check to see if they own the endpoint itself:
SELECT SUSER_NAME(principal_id) AS endpoint_owner ,name AS endpoint_name
FROM sys.database_mirroring_endpoints;
--If so, you'll need to change the endpoint owner. Say the endpoint is called Mirroring, and you want to change the owner to SA:
--ALTER AUTHORIZATION ON ENDPOINT::Mirroring TO sa;
or following these instrustions:
--1) Check to see if this logon only has server level permissions and check to see
--if this login has granted permissions to another server principal.
--Use this query to identify the permissions granted.
Select perm.* from sys.server_permissions perm
INNER JOIN sys.server_principals prin ON perm.grantor_principal_id = prin.principal_id
where prin.name = 'xxx\the_login' /* Login in Question */
--2) The permissions granted will need to be revoked , to allow the DROP LOGIN to complete.
--The permissions can be granted again by a suitable LOGIN.
there is also a very nice article related to this:
Drop Login issues for logins tied to SQL Server Availability Groups
You'll have to check for "server permissions" and "explicit permissions".
I'm trying to create a role to give a few users permission to create and alter views, procedures and tables.
I don't want these users to be able to select from/update/delete/alter etc. any table in the database, there are tables we want to keep control of - but they should have full permissions on any objects they create.
I've given the users permissions to create views etc. and that works fine, but they can't then select from views they then create. Is it possible to do this?
-- ADDED 25/july/2013
Example:
An example user Mike has specific permissions granted on a handful of tables. All Grant, no Deny.
No other database level permissions beyond "connect"
Plus is a member of public (not altered - no denys), plus 3 other roles we have set up
Role: Standard_Reader
Specific Select permissions on a number of tables. All Grant, no Deny.
No other database level permissions
Role: SensitiveDemographicsReader
Specific Select permissions on sensitive tables. All Grant, no Deny
Role: Analyst
No Specific securables
Database level permissions:
Create Function
Create Procedure
Create Table
Create View
This user can create a table or view, but once created, can't select from it.
Is it possible to set up SQL server so that whenever a user user creates a table or view they then have permissions to select from it (assuming they have permissions on underlying tables in view)
-- EDIT
After some investigation it has become apparent that for some reason in our database, ownership of objects is not acruing to their creators.
Found using this code
select so.name, su.name, so.crdate from sysobjects so join sysusers su on so.uid = su.uid
order by so.crdate
All owners, with a couple of exceptions are DBO.
I can't understand why ownership is not passing to the creators of objects. Any idea what could cause this?
Sounds like what you're using to deny them in the first place is overriding the default settings. Can you post more information on what permissions the users have?
Can't comment :(
I would comment but lack privileges; have you taken a look at MySQL table permissions? It's a rather good system.
you need to grant SELECT on the schema to user/group:
GRANT SELECT ON SCHEMA::dbo TO User/Group;
This join is
SELECT
s.id,
s.sector_abbr,
s.sector_desc,
l.id,
l.sector_id,
l.vendor_address_id
FROM sectors s
LEFT JOIN sector_vendor_address_link l
ON s.id = l.sector_id
is giving me this error
ERROR: ERROR: permission denied for relation sector_vendor_address_link
Using this id and password through razorSQL, I was able to do updates to these same tables, so I can't imagine it is a permissions problem. Perhaps I am wrong. Is my join just malformed?
Thanks!
EDIT:
It seems that I must manually set All privileges for each table. Is there any way using phpPgAdmin to globally set a users permission for the entire database?
Yes, you can set privs for newly created tables using ALTER DEFAULT PRIVILEGES.
For existing tables you must use GRANT to assign the desired rights. The ALL TABLES clause will be useful for that job.