2013-11-20 2 views
0

Используя следующий метод, я выдаю себя за пользователя локального администратора (с повышенными привилегиями) и передаю функцию, которая должна выполняться в контексте олицетворения.Операции 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

ответ

1

Глупый меня!

Установив глагол, имя пользователя и пароль свойства в процессе запуска информацию можно установить экземпляр LocalDB и указан другой владелец ...

public static ConsoleOutputResult CreateInstance(UserInformation user) 
    { 
     if (user == null) 
      throw new ArgumentNullException("user"); 

     ConsoleOutputResult retval = new ConsoleOutputResult(); 
     try 
     { 
      ProcessStartInfo startInfo = new ProcessStartInfo(Path.Combine(localDBPath, "SqlLocalDB.exe"), String.Format(CultureInfo.InvariantCulture, "create {0}", instanceName)) 
      { 
       CreateNoWindow = true, 
       Domain = user.Domain, 
       ErrorDialog = false, 
       LoadUserProfile = true, 
       Password = user.Password.ConvertToSecureString(), 
       RedirectStandardError = true, 
       RedirectStandardOutput = true, 
       UserName = user.Name, 
       UseShellExecute = false, 
       Verb = "runas" 
      }; 
      using (Process process = Process.Start(startInfo)) 
      { 
       process.WaitForExit(); 
       retval.Error = process.StandardError.ReadToEnd(); 
       retval.Output = process.StandardOutput.ReadToEnd(); 
       retval.Success = String.IsNullOrEmpty(retval.Error); 
       if (retval.Success) 
        LogUtility.Instance.Write(retval.Output, 4); 
      } 
     } 
     catch (Exception e) 
     { 
      string logMessage = String.Format(CultureInfo.InvariantCulture, ErrorMessages.ErrorCreateLocalDB, e.Message); 
      retval.ProcessGeneralException(e, logMessage); 
      throw new SmartAppWizardException(logMessage, e.InnerException); 
     } 
     return retval; 
    } 
Смежные вопросы