diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-10-29 04:32:43 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-10-29 04:33:13 +0900 |
| commit | a0b4e47acc228e48165966d8e139277b8f6f450e (patch) | |
| tree | d363a6781536ce946aa445271ca1d3df587e6031 /internal/outcome/spaccount.go | |
| parent | a52f7038e5a607dd0901244abb791c96deaf9c2d (diff) | |
internal/outcome: rename from app
This is less ambiguous, and more accurately describes the purpose of the package.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/outcome/spaccount.go')
| -rw-r--r-- | internal/outcome/spaccount.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/internal/outcome/spaccount.go b/internal/outcome/spaccount.go new file mode 100644 index 00000000..0e9c602a --- /dev/null +++ b/internal/outcome/spaccount.go @@ -0,0 +1,56 @@ +package outcome + +import ( + "encoding/gob" + "fmt" + "syscall" + + "hakurei.app/container/fhs" + "hakurei.app/internal/validate" +) + +func init() { gob.Register(spAccountOp{}) } + +// spAccountOp sets up user account emulation inside the container. +type spAccountOp struct{} + +func (s spAccountOp) toSystem(state *outcomeStateSys) error { + // do checks here to fail before fork/exec + if state.Container == nil || state.Container.Home == nil || state.Container.Shell == nil { + // unreachable + return syscall.ENOTRECOVERABLE + } + + // default is applied in toContainer + if state.Container.Username != "" && !validate.IsValidUsername(state.Container.Username) { + return newWithMessage(fmt.Sprintf("invalid user name %q", state.Container.Username)) + } + return nil +} + +func (s spAccountOp) toContainer(state *outcomeStateParams) error { + const fallbackUsername = "chronos" + + username := state.Container.Username + if username == "" { + username = fallbackUsername + } + + state.params.Dir = state.Container.Home + state.env["HOME"] = state.Container.Home.String() + state.env["USER"] = username + state.env["SHELL"] = state.Container.Shell.String() + + state.params. + Place(fhs.AbsEtc.Append("passwd"), + []byte(username+":x:"+ + state.mapuid.String()+":"+ + state.mapgid.String()+ + ":Hakurei:"+ + state.Container.Home.String()+":"+ + state.Container.Shell.String()+"\n")). + Place(fhs.AbsEtc.Append("group"), + []byte("hakurei:x:"+state.mapgid.String()+":\n")) + + return nil +} |
