lakin@csli.stanford.edu (Fred Lakin) (01/12/91)
Sometimes in the middle of a session I want to read or modify a file requiring root privs. At the moment, I have to go to a shell, become su, and start another emacs. Is there some to momentarily enable (and later "turn back off") su privs in an emacs started by a regular user?? tnx, f starnet!bass!lakin@apple.com
hollen@megatek (Dion Hollenbeck) (01/14/91)
In article <LAKIN.91Jan11160003@csli.stanford.edu> lakin@csli.stanford.edu (Fred Lakin) writes: > Sometimes in the middle of a session I want to read or modify a file > requiring root privs. At the moment, I have to go to a shell, become > su, and start another emacs. Is there some to momentarily enable (and > later "turn back off") su privs in an emacs started by a regular > user?? > The answer is not merely for emacs, but for getting root privs in general on a single command. 1) You do NOT want a shell script to have root priv (even setuid). 2) You do want an executable to have root priv via setuid. Here is a program which I compile into an executable named "-". When I want to do just a single command as root, I do something like this: - mkdir /foo This program will make sure you are you, and will make sure that it is it before executing the command you pass to it as root -------------------------- cut here ---------------------- /* * doasroot.c * * Program to run commands as root * * After it has been compiled, rename to - and chown to * root and setuid as root * * $Log: doasroot.c,v $ * Revision 1.4 90/09/01 10:40:42 hollen * fixed envp * * Revision 1.3 90/08/30 07:28:18 hollen * fixed invocation with absolute path to pass correct args * * Revision 1.2 90/08/28 06:51:26 hollen * added code to make sure regular file and executable * made exit messages for valid user a little more helpful * * Revision 1.1 90/08/27 14:33:51 hollen * Initial revision * * */ #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> extern char *getenv() ; extern char *findfileinpath() ; #define MASTER 740 #define PROGRAM "-" #define BAILOUT \ {fprintf(stderr, "Unauthorized use not allowed\n") ; exit(1);} #define FALSE 0 #define TRUE !FALSE main( argc, argv, envp ) int argc ; char *argv[] ; char *envp[] ; { char *execpath; struct stat stbuf; if ( argc < 2 ) BAILOUT ; /* only valid if on path an invoked exactly as program name */ if ( strcmp(argv[0], PROGRAM) != NULL ) BAILOUT ; /* only valid if invoked by proper user */ if (MASTER != getuid()) { (void)printf( "Bad UID %d\n", getuid()) ; BAILOUT ; } /* program is valid, user is valid, find exececutable */ /* if there is a '/' in name see if the file exists and use it */ if ( strrchr(argv[1], '/') != 0 ) { if ( stat(argv[1], &stbuf) != 0 ) { BAILOUT ; } else { if (execve( argv[1], &argv[1], envp ) == -1 ) { perror("exec failed") ; exit(1) ; } } /*NOTREACHED*/ exit(0) ; } /* no '/' in name, search user path for it */ if ( (execpath = findfileinpath(argv[1])) == NULL ) { (void)fprintf(stderr, "Command not found\n") ; exit(1) ; } /* replace program name pointer with full path name pointer */ argv[1] = execpath ; if (execve( execpath, &argv[1], envp ) == -1 ) { perror("exec failed") ; exit(1) ; } /*NOTREACHED*/ } char * findfileinpath( fname ) char *fname ; { char *foundpath ; char *mypath ; char *ptr ; struct stat stbuf; int found = FALSE; if ( (mypath = getenv( "PATH" )) == NULL) return(NULL); if ( (foundpath = (char *)malloc(strlen(mypath))) == NULL ) return(NULL) ; ptr = strtok(mypath, ":"); while(!found && ptr) { strcpy(foundpath, ptr) ; strcat(foundpath, "/") ; strcat(foundpath, fname) ; if ( stat(foundpath, &stbuf) == 0 ) { if( (stbuf.st_mode & (S_IFREG|S_IEXEC)) == (S_IFREG|S_IEXEC)) found = TRUE ; else (void)fprintf(stderr, "Found match %s, but not executable\n", foundpath); } ptr = strtok((char *)NULL, ":"); } /* foundpath is purposely not freed here */ if ( !found ) return(NULL) ; else return(foundpath) ; } ---------------------- cut here ------------------------- Hope this does the trick. dion -- ----- Dion Hollenbeck (619) 455-5590 x2814 Megatek Corporation, 9645 Scranton Road, San Diego, CA 92121 uunet!megatek!hollen or hollen@megatek.uucp
marc@arnor.uucp (01/16/91)
This could be implemented if someone wanted to by the following scheme. You start emacs with root privs. It sets its effective uid/gid back to the user's. Then, commands which wanted temporary root privs could switch the process to root, do there thing, and switch back. My solution is to run a seperate emacs, normally iconified, started from root. The window is white on a red background, so I won't accidently use it. -- Marc Auslander <marc@ibm.com>