我想通过NSS发送请求来获取用户的补充组列表。根据我的估算,以下程序应该让我列举所有组(因此我可以比较成员):
#include <stdio.h>
#include <grp.h>
#include <stdlib.h>
struct group *groupStruct;
int main(){
setgrent();
while ( groupStruct=getgrent() )
printf("%s\n", groupStruct->gr_name);
endgrent();
return 0;
}
我基于id
的{{1}}源代码的这部分假设是基于id -Gn
执行的(因为那是我要复制的功能)。看着它看起来像是通过getugroups (0, NULL, username, gid)
得到了一个组列表,其中getugroups()
被定义在另一个文件中(基本上找到的代码here)。它看起来像是通过与上面相同的setgrent()/ getgrent()程序,所以我的感觉是我的简单程序应该枚举系统的组(相反,它只在/etc/group
中执行组,但我在这台机器上有winbind,id -Gn
拉入用户所属的winbind组。)
答案 0 :(得分:1)
后人:
我仍然不知道为什么id -Gn
代码有效但不是我的代码,但我认为我经过很多来回修复了我自己的问题。基本上我正在构建一个共享对象并通过一个帮助程序枚举它们当前的成员资格,该程序使用initgroups
/ getgroups
将正在运行的进程(帮助程序可执行文件)角色设置为目标用户的默认角色(登录后他们会得到什么。这是帮助程序的完整代码:
#include <stdio.h>
#include <unistd.h>
struct group *groupStruct;
int main(int argc, char *argv[]){
int numgroups, iter, retCode;
int numgroups_max = sysconf(_SC_NGROUPS_MAX) + 1;
gid_t groupList[numgroups_max];
if (argc != 2){
printf("Insufficient Arguments.\n");
return 1;
}
retCode=initgroups(argv[1], 0);
if (retCode != 0){
printf("Unspecified failure: %d\n\n", retCode);
return 1;
}
numgroups = getgroups(numgroups_max, groupList);
for (iter=0; iter <= numgroups; iter++){
if (iter != 0 && iter != numgroups )
printf(" ");
// "zero" means both "nothing more" and could be the root user's primary group, allow the first one through
if ( groupList[iter] == 0 && getuid() == 0 ){
if ( iter != 0 )
break;
}else if ( groupList[iter] == 0 )
break;
printf("%d", groupList[iter]);
}
return 0;
}
用户名是硬编码的,仅用于测试目的。编译和测试后,它会为用户生成组ID。更改硬编码值(或将其推入argv)可以解决问题。我将其推送到帮助程序可执行文件中,因为它正在更改正在运行的进程的角色(至少是组成员身份部分)。
我可能会将它移到库的性能/安全性调用例程中(我可以在使用getgroups
和setgroups
之前保存补充组和主要组)但是我做的更快单独的可执行文件中的概念证明。