如何使用 C 程序在没有 root 访问权限的情况下挂载文件系统?
How to mount file system without root access using C program?
我面临一个问题。我的要求是,我需要以普通用户身份挂载 NFS
目录。我不想使用 root
。为此,我开发了下面的简单程序来实现这一点。但是,它没有按预期工作。
我的程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
void usage( char *progName ) {
printf("Usage : %s {mount|umount}\n",progName);
}
int main( char argc , char *argv[] )
{
if ( argc != 2 ) {
usage( argv[0] );
return EXIT_FAILURE;
}
if ( strcmp(argv[1] , "mount") == 0 ) {
execlp("mount", "mount", "192.168.12.3:/home/share", "/home/share", NULL);
}
else if( strcmp(argv[1] , "umount" ) == 0 ) {
execlp("umount", "umount", "/home/share", NULL);
}
else {
usage( argv[0] );
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
然后,
$ cc mount_share.c -o Mount
我还为可执行文件设置了set user id
$ chmod u+s Mount
$ ls -lhrt Mount
-rwsr-xr-x 1 root root 8.3K Jun 4 17:47 Mount
然后我以普通用户的身份执行了Mount
,还是报错。也就是说,
mount: only root can do that
据我所知,应该可以。
你能指出我的代码有什么问题吗?
还有其他方法可以实现吗?
SuDo 是专门为此目的设计的 - 允许非特权用户 运行 特权命令(委托权限)。
为了解决您的问题,您必须在尝试 execlp(3)
之前添加 setuid(0);
正如 user1641854 所说,您可以使用 sudo
。如果你不想这样做,你也可以将预期的挂载点添加到 /etc/fstab
并确保它设置了 user
标志以允许非根用户挂载它
类似于:
192.168.12.3:/home/share /home/share nfs user
尽管您可能还需要其他标志。
您的方法在实践中是完全错误的:使用 sudo
或 super
(或直接调用 mount(2) 系统调用,这对于 NFS 挂载来说很棘手)。
您应该在 execlp
之前更改(至 root
,即 0)真实和有效的 uid,使用 setreuid(2)
请注意,可执行文件上的 setuid 标志使您的程序能够 setreuid
(或调用 setuid
),但不会自动执行此操作(因为您的程序可以做一些事情 - 作为普通用户 - 在 调用 setreuid
之前,例如打开一些配置文件以供普通用户读取 运行你的命令)
另见 Advanced Linux Programming, execve(2), capabilities(7), credentials(7)
我面临一个问题。我的要求是,我需要以普通用户身份挂载 NFS
目录。我不想使用 root
。为此,我开发了下面的简单程序来实现这一点。但是,它没有按预期工作。
我的程序:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
void usage( char *progName ) {
printf("Usage : %s {mount|umount}\n",progName);
}
int main( char argc , char *argv[] )
{
if ( argc != 2 ) {
usage( argv[0] );
return EXIT_FAILURE;
}
if ( strcmp(argv[1] , "mount") == 0 ) {
execlp("mount", "mount", "192.168.12.3:/home/share", "/home/share", NULL);
}
else if( strcmp(argv[1] , "umount" ) == 0 ) {
execlp("umount", "umount", "/home/share", NULL);
}
else {
usage( argv[0] );
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
然后,
$ cc mount_share.c -o Mount
我还为可执行文件设置了set user id
$ chmod u+s Mount
$ ls -lhrt Mount
-rwsr-xr-x 1 root root 8.3K Jun 4 17:47 Mount
然后我以普通用户的身份执行了Mount
,还是报错。也就是说,
mount: only root can do that
据我所知,应该可以。
你能指出我的代码有什么问题吗?
还有其他方法可以实现吗?
SuDo 是专门为此目的设计的 - 允许非特权用户 运行 特权命令(委托权限)。
为了解决您的问题,您必须在尝试 execlp(3)
setuid(0);
正如 user1641854 所说,您可以使用 sudo
。如果你不想这样做,你也可以将预期的挂载点添加到 /etc/fstab
并确保它设置了 user
标志以允许非根用户挂载它
类似于:
192.168.12.3:/home/share /home/share nfs user
尽管您可能还需要其他标志。
您的方法在实践中是完全错误的:使用 sudo
或 super
(或直接调用 mount(2) 系统调用,这对于 NFS 挂载来说很棘手)。
您应该在 execlp
之前更改(至 root
,即 0)真实和有效的 uid,使用 setreuid(2)
请注意,可执行文件上的 setuid 标志使您的程序能够 setreuid
(或调用 setuid
),但不会自动执行此操作(因为您的程序可以做一些事情 - 作为普通用户 - 在 调用 setreuid
之前,例如打开一些配置文件以供普通用户读取 运行你的命令)
另见 Advanced Linux Programming, execve(2), capabilities(7), credentials(7)