Skip to content

Commit

Permalink
Windows: Do not fail ProcState.Get when run by non-admin #121
Browse files Browse the repository at this point in the history
When running under Windows as a non-administrator  user, ProcState.Get()
will fail with the error "OpenProcessToken failed for pid=XXX:
Permission denied".

This is a known issue under Windows: A non-admin won't be able to
access the token of most processes, regardless of privileges
(i.e. SeDebugPrivilege).

We should still allow ProcState.Get to return with a missing username
instead of failing completely.
  • Loading branch information
adriansr authored May 27, 2019
2 parents 1227b9d + ca8679e commit eed54fc
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added

### Fixed
- ProcState.Get() doesn't fail under Windows when it cannot obtain process ownership information. #121

### Changed

Expand Down
17 changes: 7 additions & 10 deletions sigar_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,11 @@ func (self *ProcState) Get(pid int) error {
errs = append(errs, errors.Wrap(err, "getParentPid failed"))
}

self.Username, err = getProcCredName(pid)
if err != nil {
errs = append(errs, errors.Wrap(err, "getProcCredName failed"))
}
// getProcCredName will often fail when run as a non-admin user. This is
// caused by strict ACL of the process token belonging to other users.
// Instead of failing completely, ignore this error and still return most
// data with an empty Username.
self.Username, _ = getProcCredName(pid)

if len(errs) > 0 {
errStrs := make([]string, 0, len(errs))
Expand Down Expand Up @@ -274,19 +275,15 @@ func getProcCredName(pid int) (string, error) {
if err != nil {
return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid)
}
// Close token to prevent handle leaks.
defer token.Close()

// Find the token user.
tokenUser, err := token.GetTokenUser()
if err != nil {
return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid)
}

// Close token to prevent handle leaks.
err = token.Close()
if err != nil {
return "", errors.Wrapf(err, "failed while closing process token handle for pid=%v", pid)
}

// Look up domain account by SID.
account, domain, _, err := tokenUser.User.Sid.LookupAccount("")
if err != nil {
Expand Down

0 comments on commit eed54fc

Please sign in to comment.