Создайте общий ресурс SMB в C # с дескриптором безопасности - PullRequest
0 голосов
/ 04 октября 2018

Я сохраняю свою информацию SMB Share на диск, чтобы я мог восстановить ее позже при необходимости.

Для этого я использую класс MSFT_SMB ​​.Я получаю все общие ресурсы SMB на своем локальном компьютере и сохраняю данные на диск.Дескриптор безопасности, полученный следующим образом, в строковом формате.

Это код, который получает все общие ресурсы:

      private const string SmbNamespace = "\\\\.\\ROOT\\Microsoft\\Windows\\SMB";
      private const string SmbShareClass = "MSFT_SmbShare";
      private const string CreateShareMethod = "CreateShare";
      private const string GetShareMethod = "GetShare";

          public virtual List<SmbShareInfo> GetAllSmbShares()
      {
          ManagementClass SmbShares = new ManagementClass(SmbNamespace + ":" + SmbShareClass);
          List<SmbShareInfo> sharesPresent = new List<SmbShareInfo>();

          try
          {
              foreach (ManagementObject smbObject in SmbShares.GetInstances())
              {
                  sharesPresent.Add(constructSmbShareInfo(smbObject));
              }
              return sharesPresent;
          }
          catch (ManagementException e)
          {
              throw new Exception(e.ToString());
          }
      }

      private SmbShareInfo constructSmbShareInfo(ManagementObject smbObject)
      {
          return new SmbShareInfo(
              Convert.ToString(smbObject["Name"]),
              Convert.ToString(smbObject["Path"]),
              Convert.ToString(smbObject["Description"]),
              Convert.ToBoolean(smbObject["Special"]),
              Convert.ToUInt32(smbObject["ConcurrentUserLimit"]),
              Convert.ToString(smbObject["SecurityDescriptor"]),
              Convert.ToUInt32(smbObject["ShareType"]),
              Convert.ToUInt32(smbObject["FolderEnumerationMode"]),
              Convert.ToBoolean(smbObject["EncryptData"]),
              Convert.ToUInt32(smbObject["CachingMode"]));
      }

Где SmbShareInfo - это класс, который я определил для хранения общего ресурса SMB.информация локально

Теперь, когда я пытаюсь снова создать общий ресурс (на новом компьютере с Windows), метод CreateShare ожидает «Имя дескриптора безопасности общего ресурса».

Как получить «имя» дескриптора безопасности и создать общий ресурс?У меня просто есть строковые дескрипторы безопасности, такие как:

O:SYG:SYD:(A;;GA;;;BA)(A;;GA;;;BO)(A;;GA;;;IU)

Это мой код для создания общего ресурса:

          ManagementObject managementObject = new ManagementClass(SmbNamespace + ":" + SmbShareClass);
          managementObject.Get();

          string[] accountNames = { "Everyone" };
          ManagementBaseObject createShareInParameters = managementObject.GetMethodParameters(CreateShareMethod);
          createShareInParameters["Name"] = fileShare.Name;
          createShareInParameters["Path"] = fileShare.Path;
          createShareInParameters["Description"] = fileShare.Description;
          createShareInParameters["ConcurrentUserLimit"] = fileShare.ConcurrentUserLimit;
          // Enable this
          //createShareInParameters["SecurityDescriptor"] = fileShare.SecurityDescriptor;
          createShareInParameters["FolderEnumerationMode"] = fileShare.FolderEnumerationMode;
          createShareInParameters["EncryptData"] = fileShare.EncryptData;
          createShareInParameters["CachingMode"] = fileShare.CachingMode;
          createShareInParameters["FullAccess"] = accountNames;

          managementObject.InvokeMethod(CreateShareMethod, createShareInParameters, null);

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

В моем коде была ошибка, наряду с дескриптором безопасности я также использовал атрибут FullAccess, который имел приоритет над дескрипторами безопасности.В конечном итоге этот код работал:

ManagementObject managementObject = new ManagementClass (SmbNamespace + ":" + SmbShareClass);managementObject.Get ();

      ManagementBaseObject createShareInParameters = managementObject.GetMethodParameters(CreateShareMethod);
      createShareInParameters["Name"] = fileShare.Name;
      createShareInParameters["Path"] = fileShare.Path;
      createShareInParameters["Description"] = fileShare.Description;
      createShareInParameters["ConcurrentUserLimit"] = fileShare.ConcurrentUserLimit;
      createShareInParameters["SecurityDescriptor"] = fileShare.SecurityDescriptor;
      createShareInParameters["FolderEnumerationMode"] = fileShare.FolderEnumerationMode;
      createShareInParameters["EncryptData"] = fileShare.EncryptData;
      createShareInParameters["CachingMode"] = fileShare.CachingMode;

      managementObject.InvokeMethod(CreateShareMethod, createShareInParameters, null);
0 голосов
/ 04 октября 2018

Я понял, что вы спрашиваете о c #, но позвольте мне предложить вам интересную альтернативу.

Вы можете использовать Get-SmbShare PowerShell вместе с New-SmbShare Сохранение настроек, если необходимо, в конфигурационный файл, возможно, в середине.Что было бы тривиально по сравнению с c #.

РЕДАКТИРОВАТЬ: И Get-SmbShareAccess / Grant-SmbShareAccess для бита описания безопасности (ACL).

Конечно, я не знаю о полном объеме проекта, который вы делаете, но такие вещи, как автоматизация системы, - это то, что дает PowerShell.На самом деле PowerShell в основном оборачивает библиотеки c # и представляет собой простой в использовании API.

Я говорю это как опытный разработчик c #, который недавно осознал всю мощь PowerShell (необходимую для нашего ландшафта DevOps).

Я понимаю, что это не ответ , а, возможно, интересная альтернатива для некоторых сценариев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...