Используя следующий метод, я выдаю себя за пользователя локального администратора (с повышенными привилегиями) и передаю функцию, которая должна выполняться в контексте олицетворения.Операции LocalDB в контексте олицетворения
/// <summary>
/// Attemps to impersonate a given windows user and to run a given function within the impersonation context.
/// </summary>
/// <param name="userInformation">The user name and password for impersonation.</param>
/// <param name="functionAsImpersonatedUser">The function to be executed within the impersonation context.</param>
/// <returns>True if the operation was successful, false and an error message otherwise.</returns>
public static BooleanResult ExecuteAsImpersonatedUser(UserInformation userInformation, Func<BooleanResult> functionAsImpersonatedUser)
{
BooleanResult retval = new BooleanResult();
IntPtr returnedToken = IntPtr.Zero;
try
{
//Note: the logon type 'batch' seems to return a token with elevated privileges
bool success = NativeMethods.LogonUser(userInformation.Name, userInformation.Domain ?? ".", userInformation.Password, (int)LogonType.Batch, (int)LogonProvider.Default, out returnedToken);
if (false == success)
{
int ret = Marshal.GetLastWin32Error();
throw new Win32Exception(ret);
}
using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(returnedToken))
{
retval = functionAsImpersonatedUser();
}
}
catch (OutOfMemoryException o)
{
string logMessage = String.Format(CultureInfo.InvariantCulture, ErrorMessages.ErrorImpersonatingUser, userInformation.Domain, userInformation.Name, o.Message);
retval.ProcessGeneralException(o, logMessage);
}
catch (SecurityException s)
{
string logMessage = String.Format(CultureInfo.InvariantCulture, ErrorMessages.ErrorImpersonatingUser, userInformation.Domain, userInformation.Name, s.Message);
retval.ProcessGeneralException(s, logMessage);
}
catch (UnauthorizedAccessException u)
{
string logMessage = String.Format(CultureInfo.InvariantCulture, ErrorMessages.ErrorImpersonatingUser, userInformation.Domain, userInformation.Name, u.Message);
retval.ProcessGeneralException(u, logMessage);
}
catch (Win32Exception w)
{
string logMessage = String.Format(CultureInfo.InvariantCulture, ErrorMessages.ErrorImpersonatingUser, userInformation.Domain, userInformation.Name, w.Message);
retval.ProcessGeneralException(w, logMessage);
}
finally
{
if (NativeMethods.CloseHandle(returnedToken))
LogUtility.Instance.Write(String.Format(CultureInfo.InvariantCulture, TranslationStrings.CloseUserHandleSuccess, userInformation.Domain, userInformation.Name), 4);
else
LogUtility.Instance.Write(String.Format(CultureInfo.InvariantCulture, ErrorMessages.ErrorCloseUserHandle, userInformation.Domain, userInformation.Name), 2);
}
return retval;
}
Проблем с этим пока нет. После замены LogonType.Interactive LogonType.Batch даже, кажется, возвращает токен пользователя с повышенными привилегиями.
Функция в контексте олицетворения создает экземпляр localDB, если требуется, запускает его, а затем пытается настроить базу данных с использованием сценариев сбрасывания и SMO. Первое, что происходит со мной, это то, что владелец экземпляра не является выдающимся администратором, почему это так: я неправильно понимаю, как работает олицетворение или localDB?
Как и следовало ожидать, используя соединение типа «Источник данных = (localdb). [Имя экземпляра]; начальный каталог = [имя_базы базы данных]; Integrated Security = true» не работает. Это, следовательно, приводит к исключению ConnectionFailureException.
Но я все еще не понимаю, почему мой выданный локальный администратор не является владельцем экземпляра (даже если я создаю экземпляр в трансформированном контексте) и, следовательно, не могу получить доступ к базе данных?
Решение может быть очевиден, но я застрял.
С наилучшими пожеланиями,
Stephan