Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / General / Security / February 2008

Tip: Looking for answers? Try searching our database.

Permission issue with EXECUTE AS

Thread view: 
Enable EMail Alerts  Start New Thread
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.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.