Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* asid.c
- * for root, run a process as a particular user:group combo
- * sets up minimal enviroment
- * compile w/gcc -g -fwritable-strings -Wall asid.c -o asid
- */
- #include <sys/types.h>
- #include <pwd.h>
- #include <grp.h>
- #include <unistd.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #define ASID_PATH "/bin:/usr/bin:/usr/local/bin"
- #define ASID_SHELL "/bin/bash"
- #define ASID_TERM "vt100" /* if unset */
- #define ASID_LINES "25" /* if unset */
- #define ASID_HOME "/tmp" /* if not in passwd */
- int main( int argc, char * argv[] , char **environ)
- {
- uid_t uid,tmpuid;
- gid_t gid,tmpgid;
- struct passwd * pwuid;
- char * cptr;
- char * ptr;
- char * usrstr;
- char * grstr;
- int i;
- char * envp;
- char ** newargv;
- /* new env */
- char * newenv[9] = {
- "PATH=" ASID_PATH ,
- "TERM=ABCDEFGHIZKLMNOPQRSTUVWXYZ0123456789",
- "LINES=1234567890",
- "SHELL=" ASID_SHELL,
- "HOME=/home/user1234567890ABCDEFGHIZKLMNOPQRSTUVWXYZ0123456789XXXXXXXXXXX",
- "LOGNAME=USER1234567890XXXXXXXXXXXXXXX",
- "USER=USER1234567890XXXXXXXXXXXXXXX",
- "MAIL=/var/spool/mail/USER1234567890XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
- NULL };
- enum { newenv_path , newenv_term, newenv_lines,
- newenv_shell, newenv_home, newenv_logname,
- newenv_user, newenv_mail };
- if ( argc < 2 ) {
- puts("Usage: asid user[:group] command [arg1] ... [argn]");
- return 2;
- }
- newargv=argv; /* argv[0] */
- newargv++; /* argv[1] */
- newargv++; /* argv[2] */
- cptr=index(argv[1], ':' );
- if ( cptr ) {
- cptr[0]=0;
- grstr=1+cptr;
- } else
- grstr="";
- usrstr=argv[1]; /* usrstr:grstr */
- tmpuid=tmpgid=99; /* default to nobody */
- tmpuid=strtol(usrstr, &ptr, 0);
- if ( *ptr != 0 ) { /* try looking up ustr*/
- struct passwd * pptr;
- if ((pptr=getpwnam(usrstr))) {
- tmpuid=pptr->pw_uid;
- gid=pptr->pw_gid;
- }
- }
- uid=tmpuid;
- tmpgid=strtol(grstr, &ptr, 0);
- if ( *ptr != 0 ) { /* try looking up */
- struct group *gptr ;
- if ((gptr=getgrnam(grstr)))
- gid=gptr->gr_gid;
- } else if ( tmpgid )
- gid=tmpgid;
- /*
- * setup newenv
- */
- envp=getenv("TERM");
- snprintf(newenv[newenv_term], 41, "TERM=%s", envp ? envp : ASID_TERM );
- envp=getenv("LINES");
- snprintf(newenv[newenv_lines], 16, "LINES=%s", envp ? envp : ASID_LINES);
- pwuid=getpwuid(uid);
- if ( pwuid && pwuid->pw_dir && pwuid->pw_dir[0] )
- snprintf(newenv[newenv_home],72,"HOME=%s", pwuid->pw_dir );
- else
- snprintf(newenv[newenv_home],72,"HOME=%s", ASID_HOME );
- if ( pwuid && pwuid->pw_name && pwuid->pw_name[0] ) {
- snprintf(newenv[newenv_logname],37,"LOGNAME=%s", pwuid->pw_name );
- snprintf(newenv[newenv_user],34,"USER=%s", pwuid->pw_name );
- snprintf(newenv[newenv_mail],72,"MAIL=/var/mail/%s",
- pwuid->pw_name );
- } else {
- snprintf(newenv[newenv_logname],37,"LOGNAME=%i", uid );
- snprintf(newenv[newenv_user],34,"USER=%i", uid );
- snprintf(newenv[newenv_mail],72,"MAIL=/var/mail/%i", uid );
- }
- /*
- * set ids, clear out groups( only use gid ) , and exec
- */
- fprintf(stderr,"%i:%i trying\n",uid,gid);
- if ( setgroups( 0, NULL ) ) {
- perror("asid:setgroups()");
- return 3;
- }
- if ( setregid( gid, gid) ) {
- perror("asid:setregid():");
- return 4;
- }
- if ( setreuid( uid, uid ) ){
- perror("asid:setreuid():");
- return 3;
- }
- if ( argc < 3 ) {
- execle("/bin/bash", "-bash", NULL, newenv);
- perror("execle:/bin/bash");
- return 4;
- } else {
- for ( i=0 ; i<9 ; i++ )
- environ[i]=newenv[i]; /* seems to work better than clearenv(), */
- environ[9]=NULL; /* putenv() */
- execvp(newargv[0], newargv);
- perror("execve:newargv[0]");
- return 5;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement