我有一个项目,我想使用root来作为普通用户执行程序。
首先我有一个正常的用户fgo whoes uid和gid是501.
id fgo
[root@cpera test]# id fgo
uid=501(fgo) gid=501(fgo) groups=501(fgo)
这是示例代码
#define _GNU_SOURCE
#include <sched.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/capability.h>
#include <sys/resource.h>
#include <unistd.h>
#include<stdlib.h>
#include <stdio.h>
#include <string.h>
int main( int argc,char *argv[]){
while(setgid(501)!=0) sleep(1);
while(setuid(501)!=0) sleep(1);
printf("start to exec\n");
execvp("/bin/sh",NULL);
}
编译并执行
gcc a.c && ./a.out
输出是:
[root@cpera test]# ./a.out
start to exec
[fgo@cpera test]$ id
uid=501(fgo) gid=501(fgo) groups=501(fgo),0(root)
我用谷歌搜索它,发现来自id的组被称为supplementary group从父进程继承。GID, current, primary, supplementary, effective and real group IDs?
如何才能使root不在子进程的组中?
答案 0 :(得分:1)
使用setgroups()重置补充组:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <grp.h>
#include <sys/types.h>
int main (int argc, char *argv[])
{
if (setgroups (0, NULL) != 0) {
perror ("setgroups");
exit (1);
}
if (setgid (501) != 0) {
perror ("setgid");
exit (1);
}
if (setuid (501) != 0) {
perror ("setuid");
exit (1);
}
printf ("start to exec\n");
if (execl ("/bin/sh", NULL) != 0) {
perror ("execl");
}
return 1;
}