克隆SQL Server 用户及权限

​《克隆 SQL Server 登陆名及权限》《SQL Server 登陆账户权限克隆——sp_DBA_LoginClone 升级版》两文介绍了如何生成一个账户的创建脚本及权限赋予脚本,《SQL Server 登录账户权限异步同步》给出了登陆账户及权限克隆的一个应用。通过自动化管理,极大的减轻了DBA的负担,同时也降低了管理时间成本。接下来的脚本给出了数据库用户(包括包含用户)、数据库角色、应用角色的创建和权限赋予脚本的生成。

USE [master]
GO
/*
      功能:克隆数据库中用户、角色应用角色创建脚本及权限赋予脚本
      样例:生成用户Jack 的创建脚本、权限赋予脚本
      exec sp_DBA_userPermisionsClone test,Jack
     
      样例:按照用户Jack模型克隆用户Jack_new
      exec sp_DBA_userPermisionsClone test,Jack,Jack_new
     
      样例:按照包含用户Jack模型克隆包含用户Jack_new
      exec sp_DBA_userPermisionsClone @dbName=test,@userName=Jack,@newUserName=Jack_new,@pwd='Password'
     
      样例:生成数据库角色的创建脚本及权限赋脚本
      exec sp_DBA_userPermisionsClone @dbName=test,@userName=testRoleIntest
     
      样例:生成应用角色的创建脚本及权限赋予脚本
      exec sp_DBA_userPermisionsClone @dbName=test,@userName=AppRole
      用户类型type
            A = 应用程序角色
            C = 映射到证书的用户
            G = Windows 组
            K = 映射到非对称密钥的用户
            R = 数据库角色
            S = SQL 用户
            U = Windows 用户
     
     
      授权类型authentication_type
            适用于:SQL Server 2012 (11.x) 及更高版本。
            指示身份验证类型。下面是可能的值及其说明。
            0:无身份验证
            1:实例身份验证
            2:数据库身份验证
            3:Windows 身份验证
            对应的authentication_type_desc
            NONE : 0
            INSTANCE : 1
            DATABASE : 2
            WINDOWS : 3
 
      数据库对象包括如下:
      --0 = 数据库
      --1 = 对象或列
      --3 = 架构
      --4 = 数据库主体
      --5 = 程序集适用范围:SQL Server 2008通过SQL Server 2019。
      --6 = 类型
      --10 = XML 架构集合的适用范围:SQL Server 2008 到SQL Server 2019。
      --15 = 消息类型适用范围:SQL Server 2008通过SQL Server 2019。
      --16 = 服务约定适用范围:SQL Server 2008通过SQL Server 2019。
      --17 = 服务适用范围:SQL Server 2008通过SQL Server 2019。
      --18 = 远程服务绑定适用范围:SQL Server 2008通过SQL Server 2019。
      --19 = 的路由适用范围:SQL Server 2008通过SQL Server 2019。
      --23 = 全文目录适用范围:SQL Server 2008通过SQL Server 2019。
      --24 = 对称密钥适用范围:SQL Server 2008通过SQL Server 2019。
      --25 = 证书适用范围:SQL Server 2008通过SQL Server 2019。
      --26 = 非对称密钥适用范围:SQL Server 2008通过SQL Server 2019。
     
*/
CREATE PROC [dbo].[sp_DBA_userPermisionsClone]
      @dbName sysname
      ,@userName sysname
      ,@newUserName sysname=NULL
      ,@newLoginName sysname=NULL
      ,@pwd VARCHAR(25) =NULL
AS
BEGIN
     
      /*
            default_language_name   sysname    
            适用于:SQL Server 2012 (11.x) 及更高版本。
            指示此主体的默认语言。
           
            default_language_lcid   int  
            适用于:SQL Server 2012 (11.x) 及更高版本。
            指示此主体的默认LCID。
           
            allow_encrypted_value_modifications bit  
            适用于:SQL Server 2016 (13.x) 及更高版本、SQL 数据库。
            取消在大容量复制操作期间对服务器进行加密元数据检查。
            这样,用户便可以使用Always Encrypted、在表或数据库之间对数据进行大容量复制,而无需解密数据。默认为OFF。
      */
      SET NOCOUNT ON
      DECLARE @type char(1)
            ,@authType INT    --授权类型
            ,@sid varbinary(85)
            ,@default_language_lcid INT
            ,@allow_encrypted_value_modifications BIT
            ,@defSchemaName sysname
      DECLARE @versionNum AS INT    --SQL Server 的版本号
    SET @versionNum = SUBSTRING(@@VERSION, 22, 4)
    DECLARE @sql NVARCHAR(MAX)
    DECLARE @j INT= NULL
            --生成创建数据库用户脚本
      IF @versionNum >= 2012
      BEGIN
            SET @sql = N'select @i=1,@type=type
                  ,@authType=authentication_type,@sid=sid
                  ,@default_language_lcid=default_language_lcid
                  ,@defSchemaName=default_schema_name from '
                  + QUOTENAME(@dbName,']') + N'.sys.database_principals
                  where name=''' + @userName + ''''
            EXEC sp_executesql @sql
                  , N'@i int output
                        ,@type char(1) output
                        ,@authType int output
                        ,@sid varbinary(85) output
                        ,@default_language_lcid INT output
                        ,@defSchemaName sysname output'
                  ,@i = @j OUTPUT
                  ,@type=@type OUTPUT
                  ,@authType=@authType OUTPUT
                  ,@sid=@sid OUTPUT
                  ,@default_language_lcid=@default_language_lcid OUTPUT
                  ,@defSchemaName=@defSchemaName OUTPUT
      END
      ELSE IF @versionNum >= 2016
      BEGIN
            SET @sql = N'select @i=1,@type=type
                  ,@authType=authentication_type,@sid=sid
                  ,@default_language_lcid=default_language_lcid
                  ,@allow_encrypted_value_modifications=allow_encrypted_value_modifications
                  ,@defSchemaName=default_schema_name from '
                  + QUOTENAME(@dbName,']') + N'.sys.database_principals
                  where name=''' + @userName + ''''
            EXEC sp_executesql @sql
                  , N'@i int output
                        ,@type char(1) output
                        ,@authType int output
                        ,@sid varbinary(85) output
                        ,@default_language_lcid INT output
                        ,@allow_encrypted_value_modifications BIT output
                        ,@defSchemaName sysname output'
                  ,@i = @j OUTPUT
                  ,@type=@type OUTPUT
                  ,@authType=@authType OUTPUT
                  ,@sid=@sid OUTPUT
                  ,@default_language_lcid=@default_language_lcid OUTPUT
                  ,@allow_encrypted_value_modifications=@allow_encrypted_value_modifications OUTPUT
                  ,@defSchemaName=@defSchemaName OUTPUT
      END
    ELSE
    begin
            SET @sql = N'select @i=1,@type=type,@sid=sid
                  ,@defSchemaName=default_schema_name from '
                  + QUOTENAME(@dbName,']') + N'.sys.database_principals
                  where name=''' + @userName + ''''
            EXEC sp_executesql @sql
                  , N'@i int output
                        ,@type char(1) output
                        ,@sid varbinary(85) output
                        ,@defSchemaName sysname output'
                  ,@i = @j OUTPUT
                  ,@type=@type OUTPUT
                  ,@sid=@sid OUTPUT
                  ,@defSchemaName=@defSchemaName OUTPUT
      END
    IF ( @j IS NULL )   --数据库不存在用户
        BEGIN
            PRINT '数据库'+@dbName+ ' 中不存在用户'+@userName
            RETURN
        END
    IF ISNULL(@authType,0)=2 AND @pwd IS NULL AND @newUserName IS NOT NULL
    BEGIN
            PRINT '创建新包含用户'+@userName+ ' 需要密码'
        RETURN
    END
      IF @newUserName IS NULL
            SET @newUserName=@userName
      IF @newLoginName IS NULL AND ISNULL(@authType,0)<>2
            SET @newLoginName=@userName
      PRINT 'USE ' + QUOTENAME(@dbName,']')
    PRINT 'GO'
    DECLARE @allowEVMDesc VARCHAR(3)
    SELECT @allowEVMDesc=CASE @allow_encrypted_value_modifications WHEN 0 THEN 'OFF' WHEN 1 THEN 'ON' ELSE '' END
 
      IF ISNULL(@authType,0)=2      --包含用户
      BEGIN
            PRINT 'CREATE USER [' + @newUserName + '] WITH PASSWORD ='+''''+ISNULL(@pwd,'')+''''
                  +',DEFAULT_SCHEMA ='+QUOTENAME(@defSchemaName,']')
                  +CASE WHEN @default_language_lcid IS NULL THEN '' ELSE ',DEFAULT_LANGUAGE = '+CONVERT(VARCHAR(10),@default_language_lcid) END
                  +CASE WHEN @userName=@newUserName or @newUserName IS NULL THEN ',SID = '+CONVERT(VARCHAR(85),@sid,1) ELSE '' END
                  +CASE WHEN @allow_encrypted_value_modifications IS NOT NULL
                        THEN ',ALLOW_ENCRYPTED_VALUE_MODIFICATIONS = '+@allowEVMDesc ELSE '' END
            PRINT 'GO'
            --DEFAULT_SCHEMA = schema_name
              --  | DEFAULT_LANGUAGE = { NONE | lcid | language name | language alias }
              --  | SID = sid 
              --  | ALLOW_ENCRYPTED_VALUE_MODIFICATIONS = [ ON | OFF ]
      END  
      ELSE IF ISNULL(@authType,0)<>2 AND @type='S'
      begin
            PRINT 'CREATE USER [' + @newUserName + '] FOR LOGIN [' + @newLoginName + '] '
                  +'WITH DEFAULT_SCHEMA ='+QUOTENAME(@defSchemaName,']')
                  +CASE WHEN @allow_encrypted_value_modifications IS NOT NULL
                        THEN ',ALLOW_ENCRYPTED_VALUE_MODIFICATIONS = '+@allowEVMDesc ELSE '' END
            PRINT 'GO'
      END
      ELSE IF  @type IN('U','G')    --Windows/Windows 组用户
      BEGIN
            IF EXISTS (SELECT 1 FROM sys.server_principals
                        WHERE name=@UserName)
            BEGIN
                  PRINT 'CREATE USER [' + @newUserName + '] FOR LOGIN [' + @newLoginName + ']'
                        +'WITH DEFAULT_SCHEMA ='+QUOTENAME(@defSchemaName,']')
                        +CASE WHEN @allow_encrypted_value_modifications IS NOT NULL
                              THEN ',ALLOW_ENCRYPTED_VALUE_MODIFICATIONS = '+@allowEVMDesc ELSE '' END
                  PRINT 'GO'
            END
            ELSE
            BEGIN
                  PRINT 'CREATE USER [' + @newUserName + ']'
                        +'WITH DEFAULT_SCHEMA ='+QUOTENAME(@defSchemaName,']')
                        +CASE WHEN @default_language_lcid IS NULL THEN '' ELSE ',DEFAULT_LANGUAGE = '+CONVERT(VARCHAR(10),@default_language_lcid) END
                        +',SID = '+CONVERT(VARCHAR(85),@sid,1)
                        +CASE WHEN @allow_encrypted_value_modifications IS NOT NULL
                              THEN ',ALLOW_ENCRYPTED_VALUE_MODIFICATIONS = '+@allowEVMDesc ELSE '' END
                  PRINT 'GO'
            END
    END
    ELSE IF @type='C'
    BEGIN
            PRINT '--映射到证书的用户'
            PRINT 'CREATE USER '+QUOTENAME(@newUserName,'] ')+'FOR      CERTIFICATE '+''''''
            PRINT 'GO'
      END
      ELSE IF @type='K'
      BEGIN
            PRINT '--映射到非对称密钥的用户'
            PRINT 'CREATE USER '+ QUOTENAME(@newUserName,'] ')+'FROM ASYMMETRIC KEY '+ ''''''
            PRINT 'GO'
      END
      ELSE IF @type='R'
      BEGIN
            PRINT '--数据库角色克隆'
            PRINT 'CREATE ROLE '+ QUOTENAME(@newUserName,']')
      END
      ELSE IF @type='A'
      BEGIN
            PRINT '--应用角色克隆'
            PRINT 'CREATE APPLICATION ROLE '+ QUOTENAME(@newUserName,']')
                  +'WITH PASSWORD = '''+ISNULL(@pwd,'')+'''  , DEFAULT_SCHEMA = '+QUOTENAME(@defSchemaName,']')
      END
--赋予用户数据库权限
    IF OBJECT_ID('tempdb..#privileges', N'U') IS NOT NULL
        DROP TABLE #privileges
    CREATE TABLE #privileges
        (
         permission_name VARCHAR(100)
        ,[state] CHAR(1)
        )
    INSERT  INTO #privileges
            EXEC
                ( 'select p.permission_name,p.state from ['
                  + @dbName
                  + '].sys.database_permissions p left join ['
                  + @dbName
                  + '].sys.database_principals pp on p.grantee_principal_id=pp.principal_id where name='''
                  + @userName + ''' and class=0'
                )
--exec sp_helprotect null,@userName
    --SELECT  *
    --FROM    #privileges
    DECLARE @action VARCHAR(100)
    ,   @state CHAR(1)
    DECLARE actions CURSOR
    FOR
    SELECT  permission_name, [state]
    FROM    #privileges
    OPEN actions
    FETCH NEXT FROM actions INTO @action, @state
    WHILE @@FETCH_STATUS = 0
        BEGIN
            --PRINT 'USE ' + @dbName
            --PRINT 'GO'
            IF @state = 'G'
                BEGIN
                    PRINT 'GRANT ' + @action + ' to [' + @newUserName + ']'
                    PRINT 'GO'
                END
            IF @state = 'D'
                BEGIN
                    PRINT 'DENY ' + @action + ' to [' + @newUserName + ']'
                    PRINT 'GO'
                END
            IF @state = 'R'
                BEGIN
                    PRINT 'REVOKE ' + @action + ' to [' + @newUserName + ']'
                    PRINT 'GO'
                END
            IF @state = 'W'
                BEGIN
                    PRINT 'GRANT ' + @action + ' to [' + @newUserName + '] WITH GRANT OPTION'
                    PRINT 'GO'
                END
            FETCH NEXT FROM actions INTO @action, @state
        END
    CLOSE actions
    DEALLOCATE actions
  
    --增加用户角色
    IF OBJECT_ID('tempdb..#roles', N'U') IS NOT NULL
        DROP TABLE #roles
    CREATE TABLE #roles ( roleName VARCHAR(50) )
    INSERT  INTO #roles
    EXEC( 'select
            case when (r.principal_id is null) then ''public''  else r.name end  roles
            from [' + @dbName + '].sys.database_principals u
            left join [' + @dbName + '].sys.database_role_members m
            join [' + @dbName
        + '].sys.database_principals r on m.role_principal_id = r.principal_id on u.principal_id = m.member_principal_id
            left join [' + @dbName + '].sys.server_principals l on u.sid = l.sid
            where u.name = ''' + @userName + ''' and u.type <> ''R'''
                )
--exec sp_helpuser @userName
    DECLARE @role VARCHAR(100)
    DECLARE roles CURSOR
    FOR
    SELECT  roleName
    FROM    #roles
    OPEN roles
    FETCH NEXT FROM roles INTO @role
    WHILE @@FETCH_STATUS = 0
        BEGIN
            --PRINT 'USE ' + @dbName
            --PRINT 'GO'
            PRINT 'EXEC sp_addrolemember N''' + @role + ''',N''' + @newUserName + ''''
            PRINT 'GO'
            FETCH NEXT FROM roles INTO @role
        END
    CLOSE roles
    DEALLOCATE roles
  
    --克隆用户的对象权限
    IF OBJECT_ID('tempdb..#text') IS NOT NULL
            DROP TABLE #text
           
    CREATE TABLE #text( grantsql VARCHAR(max))
  
    --1 = 对象或列
    SET @sql=
      'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON OBJECT::''+QUOTENAME(s.name,''['')+''.''
            +quotename(o.name,''['')
            +CASE WHEN c.NAME IS NOT NULL THEN ''(''+QUOTENAME(c.name,''['')+'') ''
                  ELSE '''' END
            +'' TO ''
            +QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION'' ELSE '''' END
      FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
      +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
      +'ON dp.grantee_principal_id=ds.principal_id  '
      +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.objects o '
      +'ON dp.major_id=o.object_id '
      +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.schemas s '
      +'ON o.schema_id=s.schema_id '
      +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.columns c ON dp.minor_id=c.column_id '
      +'    AND dp.major_id=c.object_id '
      +'WHERE ds.name='''+@userName+''' AND class=1'
     
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
  
      --3 = 架构
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
                  ELSE ''GRANT '' END
                  +permission_name COLLATE Chinese_PRC_90_CI_AI
                  +'' ON SCHEMA::''
                  +QUOTENAME(s.name,''['')
                  +'' TO ''
                  +QUOTENAME('''+@newLoginName+''',''['')
                  +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION'' ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds ON dp.grantee_principal_id=ds.principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.schemas s ON dp.major_id=s.schema_id '
            +'WHERE class=3 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --4 = 数据库主体
      --[ USER :: database_user ]
      --     | [ ROLE :: database_role ]
      --     | [ APPLICATION ROLE :: application_role ]
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
                        ELSE ''GRANT '' END
                        +permission_name COLLATE Chinese_PRC_90_CI_AI
                        +CASE s.type WHEN ''U'' THEN ''  ON USER::''
                        WHEN ''R'' THEN  '' ON ROLE::''
                        WHEN ''A'' THEN '' ON APPLICATION ROLE::'' END
                        +QUOTENAME(s.name,''['')
                        +'' TO ''
                        +QUOTENAME('''+@newLoginName+''',''['')
                        +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                              ELSE '''' END
                  FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
                  +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals s ON dp.major_id=s.principal_id '
                  +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals d ON dp.grantee_principal_id=d.principal_id '
                  +'WHERE class=4 AND d.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --5 = 程序集适用范围:SQL Server 2008通过SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
                  ELSE ''GRANT '' END
                  +permission_name COLLATE Chinese_PRC_90_CI_AI
                  +'' ON ASSEMBLY::''
                  +QUOTENAME(ab.name,''['')
                  +'' TO ''
                  +QUOTENAME('''+@newLoginName+''',''['')
                  +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                        ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON dp.grantee_principal_id=ds.principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.assemblies ab '
            +'ON dp.major_id=ab.assembly_id '
            +'WHERE class=5 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --6 = 类型
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON TYPE::''
            +QUOTENAME(s.name,''['')+''.''
            +QUOTENAME(t.name,''['')
            +'' TO ''
            +QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON dp.grantee_principal_id=ds.principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.types t '
            +'ON dp.major_id=t.user_type_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.schemas s ON t.schema_id=s.schema_id '
            +'WHERE class=6 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --10 = XML 架构集合的适用范围:SQL Server 2008 到SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON XML SCHEMA COLLECTION::''
            +QUOTENAME(xmlsc.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.xml_schema_collections xmlsc '
            +'ON dp.major_id=xmlsc.xml_collection_id '
            +'WHERE class=10 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --15 = 消息类型适用范围:SQL Server 2008通过SQL Server 2019。
      --授予对Service Broker 消息类型的权限。
      --SELECT * FROM sys.service_message_types
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON message type::''
            +QUOTENAME(m.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.service_message_types m '
            +'ON dp.major_id=m.message_type_id '
            +'WHERE class=15 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --16 = 服务约定适用范围:SQL Server 2008通过SQL Server 2019。
      --SELECT * FROM sys.service_contracts
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON Contract::''
            +QUOTENAME(s.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.service_contracts s '
            +'ON dp.major_id=s.service_contract_id '
            +'WHERE class=16 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --17 = 服务适用范围:SQL Server 2008通过SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON Service::''
            +QUOTENAME(s.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.services s '
            +'ON dp.major_id=s.service_id '
            +'WHERE class=17 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --18 = 远程服务绑定适用范围:SQL Server 2008通过SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON REMOTE SERVICE BINDING::''
            +QUOTENAME(s.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.remote_service_bindings s '
            +'ON dp.major_id=s.remote_service_binding_id '
            +'WHERE class=18 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --19 = 的路由适用范围:SQL Server 2008通过SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON Route::''
            +QUOTENAME(r.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.routes r '
            +'ON dp.major_id=r.route_id '
            +'WHERE class=19 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --23 = 全文目录适用范围:SQL Server 2008通过SQL Server 2019。
      --SELECT * FROM sys.fulltext_catalogs
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON fulltext catalog::''
            +QUOTENAME(f.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.fulltext_catalogs  f '
            +'ON dp.major_id=f.fulltext_catalog_id '
            +'WHERE class=23 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --29 = 全文目录停止列表适用范围:SQL Server 2008通过SQL Server 2019。
      --SELECT * FROM sys.fulltext_stoplists
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON fulltext stoplist::''
            +QUOTENAME(f.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.fulltext_stoplists  f '
            +'ON dp.major_id=f.stoplist_id '
            +'WHERE class=29 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --24 = 对称密钥适用范围:SQL Server 2008通过SQL Server 2019。
      --SELECT * FROM sys.symmetric_keys
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON SYMMETRIC KEY::''
            +QUOTENAME(asy.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.symmetric_keys asy '
            +'ON dp.major_id=asy.symmetric_key_id '
            +'WHERE class=24 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --25 = 证书适用范围:SQL Server 2008通过SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON CERTIFICATE::''
            +QUOTENAME(c.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.certificates c '
            +'ON dp.major_id=c.certificate_id '
            +'WHERE class=25 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
     
      --26 = 非对称密钥适用范围:SQL Server 2008通过SQL Server 2019。
      SET @sql=
            'SELECT CASE state WHEN ''D'' THEN ''DENY ''
            ELSE ''GRANT '' END
            +permission_name COLLATE Chinese_PRC_90_CI_AI
            +'' ON ASYMMETRIC KEY::''
            +QUOTENAME(asy.name,''['')
            +'' TO ''+QUOTENAME('''+@newLoginName+''',''['')
            +CASE WHEN state=''W'' THEN '' WITH GRANT OPTION''
                  ELSE '''' END
            FROM '+QUOTENAME(@dbName,']')+'.'+'sys.database_permissions dp '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.database_principals ds '
            +'ON ds.principal_id=dp.grantee_principal_id '
            +'LEFT JOIN '+QUOTENAME(@dbName,']')+'.'+'sys.asymmetric_keys asy '
            +'ON dp.major_id=asy.asymmetric_key_id '
            +'WHERE class=26 AND ds.name='''+@userName+''''
      INSERT INTO #text ( grantsql )
      EXEC(@sql)
   
    DECLARE cur CURSOR
    FOR
    SELECT  *
    FROM    #text
    OPEN cur
    FETCH NEXT FROM cur INTO @sql
    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @sql
        FETCH NEXT FROM cur INTO @sql
    END
    CLOSE cur
    DEALLOCATE cur
    DROP TABLE #text
        --END    
END
GO
EXECUTE sys.sp_MS_marksystemobject 'sp_DBA_userPermisionsClone';
GO

sp_DBA_userPermisionsClone功能测试

为检验sp_DBA_userPermisionsClone的可用性,接下来打算创建测试环境,并对功能进行测试。

创建测试环境

--SQL  Server  2008 测试环境
-- 创建两个数据库
IF EXISTS(SELECT name FROM sys.databases WHERE name = 'test')
  DROP DATABASE test;
 
CREATE DATABASE test;
GO
IF EXISTS(SELECT name FROM sys.databases WHERE name = 'test1')
  DROP DATABASE test1;
 
CREATE DATABASE test1;
GO
--创建登陆帐户
USE master;
GO
IF EXISTS ( SELECT  *
            FROM    sys.server_principals
            WHERE   name = 'Jack' )
    DROP LOGIN [Jack];
CREATE LOGIN [Jack] WITH PASSWORD = 'dMkdj!d8@j',CHECK_EXPIRATION=OFF;
GO
-- 创建用户并赋予权限
USE test;
GO
CREATE USER [Jack] FROM LOGIN [Jack];
GO
CREATE USER [Jack1] WITHOUT LOGIN;
--创建数据库角色
CREATE ROLE [testRoleIntest]
--赋予角色执行存储过程权限
GRANT EXECUTE to [testRoleIntest]
--创建应用角色
CREATE APPLICATION ROLE [AppRole]WITH PASSWORD = 'dMkdj!d8@j'
GRANT CONTROL to [AppRole]
--添加角色成员
EXEC sp_addrolemember @rolename = 'db_securityadmin', @membername = 'Jack';
CREATE ROLE testRoleIntest;
GO
EXEC sp_addrolemember @rolename = 'testRoleIntest', @membername = 'Jack';
GO
USE [test]
GO
--0 = 数据库
GRANT ALTER ANY SCHEMA to [jack];
GRANT CREATE TABLE TO [Jack];
GRANT CREATE PROCEDURE TO [Jack] WITH GRANT OPTION;
GO
--1 = 对象或列
--创建表test
IF OBJECT_ID('dbo.test', 'U') IS NOT NULL
    DROP TABLE dbo.test;
CREATE TABLE dbo.test
    (
     a INT IDENTITY
    ,b VARCHAR(30)
    ,d DATETIME DEFAULT CURRENT_TIMESTAMP
    );
go
-- 赋予Jack用户查询test的a、d两列的权限
GRANT SELECT on object::dbo.test (a, d) to [Jack];
--拒绝Jack 用户对表test 的更新
DENY UPDATE on object::dbo.test to [Jack];
GO
--3 = 架构
--为Jack用户赋予对架构dbo的查询权限
GRANT SELECT ON SCHEMA::dbo TO [Jack];
--4 = 数据库主体
GRANT ALTER ON ROLE::testRoleIntest TO Jack
GRANT CONTROL ON APPLICATION ROLE::AppRole TO Jack
GRANT ALTER ON USER::Jack1 TO Jack
--5 = 程序集适用范围:SQL Server 2008通过SQL Server 2019。
GRANT REFERENCES ON ASSEMBLY::[Microsoft.SqlServer.Types] TO Jack
--6 = 类型
CREATE TYPE [dbo].[testType] FROM [bigint] NULL
GO
GRANT TAKE OWNERSHIP ON TYPE::dbo.testType TO Jack
--15 = 消息类型适用范围:SQL Server 2008通过SQL Server 2019。
ALTER DATABASE test SET ENABLE_BROKER;
USE test
CREATE MESSAGE TYPE [//Mytest/Sample/RequestMsg] VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [//Mytest/Sample/ReplyMsg] VALIDATION = WELL_FORMED_XML;
GRANT REFERENCES ON MESSAGE TYPE::[//Mytest/Sample/ReplyMsg] TO [Jack]
--16 = 服务约定适用范围:SQL Server 2008通过SQL Server 2019。
CREATE CONTRACT [//Mytest/Sample/MyContract] (
[//Mytest/Sample/RequestMsg] SENT BY INITIATOR,
[//Mytest/Sample/ReplyMsg] SENT BY TARGET);
GRANT ALTER ON CONTRACT::[//Mytest/Sample/MyContract] TO [Jack]
CREATE QUEUE InitQu;
 
 --17 = 服务适用范围:SQL Server 2008通过SQL Server 2019。
CREATE SERVICE [//Mytest/Sample/InitSvc] ON QUEUE InitQu;
DENY ALTER ON SERVICE::[//Mytest/Sample/InitSvc] TO [Jack]
GRANT VIEW DEFINITION ON SERVICE::[//Mytest/Sample/InitSvc] TO [Jack]
--19 = 的路由适用范围:SQL Server 2008通过SQL Server 2019。
CREATE ROUTE ExpenseRoute WITH SERVICE_NAME=  '//Mytest/Sample/InitSvc', ADDRESS='tcp://www.sqlserver.com:1234';
DENY VIEW DEFINITION ON ROUTE::ExpenseRoute TO [Jack]
GRANT ALTER ON  ROUTE::ExpenseRoute TO [Jack]
--23 = 全文目录适用范围:SQL Server 2008通过SQL Server 2019。
CREATE FULLTEXT CATALOG ftCat AS DEFAULT;
CREATE FULLTEXT STOPLIST mystopList;
GRANT ALTER ON FULLTEXT CATALOG::ftcat TO [Jack]
Deny view definition on fulltext Stoplist::myStopList to [Jack]
GRANT ALTER ON FULLTEXT Stoplist::myStopList to [Jack]
go
USE test1;
GO
CREATE USER [Jack] FROM LOGIN [Jack];
GO
GRANT IMPERSONATE ON USER::dbo TO [Jack];
GO
--1 = 对象或列
CREATE PROCEDURE dbo.SimpleProc
AS
BEGIN
  SET NOCOUNT ON;
  SELECT 'test Procedure';
END;
GO
GRANT EXECUTE ON dbo.SimpleProc TO [Jack];
DENY VIEW DEFINITION ON dbo.SimpleProc TO [Jack];
GO
Use test1
go
--10 = XML 架构集合的适用范围:SQL Server 2008 到SQL Server 2019。
CREATE XML SCHEMA COLLECTION [http://Samples/SQL/ServiceBroker/msgOperationSchema] AS
N'<?xml version="1.0" encoding="UTF-16"?>
<xsd:schema targetNamespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" 
   xmlns          ="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions" 
   elementFormDefault="qualified" 
   attributeFormDefault="unqualified"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
 
    <xsd:complexType name="StepType" mixed="true" >
        <xsd:choice  minOccurs="0" maxOccurs="unbounded" > 
            <xsd:element name="tool" type="xsd:string" />
            <xsd:element name="material" type="xsd:string" />
            <xsd:element name="blueprint" type="xsd:string" />
            <xsd:element name="specs" type="xsd:string" />
            <xsd:element name="diag" type="xsd:string" />
        </xsd:choice> 
    </xsd:complexType>
 
    <xsd:element  name="root">
        <xsd:complexType mixed="true">
            <xsd:sequence>
                <xsd:element name="Location" minOccurs="1" maxOccurs="unbounded">
                    <xsd:complexType mixed="true">
                        <xsd:sequence>
                            <xsd:element name="step" type="StepType" minOccurs="1" maxOccurs="unbounded" />
                        </xsd:sequence>
                        <xsd:attribute name="LocationID" type="xsd:integer" use="required"/>
                        <xsd:attribute name="SetupHours" type="xsd:decimal" use="optional"/>
                        <xsd:attribute name="MachineHours" type="xsd:decimal" use="optional"/>
                        <xsd:attribute name="LaborHours" type="xsd:decimal" use="optional"/>
                        <xsd:attribute name="LotSize" type="xsd:decimal" use="optional"/>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>' ;
GO
GRANT ALTER ON XML SCHEMA COLLECTION::dbo.[http://Samples/SQL/ServiceBroker/msgOperationSchema] TO [Jack];
DENY TAKE OWNERSHIP ON XML SCHEMA COLLECTION::dbo.[http://Samples/SQL/ServiceBroker/msgOperationSchema] TO [Jack];
 
GO
USE test1
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'S0m3Str0ng!!P4ssw0rd@';
--26 = 非对称密钥适用范围:SQL Server 2008通过SQL Server 2019。
CREATE ASYMMETRIC KEY ASymKey WITH ALGORITHM = RSA_2048;
GRANT CONTROL ON ASYMMETRIC KEY::ASymKey TO [Jack];
--24 = 对称密钥适用范围:SQL Server 2008通过SQL Server 2019。
CREATE SYMMETRIC KEY SymKey1 WITH ALGORITHM = AES_256
ENCRYPTION BY ASYMMETRIC KEY ASymKey;
CREATE SYMMETRIC KEY SymKey2 WITH ALGORITHM = AES_256
ENCRYPTION BY CERTIFICATE testCert;
GO
GRANT CONTROL ON SYMMETRIC KEY::SymKey1 TO [Jack];
GRANT CONTROL ON SYMMETRIC KEY::SymKey2 TO [Jack];
--25 = 证书适用范围:SQL Server 2008通过SQL Server 2019。
CREATE CERTIFICATE testCert
WITH SUBJECT = 'A test Cert to Show Permission Cloning';
GRANT VIEW DEFINITION ON CERTIFICATE::testCert TO [Jack];
--18 = 远程服务绑定适用范围:SQL Server 2008通过SQL Server 2019。
--定义消息类型
CREATE MESSAGE TYPE [http://Samples/SQL/ServiceBroker/msgOperation]
VALIDATION = VALID_XML WITH SCHEMA COLLECTION
[http://Samples/SQL/ServiceBroker/msgOperationSchema];
--定义消息契约 
CREATE CONTRACT [http://Samples/SQL/ServiceBroker/msgOperationContract]
(
[http://Samples/SQL/ServiceBroker/msgOperation]
SENT BY INITIATOR
);
--初始方
--定义队列
CREATE QUEUE msgOperationInitQueue
WITH
STATUS = ON,
RETENTION = OFF
GO
--定义初始服务
CREATE SERVICE [http://Samples/SQL/ServiceBroker/msgOperationInitService]
ON QUEUE msgOperationInitQueue
([http://Samples/SQL/ServiceBroker/msgOperationContract]);
GO
--定义初始存储过程
CREATE PROCEDURE dbo.usp_msgOperation_SET
@msgId int,
@msgContent nvarchar(2000)
AS
declare @message_body as xml([http://Samples/SQL/ServiceBroker/msgOperationSchema]);
declare @dialog as uniqueidentifier;
--填充消息体
SET @message_body =''+cast(@msgId as varchar)+''+@msgContent+'';
BEGIN DIALOG @dialog
FROM SERVICE [http://Samples/SQL/ServiceBroker/msgOperationInitService]
TO SERVICE 'http://Samples/SQL/ServiceBroker/msgOperationProcessService'
ON CONTRACT [http://Samples/SQL/ServiceBroker/msgOperationContract];
--WITH ENCRYPTION = OFF , LIFETIME = 3600;
--发送消息
SEND ON CONVERSATION @dialog
MESSAGE TYPE [http://Samples/SQL/ServiceBroker/msgOperation] (@message_body);
END CONVERSATION @dialog;
GO
--实现ServiceBroker安全配置
--创建拥有服务的用户
CREATE USER msgOperationInitServiceUser WITHOUT LOGIN;
ALTER AUTHORIZATION ON
SERVICE::[http://Samples/SQL/ServiceBroker/msgOperationInitService]
TO
msgOperationInitServiceUser;
--创建与该用户关联的私钥证书
CREATE CERTIFICATE msgOperactionInitServiceCertPriv AUTHORIZATION msgOperationInitServiceUser
WITH SUBJECT = 'ForMsgOperactionInitService',
START_DATE = '01/01/2009',
EXPIRY_DATE = '01/01/2100';
--将公钥证书备份到文件以供目标方服务使用
BACKUP CERTIFICATE msgOperactionInitServiceCertPriv
TO FILE = 'D:\msgOperactionInitServiceCertPub.cer';
--创建调用目标服务的用户
CREATE USER msgOperationProcessServiceUser WITHOUT LOGIN;
--导入目标服务的证书并把刚才创建的用户设为所有者
CREATE CERTIFICATE msgOperactionProcessServiceCertPub AUTHORIZATION msgOperationProcessServiceUser
FROM FILE = 'D\pub\msgOperactionProcessServiceCertPub.cer';
--建立目标服务远程服务绑定
CREATE REMOTE SERVICE BINDING ToMsgOperactionProcessService
TO SERVICE 'http://Samples/SQL/ServiceBroker/msgOperationProcessService'
WITH USER = msgOperationProcessServiceUser;
GRANT ALTER ON REMOTE SERVICE BINDING::ToMsgOperactionProcessService TO Jack

测试普通用户

EXEC sp_DBA_userPermisionsClone test,jack

测试结果

USE test
GO
CREATE USER [jack] FOR LOGIN [jack] WITH DEFAULT_SCHEMA =[dbo]
GO
GRANT ALTER ANY SCHEMA to [jack]
GO
GRANT CONNECT to [jack]
GO
GRANT CREATE PROCEDURE to [jack] WITH GRANT OPTION
GO
GRANT CREATE TABLE to [jack]
GO
EXEC sp_addrolemember N'testRoleIntest',N'jack'
GO
EXEC sp_addrolemember N'db_securityadmin',N'jack'
GO
DENY UPDATE ON OBJECT::[dbo].[test] TO [jack]
GRANT SELECT ON OBJECT::[dbo].[test]([a])  TO [jack]
GRANT SELECT ON OBJECT::[dbo].[test]([d])  TO [jack]
GRANT SELECT ON SCHEMA::[dbo] TO [jack]
 
GRANT CONTROL ON APPLICATION ROLE::[AppRole] TO [jack]
GRANT ALTER ON ROLE::[testRoleIntest] TO [jack]
GRANT REFERENCES ON ASSEMBLY::[Microsoft.SqlServer.Types] TO [jack]
GRANT TAKE OWNERSHIP ON TYPE::[dbo].[testType] TO [jack]
GRANT REFERENCES ON message type::[//Mytest/Sample/ReplyMsg] TO [jack]
GRANT ALTER ON Contract::[//Mytest/Sample/MyContract] TO [jack]
DENY ALTER ON Service::[//Mytest/Sample/InitSvc] TO [jack]
GRANT VIEW DEFINITION ON Service::[//Mytest/Sample/InitSvc] TO [jack]
GRANT ALTER ON Route::[ExpenseRoute] TO [jack]
DENY VIEW DEFINITION ON Route::[ExpenseRoute] TO [jack]
GRANT ALTER ON fulltext catalog::[ftCat] TO [jack]
GRANT ALTER ON fulltext stoplist::[mystopList] TO [jack]
DENY VIEW DEFINITION ON fulltext stoplist::[mystopList] TO [jack]
EXEC sp_DBA_userPermisionsClone test1,jack

测试结果

USE test1
GO
CREATE USER [jack] FOR LOGIN [jack] WITH DEFAULT_SCHEMA =[dbo]
GO
GRANT CONNECT to [jack]
GO
EXEC sp_addrolemember N'public',N'jack'
GO
GRANT EXECUTE ON OBJECT::[dbo].[SimpleProc] TO [jack]
DENY VIEW DEFINITION ON OBJECT::[dbo].[SimpleProc] TO [jack]
GRANT IMPERSONATE  ON USER::[dbo] TO [jack]
GRANT ALTER ON XML SCHEMA COLLECTION::[http://Samples/SQL/ServiceBroker/msgOperationSchema] TO [jack]
DENY TAKE OWNERSHIP ON XML SCHEMA COLLECTION::[http://Samples/SQL/ServiceBroker/msgOperationSchema] TO [jack]
GRANT ALTER ON REMOTE SERVICE BINDING::[ToMsgOperactionProcessService] TO [jack]
GRANT CONTROL ON SYMMETRIC KEY::[SymKey1] TO [jack]
GRANT CONTROL ON SYMMETRIC KEY::[SymKey2] TO [jack]
GRANT VIEW DEFINITION ON CERTIFICATE::[testCert] TO [jack]
GRANT CONTROL ON ASYMMETRIC KEY::[ASymKey] TO [jack]

测试角色

EXEC sp_DBA_userPermisionsClone test,testRoleIntest

测试结果

USE test
GO
--数据库角色克隆
CREATE ROLE [testRoleIntest]
GRANT EXECUTE to [testRoleIntest]
GO

测试应用角色

EXEC sp_DBA_userPermisionsClone test,AppRole

测试结果

USE test
GO
--应用角色克隆
CREATE APPLICATION ROLE [AppRole]WITH PASSWORD = ''  , DEFAULT_SCHEMA = [dbo]
GRANT CONTROL to [AppRole]
GO
EXEC sp_addrolemember N'public',N'AppRole'
GO

SQL Server 2016部分包含数据库中包含用户测试

--SQL Server 2016 部分包含数据库中包含用户测试
--创建部分包含数据库
CREATE DATABASE [test2]
 CONTAINMENT = PARTIAL
 
 --创建包含用户
USE test2
GO
CREATE USER [Jack] WITH PASSWORD ='a8ea v*(Rd##+'
--赋予包含用户权限
GRANT CONNECT to [Jack]
GO
GRANT SELECT to [Jack]
GO
EXEC sp_DBA_userPermisionsClone test2,Jack

测试结果

USE test2
GO
CREATE USER [Jack] WITH PASSWORD ='',DEFAULT_SCHEMA =[dbo],SID = 0x010500000000000903000000301792D81CCF6B4093A36928EE829FF0
GO
GRANT CONNECT to [Jack]
GO
GRANT SELECT to [Jack]
GO
EXEC sp_addrolemember N'public',N'Jack'
GO

从测试结果来看,sp_DBA_userPermisionsClone完美实现了对用户(包括包含用)、角色、应用角色权限角色的克隆。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ubuntu Server 克隆和恢复是指在 Ubuntu 服务器上创建克隆副本或者备份,在需要的时候恢复到原始状态。下面我将详细介绍如何进行克隆和恢复。 1. 克隆 Ubuntu Server: - 首先,确保服务器上已安装了合适的克隆软件,如 Clonezilla。 - 创建一个用于存储克隆副本的外部存储设备,如 USB 驱动器。 - 将服务器关机,并将克隆软件的光盘或 USB 驱动器插入服务器。 - 启动服务器并从克隆软件启动,按照克隆软件的操作指南选择克隆源和目标设备。 - 等待克隆过程完成,然后将克隆副本外部存储设备从服务器中取出。 2. 恢复 Ubuntu Server: - 将克隆副本外部存储设备插入需要恢复的服务器。 - 启动服务器,并通过 BIOS 设置引导顺序以从外部存储设备启动。 - 选择克隆软件的激活克隆恢复选项,按照软件的操作指南选择克隆副本和目标设备。 - 等待恢复过程完成,然后重新启动服务器从恢复后的系统启动。 需要注意的是,在克隆和恢复 Ubuntu Server 时要进行适当的备份,以防止数据丢失或损坏。确保克隆副本和目标设备有足够的存储空间,以容纳系统和数据。在进行恢复前,验证克隆副本的完整性,以确保克隆副本没有受到任何损坏或错误。 克隆和恢复 Ubuntu Server 可以帮助加快系统部署和恢复速度,减少手动配置的工作量。无论是用于创建开发环境还是备份生产服务器,这些步骤都是非常有用的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值