Microsoft sql server ошибка 15025

imageВо время миграции баз данных SQL Server 2012 из ранее используемого кластерного экземпляра SQL Server на физических серверах в новый кластерный экземпляр в виртуальной среде Hyper-V столкнулся с одной интересной проблемой. Сразу скажу, что она никак не связана ни с Hyper-V, ни с виртуализацией в целом, а скорее с простым незнанием некоторых аспектов работы SQL Server.

При копировании баз данных была предпринята попытка использования мастера копирования баз (Copy Database Wizard), который доступен нам в составе SQL Server Management Studio по аналогии с ранее описанной процедурой. Процедура копирования контентной базы данных одного из веб-приложений SharePoint и связанных с ней SQL-логинов была прервана с ошибкой, говорящей о том, что один из SQL-логинов невозможно найти в домене. Выяснилось, что этот SQL-логин когда-то ранее было создан на SQL Server с привязкой к существующей на тот момент доменной учетной записи пользователя, однако на текущий момент учётной записи с таким именем в домене действительно нет. Это подтвердил также и вывод хранимой процедуры sp_validatelogins, которая умеет обнаруживать “осиротевшие” SQL-логины:

EXEC sp_validatelogins; 
GO

image

В нашем примере проблемный SQL-логин имел имя KOMs-KOM-SP-ORD. Соответственно этому SQL-логину ранее и были права необходимые для работы с контентной базой данных веб-приложения SharePoint, но вместе с этим само веб-приложение в SharePoint на текущий момент времени работало от имени совершенно другой учетной записи – KOMs-KOM-SP-IRS. Это ввело меня в некоторый ступор. Как такое вообще возможно… И пока до меня не “дошло”, в чём же на самом деле заключается проблема, выполнялись разного рода манипуляции. Например, будучи уверенным в том, что учетной записи веб-приложения таки нужен доступ к его контентной базе данных SharePoint, я попытался добавить в SQL Server новый SQL-логин — KOMs-KOM-SP-IRS. Но в ответ получил странное сообщение о том, что такой логин в SQL Server уже присутствует… 

Create failed for Login 'XXXXXX'.  (Microsoft.SqlServer.Smo)
...
The server principal 'XXXXXX' already exists. (Microsoft SQL Server, Error: 15025)

image

Но как? Ведь я не вижу этого логина в консоли…

И тут меня осенило, что скорее всего, нынешняя доменная учетная запись KOMs-KOM-SP-IRS это и есть учётная запись KOMs-KOM-SP-ORD, просто переименованная в домене после того, как в SQL Server был создан сопряжённый с ней SQL-логин. Чтобы проверить это предположение, нужно было выяснить доменный идентификатор безопасности (SID) хранимый в SQL Server для SQL-логина KOMs-KOM-SP-ORD и сравнить его с SID пользователя KOMs-KOM-SP-IRS в домене на данный момент. Новой сложностью стало то, что SQL Server возвращает значение SID в формате VARBINARY(85), а в домене оно хранится в другом формате.

Выполнить преобразование полученного из SQL Server значения SID в формат аналогичный атрибуту objectSid для учетных записей в домене Active Directory помог SQL-скрипт из статьи Help: SQL Server — SQL Internals — How to map login SID to domain account?, за что её автору большое спасибо…

DECLARE @varBinarySID VARBINARY(85)
-- в переменной varBinarySID указываем значение SID в формате varbinary(85)
SELECT @varBinarySID = 0x010500000000000515000000685889B0E3259CD7E0ED9A5545030300
DECLARE @StringSID VARCHAR(100)
DECLARE @len AS INT
SET @len = LEN(@varBinarySID)
DECLARE @loop AS INT
SELECT @StringSID = 'S-'
SELECT @StringSID = @StringSID + CONVERT(VARCHAR, CONVERT(INT, CONVERT(VARBINARY, SUBSTRING(@varBinarySID, 1, 1))))
SELECT @StringSID = @StringSID + '-'
SELECT @StringSID = @StringSID + CONVERT(VARCHAR, CONVERT(INT, CONVERT(VARBINARY, SUBSTRING(@varBinarySID, 3, 6))))
SET @loop = 9
WHILE @loop < @len
BEGIN
    DECLARE @temp_var BINARY (4)
    SELECT @temp_var = SUBSTRING(@varBinarySID, @loop, 4)
    SELECT @StringSID = @StringSID + '-' + CONVERT(VARCHAR, CONVERT(BIGINT, CONVERT(VARBINARY, REVERSE(CONVERT(VARBINARY, @temp_var)))))
    SET @loop = @loop + 4
END
SELECT @StringSID 'String SID'

image

Итак, значение objectSid в более привычном формате получено  и теперь всё что остаётся сделать, это сравнить это значение с учетной записью KOMs-KOM-SP-IRS. Методов для этого много разных, как один из самых простых и быстрых воспользоваться обратным преобразованием SID в имя с помощью утилиты Марка Руссиновича — Psgetsid

image

Получается, что действительно, SQL-логин KOMs-KOM-SP-ORD имеет привязку к доменному SID учетной записи KOMs-KOM-SP-IRS. Как я уже и сказал, такая ситуация возможна в случае если в домене учетная запись была переименована после создания соответствующего логина в SQL Server. Теперь, чтобы окончательно поставить всё на свои места осталось только переименовать SQL-логин в актуальное для доменной учетной записи имя.

  • Hi Muhammed,

    Please go through the below steps,

    
    
    use master 
    go
    drop login <yourloginname>
    go
    create login <yourloginname> with password='yourpassword',<requiredoptions>
    go

    for the various option available with create login pls refer :

    http://msdn.microsoft.com/en-us/library/ms189751.aspx

    If the login is already there, you can try to fix the orphan users in DB instead of deleting the login.

     you can use

    alter user username with login=loginname

    please refer alter user syntax here

    http://msdn.microsoft.com/en-us/library/ms176060.aspx

    or

    You can make use of  sp_change_users_login which is deprecated to fix the orphan user issue after restoring Db from one server to another server.

    After fixing the orphan users issue your login in the new server will be able to connect to the restored DB with all the permissions as in the old server.

    But if you have already deleted the users in the DB, then you have to create the user for the login.

    Thanks

    • Edited by

      Tuesday, June 18, 2013 8:47 AM

    • Marked as answer by
      Fanny Liu
      Saturday, June 22, 2013 9:38 AM

  • Table of Contents

    • Error
    • Background
    • Solution

    Error

    Error message: THE SERVER PRINCIPAL ALREADY EXISTS ? MSG 15025, LEVEL 16, STATE 2, LINE 1

    Background

    I cannot find the login physically though but getting the error while trying to create a new login.

    Solution

    Use below scripts to fix the issue

    select suser_sid ('DomainloginName'); go

    Result: 0x0105000000000005150000000C04XXXXXXXXXXXXXXXXXXXXXXXXX

    select * from sys.server_principals sp where sid=0x0105000000000005150000000C04XXXXXXXXXXXXXXXXXXXXXXXXX

    IF EXISTS (SELECT * FROM sys.server_principals WHERE name = N'DomainLoginName') DROP LOGIN [DomainLoginName]

    Able to create a new login now.


    • Remove From My Forums
    • Question

    • My task is to move the databases associated with an application from one server to another.  Both servers have the same os (Windows Serer 2008 R2 Enterprise), the same SQL implementation (Windows SQL Server 2008 R2) and the same installed application
      software.  My intent is to make the data entered into Server A available on Server B without the necessity of re-entering.  All this is done programatically using C# and SMO.  

      After backing up the databases from Server A and restoring them to Server B, I find that Login X is missing from Server B’s Security.Logins folder.  When I attempt to add the Login, I get the following error message box:

      I succeeded in deleting the User associated with this login, but the error persists.

      How do I go about correcting this problem?

      Thanks in advance for your help.

      Barry


      My opinions are strictly my own. They do not reflect the positions of policies of AccessData Group LLC, or any other organized group. For that matter, they just barely reflect my OWN positions and policies!

    Answers

    • When you move a database from one server to another, the mapping between SQL logins and users always get out of sync. This is because the connection between server and database is by SID, not by name.

      Assuming that the user and login names are supposed to be identical, a quick way to resolve this is to run this script:

      SELECT 'ALTER USER ' + quotename(name) +
                   ' WITH LOGIN = ' + quotename(name)
      FROM     sys.database_principals dp
      WHERE    suser_sname(SID) <> name
          AND    name <> 'dbo'
          AND    type = 'S'     

      And then copy the results into a query window and run it.

      If the database is owned by someone else than sa, it is a good idea to change ownership to sa and back.


      Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

      • Proposed as answer by

        Wednesday, December 14, 2011 6:43 AM

      • Unproposed as answer by
        amber zhang
        Wednesday, December 14, 2011 7:18 AM
      • Marked as answer by
        BarryCarroll
        Thursday, December 15, 2011 11:04 PM

    I have a user who is using the application except for one view she cannot get access to.
    she has rights to it in the application however, when look at the sql users she is not there as the integrated windows login or as a user under the database

    when I try and recreate her I get

    The server principal ‘mydomaingoldiee’ already exists. (Microsoft SQL Server, Error: 15025)

    any suggestions on how to resolve

    Microsoft SQL Server 2008

  • Microsoft sql server ошибка 10054
  • Microsoft sql server management studio ошибка 26
  • Microsoft sql server 2014 ошибка 18456
  • Microsoft sql server 2005 ошибка базы
  • Microsoft sql native client ошибка связи hresult 80004005