linux 父子进程权限,linux下程序拥有可以提升root权限,需要提升权限可通过fork子进程去完成...

1.程序拥有可提升root权限的方法

sudo -S setcap cap_setuid+ep 应用程序

如果sudo执行失败,将用户加入sudo权限组中。

2.为了保证每次权限可以多次使用,通过fork子进程去完成相应的任务。

切换权限用户使用的函数是setuid();

#include int main()

{

uid_t cur_uid = 0;

cur_uid = getuid();

//切换到root权限

if (setuid(0) < 0)

{

fprintf(stderr, "The switch to root user failed!");

return -1;

}

//执行需要在root权限的操作

//为了安全,将权限降回去

if (setuid(cur_uid) < 0)

{

fprintf(stderr, "Recovery process user failed!");

return -1;

}

return 0;

}

使用上面的代码存在一个问题,将权限提升到root权限的时候执行完相应的操作,在降回去普通用户,将无法再次提升到root权限。想知道详细的可以阅读setuid()的机制。

这里作者实现一个类似popen的可读函数,该函数通过fork出子进程提升到root权限,执行root权限才能执行的命令,通过创建管道的方式,将结果传回给主进程。通过这样的方式,就可以保证主进程的特殊权限一直存在,可以重复使用。

static FILE *readpopen(const char *cmd)

{

int pipefd[2];

int pid_t;

uid_t cur_uid = 0;

if(cmd == NULL)

{

fprintf(stderr,"readpopen() param error");

return NULL;

}

//创建管道

if(pipe(pipefd) < 0)

{

fprintf(stderr, "readpopen() pipe create error");

return NULL;

}

pid_t = fork();

if(pid_t < 0)

return NULL;

if(0 == pid_t)

{

cur_uid = getuid();

if (setuid(0) < 0)

{

fprintf(stderr, "The switch to root user failed!");

return NULL;

}

close(pipefd[0]);

dup2(pipefd[1], STDOUT_FILENO);

close(pipefd[1]);

execl("/bin/bash", "sh", "-c", cmd, (char *)NULL);

/* Recovery process user privilege */

if (setuid(cur_uid) < 0)

{

fprintf(stderr, "The switch to user failed!");

return NULL;

}

exit(0);

}

waitpid(pid_t, NULL, 0);

close(pipefd[1]);

return fdopen(pipefd[0], "r");

}

你可能感兴趣的