we got some dhrek we got some doneky we got some fienona

This commit is contained in:
Sasha Koshka 2023-06-01 03:37:08 -04:00
parent 32bc44c90f
commit 7726d732d4
4 changed files with 85 additions and 58 deletions

View File

@ -5,7 +5,10 @@ package cli
import "os" import "os"
import "fmt" import "fmt"
import "flag" import "flag"
import "os/user"
import "strings" import "strings"
import "strconv"
import "path/filepath"
// Sayf is like Printf, but prints the program name before the message. This is // Sayf is like Printf, but prints the program name before the message. This is
// used for printing messages and errors. // used for printing messages and errors.
@ -25,6 +28,16 @@ func ServiceUser (service string) string {
return "hn-" + strings.ToLower(service) return "hn-" + strings.ToLower(service)
} }
// DataDir returns the standard Hnakra data directory.
func DataDir () string {
return "/var/hnakra"
}
// ServiceDir returns the standard data directory of a service.
func ServiceDir (service string) string {
return filepath.Join(DataDir(), "services", ServiceUser(service))
}
// NeedRoot halts the program and displays an error if it is not being run as // NeedRoot halts the program and displays an error if it is not being run as
// root. This should be called whenever an operation takes place that requires // root. This should be called whenever an operation takes place that requires
// root privelages. // root privelages.
@ -35,3 +48,34 @@ func NeedRoot() {
os.Exit(1) os.Exit(1)
} }
} }
// MkdirFor makes a directory makes the specified directory (if it doesnt
// already exist) and gives ownership of it to the specified uid and gid.
func MkdirFor (directory string, uid, gid int) error {
err := os.MkdirAll(directory, 0755)
if err != nil { return err }
err = os.Chmod(directory, 0770)
if err != nil { return err }
err = os.Chown(directory, uid, gid)
if err != nil { return err }
return nil
}
// LookupUID returns the uid and gid of the given username, if it exists.
func LookupUID (name string) (uid, gid uint32, err error) {
user, err := user.Lookup(name)
if err != nil {
return 0, 0, err
}
puid, err := strconv.Atoi(user.Uid)
if err != nil {
return 0, 0, err
}
pgid, err := strconv.Atoi(user.Gid)
if err != nil {
return 0, 0, err
}
return uint32(puid), uint32(pgid), nil
}

View File

@ -64,7 +64,7 @@ func execStart (service string) {
return return
} }
uid, gid, err := spawn.LookupUID(fullName) uid, gid, err := cli.LookupUID(fullName)
if err != nil { if err != nil {
cli.Sayf("cannot start service: %v\n", err) cli.Sayf("cannot start service: %v\n", err)
os.Exit(1) os.Exit(1)
@ -78,7 +78,7 @@ func execStart (service string) {
logDir := filepath.Join("/var/log/", fullName) logDir := filepath.Join("/var/log/", fullName)
env := append(os.Environ(), "HNAKRA_LOG_DIR=" + logDir) env := append(os.Environ(), "HNAKRA_LOG_DIR=" + logDir)
err = ensureLogDir(logDir, int(uid), int(gid)) err = cli.MkdirFor(logDir, int(uid), int(gid))
if err != nil { if err != nil {
cli.Sayf("cannot start service: %v\n", err) cli.Sayf("cannot start service: %v\n", err)
os.Exit(1) os.Exit(1)
@ -125,17 +125,6 @@ func execStop (service string) {
} }
} }
func ensureLogDir (directory string, uid, gid int) error {
err := os.MkdirAll(directory, 0755)
if err != nil { return err }
err = os.Chmod(directory, 0770)
if err != nil { return err }
err = os.Chown(directory, uid, gid)
if err != nil { return err }
return nil
}
func ensurePidFile (file string, uid, gid int) error { func ensurePidFile (file string, uid, gid int) error {
pidFile, err := os.Create(file) pidFile, err := os.Create(file)
if err != nil { return err } if err != nil { return err }

View File

@ -6,7 +6,6 @@ import "fmt"
import "time" import "time"
import "errors" import "errors"
import "syscall" import "syscall"
import "os/user"
import "strconv" import "strconv"
import "path/filepath" import "path/filepath"
@ -45,24 +44,6 @@ func Spawn (path string, uid, gid uint32, env []string, args ...string) (pid int
return process.Pid, process.Release() return process.Pid, process.Release()
} }
// LookupUID returns the uid and gid of the given username, if it exists.
func LookupUID (name string) (uid, gid uint32, err error) {
user, err := user.Lookup(name)
if err != nil {
return 0, 0, err
}
puid, err := strconv.Atoi(user.Uid)
if err != nil {
return 0, 0, err
}
pgid, err := strconv.Atoi(user.Gid)
if err != nil {
return 0, 0, err
}
return uint32(puid), uint32(pgid), nil
}
// PidFile returns the path of a pidfile under the specified name. More // PidFile returns the path of a pidfile under the specified name. More
// specifically, it returns `/run/<name>.pid`. // specifically, it returns `/run/<name>.pid`.
func PidFile (name string) string { func PidFile (name string) string {

View File

@ -76,6 +76,8 @@ func main () {
delUserCommand := flag.NewFlagSet("deluser", flag.ExitOnError) delUserCommand := flag.NewFlagSet("deluser", flag.ExitOnError)
delUserService := delUserCommand.String ("s", "router", delUserService := delUserCommand.String ("s", "router",
"Service to delete the user for") "Service to delete the user for")
delUserRmData := delUserCommand.Bool ("rmd", false,
"Whether to remove the service's data directory")
authCommand := flag.NewFlagSet("auth", flag.ExitOnError) authCommand := flag.NewFlagSet("auth", flag.ExitOnError)
authService := authCommand.String ("s", "router", authService := authCommand.String ("s", "router",
@ -108,7 +110,7 @@ func main () {
execAdduser(*addUserService) execAdduser(*addUserService)
case "deluser": case "deluser":
delUserCommand.Parse(subCommandArgs) delUserCommand.Parse(subCommandArgs)
execDeluser(*delUserService) execDeluser(*delUserService, *delUserRmData)
case "auth": case "auth":
authCommand.Parse(subCommandArgs) authCommand.Parse(subCommandArgs)
execAuth(*authService, *authUser) execAuth(*authService, *authUser)
@ -144,57 +146,68 @@ func execHash (cost int, key string) {
func execAdduser (service string) { func execAdduser (service string) {
fullName := cli.ServiceUser(service) fullName := cli.ServiceUser(service)
dataDir := cli.ServiceDir(service)
if adduser, err := exec.LookPath("adduser"); err == nil {
// BUSYBOX // BUSYBOX
adduser, err := exec.LookPath("adduser")
if err == nil {
addgroup, _ := exec.LookPath("addgroup") addgroup, _ := exec.LookPath("addgroup")
tryCommand (exec.Command(addgroup, fullName, "-S"), tryCommand (exec.Command(addgroup, fullName, "-S"),
"could not add group") "could not add group")
tryCommand (exec.Command(adduser, fullName, "-SHDG", fullName), tryCommand (exec.Command(adduser, fullName, "-SHDG", fullName),
"could not add user") "could not add user")
return } else if useradd, err := exec.LookPath("useradd"); err == nil {
}
// GNU // GNU
useradd, err := exec.LookPath("useradd")
if err == nil {
tryCommand (exec.Command ( tryCommand (exec.Command (
useradd, fullName, "-rUM", useradd, fullName, "-rUM",
"--shell", "/sbin/nologin"), "could not add user") "--shell", "/sbin/nologin"), "could not add user")
return } else {
}
cli.Sayf("could not add user: no command adduser or useradd\n") cli.Sayf("could not add user: no command adduser or useradd\n")
os.Exit(1) os.Exit(1)
} }
func execDeluser (service string) { // create data directory
fullName := cli.ServiceUser(service) uid, gid, err := cli.LookupUID(fullName)
if err != nil {
// BUSYBOX cli.Sayf("could not create data dir: %v\n", err)
deluser, err := exec.LookPath("deluser") os.Exit(1)
if err == nil { }
tryCommand (exec.Command(deluser, fullName, "--remove-home"), err = cli.MkdirFor(dataDir, int(uid), int(gid))
"could not delete user") if err != nil {
return cli.Sayf("could not create data dir: %v\n", err)
os.Exit(1)
}
} }
func execDeluser (service string, rmData bool) {
fullName := cli.ServiceUser(service)
dataDir := cli.ServiceDir(service)
if deluser, err := exec.LookPath("deluser"); err == nil {
// BUSYBOX
tryCommand (exec.Command(deluser, fullName, "--remove-home"),
"could not delete user")
} else if userdel, err := exec.LookPath("userdel"); err == nil {
// GNU // GNU
userdel, err := exec.LookPath("userdel")
if err == nil {
tryCommand (exec.Command(userdel, fullName, "-r"), tryCommand (exec.Command(userdel, fullName, "-r"),
"could not delete user") "could not delete user")
groupdel, _ := exec.LookPath("groupdel") groupdel, _ := exec.LookPath("groupdel")
tryCommand (exec.Command(groupdel, fullName), tryCommand (exec.Command(groupdel, fullName),
"could not delete group") "could not delete group")
return } else {
}
cli.Sayf("could not delete user: no command deluser or userdel\n") cli.Sayf("could not delete user: no command deluser or userdel\n")
os.Exit(1) os.Exit(1)
} }
// delete data directory
if rmData {
err := os.RemoveAll(dataDir)
if err != nil {
cli.Sayf("could not delete data dir: %v\n", err)
os.Exit(1)
}
}
}
func execAuth (service, user string) { func execAuth (service, user string) {
fullName := cli.ServiceUser(service) fullName := cli.ServiceUser(service)