Add uid and gid handling
Add the ability to drop to normal user with configurable user and group ids
This commit is contained in:
parent
1985b09e8a
commit
f1a9fdef88
|
@ -4,6 +4,7 @@ import (
|
|||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -14,6 +15,8 @@ type Config struct {
|
|||
BindAddr string // Optional binding address
|
||||
ContentDir string // Gemini content directory to serve
|
||||
Chroot string // chroot directory, if configured
|
||||
Uid int // If not 0 the program will switch to this user id after initialization
|
||||
Gid int // If not 0 the program will switch to this group id after initialization
|
||||
}
|
||||
|
||||
func (cf *Config) SetDefaults() {
|
||||
|
@ -56,6 +59,16 @@ func (cf *Config) LoadConfigFile(filename string) error {
|
|||
cf.ContentDir = value
|
||||
} else if name == "chroot" {
|
||||
cf.Chroot = value
|
||||
} else if name == "uid" {
|
||||
cf.Uid, err = strconv.Atoi(value)
|
||||
if err != nil || cf.Uid < 0 || cf.Uid > 65536 {
|
||||
return fmt.Errorf("Invalid uid in line %d", lineCount)
|
||||
}
|
||||
} else if name == "gid" {
|
||||
cf.Gid, err = strconv.Atoi(value)
|
||||
if err != nil || cf.Gid < 0 || cf.Gid > 65536 {
|
||||
return fmt.Errorf("Invalid gid in line %d", lineCount)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("Unknown setting in line %d", lineCount)
|
||||
}
|
||||
|
|
|
@ -52,6 +52,26 @@ func chroot(dir string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func setuid(uid int) error {
|
||||
if err := syscall.Setuid(uid); err != nil {
|
||||
return err
|
||||
}
|
||||
if syscall.Getuid() != uid {
|
||||
return fmt.Errorf("getuid != %d", uid)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setgid(gid int) error {
|
||||
if err := syscall.Setgid(gid); err != nil {
|
||||
return err
|
||||
}
|
||||
if syscall.Getgid() != gid {
|
||||
return fmt.Errorf("getgid != %d", gid)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
config.SetDefaults()
|
||||
|
||||
|
@ -84,6 +104,8 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
/* Drop privileges here*/
|
||||
|
||||
// Chroot, if configured to do so
|
||||
if config.Chroot != "" {
|
||||
if err := chroot(config.Chroot); err != nil {
|
||||
|
@ -91,6 +113,21 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
// Setuid and setgid if configured
|
||||
if config.Gid > 0 {
|
||||
if err := setgid(config.Gid); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "setgid failed: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("gid = %d\n", syscall.Getgid())
|
||||
}
|
||||
if config.Uid > 0 {
|
||||
if err := setuid(config.Uid); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "setuid failed: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("uid = %d\n", syscall.Getuid())
|
||||
}
|
||||
|
||||
// Make the content dir absolute
|
||||
if !strings.HasPrefix(config.ContentDir, "/") {
|
||||
|
|
|
@ -18,3 +18,7 @@ ContentDir = ./gemini/
|
|||
## Chroot into this directory (uncomment to enable)
|
||||
## Note: If enabled, the ContentDir needs to be adapted accordingly
|
||||
# chroot = /srv/gemini/
|
||||
|
||||
## Custom user and group ids to run orion as
|
||||
# Uid = 5000
|
||||
# Gid = 5000
|
||||
|
|
Loading…
Reference in a new issue