cmd/hsu: return hsurc id
All checks were successful
Test / Create distribution (push) Successful in 24s
Test / Sandbox (push) Successful in 2m19s
Test / Hpkg (push) Successful in 3m28s
Test / Sandbox (race detector) (push) Successful in 3m53s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Hakurei (push) Successful in 43s
Test / Flake checks (push) Successful in 1m34s
All checks were successful
Test / Create distribution (push) Successful in 24s
Test / Sandbox (push) Successful in 2m19s
Test / Hpkg (push) Successful in 3m28s
Test / Sandbox (race detector) (push) Successful in 3m53s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Hakurei (push) Successful in 43s
Test / Flake checks (push) Successful in 1m34s
The uid format is stable, this value is what caller has to obtain through hsu. Closes #14. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -255,7 +255,7 @@ func (seal *outcome) main() {
|
||||
// passed through to shim by hsu
|
||||
shimEnv + "=" + strconv.Itoa(fd),
|
||||
// interpreted by hsu
|
||||
"HAKUREI_APP_ID=" + seal.user.identity.String(),
|
||||
"HAKUREI_IDENTITY=" + seal.user.identity.String(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,69 +17,48 @@ import (
|
||||
|
||||
// Hsu caches responses from cmd/hsu.
|
||||
type Hsu struct {
|
||||
uidOnce sync.Once
|
||||
uidCopy map[int]struct {
|
||||
uid int
|
||||
err error
|
||||
}
|
||||
uidMu sync.RWMutex
|
||||
idOnce sync.Once
|
||||
idErr error
|
||||
id int
|
||||
}
|
||||
|
||||
var ErrHsuAccess = errors.New("current user is not in the hsurc file")
|
||||
|
||||
func (h *Hsu) Uid(identity int) (int, error) {
|
||||
h.uidOnce.Do(func() {
|
||||
h.uidCopy = make(map[int]struct {
|
||||
uid int
|
||||
err error
|
||||
})
|
||||
h.idOnce.Do(func() {
|
||||
h.id = -1
|
||||
hsuPath := internal.MustHsuPath()
|
||||
|
||||
cmd := exec.Command(hsuPath)
|
||||
cmd.Path = hsuPath
|
||||
cmd.Stderr = os.Stderr // pass through fatal messages
|
||||
cmd.Env = make([]string, 0)
|
||||
cmd.Dir = container.FHSRoot
|
||||
var (
|
||||
p []byte
|
||||
exitError *exec.ExitError
|
||||
)
|
||||
|
||||
const step = "obtain uid from hsu"
|
||||
if p, h.idErr = cmd.Output(); h.idErr == nil {
|
||||
h.id, h.idErr = strconv.Atoi(string(p))
|
||||
if h.idErr != nil {
|
||||
h.idErr = &hst.AppError{Step: step, Err: h.idErr, Msg: "invalid uid string from hsu"}
|
||||
}
|
||||
} else if errors.As(h.idErr, &exitError) && exitError != nil && exitError.ExitCode() == 1 {
|
||||
// hsu prints an error message in this case
|
||||
h.idErr = &hst.AppError{Step: step, Err: ErrHsuAccess}
|
||||
} else if os.IsNotExist(h.idErr) {
|
||||
h.idErr = &hst.AppError{Step: step, Err: os.ErrNotExist,
|
||||
Msg: fmt.Sprintf("the setuid helper is missing: %s", hsuPath)}
|
||||
}
|
||||
})
|
||||
|
||||
{
|
||||
h.uidMu.RLock()
|
||||
u, ok := h.uidCopy[identity]
|
||||
h.uidMu.RUnlock()
|
||||
if ok {
|
||||
return u.uid, u.err
|
||||
}
|
||||
uid := -1
|
||||
if h.id >= 0 {
|
||||
uid = 1000000 + h.id*10000 + identity
|
||||
}
|
||||
|
||||
h.uidMu.Lock()
|
||||
defer h.uidMu.Unlock()
|
||||
|
||||
u := struct {
|
||||
uid int
|
||||
err error
|
||||
}{}
|
||||
defer func() { h.uidCopy[identity] = u }()
|
||||
|
||||
u.uid = -1
|
||||
hsuPath := internal.MustHsuPath()
|
||||
|
||||
cmd := exec.Command(hsuPath)
|
||||
cmd.Path = hsuPath
|
||||
cmd.Stderr = os.Stderr // pass through fatal messages
|
||||
cmd.Env = []string{"HAKUREI_APP_ID=" + strconv.Itoa(identity)}
|
||||
cmd.Dir = container.FHSRoot
|
||||
var (
|
||||
p []byte
|
||||
exitError *exec.ExitError
|
||||
)
|
||||
|
||||
const step = "obtain uid from hsu"
|
||||
if p, u.err = cmd.Output(); u.err == nil {
|
||||
u.uid, u.err = strconv.Atoi(string(p))
|
||||
if u.err != nil {
|
||||
u.err = &hst.AppError{Step: step, Err: u.err, Msg: "invalid uid string from hsu"}
|
||||
}
|
||||
} else if errors.As(u.err, &exitError) && exitError != nil && exitError.ExitCode() == 1 {
|
||||
// hsu prints an error message in this case
|
||||
u.err = &hst.AppError{Step: step, Err: ErrHsuAccess}
|
||||
} else if os.IsNotExist(u.err) {
|
||||
u.err = &hst.AppError{Step: step, Err: os.ErrNotExist,
|
||||
Msg: fmt.Sprintf("the setuid helper is missing: %s", hsuPath)}
|
||||
}
|
||||
return u.uid, u.err
|
||||
return uid, h.idErr
|
||||
}
|
||||
|
||||
// MustUid calls [State.Uid] and terminates on error.
|
||||
|
||||
Reference in New Issue
Block a user