each process has an actual user identifier and an actual group identifier , which is always the user identifier and group identifier of the user who started the process.
The valid user identifiers and valid group identifiers for a process may be more important, and they are used to determine whether a user can access a certain file. In general, they are consistent with the actual user identifier and the actual group identifier.
There are several system calls that can be used to get the user identifier and group identifier for the process, as described in the following procedure:
/* Fetch the actual user identifier for the process */
Uid=getuid ();
/* Take a valid user identifier for the process */
Euid=geteuid ();
/* Take the actual group identifier for the process */
Gid=getgid ();
/* Fetch valid group identifier for process */
Egid=getegid ();
In addition, there are two system calls that can be used to set the process's valid user identifiers and valid group identifiers, using the following format:
/* Set a valid user identifier for the process */
Status=setuid (NEWUID);
/* Set a valid group identifier for the process */
Status=setgid (NEWID)
With these two system invocations, a process can change its own identifier, which in turn changes its own permissions (because the permissions in Linux are judged by identifiers). For example, a process rooted by a root can discard some of the root permissions in this way and only retain the permissions required to work. This can improve the security of the system.
<span style= "FONT-SIZE:14PX;" > #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h>int Main (int argc,char* argv[]) {int fd;fd = fork (), switch (FD) {case-1:{perror ("fork"); exit ( -1);} break Case 0:{ //START process user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ());//set User ID to 1000, change user rights setuid ( 1000);//changed user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ());//root users can view shadow files and test permissions change EXECLP ("Cat" , "Cat", "/etc/shadow", NULL);} break;default:{//START process user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ()),//root user to view Shadow file EXECLP ("Cat" , "Cat", "/etc/shadow", NULL);} break;} return 0;} </span>
Run the results under root permissions:
[Email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
Cat:/etc/shadow: Insufficient permissions
Uid=0,euid=0
root:$ $MG 0tts8ywcpokmrg$tvrzqkq6ik52ucasgfhimkdvhb7zp.rpqd5go/1w07eyqj0jgue9s/uijutyyyqa9irm2vwj7r.dway.5ixip0 : 15195:0:99999:7:::
Bin:*:14789:0:99999:7:::
However, it is important to note that once the root process abandons the root privilege in this way, it will no longer be able to regain root with the setuid () call, because a process with a non-root identifier cannot set the root identifier. You can then call Seteuid () and Setegid () using the other two systems of Linux. It is called in exactly the same way as the first two. However, they are determined according to the identifier of the process program file. Therefore, a root program file can be re-seteuid () to root at any time.
<span style= "FONT-SIZE:14PX;" > #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h>int Main (int argc,char* argv[]) {//START process user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ());// Set user ID to 1000, change user rights setuid (1000),//change user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ()),//set user ID to 0, change user permissions to Rootif ( -1 = = setuid (0)) {perror ("setuid to Root"); exit (-1);} Changed user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ()); return 0;} </span>
Root Run Results:
[Email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
Setuid to Root:operation not permitted
<span style= "FONT-SIZE:14PX;" > #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h>int Main (int argc,char* argv[]) {//START process user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ());// Set user ID to 1000, change user rights setuid (1000),//change user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ()),//set user ID to 1000, change user permissions for yourself if ( -1 = = setuid ()) {perror ("setuid to Root"); exit (-1);} Changed user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ()); return 0;} </span>
Operation Result:
The above example shows that a process that is not referenced by a superuser can only be reset to its actual user identifier and the actual group identifier by its valid user and valid group identifiers. Processes referenced by the superuser are free to set their valid user identifiers and valid group identifiers.
Use Setuid () to permanently change permissions, and now use Seteuid () to temporarily change user permissions:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include < Stdlib.h>int Main (int argc,char* argv[]) {//START process user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ());// Set a valid user ID of 1000, temporarily change user permissions Seteuid (1000),//change the user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ());// Set a valid user ID of 0, change the user permissions for yourself if ( -1 = = setuid (0)) {perror ("setuid to Root"), exit (-1);} Changed user ID and valid user idprintf ("uid=%d,euid=%d\n", Getuid (), Geteuid ()); return 0;}
Operation Result:
#./a.out
Uid=0,euid=0
uid=0,euid=1000
Uid=0,euid=0
[Email protected] file]#./a.out
Uid=0,euid=0
uid=0,euid=1000
Uid=0,euid=0[[email protected] file]#./a.out
Uid=0,euid=0
uid=0,euid=1000
Uid=0,euid=0
[Email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
Uid=1000,euid=1000[[email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
Uid=1000,euid=1000[[email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
Uid=1000,euid=1000[[email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
Uid=1000,euid=1000[[email protected] file]#./a.out
Uid=0,euid=0
uid=1000,euid=1000
uid=1000,euid=1000