mirror of https://gogs.blitter.com/RLabs/xs
Changed to use runShellAs() (pass cmdline to bash) rather than runCmdAs (os.exec)
to allow pipelines, redir etc.
This commit is contained in:
parent
6fd8ac1519
commit
59337db7e3
|
@ -66,6 +66,48 @@ func runCmdAs(who string, cmd string, conn hkex.Conn) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Run a command (via default shell) as a specific user
|
||||
//
|
||||
// Uses ptys to support commands which expect a terminal.
|
||||
func runShellAs(who string, cmd string, interactive bool, conn hkex.Conn) (err error) {
|
||||
u, _ := user.Lookup(who)
|
||||
var uid, gid uint32
|
||||
fmt.Sscanf(u.Uid, "%d", &uid)
|
||||
fmt.Sscanf(u.Gid, "%d", &gid)
|
||||
fmt.Println("uid:", uid, "gid:", gid)
|
||||
|
||||
var c *exec.Cmd
|
||||
if interactive {
|
||||
c = exec.Command("/bin/bash", "-i")
|
||||
} else {
|
||||
c = exec.Command("/bin/bash", "-c", cmd)
|
||||
}
|
||||
c.SysProcAttr = &syscall.SysProcAttr{}
|
||||
c.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
|
||||
c.Stdin = conn
|
||||
c.Stdout = conn
|
||||
c.Stderr = conn
|
||||
|
||||
// Start the command with a pty.
|
||||
ptmx, err := pty.Start(c) // returns immediately with ptmx file
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Make sure to close the pty at the end.
|
||||
defer func() { _ = ptmx.Close() }() // Best effort.
|
||||
// Copy stdin to the pty and the pty to stdout.
|
||||
go func() { _, _ = io.Copy(ptmx, conn) }()
|
||||
_, _ = io.Copy(conn, ptmx)
|
||||
|
||||
//err = c.Run() // returns when c finishes.
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Command finished with error: %v", err)
|
||||
log.Printf("[%s]\n", cmd)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Demo of a simple server that listens and spawns goroutines for each
|
||||
// connecting client. Note this code is identical to standard tcp
|
||||
// server code, save for declaring 'hkex' rather than 'net'
|
||||
|
@ -155,14 +197,14 @@ func main() {
|
|||
if rec.op[0] == 'c' {
|
||||
// Non-interactive command
|
||||
fmt.Println("[Running command]")
|
||||
runCmdAs(string(rec.who), string(rec.cmd), conn)
|
||||
runShellAs(string(rec.who), string(rec.cmd), false, conn)
|
||||
// Returned hopefully via an EOF or exit/logout;
|
||||
// Clear current op so user can enter next, or EOF
|
||||
rec.op[0] = 0
|
||||
fmt.Println("[Command complete]")
|
||||
} else if rec.op[0] == 's' {
|
||||
fmt.Println("[Running shell]")
|
||||
runCmdAs(string(rec.who), "bash -l -i", conn)
|
||||
runShellAs(string(rec.who), string(rec.cmd), true, conn)
|
||||
// Returned hopefully via an EOF or exit/logout;
|
||||
// Clear current op so user can enter next, or EOF
|
||||
rec.op[0] = 0
|
||||
|
|
Loading…
Reference in New Issue