mirror of https://github.com/winsw/winsw
				
				
				
			Handle special accounts
							parent
							
								
									bd61d2986f
								
							
						
					
					
						commit
						fcbc087b4b
					
				| 
						 | 
				
			
			@ -9,9 +9,9 @@ namespace WinSW.Native
 | 
			
		|||
    {
 | 
			
		||||
        /// <exception cref="CommandException" />
 | 
			
		||||
        /// <exception cref="Win32Exception" />
 | 
			
		||||
        internal static void AddServiceLogonRight(string userName)
 | 
			
		||||
        internal static void AddServiceLogonRight(ref string userName)
 | 
			
		||||
        {
 | 
			
		||||
            IntPtr sid = GetAccountSid(userName);
 | 
			
		||||
            IntPtr sid = GetAccountSid(ref userName);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -19,13 +19,12 @@ namespace WinSW.Native
 | 
			
		|||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _ = FreeSid(sid);
 | 
			
		||||
                Marshal.FreeHGlobal(sid);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="CommandException" />
 | 
			
		||||
        private static IntPtr GetAccountSid(string accountName)
 | 
			
		||||
        private static IntPtr GetAccountSid(ref string accountName)
 | 
			
		||||
        {
 | 
			
		||||
            int sidSize = 0;
 | 
			
		||||
            int domainNameLength = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -35,24 +34,23 @@ namespace WinSW.Native
 | 
			
		|||
                accountName = Environment.MachineName + accountName.Substring(1);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _ = LookupAccountName(null, accountName, IntPtr.Zero, ref sidSize, IntPtr.Zero, ref domainNameLength, out _);
 | 
			
		||||
            _ = LookupAccountName(null, accountName, IntPtr.Zero, ref sidSize, null, ref domainNameLength, out _);
 | 
			
		||||
 | 
			
		||||
            IntPtr sid = Marshal.AllocHGlobal(sidSize);
 | 
			
		||||
            IntPtr domainName = Marshal.AllocHGlobal(domainNameLength * sizeof(char));
 | 
			
		||||
            string? domainName = domainNameLength == 0 ? null : new string('\0', domainNameLength - 1);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            if (!LookupAccountName(null, accountName, sid, ref sidSize, domainName, ref domainNameLength, out _))
 | 
			
		||||
            {
 | 
			
		||||
                if (!LookupAccountName(null, accountName, sid, ref sidSize, domainName, ref domainNameLength, out _))
 | 
			
		||||
                {
 | 
			
		||||
                    Throw.Command.Win32Exception("Failed to find the account.");
 | 
			
		||||
                }
 | 
			
		||||
                Throw.Command.Win32Exception("Failed to find the account.");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
                return sid;
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            // intentionally undocumented
 | 
			
		||||
            if (!accountName.Contains("\\") && !accountName.Contains("@"))
 | 
			
		||||
            {
 | 
			
		||||
                Marshal.FreeHGlobal(domainName);
 | 
			
		||||
                accountName = domainName + '\\' + accountName;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return sid;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <exception cref="Win32Exception" />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,6 @@ namespace WinSW.Native
 | 
			
		|||
{
 | 
			
		||||
    internal static class SecurityApis
 | 
			
		||||
    {
 | 
			
		||||
        [DllImport(Libraries.Advapi32, SetLastError = false)]
 | 
			
		||||
        internal static extern IntPtr FreeSid(IntPtr sid);
 | 
			
		||||
 | 
			
		||||
        [DllImport(Libraries.Advapi32, SetLastError = true)]
 | 
			
		||||
        internal static extern bool GetTokenInformation(
 | 
			
		||||
            IntPtr tokenHandle,
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +21,7 @@ namespace WinSW.Native
 | 
			
		|||
            string accountName,
 | 
			
		||||
            IntPtr sid,
 | 
			
		||||
            ref int sidSize,
 | 
			
		||||
            IntPtr referencedDomainName,
 | 
			
		||||
            string? referencedDomainName,
 | 
			
		||||
            ref int referencedDomainNameLength,
 | 
			
		||||
            out int use);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -345,7 +345,7 @@ namespace WinSW
 | 
			
		|||
                    username = config.ServiceAccountUserName ?? username;
 | 
			
		||||
                    password = config.ServiceAccountPassword ?? password;
 | 
			
		||||
 | 
			
		||||
                    if (username is null || password is null)
 | 
			
		||||
                    if (username is null || password is null && !IsSpecialAccount(username))
 | 
			
		||||
                    {
 | 
			
		||||
                        switch (config.ServiceAccountPrompt)
 | 
			
		||||
                        {
 | 
			
		||||
| 
						 | 
				
			
			@ -364,9 +364,9 @@ namespace WinSW
 | 
			
		|||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (username != null)
 | 
			
		||||
                if (username != null && !IsSpecialAccount(username))
 | 
			
		||||
                {
 | 
			
		||||
                    Security.AddServiceLogonRight(username);
 | 
			
		||||
                    Security.AddServiceLogonRight(ref username);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                using Service sc = scm.CreateService(
 | 
			
		||||
| 
						 | 
				
			
			@ -422,7 +422,7 @@ namespace WinSW
 | 
			
		|||
                        username = Console.ReadLine();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (password is null)
 | 
			
		||||
                    if (password is null && !IsSpecialAccount(username))
 | 
			
		||||
                    {
 | 
			
		||||
                        Console.Write("Password: ");
 | 
			
		||||
                        password = ReadPassword();
 | 
			
		||||
| 
						 | 
				
			
			@ -430,6 +430,16 @@ namespace WinSW
 | 
			
		|||
 | 
			
		||||
                    Console.WriteLine();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                static bool IsSpecialAccount(string accountName) => accountName switch
 | 
			
		||||
                {
 | 
			
		||||
                    @"LocalSystem" => true,
 | 
			
		||||
                    @".\LocalSystem" => true,
 | 
			
		||||
                    @"NT AUTHORITY\LocalService" => true,
 | 
			
		||||
                    @"NT AUTHORITY\NetworkService" => true,
 | 
			
		||||
                    string name when name == $@"{Environment.MachineName}\LocalSystem" => true,
 | 
			
		||||
                    _ => false
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void Uninstall(string? pathToConfig, bool noElevate)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue