setuid() 函数失败 - 操作不允许

3

changeIDs()试图使用setuid()来更改有效用户id,但它总是出错,我不确定原因。

我的电脑上有两个用户。user是一个UID为1000的管理员。另一个标准用户user2的UID为1001。

我想使用这个程序将user2的有效UID设置为user1(1000)的UID。为什么setuid()一直出错呢?

我确保在可执行程序上运行了chmod u+s,但它仍然失败。

setuid()错误 - errno: 操作不允许

另外,你知道为什么我的perror字符串中的E被截断了吗?

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>

void getArguments(int argc, char **argv);
void displayIDs();
void changeID(int userid);



int main(int argc, char **argv)
{
    getArguments(argc, argv);

    return 0;
}



/*
 * The program accepts an option of “c” followed by a numeric user id.
 * When executing the program with the c option followed by a user id,
 * the system displays the real, effective, and saved set user id,
 * then attempts to change the effective user id to the numeric user
 * id passed into the application, and then displays the real,
 * effective, and saved set user id. (20 pts)
 */
void changeID(int userid)
{
    printf("Original IDs:\n==================\n");
    displayIDs();

    uid_t newid = (uid_t)userid;

    //pass the id var as references as outlined in the setuid() man pages
    //error check, fail returns -1
    /*
    if(setresuid(&newid, &newid, &newid) == -1)
    {
        perror("Error with setuid() - errno " + errno);
    }
    */


    if(setuid(&newid) == -1)
    {
        perror("Error with setuid() - errno " + errno);
    }


    printf("\n(Attempted) Changed IDs:\n==================\n");
    displayIDs();
}



/*
 * The program accepts an option of “g.”
 * When executing the program with the g option,
 * the system displays the real, effective,
 * and saved set user id. (10 pts)
 */
void displayIDs()
{
    uid_t ruid;//real user id
    uid_t euid;//effective user id
    uid_t suid;//saved set id

    //pass the id vars as references as outlined in the getresuid() man pages
    //error check, fail returns -1
    if ( getresuid(&ruid, &euid, &suid) == -1)
    {
        perror("Error with getresuid() - errno " + errno);
    }

    printf("Real User ID: %d\n", ruid);
    printf("Effective User ID: %d\n", euid);
    printf("Saved Set User ID: %d\n", suid);
}



//get the arguments from the command line and pass it into the program, calling the right function
void getArguments(int argc, char **argv)
{
    int option = 0;

    while ((option = getopt(argc, argv, "gc:")) != -1)
    {

        switch (option)
        {
             case 'g' :
                 displayIDs();
                 break;
             case 'c' :
                 changeID(optarg);
                 break;
             case '?' :
                 printf("Invalid argument\n");
                 break;
             default:
                 printf("Invalid - no argument (g or c)\n");
                 break;
        }
    }
}

我认为你误解了 setuid 的作用 - 它不会改变系统上用户的 uid。它会更改当前进程的用户 ID,使其看起来像是由不同的用户运行。通常只有 root 可以这样做。 - Nate Eldredge
2个回答

2

setuid()错误 - 错误码: 操作不允许

另外,你知道为什么我的perror字符串中的E被截断了吗?

这是因为你传递给perror()的参数是"Error with setuid() - errno " + errno,相当于&"Error with setuid() - errno "[errno],由于errno等于1,所以它等于该字符串的第二个字符的地址。
你似乎习惯于使用具有连接运算符+的语言,但在C语言中并非如此。


1
它失败了,因为你要设置的有效用户ID既不是0(root),也不与你预期的ID相同。
下面是来自setuid(2)的内容:
setuid()函数将当前进程的真实用户ID、有效用户ID和保存的用户ID设置为指定值。如果有效用户ID是超级用户的ID,或者指定的用户ID与有效用户ID相同,则允许使用setuid()函数。如果不是这样,但指定的用户ID与真实用户ID相同,则setuid()将把有效用户ID设置为真实用户ID。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接