简体   繁体   English

setuid()失败-不允许操作

[英]setuid() failing - operation not permitted

changeIDs() is trying to use setuid() to change the effective user id but it always errors out and I'm not sure why. changeIDs()试图使用setuid()来更改有效的用户ID,但是它总是出错,我不确定为什么。

I have two users on computer. 我在计算机上有两个用户。 user is an admin with UID of 1000. The other standard user, user 2, has a UID of 1001. user是UID为1000的管理员。另一个标准用户user 2的UID为1001。

I want to use this program to set user2's effective UID to that of user1 (1000). 我想使用此程序将user2的有效UID设置为user1的有效UID(1000)。 Why does setuid() keep erroring? 为什么setuid()不断出错?

I made sure to run chmod u+s on the program executable as well and it still fails. 我确保在程序可执行文件上也运行chmod u + s,但仍然失败。

rror with setuid() - errno : Operation not permitted 带有setuid()的rror-errno:不允许操作

Also, do you know why the E in cut off in my perror strings? 另外,您知道为什么我的错误字符串中的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;
        }
    }
}

rror with setuid() - errno : Operation not permitted 带有setuid()的rror-errno:不允许操作

Also, do you know why the E in cut off in my perror strings? 另外,您知道为什么我的错误字符串中的E会中断吗?

This is because you pass perror() "Error with setuid() - errno " + errno , which is equivalent to &"Error with setuid() - errno "[errno] , which is (since errno equals 1) equal to the address of the second char of the string. 这是因为您传递了perror() "Error with setuid() - errno " + errno ,与&"Error with setuid() - errno "[errno] ,即(因为errno等于1)等于地址字符串的第二个char
You seem to be used to a language with a concatenation operator + , which is not the case in C. 您似乎已经习惯了带有连接运算符+的语言,而C语言中不是这种情况。

It fails because neither the effective user ID you're going to set is 0(root) nor the effective Id is identical to the ID you expected. 之所以失败,是因为您要设置的有效用户ID都不为0(root),或者有效ID与您期望的ID都不相同。

Below comes from setuid(2) : 下面来自setuid(2)

The setuid() function sets the real and effective user IDs and the saved set-user-ID of the current process to the specified value. setuid()函数将实际和有效的用户ID以及当前进程的已保存的set-user-ID设置为指定值。 The setuid() function is permitted if the effective user ID is that of the super user, or if the specified user ID is the same as the effective user ID. 如果有效用户ID是超级用户的ID,或者如果指定的用户ID与有效用户ID相同,则允许setuid()函数。 If not, but the specified user ID is the same as the real user ID, setuid() will set the effective user ID to the real user ID. 如果不是,但是指定的用户ID与真实用户ID相同,则setuid()会将有效用户ID设置为真实用户ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM