Setuid function parsing, setuid Function
Before discussing this setuid function, we should first understand the three UID values maintained by the kernel for each process. These three UIDs are the actual user ID (real UID), valid user ID (valid uid), and saved set user ID (saved set-user-ID ).
First, the actual user ID is the user we are currently logged on to. The actual user ID of the program we are running is the user ID. A valid user ID is the user ID of the current process, which is generally the actual user ID. If the executable file has the SUID permission, its valid user ID is the owner of the executable file. The saved Set User ID is a copy of the valid user ID, which is related to the SUID permission.
The most typical example of the SUID is the passwd command. The owner of the executable file passwd is root, but other users also have the execution permission for it, and it has the SUID permission. When other users execute the executable file passwd, the generated process runs with the root user ID. As shown in:
The owner of this passwd is root, and in the permission column, s represents the SUID permission. I run this command with michael, a common user. The process is as follows:
We can see that the command for the process in the penultimate line is passwd, but its USER is root. This is the SUID permission.
Next, let's get started with the setuid function. This is the description and return value of the setuid function:
If the request is successful, 0 is returned. If the request fails,-1 is returned, and errno is set to an appropriate value.
For the functions of this function, APUE (Advanced Programming in UNIX environment) is written as follows:
In this way, the concept may be a bit cool. I will explain it here:
Before getting started, I will verify that my computer supports the "saved settings user ID" function and run the following code on my computer:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<stdarg.h> 5 #include<errno.h> 6 #include<unistd.h> 7 #define BUFSIZE 512 8 void err_exit(char *fmt,...); 9 int main(int argc,char *argv[])10 {11 if(sysconf(_SC_SAVED_IDS) > 0)12 printf("_POSIX_SAVED_IDS effective!\n");13 14 return 0;15 }
The program running result is as follows:
First, let's talk about the users I use. A total of three users are used: root (UID = 0), michael (UID = 500), and xiaojie (UID = 501), as shown in:
First, if the process has the superuser privilege, all three UIDs are set to the value of the UID (the parameter of the setuid function. For example, the following code:
1 # include <sys/types. h> 2 # include <unistd. h> 3 # include <stdio. h> 4 int main (int argc, char * argv []) 5 {6 uid_t ruid, euid, suid; 7 // these three UIDs are the actual user IDs and valid user IDs respectively, the saved Set User ID is 8 9 setuid (500); 10 getresuid (& ruid, & euid, & suid); 11 printf ("real: % d \ teffective: % d \ tset-user-id: % d \ n ", ruid, euid, suid); 12 13 return 0; 14}
I use the root user to run this program, so the valid user ID of the process at the beginning is 0, and then the process calls setuid (500 ), the values of the three UIDs are set to 500 (the value of the three UIDs of the process is obtained through the getresuid function in the Program). The running result is as follows:
Next, let's discuss the second case. If the uid parameter of the function is equal to the actual user ID of the process or the Set User ID that is saved, set the valid user ID to uid, the other two (the actual user ID and the saved user ID) remain unchanged. For example, the following program:
1 #include<sys/types.h> 2 #include<unistd.h> 3 #include<stdio.h> 4 void err_exit(char *fmt,...); 5 int main(int argc,char *argv[]) 6 { 7 uid_t ruid,euid,suid; 8 9 printf("Before:\n");10 if(-1 == getresuid(&ruid,&euid,&suid))11 err_exit("[getresuid]: ");12 printf("real:%d\teffective:%d\tset-user:%d\n",ruid,euid,suid);13 setuid(500);14 printf("After:\n");15 if(-1 == getresuid(&ruid,&euid,&suid))16 err_exit("[getresuid]: ");17 printf("real:%d\teffective:%d\tset-user:%d\n",ruid,euid,suid);18 19 return 0;20 }
For the executable file generated by this code, I changed its owner to xiaojie (UID = 501) and added SUID permission to it, as shown in:
Then I use michael user (UID = 500) to run this program. The actual user ID of this program is 500, while the valid user ID and the saved user ID are both 501. Next, call the setuid function in this program. The input parameter is 500. You can guess that only valid user IDs are affected, and the saved user IDs remain unchanged. Shows the running result:
This is in line with our expectations. Only valid user IDs are affected, and the actual user IDs and saved user IDs are not changed. (Here I only verified that the saved user ID settings are not affected. You can also write a program to verify that the actual user ID is not affected .)
Finally, if the value of the uid parameter of the setuid function is not equal to the actual user ID or the saved user ID, in addition, the valid user ID of this process is not 0 (non-privileged process ). In this case, an error occurs and errno is set to EPERM. For example, the following program:
1 #include<sys/types.h> 2 #include<unistd.h> 3 #include<stdio.h> 4 #include<string.h> 5 #include<errno.h> 6 int main(int argc,char *argv[]) 7 { 8 uid_t ruid,euid,suid; 9 10 getresuid(&ruid,&euid,&suid);11 printf("real:%d\teffective:%d\tset-user:%d\n",ruid,euid,suid);12 13 if(-1 == setuid(500))14 {15 printf("%s\n",strerror(errno));16 if(errno == EPERM)17 {18 printf("Error number is EPERM!\n");19 }20 }21 else22 {23 getresuid(&ruid,&euid,&suid);24 printf("real:%d\teffective:%d\tset-user:%d\n",ruid,euid,suid);25 }26 27 return 0;28 }
When I run this program as a xiaojie user (UID = 501), all three user IDs of this program are 501. Then, in this program, setuid (500) is called ). The program reports an error and sets errno to EPERM, as shown in:
OK. This is the explanation of the setuid function on APUE. After talking so much about it, we can say that root is a god, and no one can handle it. Ordinary users can only manage their own tasks (change the valid ID of the process to their own ID.
OK, that's all. I hope this article will help you.