SQL Server Forum / General / Security / February 2008
Permission issue with EXECUTE AS
|
|
Thread rating:  |
INTP56 - 12 Feb 2008 14:36 GMT I've been posting in Programming as initially I thought this was a code problem, but thought I would try here. I've included my script at the end.
Basically, when I run the script logged in as me, everything works as expected. However, when I run the script logged in as the machine account SQL Server runs under, I get an error. And the error moves depending on how I specify the logins. I'm looking for help trying to track this problem down, as the production server DBA's also create the databases under a machine account, then let me log in to create the objects.
TIA, Bob
--!01_SetupScript.SQL -- This is a test script when trying to figure out how to bulk insert files -- without giving users specific bulkadmin permissions -- This runs fine under my domain account, -- but fails when I run it under the machine domain account. -- SQL Server 2005 starts in. USE master; SET NOCOUNT ON; GO -- Drop existing database and login accounts IF EXISTS(SELECT * FROM sys.databases WHERE name = 'BulkCopyTest') DROP DATABASE BulkCopyTest; IF EXISTS(SELECT * FROM sys.server_principals WHERE name = 'BulkUser') DROP LOGIN BulkUser; IF EXISTS(SELECT * FROM sys.server_principals WHERE name = 'BulkAccount') DROP LOGIN BulkAccount; GO
CREATE LOGIN BulkUser WITH PASSWORD = 'bulk$1user'; CREATE LOGIN BulkAccount WITH PASSWORD = 'bulk$1account'; GRANT ADMINISTER BULK OPERATIONS TO BulkAccount; --REVOKE CONNECT SQL FROM BulkAccount; GO
CREATE DATABASE BulkCopyTest; ALTER DATABASE BulkCopyTest SET TRUSTWORTHY ON; GO
USE BulkCopyTest; -- If I don't use the FOR LOGIN clause, I get msg 33009 when I EXECUTE AS later IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE name = 'BulkUser') CREATE USER BulkUser FOR LOGIN BulkUser; IF NOT EXISTS(SELECT * FROM sys.database_principals WHERE name = 'BulkAccount') CREATE USER BulkAccount FOR LOGIN BulkAccount; GO
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'vContext') DROP VIEW dbo.vContext; GO CREATE VIEW dbo.vContext AS SELECT GETDATE() AS CurrentTime ,ORIGINAL_LOGIN() AS OriginalLogin ,SUSER_SNAME() AS SUserSName ,SYSTEM_USER AS SystemUser ,USER_NAME() AS UserName ,SESSION_USER AS SessionUser ,CURRENT_USER AS CurrentUser; GO GRANT SELECT ON dbo.vContext TO public; GO
IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'BulkTable') BEGIN CREATE TABLE dbo.BulkTable (RowNum INT IDENTITY(1,1) PRIMARY KEY ,DT DATETIME DEFAULT (GETDATE()) ,H1 VARCHAR(36) ,H2 VARCHAR(36) ); GRANT INSERT ON dbo.BulkTable TO BulkAccount; --Not sure I need this, considering ownership chaining. END; GO
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_NAME = 'vBulkTable') DROP VIEW dbo.vBulkTable; GO CREATE VIEW dbo.vBulkTable AS SELECT H1,H2 FROM dbo.BulkTable; GO GRANT INSERT ON dbo.vBulkTable TO BulkAccount; GO
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE' AND ROUTINE_NAME = 'BulkInsertTest') DROP PROCEDURE dbo.BulkInsertTest; GO
CREATE PROCEDURE dbo.BulkInsertTest (@UNCFilePath AS VARCHAR(256) ,@FirstRow AS INT = 2 ,@ErrorString VARCHAR(4000) = '' OUTPUT ) WITH EXECUTE AS 'BulkAccount' AS DECLARE @SQL VARCHAR(4000); BEGIN SET @SQL = 'BULK INSERT dbo.vBulkTable FROM '; SET @SQL = @SQL + CHAR(39) + @UNCFilePath + CHAR(39); SET @SQL = @SQL + ' WITH (TABLOCK,FirstRow=' + CAST(@FirstRow AS VARCHAR) + ')'; SELECT *,@SQL AS SQLStatement FROM dbo.vContext; EXEC(@SQL); END; GO GRANT EXECUTE ON dbo.BulkInsertTest TO public; GO
--Get msg 33009 here if not using FOR LOGIN clause when creating users EXECUTE AS LOGIN = 'BulkUser';
SELECT * FROM dbo.vContext; DECLARE @strError AS VARCHAR(4000);
--Get msg 33009 here if using FOR LOGIN clause when creating users EXEC dbo.BulkInsertTest @UNCFilePath = 'H:\SQLServerBulkInsertTest\ServiceBrokerBulkFile.txt' ,@FirstRow = 2 ,@ErrorString = @strError OUTPUT; --Actual Message --Msg 33009, Level 16, State 2, Procedure BulkInsertTest, Line 0 --The database owner SID recorded in the master database differs from the database owner SID recorded in database 'BulkCopyTest'. You should correct this situation by resetting the owner of database 'BulkCopyTest' using the ALTER AUTHORIZATION statement.
IF LEN(ISNULL(@strError,'')) > 0 SELECT @strError AS ErrorString; REVERT; SELECT * FROM dbo.vContext; SELECT * FROM dbo.BulkTable; GO
-- Clean Up USE master; IF EXISTS(SELECT * FROM sys.databases WHERE name = 'BulkCopyTest') DROP DATABASE BulkCopyTest; IF EXISTS(SELECT * FROM sys.server_principals WHERE name = 'BulkUser') DROP LOGIN BulkUser; IF EXISTS(SELECT * FROM sys.server_principals WHERE name = 'BulkAccount') DROP LOGIN BulkAccount; GO
Erland Sommarskog - 12 Feb 2008 23:18 GMT > I've been posting in Programming as initially I thought this was a code > problem, but thought I would try here. I've included my script at the end. [quoted text clipped - 6 lines] > databases under a machine account, then let me log in to create the > objects. There is something fishy going on here. It seems that the domain account does not have CONTROL SERVER permission, but then again it create databases and logins and grant permissions, so it does have a good set of permissions anyway.
Do this: find a database which is not owned by the domain account and do USE on that database, and then run "SELECT USER". If it says "dbo", you are sysadmin after all.
But even if you are not sysadmin (that is, have CREATE SERVER), I don't see why you would have to specify FOR LOGIN. FOR LOGIN should simply not matter when username and login name are the same. And same goes for the strange error you get. Had the database been restored from a different server - but you have just created it.
Just to check: you have SP2 of SQL 2005, haven't you?
If you are able to nail exactly which server-level permissions your machine has, we might be able to repro it, and maybe then understand what is going on. Right now, I'm clueless.
 Signature Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
Books Online for SQL Server 2005 at http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx Books Online for SQL Server 2000 at http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
INTP56 - 14 Feb 2008 15:38 GMT I went to every database with the machine account and it showed up as dbo.
I have
Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
I can't see any difference from SQL Server's point of view between the machine account and mine (though I think the machine account has too many privs) other than they are different accounts. EXCEPT the domain admins know it's a machine account ... and maybe as such that domain account does not have some special priv that my account does have. That's my next step, see if I can talk to a domain admin and glean what I can from them.
Unfortunately, the DBA's here are really Oracle DBA's pressed into service as SQL Server DBA's and have not been able to help much on this particular issue.
I do appreciate your time and effort Erland.
At this point, this is a personal issue of mine, as I have developed similar functionality for why I was doing this in the first place via SSIS packages. However, it does bug me that I can't seem to resolve the issue. Or at least know why it's happening, even if it can't be resolved.
Bob
> > I've been posting in Programming as initially I thought this was a code > > problem, but thought I would try here. I've included my script at the end. [quoted text clipped - 27 lines] > machine has, we might be able to repro it, and maybe then understand > what is going on. Right now, I'm clueless. INTP56 - 14 Feb 2008 18:10 GMT It appears I have finally determined the difference.
After talking with the network guy, he noted that I was NOT a member of the group that has the sysadmin rights for that box, but my personal domain account had been explicitly given sysadmin rights to the box. Which he was irked at, because that is not supposed to happen, I should have been added to the admin group. However, the machine account was in that group.
But, that IS A DIFFERENCE, even though we have the same "rights" either way. So I found out what other accounts were given rights via the group, and tracked those guys down and ran my script under their accounts, and BAM, got the error. There was one other account that had been given explicit access (also shouldn't be) and my script ran without errors on that account. If it wasn't for the fact this box is a test server, and not under the network team's direct control, this situation would have never been allowed to exist.
At last I have resolution. And now I know I can't go down that path without jumping through more hoops, because company policy dictates not giving individuals explict rights, it's done via group membership.
Thanks again Erland, this one was driving me nuts.
Bob
> > I've been posting in Programming as initially I thought this was a code > > problem, but thought I would try here. I've included my script at the end. [quoted text clipped - 27 lines] > machine has, we might be able to repro it, and maybe then understand > what is going on. Right now, I'm clueless. Erland Sommarskog - 14 Feb 2008 22:28 GMT > It appears I have finally determined the difference. > [quoted text clipped - 13 lines] > not under the network team's direct control, this situation would have > never been allowed to exist. There is still something fishy here. I can't see any reason why it should not work on the other accounts. I think something is wacko here, but not having access to the box to see the misery, I cannot really tell what is going on.
 Signature Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se
Books Online for SQL Server 2005 at http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx Books Online for SQL Server 2000 at http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
INTP56 - 27 Feb 2008 16:10 GMT Erland, I think I was wrong before. While solving some other problems, I think I hit the real reason.
When I create databases under the machine account, the dbo user gets mapped to the sa login. When I create databases under my account, dbo gets mapped to me. I don't understand why, other than SQL Server was installed and runs under the machine account, so maybe it "knows" to substitute sa for the machine account.
So now, when I try to EXECUTE AS under my account, my current login matches the dbo login and everything is wonderful. But as the machine account, the current login doesn't exactly match the dbo login, which is why is wants me to ALTER AUTHORIZATION.
I posted another thread in programming asking about database ownership.
Thanks again, Bob
> > It appears I have finally determined the difference. > > [quoted text clipped - 18 lines] > but not having access to the box to see the misery, I cannot really tell > what is going on.
|
|
|