Pull request: all: support setgid, setuid on unix
Updates #2763. Squashed commit of the following: commit bd2077c6569b53ae341a58aa73de6063d7037e8e Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Fri Jun 4 16:25:17 2021 +0300 all: move rlimit_nofile, imp docs commit ba95d4ab7c722bf83300d626a598aface37539ad Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Fri Jun 4 15:12:23 2021 +0300 all: support setgid, setuid on unix
This commit is contained in:
@@ -4,17 +4,30 @@ package aghos
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
)
|
||||
|
||||
// ErrUnsupported is returned when the functionality is unsupported on the
|
||||
// current operating system.
|
||||
//
|
||||
// TODO(a.garipov): Make a structured error and use it everywhere instead of
|
||||
// a bunch of fmt.Errorf and all that.
|
||||
const ErrUnsupported errors.Error = "unsupported"
|
||||
// UnsupportedError is returned by functions and methods when a particular
|
||||
// operation Op cannot be performed on the current OS.
|
||||
type UnsupportedError struct {
|
||||
Op string
|
||||
OS string
|
||||
}
|
||||
|
||||
// Error implements the error interface for *UnsupportedError.
|
||||
func (err *UnsupportedError) Error() (msg string) {
|
||||
return fmt.Sprintf("%s is unsupported on %s", err.Op, err.OS)
|
||||
}
|
||||
|
||||
// Unsupported is a helper that returns an *UnsupportedError with the Op field
|
||||
// set to op and the OS field set to the current OS.
|
||||
func Unsupported(op string) (err error) {
|
||||
return &UnsupportedError{
|
||||
Op: op,
|
||||
OS: runtime.GOOS,
|
||||
}
|
||||
}
|
||||
|
||||
// CanBindPrivilegedPorts checks if current process can bind to privileged
|
||||
// ports.
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
package aghos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
@@ -16,7 +15,7 @@ func canBindPrivilegedPorts() (can bool, err error) {
|
||||
}
|
||||
|
||||
func setRlimit(val uint64) (err error) {
|
||||
return ErrUnsupported
|
||||
return Unsupported("setrlimit")
|
||||
}
|
||||
|
||||
func haveAdminRights() (bool, error) {
|
||||
@@ -41,7 +40,7 @@ func haveAdminRights() (bool, error) {
|
||||
}
|
||||
|
||||
func sendProcessSignal(pid int, sig syscall.Signal) error {
|
||||
return fmt.Errorf("not supported on Windows")
|
||||
return Unsupported("kill")
|
||||
}
|
||||
|
||||
func isOpenWrt() (ok bool) {
|
||||
|
||||
11
internal/aghos/user.go
Normal file
11
internal/aghos/user.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package aghos
|
||||
|
||||
// SetGroup sets the effective group ID of the calling process.
|
||||
func SetGroup(groupName string) (err error) {
|
||||
return setGroup(groupName)
|
||||
}
|
||||
|
||||
// SetUser sets the effective user ID of the calling process.
|
||||
func SetUser(userName string) (err error) {
|
||||
return setUser(userName)
|
||||
}
|
||||
50
internal/aghos/user_unix.go
Normal file
50
internal/aghos/user_unix.go
Normal file
@@ -0,0 +1,50 @@
|
||||
// +build darwin freebsd linux netbsd openbsd
|
||||
|
||||
//go:build darwin || freebsd || linux || netbsd || openbsd
|
||||
|
||||
package aghos
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func setGroup(groupName string) (err error) {
|
||||
g, err := user.LookupGroup(groupName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("looking up group: %w", err)
|
||||
}
|
||||
|
||||
gid, err := strconv.Atoi(g.Gid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing gid: %w", err)
|
||||
}
|
||||
|
||||
err = syscall.Setgid(gid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting gid: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setUser(userName string) (err error) {
|
||||
u, err := user.Lookup(userName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("looking up user: %w", err)
|
||||
}
|
||||
|
||||
uid, err := strconv.Atoi(u.Uid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing uid: %w", err)
|
||||
}
|
||||
|
||||
err = syscall.Setuid(uid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting uid: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
16
internal/aghos/user_windows.go
Normal file
16
internal/aghos/user_windows.go
Normal file
@@ -0,0 +1,16 @@
|
||||
// +build windows
|
||||
|
||||
//go:build windows
|
||||
|
||||
package aghos
|
||||
|
||||
// TODO(a.garipov): Think of a way to implement these. Perhaps by using
|
||||
// syscall.CreateProcessAsUser or something from the golang.org/x/sys module.
|
||||
|
||||
func setGroup(_ string) (err error) {
|
||||
return Unsupported("setgid")
|
||||
}
|
||||
|
||||
func setUser(_ string) (err error) {
|
||||
return Unsupported("setuid")
|
||||
}
|
||||
Reference in New Issue
Block a user