Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: How to get group ids of one username (like id -Gn )

Tags:

python

linux

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`
like image 863
Ade YU Avatar asked Feb 17 '12 06:02

Ade YU


People also ask

How can I find group GID?

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.

What is group ID and 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.

What is an id group?

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.


4 Answers

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
like image 133
Gareth A. Lloyd Avatar answered Oct 02 '22 16:10

Gareth A. Lloyd


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

like image 44
cs_alumnus Avatar answered Oct 02 '22 17:10

cs_alumnus


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)
like image 26
Jens Timmerman Avatar answered Oct 02 '22 15:10

Jens Timmerman


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]
like image 20
jserras Avatar answered Oct 02 '22 17:10

jserras