ストアドプロシージャの所有者がテーブルに対して選択、挿入、更新または削除する権限を持つ場合、ストアドプロシージャ内のステートメントの選択、挿入、更新、および削除は、呼び出し元がたとえ呼び出し元がテーブルに対して選択、挿入、更新または削除を直接実行する権限を持っていなくても、ストアドプロシージャを呼び出すことができます。
ただし、ストアドプロシージャの所有者にDDL権限があっても、呼び出し元にDDLを実行する権限がない限り、ストアドプロシージャはDDLを実行できません。これはtruncate tableにも適用されます。
回答:db_datareader
とdb_datawriter
をユーザに付与すると、すべてのテーブルですでに完全なDMLがユーザに与えられています。ストアドプロシージャに対してexecuteを実行しても、追加の権限は与えられません。
ストアドプロシージャを使用すると、すべての外部プログラムが通過するゲートを提供することによって、データの整合性を高めることができます。挿入、削除、または更新を許可しないで、作業を実行するSPを作成し、データに関する適切なルールを適用します。 Joe Kuemerle氏は、ストアドプロシージャを使用してセキュリティを強化することができると指摘しています。
SQL Server 2000でアプリケーションを開発しているときにこの現象が確認されていますが、これもSQL Server 2008で再テストされ、同じ動作が検出されました。私はこの動作に関する文書を見つけることができませんでした。
DBOとしてログインし、SAは、テーブルを作成します。
create table dbo.SO (PK int identity constraint SO_PK primary key
, SomeData varchar(1000)
)
そして、基本的なDMLのためのいくつかのストアドプロシージャを作成:
:DBOとして
create procedure dbo.InsertSO (@SomeData varchar(1000)) as
begin
insert into dbo.SO (SomeData) values (@SomeData)
return SCOPE_IDENTITY()
end
go
create procedure dbo.SelectSO (@PK int=null) as
begin
if @PK is not null
select PK, SomeData from dbo.SO where PK = @PK
else
select PK, SomeData from dbo.SO
end
go
create procedure dbo.CountSO as
begin
select COUNT(*) as CountSO from SO
end
go
create procedure dbo.DeleteSO (@PK int=null) as
begin
if @PK is not null
delete dbo.SO where PK = @PK
else
delete dbo.SO
end
go
create procedure dbo.UpdateSO (@PK int, @NewSomeData varchar(1000)) as
begin`
update dbo.SO
set SomeData = @NewSomeData
where PK = @PK
end
go
create procedure dbo.TruncateSO as
begin
truncate table dbo.SO
end
go
を、我々は次のSQL文を実行することができます
declare @PK_to_update int
insert into dbo.SO (SomeData) values ('Hello world!')
set @PK_to_update = SCOPE_IDENTITY()
declare @PK_to_delete int
insert into dbo.SO (SomeData) values ('Goodbye cruel world!')
set @PK_to_delete = SCOPE_IDENTITY()
insert into dbo.SO (SomeData) values ('Four score and seven years ago...')
select PK, SomeData
from dbo.SO
delete dbo.so
where PK = @PK_to_delete
update dbo.SO
set SomeData = 'Hello Milky Way!'
where PK = @PK_to_update
select PK, SomeData
from dbo.SO
truncate table dbo.SO
select COUNT(*) as CountSO from dbo.SO
または同等の処理をストアードプロシージャーを使用して実行します。
go
declare @PK_to_update int
exec @PK_to_update = dbo.InsertSO 'Hello world!'
declare @PK_to_delete int
exec @PK_to_delete = dbo.InsertSO 'Goodbye cruel world!'
exec dbo.InsertSO 'Four score and seven years ago...'
exec dbo.SelectSO
exec dbo.DeleteSO @PK_to_delete
exec dbo.UpdateSO @PK_to_update, 'Hello Milky Way!'
exec dbo.SelectSO
exec dbo.TruncateSO
exec dbo.CountSO
さて、DDLストアドプロシージャとテスト作成:
create procedure dbo.DropSO as
begin
drop table dbo.SO
end
go
begin transaction
select TABLE_NAME from INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'SO'
exec dbo.DropSO
select TABLE_NAME from INFORMATION_SCHEMA.TABLES
where TABLE_NAME = 'SO'
rollback transaction
をそして今、別のユーザーを作成し、すべてのストアドプロシージャの実行権限を付与します。他の権利を与えないでください。 (混合モード認証が推奨されていない。国民が余分な権利と混合モード認証を持っていないと仮定しますが、権利を簡単にどのように処理されるかテストします。)
exec sp_addlogin @loginame = 'SoLogin' , @passwd = 'notsecure', @defdb = 'Scratch'
exec sp_adduser @loginame = 'SoLogin', @name_in_db = 'SoUser'
go
grant execute on dbo.InsertSo to SoUser
grant execute on dbo.InsertSO to SoUser
grant execute on dbo.SelectSO to SoUser
grant execute on dbo.CountSO to SoUser
grant execute on dbo.DeleteSO to SoUser
grant execute on dbo.UpdateSO to SoUser
grant execute on dbo.TruncateSO to SoUser
grant execute on dbo.DropSO to SoUser
ログインをSoLoginように。 DMLをお試しください:
declare @PK_to_update int
insert into dbo.SO (SomeData) values ('Hello world!')
set @PK_to_update = SCOPE_IDENTITY()
declare @PK_to_delete int
insert into dbo.SO (SomeData) values ('Goodbye cruel world!')
set @PK_to_delete = SCOPE_IDENTITY()
insert into dbo.SO (SomeData) values ('Four score and seven years ago...')
select PK, SomeData
from dbo.SO
delete dbo.so
where PK = @PK_to_delete
update dbo.SO
set SomeData = 'Hello Milky Way!'
where PK = @PK_to_update
select PK, SomeData
from dbo.SO
truncate table dbo.SO
go
select COUNT(*) as CountSO from dbo.SO
go
drop table dbo.so
何もないが、エラー:
Msg 229, Level 14, State 5, Line 2
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 6
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 9
The INSERT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 11
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 14
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 14
The DELETE permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 17
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 17
The UPDATE permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 229, Level 14, State 5, Line 21
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 1088, Level 16, State 7, Line 24
Cannot find the object "SO" because it does not exist or you do not have permissions.
Msg 229, Level 14, State 5, Line 1
The SELECT permission was denied on the object 'SO', database 'Scratch', schema 'dbo'.
Msg 3701, Level 14, State 20, Line 2
Cannot drop the table 'SO', because it does not exist or you do not have permission.
基本的なDMLストアドプロシージャを試してみてください。
declare @PK_to_update int
exec @PK_to_update = dbo.InsertSO 'Hello world!'
declare @PK_to_delete int
exec @PK_to_delete = dbo.InsertSO 'Goodbye cruel world!'
exec dbo.InsertSO 'Four score and seven years ago...'
exec dbo.SelectSO
exec dbo.DeleteSO @PK_to_delete
exec dbo.UpdateSO @PK_to_update, 'Hello Milky Way!'
exec dbo.SelectSO
のSPの所有者が権利権利を持っているので、彼らは、仕事、 SoUserはしません。
切り捨てるか、ドロップストアドプロシージャ試してみてください。そして、私は明示的にユーザーのためのDROP TABLE権限を否定するならば、質問に概説された場合にそう
Msg 1088, Level 16, State 7, Procedure TruncateSO, Line 4
Cannot find the object "SO" because it does not exist or you do not have permissions.
Msg 3701, Level 14, State 20, Procedure DropSO, Line 4
Cannot drop the table 'SO', because it does not exist or you do not have permission.
これは(所有権連鎖)と呼ばれるSQL Server機能が原因で動作し続けます(動作し続ける)ためです。テーブルとspocの両方が同じ所有者(dbo)を持つため、SQLではオブジェクトの共通所有者がこれらのオブジェクトを変更できます。したがって、dboが所有するsprocは、追加のセキュリティチェックなしでテーブル(dboが所有する)を操作することができます。これについては、http://blogs.msdn.com/lcris/archive/2007/09/13/basic-sql-server-security-concepts-ownership-chaining-good-and-evil-schemas.aspxを参照してください。 –
@Joe:リンクをありがとう。それは有益だった。 「オブジェクトを変更するオブジェクトの共通の所有者...」と言えば、選択、挿入、削除、および更新ステートメントによるオブジェクト内のDATAの変更に限られます。オブジェクトは変更できません。オーナーシップチェーンでは、デフォルトでトランケートを実行することはできません。私はこれらの点について不明確な文書を見つけました。上記の例を提供することによって、呼び出し元に権利がない場合でもSP内で実行できることと実行できないことを明確にしようとしました。 –