diff options
| -rw-r--r-- | actions/context.go | 10 | ||||
| -rw-r--r-- | cmd/fscrypt/flags.go | 26 | ||||
| -rw-r--r-- | crypto/crypto_test.go | 6 | ||||
| -rw-r--r-- | pam/pam.go | 8 | ||||
| -rw-r--r-- | util/users.go | 50 | ||||
| -rw-r--r-- | util/util.go | 13 |
6 files changed, 78 insertions, 35 deletions
diff --git a/actions/context.go b/actions/context.go index 8ad1357..ed7729d 100644 --- a/actions/context.go +++ b/actions/context.go @@ -67,7 +67,7 @@ type Context struct { // NewContextFromPath makes a context for the filesystem containing the // specified path and whose Config is loaded from the global config file. On // success, the Context contains a valid Config and Mount. The target defaults -// the the current effective user if none is specified. +// the the current user if none is specified. func NewContextFromPath(path string, target *user.User) (*Context, error) { ctx, err := newContextFromUser(target) if err != nil { @@ -85,7 +85,7 @@ func NewContextFromPath(path string, target *user.User) (*Context, error) { // NewContextFromMountpoint makes a context for the filesystem at the specified // mountpoint and whose Config is loaded from the global config file. On // success, the Context contains a valid Config and Mount. The target defaults -// the the current effective user if none is specified. +// the the current user if none is specified. func NewContextFromMountpoint(mountpoint string, target *user.User) (*Context, error) { ctx, err := newContextFromUser(target) if err != nil { @@ -102,13 +102,11 @@ func NewContextFromMountpoint(mountpoint string, target *user.User) (*Context, e // newContextFromUser makes a context with the corresponding target user, and // whose Config is loaded from the global config file. If the target is nil, the -// effecitive user is used. +// current user is used. func newContextFromUser(target *user.User) (*Context, error) { var err error if target == nil { - if target, err = util.EffectiveUser(); err != nil { - return nil, err - } + target = util.CurrentUser() } ctx := &Context{TargetUser: target} diff --git a/cmd/fscrypt/flags.go b/cmd/fscrypt/flags.go index 5137eff..b6eb446 100644 --- a/cmd/fscrypt/flags.go +++ b/cmd/fscrypt/flags.go @@ -282,25 +282,27 @@ func getPolicyFromFlag(flagValue string, target *user.User) (*actions.Policy, er return actions.GetPolicy(ctx, descriptor) } -// parseUserFlag returns the user specified by userFlag or the current effective -// user if the flag value is missing. If the effective user is root, however, a -// user must specified in the flag. If checkKeyring is true, we also make sure -// there are no problems accessing the user keyring. +// parseUserFlag returns the user specified by userFlag or the current user if +// the flag is not given. If the effective user is root, however, a user must be +// specified in the flag. If checkKeyring is true, we also make sure there are +// no problems accessing the user keyring. func parseUserFlag(checkKeyring bool) (targetUser *user.User, err error) { if userFlag.Value != "" { - targetUser, err = user.Lookup(userFlag.Value) + if targetUser, err = user.Lookup(userFlag.Value); err != nil { + return nil, err + } } else { - if util.IsUserRoot() { + targetID := util.CurrentUserID() + if targetID == 0 { return nil, ErrSpecifyUser } - targetUser, err = util.EffectiveUser() - } - if err != nil { - return nil, err + targetUser = util.GetUser(targetID) } if checkKeyring { - _, err = security.UserKeyringID(targetUser, true) + if _, err = security.UserKeyringID(targetUser, true); err != nil { + return nil, err + } } - return targetUser, err + return targetUser, nil } diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 444f847..a353052 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -62,10 +62,10 @@ var ( fakeInvalidPolicyKey, _ = makeKey(42, metadata.PolicyKeyLen-1) fakeWrappingKey, _ = makeKey(17, metadata.InternalKeyLen) - testUser, _ = util.EffectiveUser() + testUser = util.CurrentUser() ) -// As the passpharase hashing function clears the passphrase, we need to make +// As the passphrase hashing function clears the passphrase, we need to make // a new passphrase key for each test func fakePassphraseKey() (*Key, error) { return NewFixedLengthKeyFromReader(bytes.NewReader(fakePassword), len(fakePassword)) @@ -613,7 +613,7 @@ func BenchmarkUnwrap(b *testing.B) { } } -func BenchmarkUnwrapNolock(b *testing.B) { +func BenchmarkUnwrapNoLock(b *testing.B) { b.StopTimer() UseMlock = false @@ -52,8 +52,9 @@ type Handle struct { func NewHandle(pamh unsafe.Pointer) (*Handle, error) { var err error h := &Handle{ - handle: (*C.pam_handle_t)(pamh), - status: C.PAM_SUCCESS, + handle: (*C.pam_handle_t)(pamh), + status: C.PAM_SUCCESS, + OrigUser: util.CurrentUser(), } var pamUsername *C.char @@ -65,9 +66,6 @@ func NewHandle(pamh unsafe.Pointer) (*Handle, error) { if h.PamUser, err = user.Lookup(C.GoString(pamUsername)); err != nil { return nil, err } - if h.OrigUser, err = util.EffectiveUser(); err != nil { - return nil, err - } return h, nil } diff --git a/util/users.go b/util/users.go new file mode 100644 index 0000000..92affa8 --- /dev/null +++ b/util/users.go @@ -0,0 +1,50 @@ +/* + * util.go - Functions for dealing with users + * + * Copyright 2017 Google Inc. + * Author: Joe Richey (joerichey@google.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package util + +import ( + "fmt" + "os" + "os/user" + "strconv" +) + +// CurrentUserID returns the uid of the effective user. +func CurrentUserID() int { + return os.Geteuid() +} + +// GetUser returns the user entry corresponding to the provided uid. +func GetUser(uid int) *user.User { + uidString := strconv.Itoa(uid) + foundUser, err := user.LookupId(uidString) + if err != nil { + return &user.User{ + Uid: uidString, + Username: fmt.Sprintf("[uid=%d]", uid), + } + } + return foundUser +} + +// CurrentUser returns the user entry for the effective user. +func CurrentUser() *user.User { + return GetUser(CurrentUserID()) +} diff --git a/util/util.go b/util/util.go index 3de4a1a..ed78519 100644 --- a/util/util.go +++ b/util/util.go @@ -19,15 +19,15 @@ // Package util contains useful components for simplifying Go code. // -// The package contains common error types (errors.go) and functions for -// converting arrays to pointers. +// The package contains functions missing from the standard library, error +// utility functions, functions for converting arrays to pointers, and functions +// for dealing with users and uids. package util import ( "bufio" "math" "os" - "os/user" "strconv" "unsafe" ) @@ -118,12 +118,7 @@ func AtoiOrPanic(input string) int { return i } -// EffectiveUser returns the user entry corresponding to the effective user. -func EffectiveUser() (*user.User, error) { - return user.LookupId(strconv.Itoa(os.Geteuid())) -} - // IsUserRoot checks if the effective user is root. func IsUserRoot() bool { - return os.Geteuid() == 0 + return CurrentUserID() == 0 } |