Подключение к NAS-серверу с проверкой чтения/записи. Ошибка олицетворения

Я работаю над программой, которая должна проверять, есть ли подключение к NAS и можно ли с него записывать и читать данные. Проверить соединение не проблема.

Я работаю на Windows Server 2012 и знаю учетные данные от NAS. Я пытался выдать себя за эти учетные данные, но это не сработало. Я всегда получаю ту же ошибку. Имя пользователя или пароль неверны. Но когда я подключаюсь к проводнику Windows с теми же учетными данными, он работает.

Это мой импорт DLL и необходимые переменные

[DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain,
    String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

// Variables
private IntPtr m_Token;
private WindowsImpersonationContext m_Context = null;
private string m_Domain;
private string m_Password;
private string m_Username;

m_Domain отличается от локального домена

Это настоящее олицетворение

            m_Token = IntPtr.Zero;
            bool logonSuccessfull = LogonUser(
               m_Username,
               m_Domain,
               m_Password,
               (int)LOGON32_TYPE_NETWORK,
               (int)LOGON32_PROVIDER_WINNT50,
               ref m_Token);
            if (logonSuccessfull == false)
            {
                int error = Marshal.GetLastWin32Error();
                throw new Win32Exception(error);
            }
            WindowsIdentity identity = new WindowsIdentity(m_Token);
            m_Context = identity.Impersonate();

LOGON32_TYPE_NETWORK равно 3, LOGON32_PROVIDER_WINNT50 равно 3

Этот код выполняется с правами администратора.

Это ошибка, которая возникает:

System.ComponentModel.Win32Exception (0x80004005): The user name or password is incorrect

Эта ошибка выбрасывается на

if (logonSuccessfull == false)
{
     int error = Marshal.GetLastWin32Error();
     throw new Win32Exception(error);
}

Есть ли другой способ? Или нужно использовать другие LogonType или LogonProvider?

Эти я тоже пробовал, но тоже не работал для меня.

private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_TYPE_NEW_CREDENTIALS = 9;

При использовании LOGON32_TYPE_NEW_CREDENTIALS он не выдает ошибку, а олицетворенный пользователь вообще не меняется.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
178
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я мог бы решить проблему, используя сетевые учетные данные и используя mpr.dll

[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource netResource,
     string password, string username, int flags);
[DllImport("mpr.dll")]
     private static extern int WNetCancelConnection2(string name, int flags, bool force);
[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
  public ResourceScope Scope;
  public ResourceType ResourceType;
  public ResourceDisplaytype DisplayType;
  public int Usage;
  public string LocalName;
  public string RemoteName;
  public string Comment;
  public string Provider;
}
public enum ResourceScope : int
{
  Connected = 1,
  GlobalNetwork,
  Remembered,
  Recent,
  Context
};

public enum ResourceType : int
{
  Any = 0,
  Disk = 1,
  Print = 2,
  Reserved = 8,
}

public enum ResourceDisplaytype : int
{
  Generic = 0x0,
  Domain = 0x01,
  Server = 0x02,
  Share = 0x03,
  File = 0x04,
  Group = 0x05,
  Network = 0x06,
  Root = 0x07,
  Shareadmin = 0x08,
  Directory = 0x09,
  Tree = 0x0a,
  Ndscontainer = 0x0b
}

void ConnectToNas(string username, string password, string networkName){
     NetworkCredential cred = new NetworkCredential(username, password);

     var netResource = new NetResource
     {
          Scope = ResourceScope.GlobalNetwork,
          ResourceType = ResourceType.Disk,
          DisplayType = ResourceDisplaytype.Share,
          RemoteName = networkName
     };

     var result = WNetAddConnection2(netResource, credentials.Password,userName,0);

     if (result != 0)
     {
          throw new Win32Exception(result, "Error while connection to NAS");
     }
}

Для закрытия соединения:

void CloseConnection(string networkName){
     WNetCancelConnection2(networkName, 0, true);
}

Таким образом я смог подключиться к NAS и проверить, доступен ли он для чтения и записи, записав на него файл, прочитав его и затем удалив.

Другие вопросы по теме