I compiled this sample set-root-id program:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
void print_ids()
{
uid_t ruid, euid, suid, rgid, egid, sgid;
getresuid(&ruid, &euid, &suid);
printf("\nruid=%d, euid=%d, suid=%d\n", ruid, euid, suid);
getresgid(&rgid, &egid, &sgid);
printf("rgid=%d, egid=%d, sgid=%d\n\n", rgid, egid, sgid);
}
void main(int argc, char *argv[])
{
print_ids();
seteuid(1000); printf("seteuid(1000): %s\n", strerror(errno));
print_ids();
seteuid(1001); printf("seteuid(1001): %s\n", strerror(errno));
print_ids();
seteuid(0); printf("seteuid(0): %s\n", strerror(errno));
print_ids();
}
Call to seteuid(0) works, but dislays an error message: "Operation not permitted":
$ gcc -Wall ./p3.c -o p3
./p3.c:32: warning: return type of ‘main’ is not ‘int’
$ su -c "chown root:root ./p3 ; chmod 4755 ./p3"
Password: ****
$ ls -l ./p3
-rwsr-xr-x 1 root root 7697 2 gen 19.21 ./p3
$ ./p3
ruid=1000, euid=0, suid=0
rgid=1000, egid=1000, sgid=1000
seteuid(1000): Success
ruid=1000, euid=1000, suid=0
rgid=1000, egid=1000, sgid=1000
seteuid(1001): Operation not permitted
ruid=1000, euid=1000, suid=0
rgid=1000, egid=1000, sgid=1000
seteuid(0): Operation not permitted
ruid=1000, euid=0, suid=0
rgid=1000, egid=1000, sgid=1000
$
Why seteuid(0) works but displays the error message? I noticed that omitting call to seteuid(1001) or call to seteuid(1000) no error messages appear.
Thank you
(I work on Debian 6, gcc version 4.4.5)