/* * set uid and gid, then copy stdin to "output.txt" * * invoked as: * * ./save [--setuidgid uid gid] [--chdir dir] * * for example: * * ./save --setuidgid 3012 3012 --chdir /home/frodo/a3 * * R. Perry, Feb. 2005 */ #include #include #include #include #include #include #include #define SAVE_FILE "output.txt" static char *progname; /* my name */ int main( int argc, char *argv[]) { uid_t uid; gid_t gid; gid_t grouplist[1]; FILE *f; char line[BUFSIZ]; /* get my name */ progname = strrchr( argv[0], '/'); progname = progname ? progname + 1 : argv[0]; /*** Must be the first command-line option: --setuidgid uid gid ***/ if( argc >= 4 && strcmp( argv[1], "--setuidgid") == 0) { uid = atoi( argv[2]); gid = atoi( argv[3]); grouplist[0] = gid; if( setgroups( 1, grouplist)) { fprintf( stderr, "%s: setgroups() failed: %s\n", progname, strerror(errno)); exit(1); } if( setgid( gid)) { fprintf( stderr, "%s: setgid() failed: %s\n", progname, strerror(errno)); exit(1); } if( setuid( uid)) { fprintf( stderr, "%s: setuid() failed: %s\n", progname, strerror(errno)); exit(1); } argc -= 3; argv += 3; } /*** Must be the first remaining command-line option: --chdir dir ***/ if( argc >= 3 && strcmp( argv[1], "--chdir") == 0) { if( chdir( argv[2])) { fprintf( stderr, "%s: chdir() failed: %s\n", progname, strerror(errno)); exit(1); } argc -= 2; argv += 2; } /* check usage */ if( argc > 1) { fprintf( stderr, "Usage: %s [--setuidgid uid gid] [--chdir dir]\n", progname); return 1; } /* open output file */ if( (f = fopen( SAVE_FILE, "w")) == NULL) { fprintf( stderr, "%s: can't open %s for writing: %s\n", progname, SAVE_FILE, strerror(errno)); return 1; } /* copy */ while( fgets( line, BUFSIZ, stdin)) fputs( line, f); fputc( '\n', f); /* ensure final newline */ fclose( f); return 0; }