Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the user that executed a program as root using Golang?

Tags:

sudo

go

I'm creating a small program that requires privileged access to a network port below 1024, so it runs with sudo.

If part of what the utility will need to do requires knowing who the user is that invoked the application, I would need a way to query who the actual user is; using the OS/user method of getting the user points to "System Administrator" or other root user because it's running in a sudo context.

Is there a way in GoLang to pull the user who is running the application under sudo? (Go 1.4.2, running on OS X 10.10.3).

like image 780
Bart Silverstrim Avatar asked Apr 19 '15 17:04

Bart Silverstrim


3 Answers

Here's how I check if the current user is root in the latest Golang version go1.16.1:

package main

import (
    "fmt"
    "log"
    "os/user"
)

func isRoot() bool {
    currentUser, err := user.Current()
    if err != nil {
        log.Fatalf("[isRoot] Unable to get current user: %s", err)
    }
    return currentUser.Username == "root"
}

func main() {   
    fmt.Printf("Am I root? %v", isRoot())

}

https://play.golang.org/p/tRMR5IW6GAc

like image 139
Alfonso M. García Astorga Avatar answered Oct 19 '22 15:10

Alfonso M. García Astorga


sudo creates the SUDO_UID/SUDO_GID and the SUDO_USER environment variables for this, which contains the user id, group id and username of the account invoking sudo. See e.g. here

So in Go you can read those environment variables with os.Getenv().

You might want to trust those variables only if running as root, i.e. if os.Geteuid() returns 0

like image 45
nos Avatar answered Oct 19 '22 14:10

nos


Since anyone can set SUDO_UID, SUDO_GID and SUDO_USER, an attacker can just export those themselves and bypass the security you're trying to implement.

The way that I've found, is to find the pid of the Go program you're currently running, get the name of the user that owns that pid, then check if its root.

import (
    "fmt"
    "os"
    "os/exec"
    "strconv"
)

func main() {
    if getProcessOwner() == "root" {
        fmt.Println("You're sudo!")
    }
}

func getProcessOwner() string {
    stdout, err := exec.Command("ps", "-o", "user=", "-p", strconv.Itoa(os.Getpid())).Output()
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    return string(stdout)
}
like image 5
Nick Saccente Avatar answered Oct 19 '22 14:10

Nick Saccente