Brief Overview of Real and Effective IDs in Linux C

A process has user and group identifiers, known as UID and GID numbers. The UIDs and GIDs control how the process interacts with files and other processes. The superuser root, identified by the UID 0, is a special case. The root superuser is allowed free reign over the system.

The real user ID is the UID of the user that forked the process. The effective user ID is the UID used for permission checking. Usually the effective and real UIDs are the same.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void){

    int val;

    printf("This process is %d\n", getpid());
    printf("The real user ID is %d\n", getuid());
    printf("The effective user ID is %d\n", geteuid());


    if((val=fork())<0){
        printf("Problem creating new process\n");
        return 1;
    }
    //fork returns 0 to newly created process    
    if(val==0){
        printf("This process is %d\n", getpid());
        printf("The real user ID is %d\n", getuid());
        printf("The effective user ID is %d\n", geteuid());
    }

    return 0;

}

The GID is the real group ID, which is the GID of the user that created the process. The effective group ID is the GID used for permission checking. Both of these numbers are analogous to the UID and the effective UID, respectively.

#include <stdio.h>
#include <unistd.h>

int main(void){

    printf("Real user ID: %d\n", getuid());
    printf("Effective user ID: %d\n", geteuid());
    printf("Real group ID: %d\n", getgid());
    printf("Effective group ID: %d\n", getegid());


    return 0;

}

We can access the credentials of a process by reading the /proc/PID/status file. These files have a line each describing the UID and GID values.

Note that in the next program we use the sprintf() function to concatenate strings. In production code, we would most likely use the slightly more complicated snprintf() function.

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

int main(void){

    int fileDescriptor;
    int value = 1;
    char pathname[50] = "/proc/";
    char intString[20];
    char buffer[256];

    pid_t processID = getpid();

    printf("This process is %d\n", processID);
    
    //generate pathname---
    //convert int process ID to string
    sprintf(intString, "%d", processID);
    //append processID string to pathname
    strcat(pathname, intString);
    //append /status to pathname
    strcat(pathname, "/status");
    //pathname generated ------
    
    //print out pathname to console
    printf("Pathname = %s\n", pathname);

    fileDescriptor = open(pathname, O_RDONLY);

    if(fileDescriptor < 0){
        printf("Error accessing %s\n", pathname);
        return 1;
    }

    while(1){
        value = read(fileDescriptor, buffer, 255);
        if(value < 0){
            printf("Error reading from %s\n", pathname);
            break;
        } else if (value == 0){
            break;
        } else {
            buffer[255]='';
            printf("%s\n", buffer);
        }
    }    

    return 0;

}

We can attempt to modify the effective user and group IDs using setuid() and setgid() functions. However, unless we are root, we ca only change the values to the same value as either the real user ID or the file’s UID or GID (for instance, if we are running the program as a user other than than the program file’s creator).

#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main(void){
    
    int returnVal;
    
    printf("current process UID %d\n", getuid());

    if((setuid(0))<0){
        printf("Failed to change effective ID.\n");
    }

    //setuid() yields EPERM error
    //if user does not have sufficient privileges 
    //to change the effective ID
    if(errno==EPERM){
        printf("That operation is not permitted.\n");
    }

    return 0;

}

We will look deeper at changing effective user IDs at a later date.

If you’re interested in learning standard C, take a look at my book on Amazon. http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s