getpwname
can only get the gid
of a username
.
import pwd
myGroupId = pwd.getpwnam(username).pw_gid
getgroups
can only get groups
of the script user.
import os
myGroupIds = os.getgroups()
How can I get all groups
of one arbitrary username
, like the id -Gn
command?
id -Gn `whoami`
In Linux, how do I find a user's UID or GID? To find a user's UID (user ID) or GID (group ID) and other information in Linux/Unix-like operating systems, use the id command. This command is useful to find out the following information: Get User name and real user ID.
Normal user IDs are assigned to individuals who use the system interactively. Each user has a unique user ID used to identify the user on the system. Each user can also be assigned one or more group IDs, Group IDs are shared by users in the same group and are not necessarily unique.
A group identifier, often abbreviated to GID, is a numeric value used to represent a specific group. The range of values for a GID varies amongst different systems; at the very least, a GID can be between 0 and 32,767, with one restriction: the login group for the superuser must have GID 0.
The following works assuming you are only interested in local users only, it will not work for things such as sssd
backed by a catalog server (for instance, ldap
).
#!/usr/bin/env python
import grp, pwd
user = "myname"
groups = [g.gr_name for g in grp.getgrall() if user in g.gr_mem]
gid = pwd.getpwnam(user).pw_gid
groups.append(grp.getgrgid(gid).gr_name)
print groups
If you want the current user's groups.
import os, grp
[grp.getgrgid(g).gr_name for g in os.getgroups()]
os.getgroups()
returns the list of gids of the current user.
grp.getgrgid(g)
returns details about a group
The only way I found to make this work correctly when having users non local to the system (e.g. ldap, sssd+ldap, freeIPA) without calling id in a subprocess is by calling the getgrouplist
c function (which is called by id eventually after going trough some abstractions):
#!/usr/bin/python
import grp, pwd, os
from ctypes import *
from ctypes.util import find_library
libc = cdll.LoadLibrary(find_library('libc'))
getgrouplist = libc.getgrouplist
# 50 groups should be enough, if not, we'll repeat the request with the correct nr bellow
ngroups = 50
getgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint * ngroups), POINTER(c_int)]
getgrouplist.restype = c_int32
grouplist = (c_uint * ngroups)()
ngrouplist = c_int(ngroups)
user = pwd.getpwuid(2540485)
ct = getgrouplist(bytes(user.pw_name, 'UTF-8'), user.pw_gid, byref(grouplist), byref(ngrouplist))
# if 50 groups was not enough this will be -1, try again
# luckily the last call put the correct number of groups in ngrouplist
if ct < 0:
getgrouplist.argtypes = [c_char_p, c_uint, POINTER(c_uint *int(ngrouplist.value)), POINTER(c_int)]
grouplist = (c_uint * int(ngrouplist.value))()
ct = getgrouplist(user.pw_name, user.pw_gid, byref(grouplist), byref(ngrouplist))
for i in range(0, ct):
gid = grouplist[i]
print(grp.getgrgid(gid).gr_name)
The result of id -Gn
when the user belongs to one or more groups in which several group names map to the same gid
might not be the same as the posted answer. For instance if /etc/groups
is similar to this:
% ypcat group | grep mygroup
mygroup:*:66485:user1,user2,user3,...
mygroup1:*:66485:user101,user102,user103,...
mygroup2:*:66485:user201,user202,user203,...
...
And if the user is not listed in mygroup
but in mygroup<n>
, id -Gn
returns mygroup
but the posted answer returns mygroup<n>
.
It seems that in my environment, because UNIX groups can have hundreds or thousands of users, this is a common group management policy, although I don't know exactly what is the user limit per group and why id -Gn
always returns mygroup
.
Nevertheless, with the code below I got a match with id -Gn
:
import pwd, grp
def getgroups(user):
gids = [g.gr_gid for g in grp.getgrall() if user in g.gr_mem]
gid = pwd.getpwnam(user).pw_gid
gids.append(grp.getgrgid(gid).gr_gid)
return [grp.getgrgid(gid).gr_name for gid in gids]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With