CREATE procedure sp_copydbsecurity
(
@SourceDB sysname=NULL,
@TargetDB sysname=NULL,
@mode varchar(10)=''
)
AS
SET NOCOUNT ON
if (@SourceDB is null) AND (@TargetDB is null)
begin
print 'You must specify either @SourceDB or @TargetDB'
return 0
end
if (@SourceDB is null)
Set @SourceDB = DB_NAME()
if (@TargetDB is null)
Set @TargetDB = DB_NAME()
if (@SourceDB = @TargetDB)
begin
print '@SourceDB and @TargetDB cannot be the same (you must pass
DEFAULT for any omitted parameter)'
return 0
end
declare @db sysname
declare @server sysname
declare @sql varchar(8000)
set @db = DB_NAME()
set @server = convert(sysname, SERVERPROPERTY('servername'))
Create Table #scriptbuf (
script varchar(7000) null,
[id] int IDENTITY(1,1) not NULL,
[sort] int not NULL
)
Set @sql = 'USE ' + @TargetDB + '
'
INSERT INTO #scriptbuf (script, sort) values(@sql, 0)
Create Table #sourceuserlist (
UserName sysname collate database_default Null
,GroupName sysname collate database_default Null
,LoginName sysname collate database_default Null
,DefDBName sysname collate database_default Null
,UID smallint Null
,SID varbinary(85) Null
)
Set @Sql = 'USE ' + @SourceDB + '
insert #sourceuserlist execute sp_helpuser
'
execute(@Sql)
Create Table #targetuserlist
(
UserName sysname collate database_default Null
,GroupName sysname collate database_default Null
,LoginName sysname collate database_default Null
,DefDBName sysname collate database_default Null
,UID smallint Null
,SID varbinary(85) Null
)
Set @Sql = 'USE ' + @TargetDB + '
insert #targetuserlist execute sp_helpuser
'
execute(@Sql)
CREATE TABLE #sourceperms (
[priv] sysname not null,
[schema] sysname not null,
[obj] sysname not null,
[user] sysname not null,
[AccessGrant] varchar(30) not null,
[action] int not null,
[protecttype] int not null,
[sysstat] int not null,
[id] int not null
)
Set @Sql = 'USE ' + @SourceDB + '
insert #sourceperms execute sp_resolveperms;2
'
execute(@Sql)
CREATE TABLE #targetperms (
[priv] sysname not null,
[schema] sysname not null,
[obj] sysname not null,
[user] sysname not null,
[AccessGrant] varchar(30) not null,
[action] int not null,
[protecttype] int not null,
[sysstat] int not null,
[id] int not null
)
Set @Sql = 'USE ' + @TargetDB + '
insert #targetperms execute sp_resolveperms;2
'
execute(@Sql)
CREATE TABLE #sourceroles (
[RoleName] sysname not null,
[RoleId] int not null,
[IsAppRole] int not null
)
Set @Sql = 'USE ' + @SourceDB + '
insert #sourceroles execute sp_helprole
'
execute(@Sql)
CREATE TABLE #targetroles (
[RoleName] sysname not null,
[RoleId] int not null,
[IsAppRole] int not null
)
Set @Sql = 'USE ' + @TargetDB + '
insert #targetroles execute sp_helprole
'
execute(@Sql)
CREATE TABLE #sourcerolemembers (
[DBRole] sysname not null,
[MemberName] sysname not null,
[MemberSID] sysname not null
)
-- for reasons unknown, sp_helprolemember does not return
-- members of user-defined db roles, even though the SQL
-- statement below was copied directly from it
Set @Sql = 'USE ' + @SourceDB + '
insert #sourcerolemembers
select DbRole = g.name, MemberName = u.name, MemberSID = u.sid
from sysusers u, sysusers g, sysmembers m
where g.uid = m.groupuid
and g.issqlrole = 1
and u.uid = m.memberuid
order by 1, 2
'
execute(@Sql)
CREATE TABLE #targetrolemembers (
[DBRole] sysname not null,
[MemberName] sysname not null,
[MemberSID] sysname not null
)
Set @Sql = 'USE ' + @TargetDB + '
insert #targetrolemembers
select DbRole = g.name, MemberName = u.name, MemberSID = u.sid
from sysusers u, sysusers g, sysmembers m
where g.uid = m.groupuid
and g.issqlrole = 1
and u.uid = m.memberuid
order by 1, 2
'
-- execute sp_helprolemember
execute(@Sql)
INSERT INTO #scriptbuf (script, sort)
SELECT 'if not exists (select * from master.dbo.syslogins where
loginname = N''' + UserName + ''')
exec sp_addlogin N''' + UserName + '''
', 1
FROM #sourceuserlist WHERE UserName NOT LIKE '%\%'
INSERT INTO #scriptbuf (script, sort)
SELECT 'if not exists (select * from master.dbo.syslogins where
loginname = N''' + UserName + ''')
exec sp_grantlogin N''' + UserName + '''
', 2
FROM #sourceuserlist WHERE UserName LIKE '%\%'
INSERT INTO #scriptbuf (script, sort)
SELECT 'exec sp_grantdbaccess N''' + UserName + ''' , N''' +
UserName + '''
', 3
FROM #sourceuserlist WHERE UserName NOT IN (SELECT UserName FROM
#targetuserlist)
INSERT INTO #scriptbuf (script, sort)
SELECT 'exec sp_addrole N''' + s.RoleName + '''
', 4
FROM #sourceroles s LEFT OUTER JOIN #targetroles t
ON s.RoleName = t.RoleName
WHERE t.RoleName is null
INSERT INTO #scriptbuf (script, sort)
SELECT 'exec sp_addrolemember ''' + s.dbrole + ''', ''' +
s.membername + '''
', 5
FROM #sourcerolemembers s LEFT OUTER JOIN #targetrolemembers t
ON s.dbrole = t.dbrole and s.membername = t.membername
WHERE t.dbrole is null
INSERT INTO #scriptbuf (script, sort)
SELECT 'if exists (select * from sysobjects where [name] = N''' +
[obj] + ''')
GRANT ' + [priv] + ' ON [' + [schema] + '].[' + [obj] + ']
TO [' + [user] + ']
', 6
FROM #sourceperms WHERE (obj NOT LIKE 'dt_%') AND (obj NOT LIKE 'sys%')
if @mode <> 'execute'
begin
print '-- generating script only, not executing'
select top 100 percent script FROM (select distinct script, sort
from #scriptbuf) drs order by [sort]
end
else
begin
select top 100 percent script FROM (select distinct script, sort
from #scriptbuf) drs order by [sort]
set @sql = 'select top 100 percent script FROM (select distinct
script, sort from #scriptbuf) drs order by [sort]'
exec master..xp_execresultset @sql, @Targetdb
end
DROP TABLE #scriptbuf
DROP TABLE #sourceuserlist
DROP TABLE #targetuserlist
DROP TABLE #sourceperms
DROP TABLE #targetperms
DROP TABLE #sourceroles
DROP TABLE #targetroles
DROP TABLE #sourcerolemembers
DROP TABLE #targetrolemembers
Comments
There are no comments yet. Be the first to comment!