-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
Comments
Why? Why not use cgo? |
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. |
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:
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. |
CLs still welcome, of course. |
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. |
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:
Gid
matches the gid, add it to an 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.The text was updated successfully, but these errors were encountered: