Add option to choose icinga2s user

Adds the --scm-user option and a check box and text field in the Agent

fixes #9119
This commit is contained in:
Jean Flach 2016-02-26 13:42:36 +01:00
parent c0bc156696
commit 4b61aee90c
6 changed files with 195 additions and 82 deletions

View 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;

View 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();
@ -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;
}
}

View 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;
}
}
}

View File

@ -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();

View 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 (;;) {

View 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) {