tags:

views:

142

answers:

1

Hi,

I'm completely new to C and I use it very rarely. This time i need it for a university project. I have to write a small c app that tests some modifications we made on the Linux kernel (on the scheduler).

Inside the script I'd like to switch to another user to see the distribution of CPU times among the different users. So I start my small C prog with root rights (i.e. with sudo ./myapp). Inside the prog - after I performed some operations which need root rights - I would like to switch back to another uid by calling seteuid(1000) or setuid(1000) where 1000 is the ID of an existing user (the one I used to log on). However the call doesn't seem to have any effect, it doesn't throw any exception neither. Here's a sample I wrote, just to test the uid switching:

#define _POSIX_SOURCE
#include <pwd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <unistd.h>
#include <string>
#include <time.h>

using namespace std;


int main(int argc, char *argv[])
{
    int uid;
    struct passwd *p;

    if ((p = getpwuid(uid = getuid())) == NULL){
         perror("getpwuid() error");
         exit(1);
    }

    printf("***************************************\n");
    printf("Executing user: %s (%d)\n", p->pw_name, p->pw_uid);
    printf("***************************************\n");

    seteuid(1000);

    if ((p = getpwuid(uid = getuid())) == NULL){
         perror("getpwuid() error");
         exit(1);
    }

    printf("***************************************\n");
    printf("Executing user: %s (%d)\n", p->pw_name, p->pw_uid);
    printf("***************************************\n");

    return 0;
}

Does anyone know why it won't work?? Any help is highly appreciated! Thx

//Edit: Corrected code as mentioned by chsh

+3  A: 

I think it is working just fine, there's just a problem with the logic in the code because you're capturing the value of getuid() into the passwd struct, and then just displaying it twice without retrieving it again after calling seteuid().

chsh
+1 - Yes, you need to re-execute the `p = getpwuid()` call.
Matthew Murdoch
sorry guys. I did a mistake copying it from the original code. I updated it as you suggested, but the problem persists. What I'm unsure now is to whether just the getpwduid call gives me a wrong result...
Juri
Well, getuid() is also going to only return the real user, not the effective user. Swapping the call to getuid() for a call to geteuid() makes it work in testing here. I think what you really want though is to just use setuid, based on your initial post.
chsh
thx a lot that was it of course. I should have taken a closer look at the src. Thx anyway
Juri