From 921f1c977c4e0704f61e3a7c092d3a4317ab278c Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 9 Oct 2017 19:12:49 -0700 Subject: Fixes --- cmd/cmd.go | 57 +++++++++++----- cmd/errors.go | 42 ++++++++++++ cmd/flag.go | 154 ++++++++++++++++++++++++++++++++++++++++++ cmd/format.go | 0 cmd/helper.go | 20 ++++++ cmd/info.go | 72 ++++++++++++++++++++ cmd/output.go | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/strings.go | 34 ++++++++++ cmd/templates.go | 0 cmd/version.go | 62 +++++++++++++++++ ext4/ext4.go | 35 ++++++++++ util/users.go | 50 ++++++++++++++ util/util.go | 11 --- 13 files changed, 711 insertions(+), 27 deletions(-) create mode 100644 cmd/errors.go create mode 100644 cmd/flag.go delete mode 100644 cmd/format.go create mode 100644 cmd/info.go create mode 100644 cmd/output.go create mode 100644 cmd/strings.go delete mode 100644 cmd/templates.go create mode 100644 cmd/version.go create mode 100644 util/users.go diff --git a/cmd/cmd.go b/cmd/cmd.go index e2f0cf4..725aaea 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -17,34 +17,59 @@ * the License. */ -// Package cmd is the common library for writing fscrypt command line binaries. +// Package cmd is the common library for writing command line binaries. // This package is mainly a wrapper around github.com/urfave/cli, but provides // additional support to make the usage look similar to the man page. // -// The main componets are the `Cmd` and `Flag` types which can be used to define -// a top-level command with many potential subcommands. This package also -// presents a smaller interface than urfave/cli, making it easier to use for -// other commands. +// The main componets are the `Cmd`, `Argument`, and `Flag` types which can be +// used to define a top-level command with many potential subcommands. This +// package also presents a smaller interface than urfave/cli, making it easier +// to use for other commands. package cmd +import "os" + // Command represents a command with many potential top-level commands. This is -// trand -type Cmd struct { - Name string +// transformed into a cli.Command in Run(). +type Command struct { + Name string UsageLines []string - SubCmds []Cmd - Arguments []Argument - Flags []cli.Flag - Man *ManEntry - Action CommandFunc + SubCmds []*Command + Arguments []*Argument + Flags []Flag + ManPage *ManEntry + Action CommandFunc } +// Argument represents a parameter passed to a function. It has an optional +// usage explains how it should be used. type Argument struct { - Name string - Usage string + ArgName string + Usage string } +// ManEntry represents an entry in a man page with a name, section, and title. type ManEntry struct { - Title string + Name string Section int + Title string +} + +// CommandFunc contains the implementation of a command. The provided args have +// the flags and leading command names removed. If a normal error is returned, +// it is printed out (with an optional explanation) and exits with FailureCode. +// If a usage error is returned, it is printed out with the command's usage and +// exits with UsageFailureCode. Returning nil causes an exit with success. +type CommandFunc func(args []string) error + +// Run executes the command with os.Args, equivalent to c.RunArgs(os.Args). +func (c *Command) Run() { + c.RunArgs(os.Args) +} + +// RunArgs executes the command with the provided args. If the Name argument is +// empty, args[0]'s basename is used instead. If the command fails, this method +// will not return. +func (c *Command) RunArgs(args []string) { + // TODO(joerichey): Implement conversion to cli.Command } diff --git a/cmd/errors.go b/cmd/errors.go new file mode 100644 index 0000000..07a1d05 --- /dev/null +++ b/cmd/errors.go @@ -0,0 +1,42 @@ +/* + * errors.go - Common errors and error handling + * + * 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 cmd + +import ( + "github.com/pkg/errors" + + "github.com/google/fscrypt/util" +) + +// Common errors used across commands +var ( + ErrUnknownVersion = errors.New("unknown (missing version tag)") + ErrCanceled = errors.New("operation canceled by user") + ErrMustForce = errors.New("operation must be forced") + ErrNotRoot = errors.New("operation must be run as root") +) + +// CheckIfRoot returns an error if the current user is not the root user. +func CheckIfRoot() error { + if id := util.CurrentUserID(); id != 0 { + return errors.Wrapf(ErrNotRoot, "user %s", util.GetUser(id).Username) + } + return nil +} diff --git a/cmd/flag.go b/cmd/flag.go new file mode 100644 index 0000000..18b2a4c --- /dev/null +++ b/cmd/flag.go @@ -0,0 +1,154 @@ +/* + * flag.go - Definitions for flags and associated formatting functions. + * + * 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 cmd + +import ( + "flag" + "fmt" + "strconv" + "time" +) + +// Flag represents a command line flag that can be passed to a command. Note +// that Flag also conforms to the cli.Flag interface. The Name, ArgName, and +// Usage of the Flag can be used to format it in a short form with ShortFormat, +// or in it's full format with the String method. +type Flag interface { + fmt.Stringer + Apply(*flag.FlagSet) + GetName() string + GetArgName() string + GetUsage() string +} + +// How the first usage line for a Flag should appear. We have two formats: +// --name +// --name= +// The appears if the prettyFlag's GetArgName() method returns a +// non-empty string. The returned string from shortFormat() does not include +// any leading or trailing whitespace. +func ShortFormat(f Flag) string { + if argName := f.GetArgName(); argName != "" { + return fmt.Sprintf("--%s=%s", f.GetName(), argName) + } + return fmt.Sprintf("--%s", f.GetName()) +} + +// How our flags should appear when displaying their usage. An example would be: +// --help +// Prints help screen for commands and subcommands. +// +// If defaultString is specified, this if appended to the usage. Example: +// +// --legacy +// Allow for support of older kernels with ext4 (before v4.8) and +// F2FS (before v4.6) filesystems. (default: true) +func longFormat(f Flag, defaultString ...string) string { + usage := f.GetUsage() + if len(defaultString) > 0 { + usage += fmt.Sprintf(" (default: %v)", defaultString[0]) + } + + usage = wrapText(usage, 2) + return fmt.Sprintf("\t%s\n%s", ShortFormat(f), usage) +} + +// BoolFlag is a Flag of type bool. +type BoolFlag struct { + Name string + Usage string + Default bool + Value bool +} + +func (f *BoolFlag) String() string { + if !f.Default { + return longFormat(f) + } + return longFormat(f, strconv.FormatBool(f.Default)) +} + +// Apply uses BoolFlag's value to set a flag.BoolVar on the FlagSet. +func (f *BoolFlag) Apply(s *flag.FlagSet) { s.BoolVar(&f.Value, f.Name, f.Default, f.Usage) } + +// GetName just returns BoolFlag's name. +func (f *BoolFlag) GetName() string { return f.Name } + +// GetArgName returns nothing as BoolFlags don't have an argument name. +func (f *BoolFlag) GetArgName() string { return "" } + +// GetUsage returns BoolFlag's usage. +func (f *BoolFlag) GetUsage() string { return f.Usage } + +// StringFlag is a Flag of type string. +type StringFlag struct { + Name string + ArgName string + Usage string + Default string + Value string +} + +func (f *StringFlag) String() string { + if f.Default == "" { + return longFormat(f) + } + return longFormat(f, strconv.Quote(f.Default)) +} + +// Apply uses StringFlag's value to set a flag.StringVar on the FlagSet. +func (f *StringFlag) Apply(s *flag.FlagSet) { s.StringVar(&f.Value, f.Name, f.Default, f.Usage) } + +// GetName just returns StringFlag's name. +func (f *StringFlag) GetName() string { return f.Name } + +// GetArgName returns StringFlag's argument name. +func (f *StringFlag) GetArgName() string { return f.ArgName } + +// GetUsage returns StringFlag's usage. +func (f *StringFlag) GetUsage() string { return f.Usage } + +// DurationFlag is a Flag of type time.Duration. +type DurationFlag struct { + Name string + ArgName string + Usage string + Default time.Duration + Value time.Duration +} + +func (f *DurationFlag) String() string { + if f.Default == 0 { + return longFormat(f) + } + return longFormat(f, f.Default.String()) +} + +// Apply uses DurationFlag's value to set a flag.DurationVar on the FlagSet. +func (f *DurationFlag) Apply(s *flag.FlagSet) { s.DurationVar(&f.Value, f.Name, f.Default, f.Usage) } + +// GetName just returns DurationFlag's name. +func (f *DurationFlag) GetName() string { return f.Name } + +// GetArgName returns DurationFlag's argument name. +func (f *DurationFlag) GetArgName() string { return f.ArgName } + +// GetUsage returns DurationFlag's usage. +func (f *DurationFlag) GetUsage() string { return f.Usage } diff --git a/cmd/format.go b/cmd/format.go deleted file mode 100644 index e69de29..0000000 diff --git a/cmd/helper.go b/cmd/helper.go index e69de29..77f6b2f 100644 --- a/cmd/helper.go +++ b/cmd/helper.go @@ -0,0 +1,20 @@ +/* + * helper.go - Helper functions for using the cmd package + * + * 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 cmd diff --git a/cmd/info.go b/cmd/info.go new file mode 100644 index 0000000..6257ec1 --- /dev/null +++ b/cmd/info.go @@ -0,0 +1,72 @@ +/* + * info.go - Global information about the program. + * + * 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 cmd + +import ( + "time" + + "github.com/urfave/cli" +) + +// Info contains the global info for the functions. +var Info struct { + // Program is the name of the top-level program being executed. If not + // set it is set in cmd.RunArgs(). + Program string + // VersionTag (if set) will be displayed in both the short and long + // version output. VersionTag is not parsed, so any string will work. + VersionTag string + // BuildTime (if set) will be displayed in the long version output. + BuildTime time.Time + // Authors (if non-empty) are displayed in the long version output. + Authors []cli.Author + // Copyright (if set) is displayed in the long version output. + Copyright string +} + +// Linker flags of the form "-X cmd.Info.VersionTag=1.0" do not work, so we use +// these separate files so variables can be set from the Makefile. +var ( + versionTag string + buildTime string +) + +// fscrypt specific initialization +func init() { + Info.VersionTag = versionTag + Info.BuildTime = buildTime + Info.Authors = []cli.Author{{ + Name: "Joe Richey", + Email: "joerichey@google.com", + }} + Info.Copyright = `Copyright 2017 Google, Inc. + + 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.` +} diff --git a/cmd/output.go b/cmd/output.go new file mode 100644 index 0000000..024705d --- /dev/null +++ b/cmd/output.go @@ -0,0 +1,201 @@ +/* + * output.go - Functions for handling command line formatting and output. + * + * 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 cmd + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "log" + "os" + "strings" + "unicode/utf8" + + "github.com/google/fscrypt/util" + "golang.org/x/crypto/ssh/terminal" +) + +var ( + // TabWidth is the number of spaces used to display a tab. + TabWidth = 8 + // LineLength is the maximum length of any output. If not set, the width + // of the terminal be detected and assigned to LineLength. + LineLength int + // FallbackLineLength is the LineLength used if detection fails. By + // default we fall back to punch cards. + FallbackLineLength = 80 + // MaxLineLength is the maximum allowed detected value of LineLength. + MaxLineLength = 120 + // Output is the io.Writer all commands should use for their normal + // output (errors should just return the appropriate error). If not set, + // it is automatically set based on the provided flags. + Output io.Writer + // HelpFlag writes help to Stdout + HelpFlag = &BoolFlag{ + Name: "help", + Usage: "Prints this 🧗help text for commands and subcommands", + } + // VerboseFlag indicates that all logging output should be printed. + VerboseFlag = &BoolFlag{ + Name: "verbose", + Usage: "Prints additional debug messages.", + } + // QuietFlag indicates that no normal output should be printed. + QuietFlag = &BoolFlag{ + Name: "quiet", + Usage: `Prints nothing except for errors and uses any default + option instead of prompting the user.`, + } + // ForceFlag indicates that the operation should proceed if possible. + ForceFlag = &BoolFlag{ + Name: "force", + Usage: `Print no confirmation prompts or warnings and + automatically proceed with the requested action.`, + } +) + +// Suffixes for questions with a yes or no default +const ( + defaultYesSuffix = "[Y/n]" + defaultNoSuffix = "[y/N]" +) + +// We use the width of the terminal unless we cannot get the width. +func init() { + if LineLength > 0 { + return + } + width, _, err := terminal.GetSize(int(os.Stdout.Fd())) + if err != nil { + LineLength = FallbackLineLength + } else { + LineLength = util.MinInt(width, MaxLineLength) + } +} + +// Takes an input string text, and wraps the text so that each line begins with +// numTabs tabs and ends with a newline (except the last line), and each line +// has length less than lineLength. If the text contains a word which is too +// long, that word gets its own line. +func wrapText(text string, numTabs int) string { + // We use a buffer to format the wrapped text so we get O(n) runtime + var buffer bytes.Buffer + spaceLeft := 0 + maxTextLen := LineLength - numTabs*TabWidth + delimiter := strings.Repeat("\t", numTabs) + for i, word := range strings.Fields(text) { + wordLen := utf8.RuneCountInString(word) + if wordLen >= spaceLeft { + // If no room left, write the word on the next line. + buffer.WriteString("\n") + buffer.WriteString(delimiter) + buffer.WriteString(word) + spaceLeft = maxTextLen - wordLen + } else { + // Write word on this line + buffer.WriteByte(' ') + buffer.WriteString(word) + spaceLeft -= 1 + wordLen + } + } + + return buffer.String() +} + +// Configures the Output and log output io.Writers. Called before running +// commands but after processing flags. +func setupOutput() { + if VerboseFlag.Value { + log.SetOutput(os.Stdout) + } else { + log.SetOutput(ioutil.Discard) + } + if Output != nil { + return + } + if QuietFlag.Value { + Output = ioutil.Discard + } else { + Output = os.Stdout + } +} + +// AskQuestion asks the user a yes or no question. Returning a boolean on a +// successful answer and an error if there was not a response from the user. +// Returns the defaultChoice on empty input (or in quiet mode). +func AskQuestion(question string, defaultChoice bool) (bool, error) { + // If in quiet mode, we just use the default. + if QuietFlag.Value { + return defaultChoice, nil + } + // Loop until failure or valid input. + for { + if defaultChoice { + fmt.Fprintf(Output, "%s %s ", question, defaultYesSuffix) + } else { + fmt.Fprintf(Output, "%s %s ", question, defaultNoSuffix) + } + + input, err := util.ReadLine() + if err != nil { + return false, err + } + + switch strings.ToLower(input) { + case "y", "yes": + return true, nil + case "n", "no": + return false, nil + case "": + return defaultChoice, nil + } + } +} + +// AskConfirmation asks the user for confirmation before performing a specific +// action. An error is returned if the user declines or IO fails. +func AskConfirmation(question, warning string, defaultChoice bool) error { + // All confirmations are "yes" if we are forcing. + if ForceFlag.Value { + return nil + } + + // Defaults of "no" require forcing. + if QuietFlag.Value { + if defaultChoice { + return nil + } + return ErrMustForce + } + + if warning != "" { + fmt.Fprintln(Output, wrapText("WARNING: "+warning, 0)) + } + + confirmed, err := AskQuestion(question, defaultChoice) + if err != nil { + return err + } + if !confirmed { + return ErrCanceled + } + return nil +} diff --git a/cmd/strings.go b/cmd/strings.go new file mode 100644 index 0000000..559c60c --- /dev/null +++ b/cmd/strings.go @@ -0,0 +1,34 @@ +/* + * strings.go - Strings and templates for output formatting + * + * 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 cmd + +import ( + "io" + "text/template" +) + +// ExecuteTemplate creates an anonymous template the text, and runs it with the +// provided writer and data. Panics if text has bad format or execution fails. +func ExecuteTemplate(w io.Writer, text string, data interface{}) { + tmpl := template.Must(template.New("").Parse(text)) + if err := tmpl.Execute(w, data); err != nil { + panic(err) + } +} diff --git a/cmd/templates.go b/cmd/templates.go deleted file mode 100644 index e69de29..0000000 diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..787e2cd --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,62 @@ +/* + * version.go - Version subcommand that can be added to any binary + * + * 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 cmd + +// Templates for use with the version command, which both parse the Info var. +var ( + VersionShortTemplate = "{{.Command}} version {{.VersionTag}}\n" + VersionLongTemplate = VersionShortTemplate + `{{if .Compiled}} +Compiled: + {{.Compiled}} +{{end}}{{if len .Authors}} +Author{{with $length := len .Authors}}{{if ne 1 $length}}s{{end}}{{end}}:{{range .Authors}} + {{.}}{{end}} +{{end}}{{if .Copyright}} +Copyright: + {{.Copyright}} +{{end}}` +) + +// Version is a command which will display either the VersionTag (by default) or +// the full version information (version, copyright, authors). +var Version = &Command{ + Name: "version", + UsageLines: []string{""}, + Flags: []Flag{longFlag}, + Action: versionAction, +} + +// Using longFlag with the version command displays the longer version info. +var longFlag = &BoolFlag{ + Name: "long", + Usage: "Print the detailed version and copyright information.", +} + +func versionAction(_ []string) error { + if Info.VersionTag == "" { + return ErrUnknownVersion + } + if longFlag.Value { + + } else { + + } + return nil +} diff --git a/ext4/ext4.go b/ext4/ext4.go index 7419929..063d68c 100644 --- a/ext4/ext4.go +++ b/ext4/ext4.go @@ -25,6 +25,9 @@ import ( "io" "io/ioutil" "os" + "time" + + "github.com/urfave/cli" ) var ( @@ -77,6 +80,38 @@ func printAndExit(err error, printUsage bool) { } func main() { + // Create our command line application + app := cli.NewApp() + app.Usage = shortUsage + app.Authors = Authors + app.Copyright = apache2GoogleCopyright + + // Grab the version and compilation time passed in from the Makefile. + app.Version = version + app.Compiled, _ = time.Parse(time.UnixDate, buildTime) + app.OnUsageError = onUsageError + + // Setup global flags + cli.HelpFlag = helpFlag + cli.VersionFlag = versionFlag + cli.VersionPrinter = func(c *cli.Context) { + cli.HelpPrinter(c.App.Writer, versionInfoTemplate, c.App) + } + app.Flags = universalFlags + + // We hide the help subcommand so that "fscrypt --help" works + // and "fscrypt help" does not. + app.HideHelp = true + + // Initialize command list and setup all of the commands. + app.Action = defaultAction + app.Commands = []cli.Command{Setup, Encrypt, Unlock, Purge, Status, Metadata} + for i := range app.Commands { + setupCommand(&app.Commands[i]) + } + + app.Run(os.Args) + set.SetOutput(ioutil.Discard) if err := set.Parse(os.Args[1:]); err != nil { printAndExit(err, true) 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..9f62b45 100644 --- a/util/util.go +++ b/util/util.go @@ -27,7 +27,6 @@ import ( "bufio" "math" "os" - "os/user" "strconv" "unsafe" ) @@ -117,13 +116,3 @@ 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 -} -- cgit v1.2.3