Eu tenho um usuário ls_readonly
que deveria ter db_datareader
privilégios em vários bancos de dados. Achei que tinha configurado direitinho:
Mas quando eu me conecto ao servidor como ls_readonly
e tento abrir o db no Object Explorer, recebo um erro:
O banco de dados wtest não está acessível. (Explorador de Objetos)
Eu abro uma janela de consulta master
e tento executar:
use wtest
Isso responde com:
Msg 916, Level 14, State 1, Line 1
The server principal "ls_readonly" is not able to access the database "wtest" under the current security context.
o que estou perdendo?
ATUALIZAÇÃO: aqui está uma pista. Se eu excluir ls_readonly
como usuário do contexto de segurança do banco de dados, vou para o usuário no contexto de segurança do servidor e em "Mapeamento do usuário" concedo acesso ao banco de dados e ele começa a funcionar.
Pode ser que o banco de dados tenha sido originalmente restaurado de um servidor diferente, que também tenha um ls_readonly
usuário. Eu acho então que a identificação do usuário não é baseada no nome de usuário?
Normalmente, todos os logins têm o mesmo
sid
com os usuários correspondentes. Esse é o sentido doCREATE USER FROM LOGIN
comando: o banco de dados principal é criado com o mesmosid
(identificador de segurança) que o login correspondente possui.Este usuário
sid
agora está armazenado em seu banco de dados, e quando vocêbackup
/restore
seu banco de dados o sid também é preservado.Imagine agora que você tem 2 servidores e ambos possuem
ls_readonly
login. para simplificar, no primeiro servidorls_readonly
temsid
= 1, no segundosid
= 2. Você tem o banco de dados MyDB onde este login está mapeado. No primeiro servidor MyDB armazenasid
= 1, no segundosid
= 2.Você faz backup do banco de dados MyDB no primeiro servidor e o restaura no segundo. Agora seu login tem
sid
= 2 e no banco de dados MyDB ésid
= 1.Você faz login como
ls_readonly
e tenta acessar o MyDB, o servidor está verificando se há sid = 2 no banco de dados, não há, portanto, o servidorls_readonly
não está mapeado para o MyDB.Isso pode ser corrigido fazendo
Este comando apenas atualiza o sid do
ls_readonly
usuário do banco de dados com o sid dols_readonly
login. Todas as permissões são preservadas.Se você recriar o usuário descartando-o, depois de descartar o usuário, todas as permissões concedidas a ele serão descartadas e você precisará concedê-las novamente.
@sepupic cobre muito bem tudo o que eu teria sugerido, mas pensei em compartilhar o seguinte script que executo sempre que restauro um banco de dados cujo backup foi feito de uma instância do SQL Server e restaurado em outra. Execute-o no banco de dados que você acabou de restaurar. Basicamente automatiza o que o @sepupic está falando. (O
execute
está comentado)Isso soa como um usuário órfão. Um usuário órfão é onde o SID do usuário não corresponde ao SID de login, não ao nome amigável que vemos (provavelmente foi causado quando um login foi excluído do servidor ou o banco de dados foi restaurado de um servidor diferente). Você não deve precisar excluir o usuário e recriá-lo, pois todas as permissões existentes seriam perdidas (ok, essa é apenas a função, mas diga que você tinha permissões individuais em outros objetos; procedimentos armazenados e tabelas etc). Existe um recurso que permite remapear o usuário para o login (mesmo que tenha o mesmo nome).
então gostaria de:
Veja aqui para mais detalhes na documentação do MS
Solte o usuário do banco de dados
Excluir e recriar o usuário
Adicionar o usuário ao banco de dados
Você pode não precisar do 2º, mas não deve doer