Here's the situation. I'm writing an automated test that walks the list of dependencies for a proc and determines if an acct has rights for all of the dependent objects.
My code looks like this:
exec sp_depends 'the_proc_name'
-- run this query on the results of sp_depends:
select
case
when exists (
select *
from sys.database_permissions dp
where grantee_principal_id=USER_ID('TheAccount')
and major_id=object_id('dbo.theDependentObject')
and minor_id=0
and state_desc = 'GRANT')
then 'true'
else 'false'
end;
It all seems to be working fine, but there's a hiccup when it encounters a function. I have one case where TheAccount doesn't have rights to a function (the query above returns false). However the proc that calls the function in question runs fine when running under TheAccount. So there's either something wrong with my test code or functions have special permission behavior in SQL-Server that I'm not aware of.
Should I change the code to only search for 'DENY' instead of 'GRANT'? Do functions that are called in procs inherit the permissions of the calling proc except when the execute rights are explicitly denied? Does my code suck?
When you are running static SQL from a stored proc, the stored proc runs with the authority of the id that last created/modified the stored proc; not the id of the person running the stored proc.
For example, this is the same ability that allows you to use a stored proc to run an Insert statement without giving the person running the stored proc Insert Authority on the underlying table.
One note - this does not apply when you are using dynamic SQL (with the exec statement). In that case, the person running the stored proc, must have the necessary authority for that SQL statement.
So I'm not sure if your unit tests will provide you what you are looking for since the rights to dependent objects are taken care of, to some extent, by the way SQL Server handles Stored Proc security.
Related
I'm not sure if this is possible but if so, my scenario would be about as simple as they come. Assuming I have 6 stored procedures called:
dbo.SyncSources
dbo.SyncData
dbo.UpdateStatistics
dbo.TruncateSourceTable
dbo.ValidateData
dbo.SearchData
None of them require any variables to be input, they simply need to be executed in the order in which they appear above. Can I create one stored procedure that will run all of them, sequentially? Keep in mind that some of the middle ones in that list take several hours to run. Also, this is on an Azure Cloud database, so SQL Server Agent is unfortunately not an option.
You can try this
create procedure OneProcedureTorunThemAll
as
begin tran
exec dbo.SyncSources
exec dbo.SyncData
exec ...
commit
it could be nice to catch errors, verify return values, etc.
I have a stored procedure that has boolean result parameter as output. But my project needs to use 3 databases. Basically, there is a main database and 2 others. The other databases using same stored procedure but they just depend on params. If I explain the scenario, you will understand. Firstly, Sorry for bad explaining.
This application using main database for session management, user configurations and so on. This is okay. The problem is same user has to use 2 different databases for creating invoices. We can pretend that these users are IT support staff. They works for 2 different companies and supporting their products and they are managing their solutions in different databases.
User
Main Database
A Company Data
B Company Data
Users have to create their invoices for each company's customers. Basically they are using same database but the name of databases are totally different. Maybe my problem has easier solution so I want to ask that How can I use Dynamic Database Name in my Stored Procedure? and my current question is I'm initialising Stored Procedure as String and after that I execute the stored procedure as String.
Procedure has no error, also says me completed successfully but there is no insert (in stored procedure). When I use the sql command (which I set manually as String) in Management Studio, Query is running perfectly.
As a summary,
I have 3 databases, Main database need to execute generating Invoice stored procedure. But database names are must be dynamic because of different companies.
When I send the database name A_COMPANY_DB, stored procedure should execute in A_COMPANY_DB. When I send B_COMPANY_DB, stored procedure should execute B_COMPANY_DB.
Both of A_COMPANY and B_COMPANY databases are same. I have to manage sql query as String because of Dynamic Database Name. So I can't reach the output parameter.
My stored procedure has only one output parameter which is bit type. But I can't use it like:
Set #dynsql = 'USE ' + QUOTENAME(#DbName) + ' exec.[dbo].[spName] ' + other params
EXECUTE sp_executesql #dynsql
In this situation I couldn't reach Output parameter. How can I set or use my Output parameter in this stored procedure?
EXECUTE sp_executesql #dynsql #outputparam OUT
Is it possible or any solution?
Sorry for bad explaining.
I have a stored procedure where I'd like to save the execution of an update statement for further down in the procedure, which I'm doing by putting the sql into a varchar variable.
My problem is that the EXECUTE() seems to use the original caller's permissions and then gives an error, as the caller does not (and should not) have UPDATE permissions for table1.
Why doesn't it use the permissions of the stored procedure's owner?
And more importantly: how can I make it use those permissions?
The stored procedure looks basically like this: (except #tsql_string is set dynamically)
create procedure dbo.woopwoop() as
BEGIN
DECLARE #tsql_string varchar(max)
SET #tsql_string = 'UPDATE table1 set c1 = 1'
EXECUTE(#tsql_string)
END
I'm on SQL Server 2008, and the owner (me) of the stored procedure is a Windows Authentication user with domain\user.
Anyone?
That's what the EXECUTE AS clause exists for - to allow you to control this:
By specifying the context in which the module is executed, you can control which user account the Database Engine uses to validate permissions on objects that are referenced by the module.
CALLER
Specifies the statements inside the module are executed in the context of the caller of the module. The user executing the module must have appropriate permissions not only on the module itself, but also on any database objects that are referenced by the module.
CALLER is the default for all modules except queues
You would be wanting to specify that the stored procedure executes as OWNER (or possibly SELF, read the above page and decide which makes most sense for you) instead.
create procedure dbo.woopwoop()
with execute as owner
as
....
From MSDN (This example grants EXECUTE permission on the stored procedure HumanResources.uspUpdateEmployeeHireInfo to an application role named Recruiting11):
USE AdventureWorks2012;
GRANT EXECUTE ON OBJECT::HumanResources.uspUpdateEmployeeHireInfo
TO Recruiting11;
GO
Source
Of course you should have permission to grant the permission.
Is there any built in way, in SQL Server, to override an existing stored procedure for a single transaction?
Say I have a stored procedure
prc_GetValidUsers
#param1 int
...
INSERT INTO *
........prc_GetIdFromString param3
...
...
Is it possible for a single transaction, to redefine what prc_GetIdFromString to be something else? Or is it impossible to do this?
If you are using SQL Server 2005, or later, you could use a SYNONYM to point at the correct code at run time. This would require moving the existing code to an SP with a new name - so the SYNONYM could have the name of the original SP (so that everything that referenced the original SP would not need to be changed). You'd also create another SP that performed the reduced functionality that you want. The SYNONYM could then be pointed at the SP that you want to run.
I'm getting somewhat confused with SQL Server security
we have a login and a user: test
we have a table: dbo.tblSessionFilter
User test has no select and no delete permission on this table (I tested this!!)
Then we have a procedure:
create procedure dbo.procFilter_Clear with execute as caller
as
delete from dbo.tblSessionfilter
where spid = ##SPID
User test has execute right on this procedure.
And now, user test can call this procedure and can delete entries from the table; although he has no direct delete access on the table, and the procedure is execute as caller !
How is that possible ?
Is it probably because procedure and table are in the same schema?
See Ownership Chains:
When multiple database objects access each other sequentially, the sequence is known as a chain. Although such chains do not independently exist, when SQL Server traverses the links in a chain, SQL Server evaluates permissions on the constituent objects differently than it would if it were accessing the objects separately.
and,
When an object is accessed through a chain, SQL Server first compares the owner of the object to the owner of the calling object. This is the previous link in the chain. If both objects have the same owner, permissions on the referenced object are not evaluated.
(My emphasis)