Hi all,
Thanks to laserlight.
The code I pasted in my earlier messages work. I have given complete test code below.
I have two users - user1 and user2 and the condition for the program to work
When user1 launches an executable with mode 4755 set and the owner and group are user2 for that executable
Now there is another executable which has mode 750, but the owner and group are user2 only.
With the given code below user1 launches the compiled output of the code given below, which launches the software /app/launcher without any issues.
I have given the debugging printf statements in the code below.
So after compiling this code, one have to change the mode (4755), ownership and group to the owner of the launcher program. A standard user cannot set this unless sudo is invoked.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <grp.h>
#include <unistd.h>
#include <pwd.h>
#include <time.h>
#include <sys/wait.h>
/*Global variables:*/
int status;
struct passwd *getuser2UID; /*A structure defined in pwd.h that will return a list of value for the given user. See 'man getpwnam' for more details:*/
/*Global variables ends*/
/*Restore the effective UIDs to its original value:*/
void dosetuid(pid_t realUID, pid_t effectiveUID)
{
int status;
#ifdef _POSIX_SAVED_IDS
status = seteuid(effectiveUID);
#else
status = setreuid(realUID, effectiveUID);
#endif
if(status < 0)
{
fprintf (stderr, "Couldn't set uid.\n");
exit(status);
}
}
/*Set the effective UID to the real UID:*/
void undosetuid(pid_t realUID, pid_t effectiveUID)
{
int status;
#ifdef _POSIX_SAVED_IDS
status = seteuid(realUID);
#else
status = setreuid(effectiveUID, realUID);
#endif
if(status < 0)
{
fprintf(stderr, "Couldn't set uid.\n");
exit(status);
}
}
void main()
{
/*UID global variables:*/
static uid_t effectiveUID, realUID;
/*Process and parent process ids:*/
int pPID = -1, pPPID = -1, cPID = -1, cPPID = -1;
/*Get the real and effective UIDs:*/
realUID = getuid();
effectiveUID = geteuid();
printf("%d %d\n", realUID, effectiveUID);
if((user2UID = getpwnam("user2")) != NULL)
{/*Do nothing:*/
printf("user2UID: %d\n", user2UID->pw_uid);
}
/*Call a function to execute GTK+ software from here:*/
pid_t PID = fork();
switch(PID)
{
case -1:
{
perror("Fork failed\n");
break;
}
case 0:
{
cPID = getpid(); cPPID = getppid();
printf("Child process\n");
printf("PPID= %d PPPID= %d\n", cPID, cPPID);
dosetuid(realUID, user2UID->pw_uid);
printf("Before: %d %d\n", getuid(), geteuid());
execv("/app/launcher", NULL);
printf("After: %d %d\n", getuid(), geteuid());
undosetuid(realUID, user2UID->pw_uid);
break;
}
default:
{
pPID = getpid(); pPPID = getppid();
printf("Parent process\n");
printf("PPID= %d PPPID= %d\n", pPID, pPPID);
break;
}
}
while((PID = waitpid(-1, &status, 0)) != -1)
{/*Wait till all child processes finishes and then exit:*/
}
return;
}