From 98fc095611f9af644eb7440a42d0acd48ec9936b Mon Sep 17 00:00:00 2001 From: Alexander Smolyakov Date: Fri, 24 Jun 2022 15:09:23 +0400 Subject: [PATCH] Revert changes related to gMSA account support (#3883) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "Added gMSA accounts support (#3791)" This reverts commit 5d4ca9b780b1e6a223263627e988af9f21677a78. * Revert "Added message - in case when account is not managed, but WindowsLogon… (#3845)" This reverts commit f1cd4f436ccbda0574f51d851b157e10434ecec4. --- .../NativeWindowsServiceHelper.cs | 76 +------------------ .../WindowsServiceControlManager.cs | 15 +--- .../Mocks/MockNativeWindowsServiceHelper.cs | 29 ------- .../NativeWindowsServiceHelperL0.cs | 56 -------------- 4 files changed, 5 insertions(+), 171 deletions(-) delete mode 100644 src/Test/L0/Listener/Configuration/Mocks/MockNativeWindowsServiceHelper.cs diff --git a/src/Agent.Listener/Configuration.Windows/NativeWindowsServiceHelper.cs b/src/Agent.Listener/Configuration.Windows/NativeWindowsServiceHelper.cs index 6b364da81d..40050f6ac5 100644 --- a/src/Agent.Listener/Configuration.Windows/NativeWindowsServiceHelper.cs +++ b/src/Agent.Listener/Configuration.Windows/NativeWindowsServiceHelper.cs @@ -76,10 +76,6 @@ public interface INativeWindowsServiceHelper : IAgentService void GrantDirectoryPermissionForAccount(string accountName, IList folders); void RevokeDirectoryPermissionForAccount(IList folders); - - bool IsWellKnownIdentity(string accountName); - - bool IsManagedServiceAccount(string accountName); } public class NativeWindowsServiceHelper : AgentService, INativeWindowsServiceHelper @@ -374,10 +370,10 @@ public bool GrantUserLogonAsServicePrivilage(string domain, string userName) } } - public bool IsWellKnownIdentity(String accountName) + public static bool IsWellKnownIdentity(String accountName) { - var ntaccount = new NTAccount(accountName); - var sid = (SecurityIdentifier)ntaccount.Translate(typeof(SecurityIdentifier)); + NTAccount ntaccount = new NTAccount(accountName); + SecurityIdentifier sid = (SecurityIdentifier)ntaccount.Translate(typeof(SecurityIdentifier)); SecurityIdentifier networkServiceSid = new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null); SecurityIdentifier localServiceSid = new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null); @@ -457,16 +453,6 @@ public void InstallService(string serviceName, string serviceDisplayName, string { Trace.Entering(); - try - { - var isManagedServiceAccount = IsManagedServiceAccount(logonAccount); - Trace.Info($"Account '{logonAccount}' is managed service account: {isManagedServiceAccount}."); - } - catch (Win32Exception e) - { - Trace.Info($"Fail to check account '{logonAccount}' is managed service account or not due to error: {e.Message}"); - } - string agentServiceExecutable = "\"" + Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), WindowsServiceControlManager.WindowsServiceControllerName) + "\""; IntPtr scmHndl = IntPtr.Zero; IntPtr svcHndl = IntPtr.Zero; @@ -942,40 +928,6 @@ public void RevokeDirectoryPermissionForAccount(IList folders) Trace.Info(StringUtil.Format($"Delete the group {groupName}.")); DeleteLocalGroup(groupName); } - /// - /// Checks if account is managed service - /// - /// account name - /// Returns true if account is managed service. - /// Throws this exception if there is some error during check. - public bool IsManagedServiceAccount(String accountName) - { - bool isServiceAccount; - accountName = SanitizeManagedServiceAccountName(accountName); - var result = this.CheckNetIsServiceAccount(null, accountName, out isServiceAccount); - if (result == 0) - { - return isServiceAccount; - } - else - { - var lastErrorCode = (int)GetLastError(); - throw new Win32Exception(lastErrorCode); - } - } - - /// - /// Checks if account is managed service - /// - /// - /// - /// - /// Returns 0 if account is managed service, otherwise - returns non-zero code - /// Throws exception if there's an error during check - public virtual uint CheckNetIsServiceAccount(string ServerName, string AccountName, out bool isServiceAccount) - { - return NativeWindowsServiceHelper.NetIsServiceAccount(ServerName, AccountName, out isServiceAccount); - } private bool IsValidCredentialInternal(string domain, string userName, string logonPassword, UInt32 logonType) { @@ -1023,25 +975,6 @@ private byte[] GetSidBinaryFromWindows(string domain, string user) } } - /// - /// Removes '$' character from managed service account name - /// - /// account name - /// - private string SanitizeManagedServiceAccountName(string accountName) - { - // remove the last '$' for MSA - ArgUtil.NotNullOrEmpty(accountName, nameof(accountName)); - if (accountName[accountName.Length - 1].Equals('$')) - { - return accountName.Remove(accountName.Length - 1); - } - else - { - return accountName; - } - } - // Helper class not to repeat whenever we deal with LSA* api internal class LsaPolicy : IDisposable { @@ -1336,9 +1269,6 @@ private enum RecoverAction RunCommand = 3 } - [DllImport("Logoncli.dll", SetLastError = true, CharSet = CharSet.Auto)] - private static extern uint NetIsServiceAccount(string ServerName, string AccountName, [MarshalAs(UnmanagedType.Bool)] out bool IsServiceAccount); - [DllImport("Netapi32.dll")] private extern static int NetLocalGroupGetInfo(string servername, string groupname, diff --git a/src/Agent.Listener/Configuration.Windows/WindowsServiceControlManager.cs b/src/Agent.Listener/Configuration.Windows/WindowsServiceControlManager.cs index 84cdd0734f..27ff33adf0 100644 --- a/src/Agent.Listener/Configuration.Windows/WindowsServiceControlManager.cs +++ b/src/Agent.Listener/Configuration.Windows/WindowsServiceControlManager.cs @@ -67,22 +67,11 @@ public void ConfigureService(AgentSettings settings, CommandSettings command) Trace.Info("LogonAccount after transforming: {0}, user: {1}, domain: {2}", logonAccount, userName, domainName); string logonPassword = string.Empty; - if (!defaultServiceAccount.Equals(new NTAccount(logonAccount)) && - !_windowsServiceHelper.IsWellKnownIdentity(logonAccount) && - !_windowsServiceHelper.IsManagedServiceAccount(logonAccount)) + if (!defaultServiceAccount.Equals(new NTAccount(logonAccount)) && !NativeWindowsServiceHelper.IsWellKnownIdentity(logonAccount)) { while (true) { - try - { - logonPassword = command.GetWindowsLogonPassword(logonAccount); - } - catch (ArgumentException e) - { - Trace.Warning("LogonAccount {0} is not managed service account, although you did not specify WindowsLogonPassword - maybe you wanted to use managed service account? Please see https://aka.ms/gmsa for guidelines to set up sMSA/gMSA account.", logonAccount, userName, domainName); - throw; - } - + logonPassword = command.GetWindowsLogonPassword(logonAccount); if (_windowsServiceHelper.IsValidCredential(domainName, userName, logonPassword)) { Trace.Info("Credential validation succeed"); diff --git a/src/Test/L0/Listener/Configuration/Mocks/MockNativeWindowsServiceHelper.cs b/src/Test/L0/Listener/Configuration/Mocks/MockNativeWindowsServiceHelper.cs deleted file mode 100644 index ede3e2296e..0000000000 --- a/src/Test/L0/Listener/Configuration/Mocks/MockNativeWindowsServiceHelper.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.VisualStudio.Services.Agent.Listener.Configuration; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Test.L0.Listener.Configuration.Mocks -{ - /// - /// Mock class for NativeWindowsServiceHelper - /// Use this to mock any functions of this class - /// - public class MockNativeWindowsServiceHelper : NativeWindowsServiceHelper - { - public bool ShouldAccountBeManagedService { get; set; } - public bool ShouldErrorHappenDuringManagedServiceAccoutCheck { get; set; } - public override uint CheckNetIsServiceAccount(string ServerName, string AccountName, out bool isServiceAccount) - { - isServiceAccount = this.ShouldAccountBeManagedService; - if (ShouldErrorHappenDuringManagedServiceAccoutCheck) - { - return 1; - } - else - { - return 0; - } - } - } -} diff --git a/src/Test/L0/Listener/Configuration/NativeWindowsServiceHelperL0.cs b/src/Test/L0/Listener/Configuration/NativeWindowsServiceHelperL0.cs index a13c892603..b44b247372 100644 --- a/src/Test/L0/Listener/Configuration/NativeWindowsServiceHelperL0.cs +++ b/src/Test/L0/Listener/Configuration/NativeWindowsServiceHelperL0.cs @@ -11,8 +11,6 @@ using System.Security.Principal; using Microsoft.VisualStudio.Services.Agent; using Microsoft.VisualStudio.Services.Agent.Tests; -using Test.L0.Listener.Configuration.Mocks; -using System.ComponentModel; namespace Test.L0.Listener.Configuration { @@ -56,59 +54,5 @@ public void EnsureGetDefaultAdminServiceAccountShouldReturnLocalSystemAccount() Assert.True(defaultServiceAccount.ToString().Equals(@"NT AUTHORITY\SYSTEM"), "If agent is getting configured as deployment agent, default service accout should be 'NT AUTHORITY\\SYSTEM'"); } } - - - [Fact] - [Trait("Level", "L0")] - [Trait("Category", "ConfigurationManagement")] - public void EnsureIsManagedServiceAccount_TrueForManagedAccount() - { - using (TestHostContext tc = new TestHostContext(this, "EnsureIsManagedServiceAccount_TrueForManagedAccount")) - { - Tracing trace = tc.GetTrace(); - - trace.Info("Creating an instance of the MockNativeWindowsServiceHelper class"); - var windowsServiceHelper = new MockNativeWindowsServiceHelper(); - windowsServiceHelper.ShouldAccountBeManagedService = true; - var isManagedServiceAccount = windowsServiceHelper.IsManagedServiceAccount("managedServiceAccount$"); - - Assert.True(isManagedServiceAccount, "Account should be properly determined as managed service"); - } - } - - [Fact] - [Trait("Level", "L0")] - [Trait("Category", "ConfigurationManagement")] - public void EnsureIsManagedServiceAccount_FalseForNonManagedAccount() - { - using (TestHostContext tc = new TestHostContext(this, "EnsureIsManagedServiceAccount_TrueForManagedAccount")) - { - Tracing trace = tc.GetTrace(); - - trace.Info("Creating an instance of the MockNativeWindowsServiceHelper class"); - var windowsServiceHelper = new MockNativeWindowsServiceHelper(); - windowsServiceHelper.ShouldAccountBeManagedService = false; - var isManagedServiceAccount = windowsServiceHelper.IsManagedServiceAccount("managedServiceAccount$"); - - Assert.True(!isManagedServiceAccount, "Account should be properly determined as not managed service"); - } - } - - [Fact] - [Trait("Level", "L0")] - [Trait("Category", "ConfigurationManagement")] - public void EnsureIsManagedServiceAccount_ThrowsExceptionDuringCheck() - { - using (TestHostContext tc = new TestHostContext(this, "EnsureIsManagedServiceAccount_TrueForManagedAccount")) - { - Tracing trace = tc.GetTrace(); - - trace.Info("Creating an instance of the MockNativeWindowsServiceHelper class"); - var windowsServiceHelper = new MockNativeWindowsServiceHelper(); - windowsServiceHelper.ShouldErrorHappenDuringManagedServiceAccoutCheck = true; - - Assert.Throws(() => windowsServiceHelper.IsManagedServiceAccount("managedServiceAccount$")); - } - } } }