如何在Go中根据用户名切换用户?

huangapple go评论105阅读模式
英文:

How to switch user in Go from username?

问题

我必须使用给定的用户名执行此命令;在bash中,它应该是这样的:

$su devrim -c "touch miki"

我猜,首先我需要从用户名获取uid,并在执行ForkExec之前使用setuid。

你能给些建议吗?我该如何做?(附注:我没有uid,只有用户名)

func exec(cmd *Command, async bool) os.Error {
    parts := strings.Fields(cmd.Command)
    command := parts[0]
    
    // cmd.Su holds the username "root" or "myUser"

    pid, err := os.ForkExec(command, parts, os.Environ(), "", []*os.File{nil, cmd.Stdout, cmd.Stderr})
    cmd.Pid = pid
    
    if !async {
        os.Wait(pid, 0)
    }
    return nil
}

编辑:由于sysuser的方法不起作用,并且我发现它只解析/etc/passwd,所以我决定自己做:

func getUid(su string) int{
    
    passwd,_ := os.Open("/etc/passwd", os.O_RDONLY , 0600)
    
    reader := bufio.NewReader(passwd)
    
    for {
        line,err := reader.ReadString('\n')
        if err != nil { 
            println(err.String()) 
            break
        }
        
        parsed := strings.Split(line,":",4)
        
        if parsed[0] == su {
            value,_ := strconv.Atoi(parsed[2])
            return value
        }
    }
    
    return -1
}

我不确定所有的/etc/passwd在*nix系统中是否都是相同的格式,我们使用Debian和Ubuntu,请小心操作。

英文:

I have to execute this command with given username; in bash it'd be,

$su devrim -c "touch miki"

i guess, first i need to get the uid from the username and use setuid before doing ForkExec.

can u advice? how do i do this ? (ps: i don't have the uid, only username)

func exec(cmd *Command, async bool) os.Error {
    parts := strings.Fields(cmd.Command)
    command := parts[0]
    
    // cmd.Su holds the username "root" or "myUser"

    pid, err := os.ForkExec(command, parts, os.Environ(), "", []*os.File{nil, cmd.Stdout, cmd.Stderr})
    cmd.Pid = pid
    
    if !async {
        os.Wait(pid, 0)
    }
    return nil
}

edit: since that sysuser thing didn't work, and i saw that it's only parsing the /etc/passwd i decided to do it myself:

func getUid(su string) int{
	
	passwd,_ := os.Open("/etc/passwd", os.O_RDONLY , 0600)
    
	reader := bufio.NewReader(passwd)
	
	for {
		line,err := reader.ReadString('\n')
		if err != nil { 
			println(err.String()) 
			break
		}
		
		parsed := strings.Split(line,":",4)
		
		if parsed[0] == su {
			value,_ := strconv.Atoi(parsed[2])
			return value
		}
	}
	
	return -1
}

i'm not sure if all /etc/passwd's are formed the same accross *nix's, we use debian and ubuntu, proceed with care.

答案1

得分: 3

这个包 http://github.com/kless/go-sysuser 可以访问用户名等信息。

syscall包有用于设置/获取UID等的调用。

英文:

This package http://github.com/kless/go-sysuser can access the usernames, etc.

The syscall package has calls for Set/Get UID, etc.

huangapple
  • 本文由 发表于 2010年10月13日 11:03:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/3920491.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定