Groups | Blog | Home
all groups > sql server programming > october 2006 >

sql server programming : Ownership of newly attached database when using sp_attach_db?


kenandcorey NO[at]SPAM gmail.com
10/30/2006 11:13:49 PM
I am confused about database ownership when using sp_attach_db. I want
to have a non-sysadmin user be able to attach and detach a database, as
well as be the owner of the database it attaches.

In SQL Server 2005, I've created a login called "Maint". I have given
this user a Server Role of "dbcreator". When I log in as Maint, I can
attach a database, and it shows "Maint" as being the owner of the
database. But when I go "USE Maint_db" it says Maint doesn't have
access:

Msg 916, Level 14, State 1, Line 1
The server principal "Maint" is not able to access the database
"Maint_DB" under the current security context.

Then I go to the Login Properties for the Maint login, and under user
mappings everything is blank. I expected to see Maint_DB have a user of
Maint with a Default Schema of dbo.

If I go to the Maint_DB properties, it does show Maint as the owner.

What am I missing? If I change the database owner to sa, and then back
to Maint, everything works as I would expect: Maint is the true owner
of the database and can access all objects in it.

Can anyone point me to what I am doing wrong? I would like to be able
to attach a database and set it's owner to Maint from a stored
procedure, while giving Maint only the minimal required access. I tried
running it as a sysadmin, and that sure made things work well. :)

Thank you in advance.

Ken
kenandcorey NO[at]SPAM gmail.com
10/31/2006 11:01:55 AM
Here's some more info. When creating a new database, it works fine.
The "Maint" login becomes the owner of the new database. Here is my
test script:

-------------------------
-- CREATE NEW DATABASE --
-------------------------
USE MASTER
GO

CREATE DATABASE Maint_DB ON PRIMARY
( NAME = N'Maint_DB_data', FILENAME = N'D:\Maint_DB.mdf' , SIZE =
2048KB , FILEGROWTH = 1024KB )
LOG ON
( NAME = N'Maint_DB_log', FILENAME = N'D:\Maint_DB.ldf' , SIZE = 2048KB
, FILEGROWTH = 10%)
GO

SELECT * FROM MAINT_DB.dbo.sysobjects
GO

DROP DATABASE Maint_DB
go



-------------------------


But when I try it when attaching an existing database, it fails. It
definitely has to do with the current user not properly becoming the
owner of the database. If I go in as a sysadmin and add "Maint" to be a
db_owner, everything then works. Here is my test script:

------------------------------
-- ATTACH EXISTING DATABASE --
------------------------------
USE MASTER
GO

CREATE DATABASE [Maint_DB] ON
( FILENAME = N'D:\ExistingDB.MDF' ),
( FILENAME = N'D:\ExistingDB.LDF' )
FOR ATTACH
GO

SELECT * FROM MAINT_DB.dbo.sysobjects
GO

------------------------

Any suggestions, other than "make Maint a sysadmin"?

Thanks.
Razvan Socol
11/1/2006 12:20:26 AM
[quoted text, click to view]

Hi, Ken

Try executing a:
use Maint_DB
exec sp_change_users_login 'Auto_Fix', 'Maint'

Razvan
kenandcorey NO[at]SPAM gmail.com
11/1/2006 11:11:55 AM
[quoted text, click to view]

Thank you for responding. I have tried that, but when logged in as
Maint3 I can't switch to the Maint_DB database. It gives me the error:

The server principal "Maint3" is not able to access the database
"Maint_DB" under the current security context.

I also tried it as SA, and it didn't help either.

Any other ideas?

Ken
Tibor Karaszi
11/2/2006 12:00:00 AM
Here's what I think is going on:

Each database has a users table, exposed as sys.database_principals. Here you can see the SID of the
owner of the database (dbo, see the sid column). Detach this on one instance, and you will have some
sid for a login on that instance.

Now, attach into another instance, and the size from above doesn't exist on the new instance. You
have an orphaned owner. Seen from the database perspective.

However, in master, there's a table for each database, exposed as sys.databases. There's a sid
stored here as well, owner_sid. When you attach, the information in sys.databases (in master) is set
to the login who attaches the database. But the information *inside* the database isn't set
accordingly. Hence the inconsistency in the SSMS dialogs.

If you now change the database owner (sp_change_dbowner), the sid *inside* the database is set
correctly.

So the solution seems to be to set the owner properly after attaching the database.

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/


[quoted text, click to view]
Razvan Socol
11/2/2006 5:48:54 AM
Hi, Ken

Try to execute this (under the sa login):

USE Maint_DB
EXEC sp_change_users_login 'update_one', 'Maint', 'Maint'

If it works, then the problem is probably related to the value for the
SID for the Maint login. The database probably originates from a
different server, where Maint had a different SID. Am I close ?

Razvan

[quoted text, click to view]
kenandcorey NO[at]SPAM gmail.com
11/2/2006 8:50:12 AM
Hi Razvan, Thank you for taking the time to reply. I did try what you
suggested, but it didn't work either. I will soon post a follow-up to
Tibor's reply, and it will explain what I think is happening. I think I
have a better understanding now with everyone's help.

Thanks agao.

Ken

[quoted text, click to view]
kenandcorey NO[at]SPAM gmail.com
11/2/2006 9:18:54 AM
Hello Tibor,

Thank you for taking the time to reply. Your suggestions helped me to
pin down what I think the problem is. The show-stopper is that to run
sp_change_dbowner you need to be able to switch to the database (USE
databasename). Unfortunately I can't do this when logged in as the
Maint user, as he doesn't even exist in the sys.database_principals
table for the Maint_DB database.

So to work around this, I plan on making sure the Maint user exists in
the Maint_DB database before I attach it. Then when I do attach it
using the Maint user, it WILL have proper access to the database.
Since I'll always be attaching it to the same database server, the SIDs
shouldn't get out of sync -- at least that is my understanding.

I plan to do the following:
- As a sysadmin
- Attach the database
- make Maint the owner
- Detach the database

Now, as the Maint user, whenever I attach the database I am already the
dbo and everything is good. My confusion was in the fact that the
login attaching the database does not automatically become the dbo
(which was my initial understanding). I'm sorry if this is confusing
-- we plan on attaching/detaching the database on a regular basis, but
we can prepare it initially.

Thanks everyone for your help.

Ken


On Nov 2, 3:01 am, "Tibor Karaszi"
[quoted text, click to view]
Tibor Karaszi
11/2/2006 7:17:33 PM
Your workaround seems to cut it, especially as this is in a controlled environment (you don't attach
this to just any SQL Server instance out there). Two things that might or might not be helpful:

Google for sp_help_revlogin. This generates a script of your existing logins so you can re-create a
login having the correct SID on the destination server.

CREATE LGOIN has a SID option where you can specify the SID for the login you are about to create.
(This feature is most probably what above routine is using in the end.)

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/


[quoted text, click to view]
AddThis Social Bookmark Button