From 66ea76445ef7345aa12236e2bfb47dd22698e7a7 Mon Sep 17 00:00:00 2001 From: narph Date: Wed, 10 Feb 2021 16:31:20 +0100 Subject: [PATCH 1/5] rewrite hasroot --- x-pack/elastic-agent/pkg/agent/cmd/install.go | 7 +++-- .../elastic-agent/pkg/agent/cmd/uninstall.go | 8 +++-- .../pkg/agent/install/root_windows.go | 29 ++++++++++++++----- .../pkg/agent/install/root_windows_test.go | 20 +++++++++++++ 4 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 x-pack/elastic-agent/pkg/agent/install/root_windows_test.go diff --git a/x-pack/elastic-agent/pkg/agent/cmd/install.go b/x-pack/elastic-agent/pkg/agent/cmd/install.go index 7fd5b23ea18..c5003f53610 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/install.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/install.go @@ -46,8 +46,11 @@ would like the Agent to operate. } func installCmd(streams *cli.IOStreams, cmd *cobra.Command, flags *globalFlags, args []string) error { - var err error - if !install.HasRoot() { + isAdmin, err := install.HasRoot() + if err != nil { + return fmt.Errorf("unable to perform install command while checking for administrator rights, %v", err) + } + if !isAdmin { return fmt.Errorf("unable to perform install command, not executed with %s permissions", install.PermissionUser) } status, reason := install.Status() diff --git a/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go b/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go index 88ec4e9eb4d..73393dcd803 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go @@ -37,8 +37,12 @@ Unless -f is used this command will ask confirmation before performing removal. } func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command, flags *globalFlags, args []string) error { - if !install.HasRoot() { - return fmt.Errorf("unable to perform uninstall command, not executed with %s permissions", install.PermissionUser) + isAdmin, err := install.HasRoot() + if err != nil { + return fmt.Errorf("unable to perform perform command while checking for administrator rights, %v", err) + } + if !isAdmin { + return fmt.Errorf("unable to perform perform command, not executed with %s permissions", install.PermissionUser) } status, reason := install.Status() if status == install.NotInstalled { diff --git a/x-pack/elastic-agent/pkg/agent/install/root_windows.go b/x-pack/elastic-agent/pkg/agent/install/root_windows.go index c72432084ac..372a75efe0a 100644 --- a/x-pack/elastic-agent/pkg/agent/install/root_windows.go +++ b/x-pack/elastic-agent/pkg/agent/install/root_windows.go @@ -7,7 +7,8 @@ package install import ( - "os" + "github.com/pkg/errors" + "golang.org/x/sys/windows" ) const ( @@ -16,12 +17,26 @@ const ( ) // HasRoot returns true if the user has Administrator/SYSTEM permissions. -func HasRoot() bool { - // only valid rights can open the physical drive - f, err := os.Open("\\\\.\\PHYSICALDRIVE0") +func HasRoot() (bool, error) { + var sid *windows.SID + // See https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership for more on the api + err := windows.AllocateAndInitializeSid( + &windows.SECURITY_NT_AUTHORITY, + 2, + windows.SECURITY_BUILTIN_DOMAIN_RID, + windows.DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &sid) if err != nil { - return false + return false, errors.Errorf("sid error: %s", err) } - defer f.Close() - return true + + token := windows.Token(0) + + member, err := token.IsMember(sid) + if err != nil { + return false, errors.Errorf("token membership error: %s", err) + } + + return member, nil } diff --git a/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go b/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go new file mode 100644 index 00000000000..faeca0fc154 --- /dev/null +++ b/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go @@ -0,0 +1,20 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// +build windows + +package install + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestInitResources(t *testing.T) { + t.Run("return error when no resource options were configured", func(t *testing.T) { + result, err := HasRoot() + assert.NoError(t, err) + assert.True(t, result) + }) +} From 7dbd771a433f73a964b1283b8ad3b208438fd59c Mon Sep 17 00:00:00 2001 From: narph Date: Wed, 10 Feb 2021 16:53:30 +0100 Subject: [PATCH 2/5] rename --- x-pack/elastic-agent/pkg/agent/install/root_windows_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go b/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go index faeca0fc154..9b50f19414e 100644 --- a/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go +++ b/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go @@ -11,8 +11,8 @@ import ( "testing" ) -func TestInitResources(t *testing.T) { - t.Run("return error when no resource options were configured", func(t *testing.T) { +func TestHasRoot(t *testing.T) { + t.Run("check if user is admin", func(t *testing.T) { result, err := HasRoot() assert.NoError(t, err) assert.True(t, result) From 83d24edcd70d9464048c21d4692ee5a691975696 Mon Sep 17 00:00:00 2001 From: narph Date: Thu, 11 Feb 2021 17:43:32 +0100 Subject: [PATCH 3/5] updates --- x-pack/elastic-agent/pkg/agent/cmd/install.go | 2 +- x-pack/elastic-agent/pkg/agent/cmd/uninstall.go | 6 +++--- x-pack/elastic-agent/pkg/agent/install/root_windows_test.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/cmd/install.go b/x-pack/elastic-agent/pkg/agent/cmd/install.go index c5003f53610..a93bec04340 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/install.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/install.go @@ -61,7 +61,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command, flags *globalFlags, // check the lock to ensure that elastic-agent is not already running in this directory locker := application.NewAppLocker(paths.Data(), agentLockFileName) - if err := locker.TryLock(); err != nil { + if err = locker.TryLock(); err != nil { if err == application.ErrAppAlreadyRunning { return fmt.Errorf("cannot perform installation as Elastic Agent is already running from this directory") } diff --git a/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go b/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go index 73393dcd803..fbc97ea94bd 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/uninstall.go @@ -39,10 +39,10 @@ Unless -f is used this command will ask confirmation before performing removal. func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command, flags *globalFlags, args []string) error { isAdmin, err := install.HasRoot() if err != nil { - return fmt.Errorf("unable to perform perform command while checking for administrator rights, %v", err) + return fmt.Errorf("unable to perform command while checking for administrator rights, %v", err) } if !isAdmin { - return fmt.Errorf("unable to perform perform command, not executed with %s permissions", install.PermissionUser) + return fmt.Errorf("unable to perform command, not executed with %s permissions", install.PermissionUser) } status, reason := install.Status() if status == install.NotInstalled { @@ -76,7 +76,7 @@ func uninstallCmd(streams *cli.IOStreams, cmd *cobra.Command, flags *globalFlags } } - err := install.Uninstall() + err = install.Uninstall() if err != nil { return err } diff --git a/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go b/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go index 9b50f19414e..964f262b29d 100644 --- a/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go +++ b/x-pack/elastic-agent/pkg/agent/install/root_windows_test.go @@ -7,14 +7,14 @@ package install import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func TestHasRoot(t *testing.T) { t.Run("check if user is admin", func(t *testing.T) { - result, err := HasRoot() + _, err := HasRoot() assert.NoError(t, err) - assert.True(t, result) }) } From a8b4c0e128a039d69ba01b2dfe13da8765e37f31 Mon Sep 17 00:00:00 2001 From: narph Date: Thu, 11 Feb 2021 18:14:14 +0100 Subject: [PATCH 4/5] fix linux --- x-pack/elastic-agent/pkg/agent/install/root_unix.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/elastic-agent/pkg/agent/install/root_unix.go b/x-pack/elastic-agent/pkg/agent/install/root_unix.go index b79f104d98d..b8f6990f6a9 100644 --- a/x-pack/elastic-agent/pkg/agent/install/root_unix.go +++ b/x-pack/elastic-agent/pkg/agent/install/root_unix.go @@ -14,6 +14,7 @@ const ( ) // HasRoot returns true if the user has root permissions. -func HasRoot() bool { - return os.Getegid() == 0 +// Added extra `nil` value to return since the HasRoot for windows will return an error as well +func HasRoot() (bool, error) { + return os.Getegid() == 0, nil } From 62e4317bc5e132e9078df33daf56a5069664a1d6 Mon Sep 17 00:00:00 2001 From: narph Date: Tue, 23 Feb 2021 16:33:13 +0100 Subject: [PATCH 5/5] update changelog --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + x-pack/elastic-agent/pkg/agent/cmd/install.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index 3d2d4551475..04e0c823d95 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -37,6 +37,7 @@ - Fix issue of missing log messages from filebeat monitor {pull}23514[23514] - Increase checkin grace period to 30 seconds {pull}23568[23568] - Fix libbeat from reporting back degraded on config update {pull}23537[23537] +- Rewrite check if agent is running with admin rights on Windows {pull}23970[23970] ==== New features diff --git a/x-pack/elastic-agent/pkg/agent/cmd/install.go b/x-pack/elastic-agent/pkg/agent/cmd/install.go index a93bec04340..c5003f53610 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/install.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/install.go @@ -61,7 +61,7 @@ func installCmd(streams *cli.IOStreams, cmd *cobra.Command, flags *globalFlags, // check the lock to ensure that elastic-agent is not already running in this directory locker := application.NewAppLocker(paths.Data(), agentLockFileName) - if err = locker.TryLock(); err != nil { + if err := locker.TryLock(); err != nil { if err == application.ErrAppAlreadyRunning { return fmt.Errorf("cannot perform installation as Elastic Agent is already running from this directory") }