Python: как получить групповые идентификаторы одного имени пользователя (например, id -Gn) - PullRequest
19 голосов
/ 17 февраля 2012

getpwname может получить только gid из username.

import pwd
myGroupId = pwd.getpwnam(username).pw_gid

getgroups может получить только groups пользователя скрипта.

import os
myGroupIds = os.getgroups()

Как я могу получить все groups одного произвольного username, как команда id -Gn?

id -Gn `whoami`

Ответы [ 4 ]

26 голосов
/ 17 февраля 2012

#!/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
3 голосов
/ 02 июля 2014

Если вы хотите, чтобы группы текущих пользователей.

import os, grp
[grp.getgrgid(g).gr_name for g in os.getgroups()]

os.getgroups () возвращает список gids текущего пользователя.о группе

3 голосов
/ 20 февраля 2013

Результат id -Gn, когда пользователь принадлежит к одной или нескольким группам, в которых несколько имен групп отображаются на один и тот же gid, может не совпадать с опубликованным ответом. Например, если /etc/groups похоже на это:

 % ypcat group | grep mygroup 
 mygroup:*:66485:user1,user2,user3,...
 mygroup1:*:66485:user101,user102,user103,...
 mygroup2:*:66485:user201,user202,user203,...
 ...

И если пользователь не указан в mygroup, а в mygroup<n>, id -Gn возвращает mygroup, а опубликованный ответ возвращает mygroup<n>.

Похоже, что в моей среде, поскольку группы UNIX могут иметь сотни или тысячи пользователей, это общая политика управления группами, хотя я точно не знаю, каков лимит пользователей на группу и почему id -Gn всегда возвращает mygroup.

Тем не менее, с кодом ниже я получил совпадение с 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]
2 голосов
/ 11 апреля 2018

Единственный способ, с помощью которого я нашел правильную работу, когда пользователи не являются локальными для системы (например, ldap, sssd + ldap, freeIPA) без вызова id в подпроцессе, - это вызов getgrouplist Функция c (которая вызывается id в конце концов после прохождения некоторых абстракций):

#!/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 enought?
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(user.pw_name, user.pw_gid, byref(grouplist), byref(ngrouplist))

# if 50 groups was not enought 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 xrange(0, ct):
    gid = grouplist[i]
    print grp.getgrgid(gid).gr_name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...