From: Jean Flach Date: Fri, 26 Feb 2016 12:42:36 +0000 (+0100) Subject: Add option to choose icinga2s user X-Git-Tag: v2.6.0~75 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4b61aee90c97c1e7fed7cf91b4e34c61ebc8c1d7;p=icinga2 Add option to choose icinga2s user Adds the --scm-user option and a check box and text field in the Agent fixes #9119 --- diff --git a/agent/windows-setup-agent/Program.cs b/agent/windows-setup-agent/Program.cs index e132bc1b1..4b85731f1 100644 --- a/agent/windows-setup-agent/Program.cs +++ b/agent/windows-setup-agent/Program.cs @@ -9,52 +9,69 @@ namespace Icinga { static class Program { - [DllImport("msi.dll", SetLastError = true)] - static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf); + [DllImport("msi.dll", SetLastError = true)] + static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf); - [DllImport("msi.dll", CharSet = CharSet.Unicode)] - static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len); + [DllImport("msi.dll", CharSet = CharSet.Unicode)] + static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len); - public static string Icinga2InstallDir + public static string Icinga2InstallDir { get { - StringBuilder szProduct; + StringBuilder szProduct; - for (int index = 0; ; index++) { - szProduct = new StringBuilder(39); - if (MsiEnumProducts(index, szProduct) != 0) - break; + for (int index = 0; ; index++) { + szProduct = new StringBuilder(39); + if (MsiEnumProducts(index, szProduct) != 0) + break; - int cbName = 128; - StringBuilder szName = new StringBuilder(cbName); + int cbName = 128; + StringBuilder szName = new StringBuilder(cbName); - if (MsiGetProductInfo(szProduct.ToString(), "ProductName", szName, ref cbName) != 0) - continue; + if (MsiGetProductInfo(szProduct.ToString(), "ProductName", szName, ref cbName) != 0) + continue; - if (szName.ToString() != "Icinga 2") - continue; + if (szName.ToString() != "Icinga 2") + continue; - int cbLocation = 1024; - StringBuilder szLocation = new StringBuilder(cbLocation); - if (MsiGetProductInfo(szProduct.ToString(), "InstallLocation", szLocation, ref cbLocation) == 0) - return szLocation.ToString(); - } + int cbLocation = 1024; + StringBuilder szLocation = new StringBuilder(cbLocation); + if (MsiGetProductInfo(szProduct.ToString(), "InstallLocation", szLocation, ref cbLocation) == 0) + return szLocation.ToString(); + } - return ""; + return ""; } } - public static string Icinga2DataDir - { - get - { - return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\icinga2"; - } - } + public static string Icinga2DataDir + { + get + { + return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\icinga2"; + } + } + + public static string Icinga2User + { + get + { + if (!File.Exists(Icinga2DataDir + "\\etc\\icinga2\\user")) + return "NT AUTHORITY\\NetworkService"; + System.IO.StreamReader file = new System.IO.StreamReader(Icinga2DataDir + "\\etc\\icinga2\\user"); + string line = file.ReadLine(); + file.Close(); + + if (line != null) + return line; + else + return "NT AUTHORITY\\NetworkService"; + } + } - public static void FatalError(Form owner, string message) + public static void FatalError(Form owner, string message) { MessageBox.Show(owner, message, "Icinga 2 Setup Wizard", MessageBoxButtons.OK, MessageBoxIcon.Error); Application.Exit(); @@ -71,10 +88,10 @@ namespace Icinga string installDir = Program.Icinga2InstallDir; - if (installDir == "") { - FatalError(null, "Icinga 2 does not seem to be installed properly."); - return; - } + if (installDir == "") { + FatalError(null, "Icinga 2 does not seem to be installed properly."); + return; + } Form form; diff --git a/agent/windows-setup-agent/SetupWizard.Designer.cs b/agent/windows-setup-agent/SetupWizard.Designer.cs index 8a2374bc6..edca6c2e9 100644 --- a/agent/windows-setup-agent/SetupWizard.Designer.cs +++ b/agent/windows-setup-agent/SetupWizard.Designer.cs @@ -39,6 +39,9 @@ this.prgConfig = new System.Windows.Forms.ProgressBar(); this.tabParameters = new System.Windows.Forms.TabPage(); this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.txtUser = new System.Windows.Forms.TextBox(); + this.chkDifferentUser = new System.Windows.Forms.CheckBox(); + this.chkInstallNSCP = new System.Windows.Forms.CheckBox(); this.chkAcceptConfig = new System.Windows.Forms.CheckBox(); this.chkAcceptCommands = new System.Windows.Forms.CheckBox(); this.txtTicket = new System.Windows.Forms.TextBox(); @@ -78,7 +81,6 @@ this.txtError = new System.Windows.Forms.TextBox(); this.lblError = new System.Windows.Forms.Label(); this.picBanner = new System.Windows.Forms.PictureBox(); - this.chkInstallNSCP = new System.Windows.Forms.CheckBox(); this.tabFinish.SuspendLayout(); this.tabConfigure.SuspendLayout(); this.tabParameters.SuspendLayout(); @@ -192,20 +194,52 @@ // // groupBox3 // + this.groupBox3.Controls.Add(this.txtUser); + this.groupBox3.Controls.Add(this.chkDifferentUser); this.groupBox3.Controls.Add(this.chkInstallNSCP); this.groupBox3.Controls.Add(this.chkAcceptConfig); this.groupBox3.Controls.Add(this.chkAcceptCommands); this.groupBox3.Location = new System.Drawing.Point(308, 359); this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(301, 111); + this.groupBox3.Size = new System.Drawing.Size(301, 135); this.groupBox3.TabIndex = 5; this.groupBox3.TabStop = false; this.groupBox3.Text = "Advanced Options"; // + // txtUser + // + this.txtUser.Location = new System.Drawing.Point(28, 111); + this.txtUser.Name = "txtUser"; + this.txtUser.ReadOnly = true; + this.txtUser.Size = new System.Drawing.Size(267, 20); + this.txtUser.TabIndex = 8; + this.txtUser.Text = "NT AUTHORITY\\NetworkService"; + // + // chkDifferentUser + // + this.chkDifferentUser.AutoSize = true; + this.chkDifferentUser.Location = new System.Drawing.Point(9, 88); + this.chkDifferentUser.Name = "chkDifferentUser"; + this.chkDifferentUser.Size = new System.Drawing.Size(109, 17); + this.chkDifferentUser.TabIndex = 7; + this.chkDifferentUser.Text = "Use different user"; + this.chkDifferentUser.UseVisualStyleBackColor = true; + this.chkDifferentUser.CheckedChanged += new System.EventHandler(this.chkDifferentUser_CheckedChanged); + // + // chkInstallNSCP + // + this.chkInstallNSCP.AutoSize = true; + this.chkInstallNSCP.Location = new System.Drawing.Point(9, 65); + this.chkInstallNSCP.Name = "chkInstallNSCP"; + this.chkInstallNSCP.Size = new System.Drawing.Size(149, 17); + this.chkInstallNSCP.TabIndex = 6; + this.chkInstallNSCP.Text = "Install/Update NSClient++"; + this.chkInstallNSCP.UseVisualStyleBackColor = true; + // // chkAcceptConfig // this.chkAcceptConfig.AutoSize = true; - this.chkAcceptConfig.Location = new System.Drawing.Point(9, 47); + this.chkAcceptConfig.Location = new System.Drawing.Point(9, 42); this.chkAcceptConfig.Name = "chkAcceptConfig"; this.chkAcceptConfig.Size = new System.Drawing.Size(190, 17); this.chkAcceptConfig.TabIndex = 1; @@ -215,7 +249,7 @@ // chkAcceptCommands // this.chkAcceptCommands.AutoSize = true; - this.chkAcceptCommands.Location = new System.Drawing.Point(9, 24); + this.chkAcceptCommands.Location = new System.Drawing.Point(9, 19); this.chkAcceptCommands.Name = "chkAcceptCommands"; this.chkAcceptCommands.Size = new System.Drawing.Size(171, 17); this.chkAcceptCommands.TabIndex = 0; @@ -262,7 +296,7 @@ this.groupBox2.Controls.Add(this.rdoListener); this.groupBox2.Location = new System.Drawing.Point(8, 359); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(294, 111); + this.groupBox2.Size = new System.Drawing.Size(294, 135); this.groupBox2.TabIndex = 2; this.groupBox2.TabStop = false; this.groupBox2.Text = "TCP Listener"; @@ -347,9 +381,9 @@ // lvwEndpoints // this.lvwEndpoints.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.colInstanceName, - this.colHost, - this.colPort}); + this.colInstanceName, + this.colHost, + this.colPort}); this.lvwEndpoints.FullRowSelect = true; this.lvwEndpoints.Location = new System.Drawing.Point(11, 83); this.lvwEndpoints.Name = "lvwEndpoints"; @@ -488,8 +522,8 @@ // lvwX509Fields // this.lvwX509Fields.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.colField, - this.colValue}); + this.colField, + this.colValue}); this.lvwX509Fields.Location = new System.Drawing.Point(6, 19); this.lvwX509Fields.Name = "lvwX509Fields"; this.lvwX509Fields.Size = new System.Drawing.Size(586, 172); @@ -592,16 +626,6 @@ this.picBanner.TabIndex = 1; this.picBanner.TabStop = false; // - // chkInstallNSCP - // - this.chkInstallNSCP.AutoSize = true; - this.chkInstallNSCP.Location = new System.Drawing.Point(9, 70); - this.chkInstallNSCP.Name = "chkInstallNSCP"; - this.chkInstallNSCP.Size = new System.Drawing.Size(149, 17); - this.chkInstallNSCP.TabIndex = 6; - this.chkInstallNSCP.Text = "Install/Update NSClient++"; - this.chkInstallNSCP.UseVisualStyleBackColor = true; - // // SetupWizard // this.AcceptButton = this.btnNext; @@ -693,10 +717,12 @@ private System.Windows.Forms.TextBox txtTicket; private System.Windows.Forms.Label lblTicket; private System.Windows.Forms.ColumnHeader colInstanceName; - private System.Windows.Forms.GroupBox groupBox3; - private System.Windows.Forms.CheckBox chkAcceptConfig; - private System.Windows.Forms.CheckBox chkAcceptCommands; - private System.Windows.Forms.CheckBox chkInstallNSCP; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.CheckBox chkAcceptConfig; + private System.Windows.Forms.CheckBox chkAcceptCommands; + private System.Windows.Forms.CheckBox chkInstallNSCP; + private System.Windows.Forms.TextBox txtUser; + private System.Windows.Forms.CheckBox chkDifferentUser; } } diff --git a/agent/windows-setup-agent/SetupWizard.cs b/agent/windows-setup-agent/SetupWizard.cs index f100cc64d..a1733e5a2 100644 --- a/agent/windows-setup-agent/SetupWizard.cs +++ b/agent/windows-setup-agent/SetupWizard.cs @@ -18,12 +18,16 @@ namespace Icinga public partial class SetupWizard : Form { private string _TrustedFile; + private string Icinga2User; public SetupWizard() { InitializeComponent(); txtInstanceName.Text = Icinga2InstanceName; + + Icinga2User = Program.Icinga2User; + txtUser.Text = Icinga2User; } private void Warning(string message) @@ -121,10 +125,12 @@ namespace Icinga String result = ""; using (Process proc = Process.Start(psi)) { - proc.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs args) { + proc.ErrorDataReceived += delegate (object sender, DataReceivedEventArgs args) + { result += args.Data + "\r\n"; }; - proc.OutputDataReceived += delegate(object sender, DataReceivedEventArgs args) { + proc.OutputDataReceived += delegate (object sender, DataReceivedEventArgs args) + { result += args.Data + "\r\n"; }; proc.BeginOutputReadLine(); @@ -186,7 +192,8 @@ namespace Icinga if (rdoNewMaster.Checked) args += " --master"; - Invoke((MethodInvoker)delegate { + Invoke((MethodInvoker)delegate + { string master_host, master_port; GetMasterHostPort(out master_host, out master_port); @@ -194,7 +201,7 @@ namespace Icinga foreach (ListViewItem lvi in lvwEndpoints.Items) { args += " --endpoint " + lvi.SubItems[0].Text; - + if (lvi.SubItems.Count > 1) args += "," + lvi.SubItems[1].Text + "," + lvi.SubItems[2].Text; } @@ -224,11 +231,16 @@ namespace Icinga SetConfigureStatus(50, "Setting ACLs for the Icinga 2 directory..."); DirectoryInfo di = new DirectoryInfo(Program.Icinga2InstallDir); DirectorySecurity ds = di.GetAccessControl(); - FileSystemAccessRule rule = new FileSystemAccessRule("NT AUTHORITY\\NetworkService", + FileSystemAccessRule rule = new FileSystemAccessRule(txtUser.Text, FileSystemRights.Modify, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow); - ds.AddAccessRule(rule); - di.SetAccessControl(ds); + try { + ds.AddAccessRule(rule); + di.SetAccessControl(ds); + } catch (System.Security.Principal.IdentityNotMappedException) { + ShowErrorText("Could not set ACLs for \"" + txtUser.Text + "\". Identitiy is not mapped.\n"); + return; + } SetConfigureStatus(75, "Installing the Icinga 2 service..."); @@ -244,14 +256,14 @@ namespace Icinga } if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", - "--scm-install daemon", + "--scm-install --scm-user \"" + txtUser.Text + "\" daemon", out output)) { - ShowErrorText("Running command 'icinga2.exe daemon --scm-install daemon' produced the following output:\n" + output); + ShowErrorText("\nRunning command 'icinga2.exe --scm-install --scm-user \"" + + txtUser.Text + "\" daemon' produced the following output:\n" + output); return; } - if (chkInstallNSCP.Checked) - { + if (chkInstallNSCP.Checked) { SetConfigureStatus(85, "Waiting for NSClient++ installation to complete..."); Process proc = new Process(); @@ -321,6 +333,11 @@ namespace Icinga Warning("You need to specify a listener port."); return; } + + if (txtUser.Text.Length == 0) { + Warning("Icinga2 user may not be empty."); + return; + } } if (tbcPages.SelectedTab == tabFinish || tbcPages.SelectedTab == tabError) @@ -356,7 +373,7 @@ namespace Icinga thread.Start(); } - /*if (tbcPages.SelectedTab == tabParameters && + /*if (tbcPages.SelectedTab == tabParameters && !File.Exists(Icinga2DataDir + "\\etc\\icinga2\\pki\\agent\\agent.crt")) { byte[] bytes = Convert.FromBase64String(txtBundle.Text); MemoryStream ms = new MemoryStream(bytes); @@ -372,7 +389,7 @@ namespace Icinga tr.ReadToEnd(Icinga2DataDir + "\\etc\\icinga2\\pki\\agent"); }*/ - if (tbcPages.SelectedTab == tabConfigure) { + if (tbcPages.SelectedTab == tabConfigure) { Thread thread = new Thread(ConfigureService); thread.Start(); } @@ -478,6 +495,13 @@ namespace Icinga while (lvwEndpoints.SelectedItems.Count > 0) { lvwEndpoints.Items.Remove(lvwEndpoints.SelectedItems[0]); } - } + } + + private void chkDifferentUser_CheckedChanged(object sender, EventArgs e) + { + txtUser.ReadOnly = !txtUser.ReadOnly; + if (txtUser.ReadOnly) + txtUser.Text = Icinga2User; + } } } diff --git a/agent/windows-setup-agent/SetupWizard.cs.rej b/agent/windows-setup-agent/SetupWizard.cs.rej new file mode 100644 index 000000000..91b7485d9 --- /dev/null +++ b/agent/windows-setup-agent/SetupWizard.cs.rej @@ -0,0 +1,18 @@ +diff a/agent/windows-setup-agent/SetupWizard.cs b/agent/windows-setup-agent/SetupWizard.cs (rejected hunks) +@@ -243,14 +246,13 @@ namespace Icinga + } + + if (!RunProcess(Program.Icinga2InstallDir + "\\sbin\\icinga2.exe", +- "--scm-install daemon", ++ "--scm-install --scm-user \"" + txtUser.Text + "\" daemon", + out output)) { + ShowErrorText(output); + return; + } + +- if (chkInstallNSCP.Checked) +- { ++ if (chkInstallNSCP.Checked) { + SetConfigureStatus(85, "Waiting for NSClient++ installation to complete..."); + + Process proc = new Process(); diff --git a/icinga-app/icinga.cpp b/icinga-app/icinga.cpp index f07508f5a..dd956bb9b 100644 --- a/icinga-app/icinga.cpp +++ b/icinga-app/icinga.cpp @@ -509,8 +509,20 @@ static int SetupService(bool install, int argc, char **argv) String szArgs; szArgs = Utility::EscapeShellArg(szPath) + " --scm"; - for (int i = 0; i < argc; i++) - szArgs += " " + Utility::EscapeShellArg(argv[i]); + std::string scmUser = "NT AUTHORITY\\NetworkService"; + std::ifstream initf(Utility::GetIcingaDataPath() + "\\etc\\icinga2\\user"); + if (initf.good()) { + std::getline(initf, scmUser); + } + initf.close(); + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "--scm-user") && i + 1 < argc) { + scmUser = argv[i + 1]; + i++; + } else + szArgs += " " + Utility::EscapeShellArg(argv[i]); + } SC_HANDLE schService = OpenService(schSCManager, "icinga2", SERVICE_ALL_ACCESS); @@ -547,14 +559,14 @@ static int SetupService(bool install, int argc, char **argv) NULL, NULL, NULL, - "NT AUTHORITY\\NetworkService", + scmUser.c_str(), NULL); if (schService == NULL) { printf("CreateService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return 1; - } + } } else { printf("Service isn't installed.\n"); CloseServiceHandle(schSCManager); @@ -571,11 +583,21 @@ static int SetupService(bool install, int argc, char **argv) printf("Service uninstalled successfully\n"); } else { - ChangeServiceConfig(schService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, - SERVICE_ERROR_NORMAL, szArgs.CStr(), NULL, NULL, NULL, NULL, NULL, NULL); + if (!ChangeServiceConfig(schService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, + SERVICE_ERROR_NORMAL, szArgs.CStr(), NULL, NULL, NULL, scmUser.c_str(), NULL, NULL)) { + printf("ChangeServiceConfig failed (%d)\n", GetLastError()); + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return 1; + } SERVICE_DESCRIPTION sdDescription = { "The Icinga 2 monitoring application" }; - ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdDescription); + if(!ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdDescription)) { + printf("ChangeServiceConfig2 failed (%d)\n", GetLastError()); + CloseServiceHandle(schService); + CloseServiceHandle(schSCManager); + return 1; + } if (!StartService(schService, 0, NULL)) { printf("StartService failed (%d)\n", GetLastError()); @@ -584,7 +606,14 @@ static int SetupService(bool install, int argc, char **argv) return 1; } - printf("Service installed successfully\n"); + printf("Service successfully installed for user '%s'\n", scmUser); + + std::ofstream fuser(Utility::GetIcingaDataPath() + "\\etc\\icinga2\\user", std::ios::out | std::ios::trunc); + if (fuser) + fuser << scmUser; + else + printf("Could not write user to %s\\etc\\icinga2\\user", Utility::GetIcingaDataPath()); + fuser.close(); } CloseServiceHandle(schService); @@ -635,7 +664,6 @@ VOID WINAPI ServiceMain(DWORD argc, LPSTR *argv) l_SvcStatus.dwServiceSpecificExitCode = 0; ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); - l_Job = CreateJobObject(NULL, NULL); for (;;) { diff --git a/icinga-installer/icinga-installer.cpp b/icinga-installer/icinga-installer.cpp index 8ff139b92..e4eea4766 100644 --- a/icinga-installer/icinga-installer.cpp +++ b/icinga-installer/icinga-installer.cpp @@ -43,6 +43,7 @@ static std::string GetIcingaInstallPath(void) return szFileName; } + static bool ExecuteCommand(const std::string& app, const std::string& arguments) { SHELLEXECUTEINFO sei = {}; @@ -281,7 +282,6 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); //AllocConsole(); - int rc; if (strcmp(lpCmdLine, "install") == 0) {