设为首页 收藏本站
查看: 1341|回复: 3

[经验分享] SQL Server解决孤立用户浅析

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2013-12-10 09:07:53 | 显示全部楼层 |阅读模式
孤立用户概念

       所谓孤立用户即指在服务器实例上未定义或错误定义了其相应 SQL Server 登录名的数据库用户无法登录到实例。 这样的用户被称为此服务器实例上的数据库的“孤立用户”。 如果删除了对应的 SQL Server 登录名,则数据库用户可能会变为孤立用户。 另外,在数据库还原或附加到 SQL Server 的其他实例之后,数据库用户也可能变为孤立用户。 如果未在新服务器实例中提供数据库用户映射到的 SID,则该用户可能变为孤立用户

检测孤立用户

检测孤立用户相当简单,可以使用下面SQL语句

Code Snippet
USE DatabaseName;
GO

EXEC sp_change_users_login @Action = 'Report';
GO
当然如果你不想用系统自带的存储过程sp_change_users_login,其实检测孤立账号也很简单,一个简单的SQL语句即可搞定:

Code Snippet
SELECT   UserName = name ,
         UserSID = sid
FROM     sysusers
WHERE    issqluser = 1
         AND ( sid IS NOT NULL
               AND sid <> 0x0
             )
         AND ( LEN(sid) <= 16 )
         AND SUSER_SNAME(sid) IS NULL
ORDER BY name
从上面可以看出,

    1:孤立账号必须是SQL Server 用户(issqluser= 1),:

    2:它必须是sys、guest、INFORMATION_SCHEMA账号以外的SQL Server用户

    SELECT * FROM sysusers WHERE SID IS NULL OR SID = 0x0;

09154651-2bfb82189ae84e59a8d064e681f30fd0.jpg

3:它返回与安全标识号 (SID) 关联的登录名必须为空值

4:SID的长度小于16


解决孤立账号

方法1:

   1: Step 1:  检测、查看对应的孤立账号
   2:  
   3:  
   4: USE <DatabaseName>;
   5:  
   6: GO
   7:  
   8: EXEC sp_change_users_login  @Action='Report';
   9:  
  10: GO
  11:  
  12: Step 2: 新建对应的登录名,例如上面检测到Test账号为孤立账号
  13:  
  14: USE [master]
  15:  
  16: GO
  17:  
  18: CREATE LOGIN [Test] WITH PASSWORD=N'Pa@#456' MUST_CHANGE, DEFAULT_DATABASE=[xxxx], CHECK_EXPIRATION=ON, CHECK_POLICY=ON
  19:  
  20: GO
  21:  
  22: Step 3:
  23:  
  24: USE EASN_EAP;
  25:  
  26: GO
  27:  
  28: EXEC sp_change_users_login @Action='Update_one',@UserNamePattern='xxxx',@LoginName='xxxx';
  29:  
  30: Step 4: 重复执行Step 1、Step 2、Step 3解决其它孤立账号,直到所有孤立账号全部被Fix掉。
  31:  
方法2:对于方法1,如果账号比较多,操作起来比较郁闷,重复干繁琐的体力活。于是我写了一个存储过程来解决



   1: SET ANSI_NULLS ON
   2: GO
   3:  
   4: SET QUOTED_IDENTIFIER ON
   5: GO
   6:  
   7:  
   8:  
   9: IF EXISTS ( SELECT  1
  10:             FROM    dbo.sysobjects
  11:             WHERE   id = OBJECT_ID(N'sp_fix_orphaned_users')
  12:                     AND OBJECTPROPERTY(id, 'IsProcedure') = 1 )
  13:     DROP PROCEDURE sp_fix_orphaned_users;
  14: GO
  15:  
  16: --==================================================================================================================
  17: --        ProcedureName        :            sp_fix_orphaned_users
  18: --        Author               :            Kerry   
  19: --        CreateDate           :            2013-12-08
  20: --        Description          :            批量解决数据库孤立账号
  21: --                                             
  22: /******************************************************************************************************************
  23:         Parameters            :                                    参数说明
  24: ********************************************************************************************************************
  25:             @DefaultPwd       :            所有孤立账户使用同一个密码@DefaultPwd
  26:             @LoginName        :            所有需要fix的孤立账户,eg 'test1|test2|test3' 表示孤立账户test1、test2、test3。
  27:             @Password         :            对应@LoginName,eg '@341|Dbd123|D#25' 分别表示上面账号对应的密码
  28: ********************************************************************************************************************
  29:    Modified Date    Modified User     Version                 Modified Reason
  30: ********************************************************************************************************************
  31:     2013-12-08             Kerry         V01.00.00                  创建该存储过程。
  32:
  33: *******************************************************************************************************************/
  34: --==================================================================================================================
  35:  
  36: CREATE PROCEDURE [dbo].[sp_fix_orphaned_users]
  37: (
  38:     @IsUseSamePwd  INT    = 0              ,
  39:     @DefaultPwd       VARCHAR(32) = NULL ,
  40:     @LoginName       NVARCHAR(MAX) =NULL,
  41:     @Password       NVARCHAR(MAX) =NULL
  42: )
  43: AS
  44:  
  45: DECLARE @UserName NVARCHAR(64);
  46: DECLARE @tmpPwd      VARCHAR(20);
  47: DECLARE @LoginRows INT;
  48: DECLARE @PwdRows   INT;
  49:  
  50:  
  51:     
  52: IF @IsUseSamePwd =1 AND @DefaultPwd IS NULL
  53: BEGIN
  54:     RAISERROR('%s Invalid. Please check the paramter %s value',16,1, '@DefaultPwd');
  55:     RETURN 1;
  56: END
  57:  
  58: IF @IsUseSamePwd = 0 AND ( @LoginName IS NULL OR  @Password IS NULL)
  59: BEGIN
  60:     RAISERROR('%s Invalid. Please check the paramter %s value',16,1, '@Password');
  61:     RETURN 1;
  62: END
  63:     
  64: IF @IsUseSamePwd = 0
  65: BEGIN
  66:  
  67:     CREATE TABLE #TempLoginNams
  68:     (
  69:         ID                INT,
  70:         UserName        VARCHAR(20),
  71:     )   
  72:  
  73:     INSERT INTO #TempLoginNams
  74:             ( ID, UserName )
  75:     SELECT * FROM dbo.SplitString(@LoginName,'|');
  76:  
  77:     CREATE TABLE #TempPassword
  78:     (
  79:         ID            INT,
  80:         UserPassrd  VARCHAR(20)
  81:     )
  82:  
  83:     INSERT INTO #TempPassword
  84:     SELECT * FROM dbo.SplitString(@Password,'|');
  85:  
  86:     SELECT @LoginRows=COUNT(1) FROM #TempLoginNams;
  87:     SELECT @PwdRows=COUNT(10) FROM #TempPassword;
  88:  
  89: IF @LoginRows != @PwdRows
  90:     BEGIN
  91:         RAISERROR('The paramter %s have different nums. Please check the paramter %s value',16,1, '@LoginName & @Password ');
  92:         RETURN 1;
  93:     END
  94:  
  95: END
  96:  
  97:  
  98: CREATE TABLE #OrphanedUser
  99: (
100:     UserName    sysname,
101:     UserId        INT
102: )
103:  
104:  
105: INSERT INTO #OrphanedUser EXEC sp_change_users_login @Action='Report';
106:  
107:  
108: DECLARE Cur_OrphanedUsers CURSOR FOR
109:     SELECT UserName FROM #OrphanedUser;
110:     
111:  
112: OPEN Cur_OrphanedUsers;
113:  
114: FETCH NEXT FROM Cur_OrphanedUsers INTO @UserName;
115: WHILE ( @@FETCH_STATUS = 0 )
116:     BEGIN
117:         IF @IsUseSamePwd = 1
118:             BEGIN
119:         
120:                 EXEC sp_change_users_login 'Auto_Fix', @UserName, NULL,
121:                     @DefaultPwd;
122:                     
123:        
124:                 EXEC sp_change_users_login @Action = 'update_one',
125:                     @UserNamePattern = @UserName, @LoginName = @UserName;
126:             END
127:         ELSE
128:             BEGIN
129:                 SELECT  @UserName = o.UserName ,
130:                         @tmpPwd = p.UserPassrd
131:                 FROM    #OrphanedUser o
132:                         LEFT JOIN #TempLoginNams l ON o.UserName = l.UserName
133:                         LEFT JOIN #TempPassword p ON l.ID = p.ID
134:                 WHERE   o.UserName = @UserName;
135:     
136:                 EXEC sp_change_users_login 'Auto_Fix', @UserName, NULL,
137:                     @tmpPwd;
138:                 EXEC sp_change_users_login @Action = 'update_one',
139:                     @UserNamePattern = @UserName, @LoginName = @UserName;
140:             END
141:   
142:         FETCH NEXT FROM Cur_OrphanedUsers INTO @UserName
143:     END
144: CLOSE Cur_OrphanedUsers
145: DEALLOCATE Cur_OrphanedUsers
146:  
147: DROP TABLE  #OrphanedUser;
148:  
149: IF @IsUseSamePwd = 0
150: BEGIN
151:     DROP TABLE #TempLoginNams;
152:     DROP TABLE #TempPassword;
153: END
154:  
155: GO

其中该存储过程调用了一个Function成为SplitString,该函数是我从网上搜索得来的,作者不详,本来想自己重写该函数,后来觉得没有必要重复造轮子。因为这个函数完全满足我的需求。

Code Snippet
CREATE FUNCTION SplitString
    (
      -- Add the parameters for the function here
      @myString VARCHAR(500) ,
      @deliminator VARCHAR(10)
    )
RETURNS @ReturnTable TABLE
    (
      -- Add the column definitions for the TABLE variable here
      [id] [int] IDENTITY(1, 1)
                 NOT NULL ,
      [part] [varchar](50) NULL
    )
AS
    BEGIN
        DECLARE @iSpaces INT
        DECLARE @part VARCHAR(50)
        --initialize spaces  
        SELECT  @iSpaces = CHARINDEX(@deliminator, @myString, 0)
        WHILE @iSpaces > 0
            BEGIN
                SELECT  @part = SUBSTRING(@myString, 0,
                                          CHARINDEX(@deliminator, @myString, 0))
                INSERT  INTO @ReturnTable
                        ( part )
                        SELECT  @part
                SELECT  @myString = SUBSTRING(@mystring,
                                              CHARINDEX(@deliminator,
                                                        @myString, 0)
                                              + LEN(@deliminator),
                                              LEN(@myString) - CHARINDEX(' ',
                                                              @myString, 0))
                SELECT  @iSpaces = CHARINDEX(@deliminator, @myString, 0)
            END
        IF LEN(@myString) > 0
            INSERT  INTO @ReturnTable
                    SELECT  @myString
        RETURN
    END
           GO


这个存储过程在执行时,有一个既可以说是小bug,也可以说没有验证的错误,就是登录名的密码设置如果过于简单,则执行

EXEC sp_change_users_login 'Auto_Fix', @UserName, NULL,   @tmpPwd; 则会报如下错误

消息 15118,级别 16,状态 1,第 1 行
密码有效性验证失败。该密码不够复杂,不符合 Windows 策略要求。
消息 15497,级别 16,状态 1,过程 sp_change_users_login,第 223 行
无法使用 sp_addlogin 添加登录名(用户 = easn)。即将终止此过程。

一时还没有找到如何去验证密码是否符合复杂度的方法,留待以后进一步完善。

假如迁移数据库后,发现有user1、user2、user3三个孤立账号,那么就可以用下面SQL去解决孤立账号问题。

   1: sp_fix_orphaned_users      @IsUseSamePwd =0    ,
   2:     @LoginName ='user1|user2|user3',
   3:     @Password      ='Jk(*45(|Jk(*45(|Jk(*45(';


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-11353-1-1.html 上篇帖子: 基于Sql Server 2008的分布式数据库的实践(终结) 下篇帖子: 关于SQLServer无法对数据库'XXX'执行删除,因为它正用于复制... 用户

尚未签到

发表于 2013-12-15 04:24:02 | 显示全部楼层
当青春已成青春,该拿什么去挥霍.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-12-21 00:30:47 | 显示全部楼层
他给她留言。你的,我都懂。我的,你有太多不懂。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

尚未签到

发表于 2013-12-26 13:36:13 | 显示全部楼层
蓝天下的我们 那么渺小 那么寂寞`

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表