how to deal with “remapping can only be done for u

2020-07-29 17:30发布

问题:

The scenario:

Trying to restore from a bacpac taken from SQL Azure.

Either to a new SQL Azure database instance, or an on premises server. For the earlier with the Management portal or the DAC Framework Client Side Tools.

It seems to work fine, and naturally the SQL users are not mapped to SQL logins after the restore.

What I tried:

When I try to map it with: alter user MyUser with login = MyLogin, it fails with:

Msg 33016, Level 16, State 1, Line 6 The user cannot be remapped to a login. Remapping can only be done for users that were mapped to Windows or SQL logins.

Running select * from sys.database_principals does list the users, but with a much longer SID than a SQL authenticated user I created to compare it to.

On premises if I run a sp_change_users_login 'Report' the users are Not listed, so are not being detected as orphaned.

On premises if I try using sp_change_users_login, it fails with:

Msg 15291, Level 16, State 1, Procedure sp_change_users_login, Line 114 Terminating this procedure. The User name 'MyUser' is absent or invalid.

On premises if I try it through the User Mapping section of the Login Properties UI, I get:

Create failed for User 'My User'. ... User, group, or role 'MyUser' already exists in the current database.

I tried doing it all over again, in case something was corrupted when restoring for some reason, same results.

The question:

How can I remap these SQL Users?

I'd like to avoid having to re-create those from scratch and any relation those have to the schema objects in the database?

Some extra info:

One type of SQL users that look a lot like what I'm seeing for the SQL Azure users, are ones created with

create user AnotherUser without login

Those fail in the exact same way in all the 3 mapping approaches I used above. That is not the case in any of the approaches for regular SQL users. Additionally the sid is also long, and begins with the same "0x010500000000000903000000"

回答1:

If you ever get that, it is Most likely a corrupt backup. Just like the linked on premises scenario, the behaviour comes out of nowhere and was traced to a corrupt backup.

In my case, it was the same. Right before posting the question, my last try was: a different backup of the database, it worked without issues.



回答2:

A sqlmatters article explains that

A user without login is a special type of user that has deliberately been set up without an associated login.

one can check if it is such a case by examining the SID:

 -- SQL to run to identify users without login :
SELECT CASE WHEN DATALENGTH(sid) = 28
             AND type = 'S'       -- only want SQL users
             AND principal_id > 4 -- ignore built in users
     THEN 1 ELSE 0 END AS is_user_without_login,*
FROM sys.database_principals 

where users without login have longer SID than regular (orphaned) users.

These special users cannot be mapped to a login because they are made that way. Someone must have intentionally or by mistake created a user WITHOUT LOGIN.



回答3:

You can also find users that can be mapped to a login with the following:

SELECT *
FROM sys.database_principals
WHERE 1=1
    AND [type] = 'S'
    AND [name] NOT IN ('dbo','guest','INFORMATION_SCHEMA','sys')
    AND authentication_type_desc IN ('WINDOWS','INSTANCE')