diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 58 |
1 files changed, 58 insertions, 0 deletions
@@ -0,0 +1,58 @@ +#define _GNU_SOURCE + +#include <assert.h> +#include <errno.h> +#include <grp.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> + +int main( int argc, char *argv[] ) { + + if ( argc < 4 ) { + fprintf( stderr, "Usage: %s user group cmd [args..]\n", argv[0] ); + return 1; + }; + + char *user = argv[1]; + char *group = argv[2]; + char *cmd = argv[3]; + char **args = argv + 3; + + char *end; + unsigned long tmp; + + struct passwd *userpw; + struct group *grouppw; + + tmp = strtoul( user, &end, 10 ); + if ( end != user && ! *end ) { + userpw = getpwuid( tmp ); + } else { + userpw = getpwnam( user ); + }; + assert( userpw != NULL ); + + tmp = strtoul( group, &end, 10 ); + if ( end != user && ! *end ) { + grouppw = getgrgid( tmp ); + } else { + grouppw = getgrnam( group ); + }; + assert( grouppw != NULL ); + + if ( setgroups( 0, NULL ) != 0 ) + assert_perror( errno ); + + if ( setregid( grouppw->gr_gid, grouppw->gr_gid ) != 0 ) + assert_perror( errno ); + + if ( setreuid( userpw->pw_uid, userpw->pw_uid ) != 0 ) + assert_perror( errno ); + + execv( cmd, args ); + assert_perror( errno ); + +} |