From 29942ffee9b513fc5e3c890ffe71e223173aa603 Mon Sep 17 00:00:00 2001 From: Mariana Dima Date: Thu, 25 Feb 2021 08:51:43 +0000 Subject: [PATCH] Rewrite check for admin (#23970) * rewrite hasroot * rename * updates * fix linux * update changelog --- x-pack/elastic-agent/CHANGELOG.next.asciidoc | 1 + x-pack/elastic-agent/pkg/agent/cmd/install.go | 7 +++-- .../elastic-agent/pkg/agent/cmd/uninstall.go | 10 +++++-- .../pkg/agent/install/root_unix.go | 5 ++-- .../pkg/agent/install/root_windows.go | 29 ++++++++++++++----- .../pkg/agent/install/root_windows_test.go | 20 +++++++++++++ 6 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 x-pack/elastic-agent/pkg/agent/install/root_windows_test.go diff --git a/x-pack/elastic-agent/CHANGELOG.next.asciidoc b/x-pack/elastic-agent/CHANGELOG.next.asciidoc index eaf03707867..06b7cbf655d 100644 --- a/x-pack/elastic-agent/CHANGELOG.next.asciidoc +++ b/x-pack/elastic-agent/CHANGELOG.next.asciidoc @@ -38,6 +38,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] - Fix issues with dynamic inputs and conditions {pull}23886[23886] - Fix bad substitution of API key. {pull}24036[24036] - Fix docker enrollment issue related to Fleet Server change. {pull}24155[24155] diff --git a/x-pack/elastic-agent/pkg/agent/cmd/install.go b/x-pack/elastic-agent/pkg/agent/cmd/install.go index d978cd72d78..979966cbf13 100644 --- a/x-pack/elastic-agent/pkg/agent/cmd/install.go +++ b/x-pack/elastic-agent/pkg/agent/cmd/install.go @@ -44,8 +44,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..fbc97ea94bd 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 command while checking for administrator rights, %v", err) + } + if !isAdmin { + return fmt.Errorf("unable to perform command, not executed with %s permissions", install.PermissionUser) } status, reason := install.Status() if status == install.NotInstalled { @@ -72,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_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 } 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..964f262b29d --- /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 ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHasRoot(t *testing.T) { + t.Run("check if user is admin", func(t *testing.T) { + _, err := HasRoot() + assert.NoError(t, err) + }) +}