private void UpdateServerFilesPermissions()

in Configurator/Core/Server/ServerConfigurationController.cs [3346:3481]


    private void UpdateServerFilesPermissions()
    {
      CancellationToken.ThrowIfCancellationRequested();
      if (FullControlDictionary.Count == 0)
      {
        try
        {
          var _administratorsGroup = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
          var _creatorOwnerUser = new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, null);
          var _systemAccountUser = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
          if (Settings.ConfigureAsService)
          {
            var serviceAccountUsername = Settings.ServiceAccountUsername.StartsWith(".")
                                       ? Settings.ServiceAccountUsername.Replace(".", Environment.MachineName)
                                       : Settings.ServiceAccountUsername;
            var sid = DirectoryServicesWrapper.GetSecurityIdentifier(serviceAccountUsername);
            if (sid == null)
            {
              Logger.LogError(string.Format(Resources.ServerConfigSidRetrievalFailure, Settings.ServiceAccountUsername));
            }
            else
            {
              FullControlDictionary.Add(sid, "User");
            }
          }

          FullControlDictionary.Add(_administratorsGroup, "Group");
          FullControlDictionary.Add(_creatorOwnerUser, "User");
          FullControlDictionary.Add(_systemAccountUser, "User");
        }
        catch (Exception ex)
        {
          Logger.LogException(ex);
        }
      }

      var success = true;
      ReportStatus(Resources.ServerConfigEventServerSecurityInfo);
      if (!IsThereServerDataFiles)
      {
        ReportStatus(Resources.ServerConfigDataDirectoryDoesNotExist);
        success = false;
      }
      else
      {
        // If permissions have already been updated, skip.
        if (ValidateServerFilesHaveRecommendedPermissions())
        {
          ReportStatus(Resources.ServerUpdateServerFilePermissionsNotNeeded);
          CurrentStep.Status = ConfigurationStepStatus.Finished;
          return;
        }
        
        var serverInstanceInfo = new MySqlServerInstance(this, ReportStatus);
        if (serverInstanceInfo.IsRunning)
        {
          ReportStatus(Resources.ServerConfigInstanceRunning);
          success = false;
        }
        else
        {
          var dataDirectory = Path.Combine(DataDirectory, "Data");
          var usersGroupSid = new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null);

          // First convert inherited permissions to explicit permissions.
          if (DirectoryServicesWrapper.DirectoryPermissionsAreInherited(dataDirectory) == true)
          {
            success = DirectoryServicesWrapper.ConvertInheritedPermissionsToExplicitPermissions(dataDirectory, true);
            ReportStatus(success
                           ? Resources.ServerConfigConvertToExplicitPermissionsSuccess
                           : Resources.ServerConfigConvertToExplicitPermissionsFailed);
          }

          // Next grant full control to selected users/groups.
          if (success)
          {
            foreach (var item in FullControlDictionary)
            {
              var accountName = DirectoryServicesWrapper.GetAccountName(item.Key);
              if (!DirectoryServicesWrapper.GrantPermissionsToDirectory(dataDirectory, accountName, FileSystemRights.FullControl, AccessControlType.Allow, true))
              {
                ReportStatus(string.Format(Resources.ServerConfigGrantedFullControlFailed, DirectoryServicesWrapper.GetAccountName(item.Key)));
                break;
              }

              ReportStatus(string.Format(Resources.ServerConfigGrantedFullControlSuccess, DirectoryServicesWrapper.GetAccountName(item.Key)));
            }
          }
          
          // Then remove access to all other users/groups.
          if (success)
          {
            // Remove all access to the users group.
            success = DirectoryServicesWrapper.RemoveGroupPermissions(dataDirectory, usersGroupSid, true);
            ReportStatus(success
                           ? string.Format(Resources.ServerConfigRemovedAccessSuccess, "users", "group")
                           : string.Format(Resources.ServerConfigRemovedAccessFailed, "users", "group"));

            // Get account names for logging purposes.
            var accountNames = new List<string>();
            foreach (var item in FullControlDictionary)
            {
              var accountName = DirectoryServicesWrapper.GetAccountName(item.Key);
              if (string.IsNullOrEmpty(accountName))
              {
                continue;
              }

              accountNames.Add(accountName);
            }

            // Remove all access to any other user/group not in the Full Control list.
            var rules = DirectoryServicesWrapper.GetAuthorizationRules(new DirectoryInfo(dataDirectory));
            foreach (FileSystemAccessRule rule in rules)
            {
              var ruleValue = rule.IdentityReference.Value;
              var account = new NTAccount(ruleValue.Contains("\\") ? ruleValue.Split('\\')[1] : ruleValue);
              if (accountNames.Contains(account.Value))
              {
                continue;
              }

              DirectoryServicesWrapper.RemoveGroupPermissions(dataDirectory, DirectoryServicesWrapper.GetSecurityIdentifier(account.Value), true);
            }
          }
        }
      }

      var message = success
        ? Resources.ServerConfigEventServerSecuritySuccess
        : Resources.ServerConfigEventServerSecurityFailed;
      ReportStatus(message);
      CurrentStep.Status = success
        ? ConfigurationStepStatus.Finished
        : ConfigurationStepStatus.Error;
    }