2013-05-22 37 views
0

我想通过NSS发送请求来获取用户的补充组列表。我的心目当中,下面的程序应该让我列举所有组(这样我就可以再比较成员):枚举C程序中的补充组

#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的是它和id -Gn执行(因为这是我想要复制的功能)。看看它看起来像通过getugroups (0, NULL, username, gid)得到的组列表getugroups()被定义在另一个文件(基本上相同的代码发现here)。它看起来像正在经历与上面相同的setgrent()/ getgrent()过程,所以我的感觉是我的简单程序应该枚举系统组(相反,它只对/etc/group有效,但我对此有winbind机器和id -Gn拉在winbind组中的用户是成员)。

+0

您的称谓说“gentent”;你的意思是“getent”吗? –

+0

是的,它甚至不是我的问题的准确标题。更新到更接近标记的地方。尽管如此,仍然有兴趣知道不同之处。 – Bratchley

+0

我设法在问题发生时错过了这个问题,但是您的解决方案或多或少是需要的。我可以给你一个关于具有相同组号但不同组名称的多个条目如何工作,以及具有不同组号的同名名称如何工作的长篇论文,但是这可能不值得。 'getgroups()'函数返回辅助组ID号;您可以使用'getgrgid()'来查找与每个这样的组相对应的名称。 –

回答

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的。 )解决了这个问题,我将其推送到帮助程序可执行文件中,因为它正在改变正在运行的进程的角色(至少是组成员的部分)。我可能会将它移动到库的调用例程中以获得性能/安全性(我可以先使用getgroupssetgroups保存补充和主要组),但我更快地在单独的可执行文件中进行概念验证。

+0

你的代码应该遍历[0..numgroups]。零作为一个小组入口并不意味着'仅此而已;这意味着用户属于组0.它应该在组列表中最多出现一次,除非有人不小心使用了'setgroups()'。所以你的打印循环的主体应该只包含最初的'if'来打印一个空白,最后的'printf()'(循环后面应该跟着一个'putchar('\ n');'或者等价物)。循环应该是'for(iter = 0; iter

+0

“零作为一个小组条目并不意味着'仅此而已;它意味着用户属于组0”我不愿意不同意你的意见,但这是不正确的。 'getgroups'填充你给出的整个数组,无论它是否有很多补充组。例如,'jadavis6'帐户有两个补充组,但是'getgroups'返回的第三个组是gid0。更不用说我把'id -G'的输出与这个命令的输出进行了比较,它是如何排序的例外),它们在功能上是相同的,如果我忽略了成员关系,这将不会发生。 – Bratchley

+0

另外,告诉我我自己的程序的输出应该是什么,这有点太过规范。更不用说,打印一个新行是没有意义的,正如我在答案中所说的那样,它是'/ usr/libexec'下的一个帮助程序,它产生一个字符串,该字符串用于由库提供给'strtok'功能。添加一个新行只是将随机空白添加到库必须解释的内容。 – Bratchley