Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/user: add non-cgo version GroupIds #19395

Closed
kevinburke opened this issue Mar 4, 2017 · 5 comments
Closed

os/user: add non-cgo version GroupIds #19395

kevinburke opened this issue Mar 4, 2017 · 5 comments

Comments

@kevinburke
Copy link
Contributor

This is slightly more complicated than the pure Go versions of LookupGroup, Lookup, LookupId, LookupGroupId, I think.

On Darwin machines, /etc/group does not contain a full or partial accounting of a user's groups. Instead the definitive information is stored in opendirectoryd and I'm not quite sure how to access that, apart from C libraries that we don't have access to.

If we wanted to do this in Go we would do:

  • loop over every entry in /etc/group.
  • If the group name starts with a plus or minus, ignore it.
  • If the group mentions the username in the secondary group list, or if the user's Gid matches the gid, add it to an array.
  • return the array.

But this would miss many groups on Darwin and possibly any extensions that glibc also lets you check, which might be a more relevant concern when you are asking for all groups instead of just the primary user/group.

I think that exec.Command("groups", u.Username).Output() would give the right answer, but the overhead is likely too high, a user's machine might not have groups or be able to run a subprocess, &c &c.

@kevinburke kevinburke changed the title non-cgo version of user.GroupIds() proposal: non-cgo version of user.GroupIds() Mar 5, 2017
@rsc rsc changed the title proposal: non-cgo version of user.GroupIds() proposal: os/user: add non-cgo version GroupIds Mar 6, 2017
@rsc
Copy link
Contributor

rsc commented Mar 6, 2017

Why? Why not use cgo?

@kevinburke
Copy link
Contributor Author

The common place I run into errors here is cross compiling; compiling for a Linux target from my Mac laptop.

I run into problems with user.LookupGroup and user.Lookup much more frequently than GroupIds(). I added non-cgo versions of those in recent CL's. For completeness I thought I would try to add this one as well.

@rsc
Copy link
Contributor

rsc commented Mar 7, 2017

I think the sad fact is that if you need those to work properly, you need to use C code: parsing /etc/groups is just not an option anymore. If cgo isn't available then invoking a system program seems OK. On my Mac at least, ["groups", username] is wrong, but ["id", "-G", username] is right (the former prints strings, the latter numeric IDs).

I'll mark this proposal as accepted: if you want to send a CL doing that, it seems fine.

But here's a trick you may not know: if you're not using any cgo beyond the standard library and those have already been built and installed in .a form, you can cross-compile programs using cgo by setting CGO_ENABLED=1 in your build environment. In particular, if you do:

mkdir ~/go1.8dist
cd ~/go1.8dist
tar xzvf ~/Downloads/go1.8.linux-amd64* # for Linux .a files
tar xzvf ~/Downloads/go1.8.darwin-amd64*
export PATH=~/go1.8dist/go/bin:$PATH
export GOROOT=~/go1.8dist/go
CGO_ENABLED=1 GOOS=linux go build -v /tmp/x.go

That builds a Linux binary that uses cgo. If there is any cgo use outside the standard library the build will fail. But if the use is limited to the standard library and the .a files are already available, it won't invoke any external C compiler or linker, and the cross-compile will succeed.

@rsc rsc changed the title proposal: os/user: add non-cgo version GroupIds os/user: add non-cgo version GroupIds Mar 7, 2017
@rsc rsc added this to the Go1.9 milestone Mar 7, 2017
@rsc
Copy link
Contributor

rsc commented Mar 7, 2017

CLs still welcome, of course.

@kevinburke
Copy link
Contributor Author

OK. I think it's probably better to leave unimplemented than to return a response that may be only partially correct.

I think it was OK to add cgo-free versions of Lookup(), LookupId() and friends because Mac/Linux may not use /etc/passwd, /etc/group as a source of truth but they at least try to keep them up to date for the purpose of id <=> name mappings. It seems like they're not reliable enough for "list a user's groups," though.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants