Exemple #1
0
        public async Task ConfigureAsync(CommandSettings command)
        {
            if (!_windowsServiceHelper.IsRunningInElevatedMode())
            {
                Trace.Error("Needs Administrator privileges to configure agent with AutoLogon capability.");
                throw new SecurityException(StringUtil.Loc("NeedAdminForAutologonCapability"));
            }

            string domainName;
            string userName;
            string logonAccount;
            string logonPassword;

            while (true)
            {
                logonAccount = command.GetWindowsLogonAccount(defaultValue: string.Empty, descriptionMsg: StringUtil.Loc("AutoLogonAccountNameDescription"));
                GetAccountSegments(logonAccount, out domainName, out userName);

                if ((string.IsNullOrEmpty(domainName) || domainName.Equals(".", StringComparison.CurrentCultureIgnoreCase)) && !logonAccount.Contains("@"))
                {
                    logonAccount = String.Format("{0}\\{1}", Environment.MachineName, userName);
                }
                Trace.Info("LogonAccount after transforming: {0}, user: {1}, domain: {2}", logonAccount, userName, domainName);

                logonPassword = command.GetWindowsLogonPassword(logonAccount);
                if (_windowsServiceHelper.IsValidAutoLogonCredential(domainName, userName, logonPassword))
                {
                    Trace.Info("Credential validation succeeded");
                    break;
                }

                if (command.Unattended)
                {
                    throw new SecurityException(StringUtil.Loc("InvalidAutoLogonCredential"));
                }

                Trace.Error("Invalid credential entered.");
                _terminal.WriteError(StringUtil.Loc("InvalidAutoLogonCredential"));
            }

            _autoLogonRegManager.UpdateRegistrySettings(command, domainName, userName, logonPassword);
            _windowsServiceHelper.SetAutoLogonPassword(logonPassword);

            await ConfigurePowerOptions();

            SaveAutoLogonSettings(domainName, userName);
            RestartBasedOnUserInput(command);
        }
Exemple #2
0
        public void ConfigureService(AgentSettings settings, CommandSettings command)
        {
            ArgUtil.NotNull(command, nameof(command));
            Trace.Entering();

            if (!_windowsServiceHelper.IsRunningInElevatedMode())
            {
                Trace.Error("Needs Administrator privileges for configure agent as windows service.");
                throw new SecurityException(StringUtil.Loc("NeedAdminForConfigAgentWinService"));
            }

            // TODO: Fix bug that exists in the legacy Windows agent where configuration using mirrored credentials causes an error, but the agent is still functional (after restarting). Mirrored credentials is a supported scenario and shouldn't manifest any errors.

            // We use NetworkService as default account for build and release agent
            // We use Local System as default account for deployment agent, deployment pool agent, environment vm agent
            bool      isDeploymentGroupScenario = command.GetDeploymentOrMachineGroup() || command.GetDeploymentPool() || command.GetEnvironmentVMResource();
            NTAccount defaultServiceAccount     = isDeploymentGroupScenario ? _windowsServiceHelper.GetDefaultAdminServiceAccount() : _windowsServiceHelper.GetDefaultServiceAccount();
            string    logonAccount = command.GetWindowsLogonAccount(defaultValue: defaultServiceAccount.ToString(), descriptionMsg: StringUtil.Loc("WindowsLogonAccountNameDescription"));

            string domainName;
            string userName;

            GetAccountSegments(logonAccount, out domainName, out userName);

            if ((string.IsNullOrEmpty(domainName) || domainName.Equals(".", StringComparison.CurrentCultureIgnoreCase)) && !logonAccount.Contains('@'))
            {
                logonAccount = String.Format("{0}\\{1}", Environment.MachineName, userName);
                domainName   = Environment.MachineName;
            }

            Trace.Info("LogonAccount after transforming: {0}, user: {1}, domain: {2}", logonAccount, userName, domainName);

            string logonPassword = string.Empty;

            if (!defaultServiceAccount.Equals(new NTAccount(logonAccount)) && !NativeWindowsServiceHelper.IsWellKnownIdentity(logonAccount))
            {
                while (true)
                {
                    logonPassword = command.GetWindowsLogonPassword(logonAccount);
                    if (_windowsServiceHelper.IsValidCredential(domainName, userName, logonPassword))
                    {
                        Trace.Info("Credential validation succeed");
                        break;
                    }
                    else
                    {
                        if (!command.Unattended())
                        {
                            Trace.Info("Invalid credential entered");
                            _term.WriteLine(StringUtil.Loc("InvalidWindowsCredential"));
                        }
                        else
                        {
                            throw new SecurityException(StringUtil.Loc("InvalidWindowsCredential"));
                        }
                    }
                }
            }

            string serviceName;
            string serviceDisplayName;

            CalculateServiceName(settings, ServiceNamePattern, ServiceDisplayNamePattern, out serviceName, out serviceDisplayName);
            if (_windowsServiceHelper.IsServiceExists(serviceName))
            {
                _term.WriteLine(StringUtil.Loc("ServiceAlreadyExists", serviceName));
                _windowsServiceHelper.UninstallService(serviceName);
            }

            Trace.Info("Verifying if the account has LogonAsService permission");
            if (_windowsServiceHelper.IsUserHasLogonAsServicePrivilege(domainName, userName))
            {
                Trace.Info($"Account: {logonAccount} already has Logon As Service Privilege.");
            }
            else
            {
                if (!_windowsServiceHelper.GrantUserLogonAsServicePrivilage(domainName, userName))
                {
                    throw new InvalidOperationException(StringUtil.Loc("CanNotGrantPermission", logonAccount));
                }
            }

            // grant permission for agent root folder and work folder
            Trace.Info("Create local group and grant folder permission to service logon account.");
            string agentRoot  = HostContext.GetDirectory(WellKnownDirectory.Root);
            string workFolder = HostContext.GetDirectory(WellKnownDirectory.Work);

            Directory.CreateDirectory(workFolder);
            _windowsServiceHelper.GrantDirectoryPermissionForAccount(logonAccount, new[] { agentRoot, workFolder });
            _term.WriteLine(StringUtil.Loc("GrantingFilePermissions", logonAccount));

            // install service.
            _windowsServiceHelper.InstallService(serviceName, serviceDisplayName, logonAccount, logonPassword);

            // create .service file with service name.
            SaveServiceSettings(serviceName);

            // Add registry key after installation
            _windowsServiceHelper.CreateVstsAgentRegistryKey();

            Trace.Info("Configuration was successful, trying to start the service");
            if (!command.GetPreventServiceStart())
            {
                _windowsServiceHelper.StartService(serviceName);
            }
        }
Exemple #3
0
        public async Task ConfigureAsync(CommandSettings command)
        {
            ArgUtil.NotNull(command, nameof(command));
            if (!_windowsServiceHelper.IsRunningInElevatedMode())
            {
                Trace.Error("Needs Administrator privileges to configure agent with AutoLogon capability.");
                throw new SecurityException(StringUtil.Loc("NeedAdminForAutologonCapability"));
            }

            string domainName;
            string userName;
            string logonAccount;
            string logonPassword;

            while (true)
            {
                logonAccount = command.GetWindowsLogonAccount(defaultValue: string.Empty, descriptionMsg: StringUtil.Loc("AutoLogonAccountNameDescription"));
                GetAccountSegments(logonAccount, out domainName, out userName);

                if ((string.IsNullOrEmpty(domainName) || domainName.Equals(".", StringComparison.CurrentCultureIgnoreCase)) && !logonAccount.Contains("@"))
                {
                    logonAccount = String.Format("{0}\\{1}", Environment.MachineName, userName);
                    domainName   = Environment.MachineName;
                }
                Trace.Info("LogonAccount after transforming: {0}, user: {1}, domain: {2}", logonAccount, userName, domainName);

                logonPassword = command.GetWindowsLogonPassword(logonAccount);
                if (_windowsServiceHelper.IsValidAutoLogonCredential(domainName, userName, logonPassword))
                {
                    Trace.Info("Credential validation succeeded");
                    break;
                }

                if (command.Unattended())
                {
                    throw new SecurityException(StringUtil.Loc("InvalidAutoLogonCredential"));
                }

                Trace.Error("Invalid credential entered.");
                _terminal.WriteError(StringUtil.Loc("InvalidAutoLogonCredential"));
            }

            _autoLogonRegManager.GetAutoLogonUserDetails(out string currentAutoLogonUserDomainName, out string currentAutoLogonUserName);

            if (currentAutoLogonUserName != null &&
                !userName.Equals(currentAutoLogonUserName, StringComparison.CurrentCultureIgnoreCase) &&
                !domainName.Equals(currentAutoLogonUserDomainName, StringComparison.CurrentCultureIgnoreCase))
            {
                string currentAutoLogonAccount = String.Format("{0}\\{1}", currentAutoLogonUserDomainName, currentAutoLogonUserName);
                if (string.IsNullOrEmpty(currentAutoLogonUserDomainName) || currentAutoLogonUserDomainName.Equals(".", StringComparison.CurrentCultureIgnoreCase))
                {
                    currentAutoLogonAccount = String.Format("{0}\\{1}", Environment.MachineName, currentAutoLogonUserName);
                }

                Trace.Warning($"AutoLogon already enabled for {currentAutoLogonAccount}.");
                if (!command.GetOverwriteAutoLogon(currentAutoLogonAccount))
                {
                    Trace.Error("Marking the agent configuration as failed due to the denial of autologon setting overwriting by the user.");
                    throw new InvalidOperationException(StringUtil.Loc("AutoLogonOverwriteDeniedError", currentAutoLogonAccount));
                }
                Trace.Info($"Continuing with the autologon configuration.");
            }

            // grant permission for agent root folder and work folder
            Trace.Info("Create local group and grant folder permission to logon account.");
            string agentRoot  = HostContext.GetDirectory(WellKnownDirectory.Root);
            string workFolder = HostContext.GetDirectory(WellKnownDirectory.Work);

            Directory.CreateDirectory(workFolder);
            _windowsServiceHelper.GrantDirectoryPermissionForAccount(logonAccount, new[] { agentRoot, workFolder });

            _autoLogonRegManager.UpdateRegistrySettings(command, domainName, userName, logonPassword);
            _windowsServiceHelper.SetAutoLogonPassword(logonPassword);

            await ConfigurePowerOptions();

            SaveAutoLogonSettings(domainName, userName);
            RestartBasedOnUserInput(command);
        }
Exemple #4
0
        public void ConfigureService(RunnerSettings settings, CommandSettings command)
        {
            Trace.Entering();

            if (!_windowsServiceHelper.IsRunningInElevatedMode())
            {
                Trace.Error("Needs Administrator privileges for configure runner as windows service.");
                throw new SecurityException("Needs Administrator privileges for configuring runner as windows service.");
            }

            // We use NetworkService as default account for actions runner
            NTAccount defaultServiceAccount = _windowsServiceHelper.GetDefaultServiceAccount();
            string    logonAccount          = command.GetWindowsLogonAccount(defaultValue: defaultServiceAccount.ToString(), descriptionMsg: "User account to use for the service");

            string domainName;
            string userName;

            GetAccountSegments(logonAccount, out domainName, out userName);

            if ((string.IsNullOrEmpty(domainName) || domainName.Equals(".", StringComparison.CurrentCultureIgnoreCase)) && !logonAccount.Contains('@'))
            {
                logonAccount = String.Format("{0}\\{1}", Environment.MachineName, userName);
                domainName   = Environment.MachineName;
            }

            Trace.Info("LogonAccount after transforming: {0}, user: {1}, domain: {2}", logonAccount, userName, domainName);

            string logonPassword = string.Empty;

            if (!defaultServiceAccount.Equals(new NTAccount(logonAccount)) && !NativeWindowsServiceHelper.IsWellKnownIdentity(logonAccount))
            {
                while (true)
                {
                    logonPassword = command.GetWindowsLogonPassword(logonAccount);
                    if (_windowsServiceHelper.IsValidCredential(domainName, userName, logonPassword))
                    {
                        Trace.Info("Credential validation succeed");
                        break;
                    }
                    else
                    {
                        if (!command.Unattended)
                        {
                            Trace.Info("Invalid credential entered");
                            _term.WriteLine("Invalid windows credentials entered. Try again or ctrl-c to quit");
                        }
                        else
                        {
                            throw new SecurityException("Invalid windows credentials entered. Try again or ctrl-c to quit");
                        }
                    }
                }
            }

            string serviceName;
            string serviceDisplayName;

            CalculateServiceName(settings, ServiceNamePattern, ServiceDisplayNamePattern, out serviceName, out serviceDisplayName);
            if (_windowsServiceHelper.IsServiceExists(serviceName))
            {
                _term.WriteLine($"The service already exists: {serviceName}, it will be replaced");
                _windowsServiceHelper.UninstallService(serviceName);
            }

            Trace.Info("Verifying if the account has LogonAsService permission");
            if (_windowsServiceHelper.IsUserHasLogonAsServicePrivilege(domainName, userName))
            {
                Trace.Info($"Account: {logonAccount} already has Logon As Service Privilege.");
            }
            else
            {
                if (!_windowsServiceHelper.GrantUserLogonAsServicePrivilege(domainName, userName))
                {
                    throw new InvalidOperationException($"Cannot grant LogonAsService permission to the user {logonAccount}");
                }
            }

            // grant permission for runner root folder and work folder
            Trace.Info("Create local group and grant folder permission to service logon account.");
            string runnerRoot = HostContext.GetDirectory(WellKnownDirectory.Root);
            string workFolder = HostContext.GetDirectory(WellKnownDirectory.Work);

            Directory.CreateDirectory(workFolder);
            _windowsServiceHelper.GrantDirectoryPermissionForAccount(logonAccount, new[] { runnerRoot, workFolder });
            _term.WriteLine($"Granting file permissions to '{logonAccount}'.");

            // install service.
            _windowsServiceHelper.InstallService(serviceName, serviceDisplayName, logonAccount, logonPassword);

            // create .service file with service name.
            SaveServiceSettings(serviceName);

            Trace.Info("Configuration was successful, trying to start the service");
            _windowsServiceHelper.StartService(serviceName);
        }