func prepareCommand(ctx *ctx) (*exec.Cmd, error) {
	cmd := ctx.exec.cmdName
	args := strings.Split(cmd, " ")

	osUserName := ctx.login
	// configure UID & GID of the requested OS user:
	osUser, err := user.Lookup(osUserName)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	uid, err := strconv.Atoi(osUser.Uid)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	gid, err := strconv.Atoi(osUser.Gid)
	if err != nil {
		return nil, trace.Wrap(err)
	}

	// get user's shell:
	shell, err := utils.GetLoginShell(ctx.login)
	if err != nil {
		log.Warn(err)
	}
	if ctx.isTestStub {
		shell = "/bin/sh"
	}
	// try to determine the host name of the 1st available proxy to set a nicer
	// session URL. fall back to <proxyhost> placeholder
	proxyHost := "<proxyhost>"
	if ctx.srv != nil {
		proxies, err := ctx.srv.authService.GetProxies()
		if err != nil {
			log.Error(err)
		}
		if len(proxies) > 0 {
			proxyHost = proxies[0].Hostname
		}
	}
	var c *exec.Cmd
	if len(args) == 1 {
		c = exec.Command(args[0])
	} else {
		c = exec.Command(shell, append([]string{"-c", cmd})...)
	}
	c.Env = []string{
		"LANG=en_US.UTF-8",
		getDefaultEnvPath(""),
		"HOME=" + osUser.HomeDir,
		"USER=" + osUserName,
		"SHELL=" + shell,
		"SSH_TELEPORT_USER=" + ctx.teleportUser,
		fmt.Sprintf("SSH_SESSION_WEBPROXY_ADDR=%s:3080", proxyHost),
	}
	c.Dir = osUser.HomeDir
	c.SysProcAttr = &syscall.SysProcAttr{}
	if _, found := ctx.env["TERM"]; !found {
		c.Env = append(c.Env, "TERM="+defaultTerm)
	}

	// execute the command under requested user's UID:GID
	me, err := user.Current()
	if err != nil {
		return nil, trace.Wrap(err)
	}
	if me.Uid != osUser.Uid || me.Gid != osUser.Gid {
		userGroups, err := osUser.GroupIds()
		if err != nil {
			return nil, trace.Wrap(err)
		}
		groups := make([]uint32, 0)
		for _, sgid := range userGroups {
			igid, err := strconv.Atoi(sgid)
			if err != nil {
				log.Warnf("Cannot interpret user group: '%v'", sgid)
			} else {
				groups = append(groups, uint32(igid))
			}
		}
		if len(groups) == 0 {
			groups = append(groups, uint32(gid))
		}
		c.SysProcAttr.Credential = &syscall.Credential{
			Uid:    uint32(uid),
			Gid:    uint32(gid),
			Groups: groups,
		}
		c.SysProcAttr.Setsid = true
	}

	// apply environment variables passed from the client
	for n, v := range ctx.env {
		c.Env = append(c.Env, fmt.Sprintf("%s=%s", n, v))
	}
	// apply SSH_xx environment variables
	remoteHost, remotePort, err := net.SplitHostPort(ctx.conn.RemoteAddr().String())
	if err != nil {
		log.Warn(err)
	} else {
		localHost, localPort, err := net.SplitHostPort(ctx.conn.LocalAddr().String())
		if err != nil {
			log.Warn(err)
		} else {
			c.Env = append(c.Env,
				fmt.Sprintf("SSH_CLIENT=%s %s %s", remoteHost, remotePort, localPort),
				fmt.Sprintf("SSH_CONNECTION=%s %s %s %s", remoteHost, remotePort, localHost, localPort))
		}
	}
	if ctx.session != nil {
		if ctx.session.term != nil {
			c.Env = append(c.Env, fmt.Sprintf("SSH_TTY=%s", ctx.session.term.tty.Name()))
		}
		if ctx.session.id != "" {
			c.Env = append(c.Env, fmt.Sprintf("SSH_SESSION_ID=%s", ctx.session.id))
		}
	}
	return c, nil
}
// prepareCommand configures exec.Cmd for executing a given command within an SSH
// session.
//
// 'cmd' is the string passed as parameter to 'ssh' command, like "ls -l /"
//
// If 'cmd' does not have any spaces in it, it gets executed directly, otherwise
// it is passed to user's shell for interpretation
prepareCommand configures exec.Cmd for executing a given command within an SSH
session.

'cmd' is the string passed as parameter to 'ssh' command, like "ls -l /"

If 'cmd' does not have any spaces in it, it gets executed directly, otherwise
it is passed to user's shell for interpretation
// prepareCommand configures exec . Cmd for executing a given command within an SSH // session . // // ' cmd ' is the string passed as parameter to ' ssh ' command like " ls - l / " // // If ' cmd ' does not have any spaces in it it gets executed directly otherwise // it is passed to user ' s shell for interpretation
func prepareCommand(ctx *ctx) (*exec.Cmd, error) {
	cmd := ctx.exec.cmdName
	args := strings.Split(cmd, " ")
	osUserName := ctx.login
	osUser, err := user.Lookup(osUserName)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	uid, err := strconv.Atoi(osUser.Uid)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	gid, err := strconv.Atoi(osUser.Gid)
	if err != nil {
		return nil, trace.Wrap(err)
	}
	shell, err := utils.GetLoginShell(ctx.login)
	if err != nil {
		log.Warn(err)
	}
	if ctx.isTestStub {
		shell = "/bin/sh"
	}
	proxyHost := "<proxyhost>"
	if ctx.srv != nil {
		proxies, err := ctx.srv.authService.GetProxies()
		if err != nil {
			log.Error(err)
		}
		if len(proxies) > 0 {
			proxyHost = proxies[0].Hostname
		}
	}
	var c *exec.Cmd
	if len(args) == 1 {
		c = exec.Command(args[0])
	} else {
		c = exec.Command(shell, append([]string{"-c", cmd})...)
	}
	c.Env = []string{
		"LANG=en_US.UTF-8",
		getDefaultEnvPath(""),
		"HOME=" + osUser.HomeDir,
		"USER=" + osUserName,
		"SHELL=" + shell,
		"SSH_TELEPORT_USER=" + ctx.teleportUser,
		fmt.Sprintf("SSH_SESSION_WEBPROXY_ADDR=%s:3080", proxyHost),
	}
	c.Dir = osUser.HomeDir
	c.SysProcAttr = &syscall.SysProcAttr{}
	if _, found := ctx.env["TERM"]; !found {
		c.Env = append(c.Env, "TERM="+defaultTerm)
	}
	me, err := user.Current()
	if err != nil {
		return nil, trace.Wrap(err)
	}
	if me.Uid != osUser.Uid || me.Gid != osUser.Gid {
		userGroups, err := osUser.GroupIds()
		if err != nil {
			return nil, trace.Wrap(err)
		}
		groups := make([]uint32, 0)
		for _, sgid := range userGroups {
			igid, err := strconv.Atoi(sgid)
			if err != nil {
				log.Warnf("Cannot interpret user group: '%v'", sgid)
			} else {
				groups = append(groups, uint32(igid))
			}
		}
		if len(groups) == 0 {
			groups = append(groups, uint32(gid))
		}
		c.SysProcAttr.Credential = &syscall.Credential{
			Uid:    uint32(uid),
			Gid:    uint32(gid),
			Groups: groups,
		}
		c.SysProcAttr.Setsid = true
	}
	for n, v := range ctx.env {
		c.Env = append(c.Env, fmt.Sprintf("%s=%s", n, v))
	}
	remoteHost, remotePort, err := net.SplitHostPort(ctx.conn.RemoteAddr().String())
	if err != nil {
		log.Warn(err)
	} else {
		localHost, localPort, err := net.SplitHostPort(ctx.conn.LocalAddr().String())
		if err != nil {
			log.Warn(err)
		} else {
			c.Env = append(c.Env,
				fmt.Sprintf("SSH_CLIENT=%s %s %s", remoteHost, remotePort, localPort),
				fmt.Sprintf("SSH_CONNECTION=%s %s %s %s", remoteHost, remotePort, localHost, localPort))
		}
	}
	if ctx.session != nil {
		if ctx.session.term != nil {
			c.Env = append(c.Env, fmt.Sprintf("SSH_TTY=%s", ctx.session.term.tty.Name()))
		}
		if ctx.session.id != "" {
			c.Env = append(c.Env, fmt.Sprintf("SSH_SESSION_ID=%s", ctx.session.id))
		}
	}
	return c, nil
}
func prepareCommand ( ctx * ctx ) ( * exec . Cmd , error ) { cmd := ctx . exec . cmdName args := strings . Split ( cmd , " " ) osUserName := ctx . login osUser , err := user . Lookup ( osUserName ) if err != nil { return nil , trace . Wrap ( err ) } uid , err := strconv . Atoi ( osUser . Uid ) if err != nil { return nil , trace . Wrap ( err ) } gid , err := strconv . Atoi ( osUser . Gid ) if err != nil { return nil , trace . Wrap ( err ) } shell , err := utils . GetLoginShell ( ctx . login ) if err != nil { log . Warn ( err ) } if ctx . isTestStub { shell = " " } proxyHost := " " if ctx . srv != nil { proxies , err := ctx . srv . authService . GetProxies ( ) if err != nil { log . Error ( err ) } if len ( proxies ) > 0 { proxyHost = proxies [ 0 ] . Hostname } } var c * exec . Cmd if len ( args ) == 1 { c = exec . Command ( args [ 0 ] ) } else { c = exec . Command ( shell , append ( [ ] string { " " , cmd } ) ... ) } c . Env = [ ] string { " " , getDefaultEnvPath ( " " ) , " " + osUser . HomeDir , " " + osUserName , " " + shell , " " + ctx . teleportUser , fmt . Sprintf ( " " , proxyHost ) , } c . Dir = osUser . HomeDir c . SysProcAttr = & syscall . SysProcAttr { } if _ , found := ctx . env [ " " ] ; ! found { c . Env = append ( c . Env , " " + defaultTerm ) } me , err := user . Current ( ) if err != nil { return nil , trace . Wrap ( err ) } if me . Uid != osUser . Uid || me . Gid != osUser . Gid { userGroups , err := osUser . GroupIds ( ) if err != nil { return nil , trace . Wrap ( err ) } groups := make ( [ ] uint32 , 0 ) for _ , sgid := range userGroups { igid , err := strconv . Atoi ( sgid ) if err != nil { log . Warnf ( " " , sgid ) } else { groups = append ( groups , uint32 ( igid ) ) } } if len ( groups ) == 0 { groups = append ( groups , uint32 ( gid ) ) } c . SysProcAttr . Credential = & syscall . Credential { Uid : uint32 ( uid ) , Gid : uint32 ( gid ) , Groups : groups , } c . SysProcAttr . Setsid = true } for n , v := range ctx . env { c . Env = append ( c . Env , fmt . Sprintf ( " " , n , v ) ) } remoteHost , remotePort , err := net . SplitHostPort ( ctx . conn . RemoteAddr ( ) . String ( ) ) if err != nil { log . Warn ( err ) } else { localHost , localPort , err := net . SplitHostPort ( ctx . conn . LocalAddr ( ) . String ( ) ) if err != nil { log . Warn ( err ) } else { c . Env = append ( c . Env , fmt . Sprintf ( " " , remoteHost , remotePort , localPort ) , fmt . Sprintf ( " " , remoteHost , remotePort , localHost , localPort ) ) } } if ctx . session != nil { if ctx . session . term != nil { c . Env = append ( c . Env , fmt . Sprintf ( " " , ctx . session . term . tty . Name ( ) ) ) } if ctx . session . id != " " { c . Env = append ( c . Env , fmt . Sprintf ( " " , ctx . session . id ) ) } } return c , nil }
prepareCommand configures exec.Cmd for executing a given command within an SSH
session.
prepareCommand configures exec . Cmd for executing a given command within an SSH session .
// configure UID & GID of the requested OS user: // get user's shell: // try to determine the host name of the 1st available proxy to set a nicer // session URL. fall back to <proxyhost> placeholder // execute the command under requested user's UID:GID // apply environment variables passed from the client // apply SSH_xx environment variables