Tuesday, September 16, 2014

Unix Prog: Change User/Group IDs

1. setuid, setgid

We can use system calls: setuid, setgid to change process user ids and group ids.

System Definition:
If the user is not super user, the user id getting set up needs to be either real user id or saved set-user-id.
 ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h  
 ......  
 /* Set the user ID of the calling process to UID.  
   If the calling process is the super-user, set the real  
   and effective user IDs, and the saved set-user-ID to UID;  
   if not, the effective user ID is set to UID. */  
 extern int setuid (__uid_t __uid) __THROW __wur;  
 ......  
 /* Set the group ID of the calling process to GID.  
   If the calling process is the super-user, set the real  
   and effective group IDs, and the saved set-group-ID to GID;  
   if not, the effective group ID is set to GID. */  
 extern int setgid (__gid_t __gid) __THROW __wur;  
 ......  

Note: After running exec, the saved_set_user_id is copied from the effective user id.

Example:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 int main(int argc, char* argv[])  
 {  
  // 1000 has to either be real user id or saved set-user-id  
  if(setuid(1000) < 0) {  
   printf("setuid error!\n");  
   exit(1);  
  }  
  printf("current effective id: %d\n", geteuid());  
  printf("current real user id: %d\n", getuid());  
   
  exit(0);  
 }  

shell:
Since current user id is 1000, so we can feel free to change effective user id to real user id. If we are not super user, we can only change effective user id to either real user id or saved set user id.
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 current effective id: 1000  
 current real user id: 1000  

2. man function workflow
1) man normally has set-user-id bit on, so when user urn the man program, process has:
real-user-id: our user id
effective-user-id: man
saved set-user-id: man

2) man access its own files

3) before man run commands on our behalf, it will call setuid to change effective user id(assume we are not the super user)
real-user-id: our user id
effective-user-id: our user id
saved set-user-id: man

4) man run commands on our behalf with our user id, so it has enough access privilege to access our files

5) man run setuid again to change effective user id back to man, since saved set-user-id is man, so this operation is successful.
real-user-id: our user id
effective-user-id: man
saved set-user-id: man

3. setreuid, setregid

setreuid, setregid can be used to change current process's real user id, effective user id or real group id, effective group id.
Without super user privilege, we can only change effective user id, to either real user id or saved set-user-id.

System Definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h  
 ......  
 /* Set the real user ID of the calling process to RUID,  
   and the effective user ID of the calling process to EUID. */  
 extern int setreuid (__uid_t __ruid, __uid_t __euid) __THROW __wur;  
 ......  
 /* Set the real group ID of the calling process to RGID,  
   and the effective group ID of the calling process to EGID. */  
 extern int setregid (__gid_t __rgid, __gid_t __egid) __THROW __wur;  
 ......  

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 int main(int argc, char* argv[])  
 {  
  // If changing the real user id to other id(not our id), or change  
  // effective user id to the id which is not real user id or saved  
  // set-user-id, we need the super user privilege  
  if(setreuid(2, 2) < 0) {  
   printf("setreuid error!\n");  
   exit(1);  
  }  
   
  printf("Current effective id: %d\n", geteuid());  
  printf("Current real user id: %d\n", getuid());  
  exit(0);  
 }  

shell:
1) Because current user id is 1000, without super user privilege we can't change the real user id to 2
2) Run the program with super user privilege, this time it is successful.
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 setreuid error!  
 ubuntu@ip-172-31-23-227:~$ sudo ./proc.out  
 Current effective id: 2  
 Current real user id: 2  

4. seteuid, setegid
seteuid, setegid can be used to change process's effective user/group id only.
Again, without super-user privilege, we can only change effective user id to either real user id or saved set-user-id.

system definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/unistd.h  
 ......  
 /* Set the effective user ID of the calling process to UID. */  
 extern int seteuid (__uid_t __uid) __THROW __wur;  
 ......  
 /* Set the effective group ID of the calling process to GID. */  
 extern int setegid (__gid_t __gid) __THROW __wur;  
 ......  

proc.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<unistd.h>  
   
 int main(int argc, char* argv[])  
 {  
  if(seteuid(2) < 0) {  
   printf("setreuid error!\n");  
   exit(1);  
  }  
   
  printf("Current effective id: %d\n", geteuid());  
  printf("Current real user id: %d\n", getuid());  
  exit(0);  
 }  

shell:
1) current user id is 1000, without super-user privilege, we can't change the current user id to 2(not real user id, not saved-set-user-id)
2) with super user privilege, we can change the effective user id to 2, but real user id is not changed, it is still 0(super user).
 ubuntu@ip-172-31-23-227:~$ ./proc.out  
 setreuid error!  
 ubuntu@ip-172-31-23-227:~$ sudo ./proc.out  
 Current effective id: 2  
 Current real user id: 0  

No comments:

Post a Comment