如何使用 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

尽管您可能还需要其他标志。

您的方法在实践中是完全错误的:使用 sudosuper(或直接调用 mount(2) 系统调用,这对于 NFS 挂载来说很棘手)。

您应该在 execlp 之前更改(至 root,即 0)真实和有效的 uid,使用 setreuid(2)

请注意,可执行文件上的 setuid 标志使您的程序能够 setreuid(或调用 setuid),但不会自动执行此操作(因为您的程序可以做一些事情 - 作为普通用户 - 调用 setreuid 之前,例如打开一些配置文件以供普通用户读取 运行你的命令)

另见 Advanced Linux Programming, execve(2), capabilities(7), credentials(7)