title: Changes to sysusers and sysxlogins in SQL 2008
body: <p>I am currently updating a MS SQL 2000 server to SQL 2008. One of the issues highlighted by the Upgrade advisor is that the undocumented table sysxlogins has been removed.</p>
  
  <p>I currently have a procedure that is run by a user 'foo' to determine if the user 'bar' exists in the database blah. If the user exists the user's password is compared to the password that was passed in to the procedure in order to determine if bar is allowed to log in to an application, it looks like this:</p>
  
  <pre><code>@UserName Varchar(50),
  @Password Varchar(50)
  
  As
  Set NoCount On
  
  ------------------------------------------------------------------------------------
  -- Check username
  ------------------------------------------------------------------------------------
  If Exists
  (
     select top 1 name
     from blah.dbo.sysusers With (NoLock)
     where name = @UserName
  )
  Begin
  
     ------------------------------------------------------------------------------------
     -- Check Password
     ------------------------------------------------------------------------------------
  
     If Not Exists
     (
        Select *
        From master.dbo.sysxlogins With (NoLock)
        Where srvid IS NULL
        And name = @Username
        And ( ((@Password is null) or (@Password = '') and password is null)
        Or (pwdcompare(@Password, password, (CASE WHEN xstatus&amp;2048 = 2048 THEN 1 ELSE 0 END)) = 1))
     )
     Begin
  
        Return 2
  
     End
  
     Else
  
     Begin
  
        ------------------------------------------------------------------------------------
        -- Check Role
        ------------------------------------------------------------------------------------
  
        Select usg.name
        From blah.dbo.sysusers usu
        left outer join (blah.dbo.sysmembers mem inner join blah.dbo.sysusers usg on mem.groupuid = usg.uid) on usu.uid = mem.memberuid
        left outer join syslogins  lo on usu.sid = lo.sid
        where usu.name = @Username
    and usg.name not like 'db_%'
  
        Return 0 -- Username and password correct
  
     End
  
  End
  
  Else
  
  Begin
  
        Return 1 -- Username incorrect
  
  End
  </code></pre>
  
  <p>This all works fine under SQL 2000, yet I must now pay the price of using undocumented system tables and make it work under 2008.</p>
  
  <p>There are two problems with this, the first problem is that foo can no longer see all of the database users when executing:</p>
  
  <pre><code>select * from blah.dbo.sysusers
  </code></pre>
  
  <p>or Microsoft's recommended alternative:</p>
  
  <pre><code>select * from blah.sys.database_principals
  </code></pre>
  
  <p>I understand that this is due to the fact that members of the public role no longer have access to object meta data unless they are a member of sysadmin or have the View Definition permission on the object.</p>
  
  <p>It is not possible for foo to be a member of sysadmin, so as far as I understand I need to grant foo the View Definition permission, but on which object? I don't think I do it on the system view, so do I do it on every single user?</p>
  
  <p>Secondly, and similarly, I need to change my reference to sysxlogins to sys.sql_logins. Again foo can only see itself and sa when executing</p>
  
  <pre><code>select * from sys.sql_logins
  </code></pre>
  
  <p>How can I get foo to see all of the server logins in this list?</p>
  
  <p>There will no doubt be similar problems when accessing sysmembers and syslogins later on in the code but hopefully an understanding of the two examples above will help me to sort the rest out.</p>
  
  <p>Thanks in advance,</p>