]> granicus.if.org Git - icinga2/commitdiff
Add option to choose icinga2s user
authorJean Flach <jean-marcel.flach@netways.de>
Fri, 26 Feb 2016 12:42:36 +0000 (13:42 +0100)
committerJean Flach <jean-marcel.flach@netways.de>
Tue, 25 Oct 2016 14:08:03 +0000 (16:08 +0200)
Adds the --scm-user option and a check box and text field in the Agent

fixes #9119

agent/windows-setup-agent/Program.cs
agent/windows-setup-agent/SetupWizard.Designer.cs
agent/windows-setup-agent/SetupWizard.cs
agent/windows-setup-agent/SetupWizard.cs.rej [new file with mode: 0644]
icinga-app/icinga.cpp
icinga-installer/icinga-installer.cpp

index e132bc1b1b98c35ff30c51c5feb5d32823c64c64..4b85731f1fafc76b264775ca61a739639ce8c4a1 100644 (file)
@@ -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;
 
index 8a2374bc64a10ba0a63b2fe7bf39ece4ef39f965..edca6c2e99d28d1b138d13b1f51f3a37f824f9c9 100644 (file)
@@ -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();
                        // 
                        // 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;
                        // 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;
                        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";
                        // 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";
                        // 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);
                        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;
                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;
        }
 }
 
index f100cc64de9f117219171b751f7ea6f83f381761..a1733e5a2b5d87a5fdb1a4c06b5644fbb5b0f478 100644 (file)
@@ -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 (file)
index 0000000..91b7485
--- /dev/null
@@ -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();
index f07508f5a7847267ae38031319905f2e7984fbd9..dd956bb9b234682dde5d796d270591e33310565b 100644 (file)
@@ -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 (;;) {
index 8ff139b92c04532898e70bb198c400dec4cd2fa2..e4eea4766a45f4a6ca46a7fb6d3e43c200d43a6f 100644 (file)
@@ -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) {