Migrated wrench command
This commit is contained in:
parent
17a816e360
commit
6f876b2a17
230
cmd/wrench/main.go
Normal file
230
cmd/wrench/main.go
Normal file
@ -0,0 +1,230 @@
|
||||
package main
|
||||
|
||||
import "os"
|
||||
import "fmt"
|
||||
import "flag"
|
||||
import "strconv"
|
||||
import "os/exec"
|
||||
import "os/user"
|
||||
import "path/filepath"
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
|
||||
func printErr (format string, values ...any) {
|
||||
fmt.Fprintf(os.Stderr, os.Args[0] + ": " + format, values...)
|
||||
}
|
||||
|
||||
func serviceUser (service string) string {
|
||||
return "hn-" + service
|
||||
}
|
||||
|
||||
func tryCommand (cmd *exec.Cmd, failReason string) {
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
printErr("%s: %s", failReason, string(output))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func ownOne (path string, uid, gid int) {
|
||||
file, err := os.Stat(path)
|
||||
if err != nil {
|
||||
printErr("could not stat %s: %v", path, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.Chown(path, uid, gid)
|
||||
if err != nil {
|
||||
printErr("could not change ownership of %s: %v", path, err)
|
||||
return
|
||||
}
|
||||
|
||||
if file.IsDir() {
|
||||
err = os.Chmod(path, 0770)
|
||||
} else {
|
||||
err = os.Chmod(path, 0660)
|
||||
}
|
||||
if err != nil {
|
||||
printErr("could not change mode of %s: %v", path, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func main () {
|
||||
user, err := user.Current()
|
||||
if err != nil {
|
||||
printErr("could not get username %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// define commands
|
||||
hashCommand := flag.NewFlagSet("hash", flag.ExitOnError)
|
||||
hashCost := hashCommand.Uint("cost", uint(bcrypt.DefaultCost), "Cost of the hash")
|
||||
hashText := hashCommand.String("k", "", "Text content of the key")
|
||||
|
||||
addUserCommand := flag.NewFlagSet("adduser", flag.ExitOnError)
|
||||
addUserService := addUserCommand.String ("s", "router",
|
||||
"Service to add a user for")
|
||||
|
||||
delUserCommand := flag.NewFlagSet("deluser", flag.ExitOnError)
|
||||
delUserService := delUserCommand.String ("s", "router",
|
||||
"Service to delete the user for")
|
||||
|
||||
authCommand := flag.NewFlagSet("auth", flag.ExitOnError)
|
||||
authService := authCommand.String ("s", "router",
|
||||
"Service to authorize the user to access")
|
||||
authUser := authCommand.String ("u", user.Username,
|
||||
"User to be given access")
|
||||
|
||||
ownCommand := flag.NewFlagSet("own", flag.ExitOnError)
|
||||
ownService := ownCommand.String ("s", "router",
|
||||
"Service to give ownership of the file to")
|
||||
ownFile := ownCommand.String ("f", ".",
|
||||
"File to take ownership of")
|
||||
ownRecursive := ownCommand.Bool ("r", false,
|
||||
"Whether or not to recurse into sub-directories")
|
||||
|
||||
// execute correct command
|
||||
switch os.Args[1] {
|
||||
case "hash":
|
||||
execHash(int(*hashCost), *hashText)
|
||||
case "adduser":
|
||||
execAdduser(*addUserService)
|
||||
case "deluser":
|
||||
execDeluser(*delUserService)
|
||||
case "auth":
|
||||
execAuth(*authService, *authUser)
|
||||
case "own":
|
||||
execOwn(*ownService, *ownFile, *ownRecursive)
|
||||
}
|
||||
}
|
||||
|
||||
func execHash (cost int, key string) {
|
||||
if cost < bcrypt.MinCost {
|
||||
printErr("cost is too low, must be at least %v", bcrypt.MinCost)
|
||||
os.Exit(1)
|
||||
}
|
||||
if cost > bcrypt.MaxCost {
|
||||
printErr("cost is too hight, can be at most %v", bcrypt.MaxCost)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(key), cost)
|
||||
if err != nil {
|
||||
printErr("could not hash key: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println(string(hash))
|
||||
}
|
||||
|
||||
func execAdduser (service string) {
|
||||
fullName := serviceUser(service)
|
||||
|
||||
// BUSYBOX
|
||||
adduser, err := exec.LookPath("adduser")
|
||||
if err == nil {
|
||||
addgroup, _ := exec.LookPath("addgroup")
|
||||
tryCommand (exec.Command(addgroup, fullName, "-S"),
|
||||
"could not add group")
|
||||
tryCommand (exec.Command(adduser, fullName, "-SHDG", fullName),
|
||||
"could not add user")
|
||||
return
|
||||
}
|
||||
|
||||
// GNU
|
||||
useradd, err := exec.LookPath("useradd")
|
||||
if err == nil {
|
||||
tryCommand (exec.Command (
|
||||
useradd, fullName, "-rUM",
|
||||
"--shell", "/sbin/nologin"), "could not add user")
|
||||
return
|
||||
}
|
||||
|
||||
printErr("could not add user: no command adduser or useradd")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func execDeluser (service string) {
|
||||
fullName := serviceUser(service)
|
||||
|
||||
// BUSYBOX
|
||||
deluser, err := exec.LookPath("deluser")
|
||||
if err == nil {
|
||||
tryCommand (exec.Command(deluser, fullName, "--remove-home"),
|
||||
"could not delete user")
|
||||
return
|
||||
}
|
||||
|
||||
// GNU
|
||||
userdel, err := exec.LookPath("userdel")
|
||||
if err == nil {
|
||||
tryCommand (exec.Command(userdel, fullName, "-r"),
|
||||
"could not delete user")
|
||||
groupdel, _ := exec.LookPath("groupdel")
|
||||
tryCommand (exec.Command(groupdel, fullName),
|
||||
"could not delete group")
|
||||
return
|
||||
}
|
||||
|
||||
printErr("could not delete user: no command deluser or userdel")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func execAuth (service, user string) {
|
||||
fullName := serviceUser(service)
|
||||
|
||||
adduser, err := exec.LookPath("adduser")
|
||||
if err == nil {
|
||||
tryCommand (exec.Command(adduser, user, fullName),
|
||||
"could not add user to group " + fullName)
|
||||
return
|
||||
}
|
||||
|
||||
// GNU
|
||||
useradd, err := exec.LookPath("usermod")
|
||||
if err == nil {
|
||||
tryCommand (exec.Command(useradd, "-a", "-g", fullName, user),
|
||||
"could not add user to group " + fullName)
|
||||
return
|
||||
}
|
||||
|
||||
printErr("could not auth user: no command adduser or usermod")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func execOwn (service, file string, recurse bool) {
|
||||
fullName := serviceUser(service)
|
||||
|
||||
userInfo, err := user.Lookup(fullName)
|
||||
uid, _ := strconv.Atoi(userInfo.Uid)
|
||||
gid, _ := strconv.Atoi(userInfo.Gid)
|
||||
|
||||
if err != nil {
|
||||
printErr("could not get user info: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if !recurse {
|
||||
ownOne(file, uid, gid)
|
||||
return
|
||||
}
|
||||
|
||||
err = filepath.Walk(file, func(
|
||||
filePath string,
|
||||
file os.FileInfo,
|
||||
err error,
|
||||
) error {
|
||||
if err != nil {
|
||||
printErr("could not traverse filesystem: %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
ownOne(filePath, uid, gid)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
printErr("could not traverse filesystem: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user