home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!husc6!necntc!ncoast!allbery
- From: mjr@osiris.UUCP (Marcus J. Ranum)
- Newsgroups: comp.sources.misc
- Subject: submission to source.misc - setuid shell...
- Message-ID: <6381@ncoast.UUCP>
- Date: 8 Dec 87 23:51:59 GMT
- Sender: smith@ncoast.UUCP
- Lines: 1625
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8712/3
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- -----cut here-----cut here-----cut here-----cut here-----
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # README
- # sushfunc.c
- # sushhelp.c
- # sushlex.c
- # sushmain.c
- # sushpath.c
- # sushperm.c
- # sushtree.c
- # sushuser.c
- # sush.h
- # Makefile
- # sush.8l
- # sushperm.5l
- # This archive created: Fri Dec 4 09:11:33 1987
- echo shar: extracting README '(794 characters)'
- sed 's/^XX//' << \SHAR_EOF > README
- XX#static char *RCSid = "$Header: README,v 1.1 87/11/24 17:35:24 mjr Exp $"
- XX# $Author: mjr $
- XX# $Log: README,v $
- XX# Revision 1.1 87/11/24 17:35:24 mjr
- XX# Initial revision
- XX#
- XX
- XX This is the source code and existing documentation for a
- XXprivileged shell. Typically it's more useful on development systems
- XXand in trusted environments. It allows a systems admin to 'grant'
- XXthe power to run certain programs as root on a user/group basis.
- XXThe problem of shell escapes in the granted programs renders sush
- XXless than 100% secure :-)
- XX
- XX Some stylistic flaws:
- XXLots of global variables. All the globals are listed in sush.h
- XXUnfortunately, this makes it hard to run recursive 'sources'.
- XX
- XX Options:
- XXif ROOTRC is defined, it will add code in sushmain.c that tries to
- XXsource a root owned .sushrc file.
- XX
- XX--mjr();
- SHAR_EOF
- if test 794 -ne "`wc -c README`"
- then
- echo shar: error transmitting README '(should have been 794 characters)'
- fi
- echo shar: extracting sushfunc.c '(5541 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushfunc.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "2:$Header: sushfunc.c,v 1.3 87/11/24 17:35:45 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushfunc.c,v $
- XX * Revision 1.3 87/11/24 17:35:45 mjr
- XX * fixed the source() function as well as the cd() to home if no args
- XX *
- XX * Revision 1.2 87/11/19 14:22:47 mjr
- XX * improved functionality of the environment variables.
- XX *
- XX * Revision 1.1 87/11/08 18:19:18 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX
- XXset()
- XX{
- XX int ind =0;
- XX int lng;
- XX unsigned mal1;
- XX unsigned mal2;
- XX
- XX /* set an environment variable */
- XX /* we assume the args are parsed (they must be to get here) */
- XX /* and flip through the envir stack looking for a blank slot*/
- XX /* when we find one we malloc the memory and copy into it. */
- XX
- XX if(sh.shrgn == 1)
- XX return(prenv());
- XX
- XX /* is the thing verbose? - if so set it */
- XX /* and immediately return */
- XX if((!strcmp(sh.sharg[1],"verbose")) || !(strcmp(sh.sharg[1],"-x"))) {
- XX verbose++;
- XX return(0);
- XX }
- XX
- XX
- XX /* see if args is right and all */
- XX if((sh.shrgn != 4) || (strcmp(sh.sharg[2],"="))) {
- XX fprintf(stderr,"syntax: set string = string\n");
- XX return(1);
- XX }
- XX
- XX lng = strlen(sh.sharg[1]);
- XX
- XX /* otherwise OK */
- XX /* search for the victim and free its memory space */
- XX for(ind = 0; ind < SHENV; ind++) {
- XX if(!strncmp(sh.shenv[ind],sh.sharg[1],lng)) {
- XX /* next thing must be an = sign */
- XX if(sh.shenv[ind][lng] == '=') {
- XX if(sh.shenv[ind])
- XX (void)free(sh.shenv[ind]);
- XX sh.shenv[ind] = '\0';
- XX }
- XX }
- XX }
- XX
- XX /* skip occupied environment space */
- XX ind = 0;
- XX while((sh.shenv[ind]) && (ind < SHENV))
- XX ind++;
- XX
- XX /* if there is room for another shell var */
- XX if(ind < SHENV) {
- XX mal1 = (unsigned)(strlen(sh.sharg[1]));
- XX mal2 = (unsigned)(strlen(sh.sharg[3]));
- XX /* allocate the memory and make the name copy */
- XX if((sh.shenv[ind] = malloc(mal1 + mal2 + 3)) == NULL) {
- XX perror("set");
- XX return(1);
- XX }
- XX (void)strcpy(sh.shenv[ind],sh.sharg[1]);
- XX (void)strcat(sh.shenv[ind],"=");
- XX (void)strcat(sh.shenv[ind],sh.sharg[3]);
- XX
- XX } else {
- XX fprintf(stderr,"set: out of environment space\n");
- XX return(1);
- XX }
- XX
- XX /* is the thing the prompt ? - if so reset it */
- XX if(!strcmp(sh.sharg[1],"prompt")) {
- XX prompt = &sh.shenv[ind][mal1+1];
- XX return(0);
- XX }
- XX
- XX /* is the thing the PATH ? - if so reset it */
- XX if(!strcmp(sh.sharg[1],"PATH")) {
- XX path = &sh.shenv[ind][mal1+1];
- XX return(0);
- XX }
- XX
- XX /* otherwise OK */
- XX if(verbose)
- XX fprintf(stderr,"%s set\n",sh.sharg[1]);
- XX return(0);
- XX}
- XX
- XXunset()
- XX{
- XX int ind;
- XX int mal1;
- XX int ind2;
- XX
- XX /* unset an environment variable */
- XX /* we assume the args are parsed (they must be to get here) */
- XX /* and flip through the envir stack looking for the named slot*/
- XX /* when we find it we free the memory and zero it. */
- XX
- XX /* is the thing verbose? - if so set it */
- XX /* and immediately return */
- XX if((!strcmp(sh.sharg[1],"verbose")) || !(strcmp(sh.sharg[1],"-x"))) {
- XX verbose =0;
- XX return(0);
- XX }
- XX
- XX /* see if args is right and all */
- XX if(sh.shrgn != 2 ) {
- XX fprintf(stderr,"syntax: unset string\n");
- XX return(1);
- XX }
- XX
- XX /* is the thing the PATH ? - if so complain */
- XX if(!strcmp(sh.sharg[1],"PATH")) {
- XX fprintf(stderr,"why unset PATH?\n");
- XX return(1);
- XX }
- XX
- XX /* used for length of search */
- XX mal1 = strlen(sh.sharg[1]);
- XX
- XX /* otherwise OK */
- XX /* search for the victim and free its memory space */
- XX for(ind = 0; ind < SHENV; ind++) {
- XX if(!strncmp(sh.shenv[ind],sh.sharg[1],mal1)) {
- XX /* next thing must be an = sign */
- XX if(sh.shenv[ind][mal1] == '=') {
- XX (void)free(sh.shenv[ind]);
- XX sh.shenv[ind] = '\0';
- XX }
- XX for (ind2 = 0; sh.shenv[ind + ind2 + 1]; ind2++) {
- XX sh.shenv[ind + ind2] = sh.shenv[ind + ind2 + 1];
- XX sh.shenv[ind + ind2 + 1] = '\0';
- XX }
- XX if(verbose)
- XX fprintf(stderr,"%s unset\n",sh.sharg[1]);
- XX return(0);
- XX }
- XX }
- XX
- XX fprintf(stderr,"unset: no environment variable %s\n",sh.sharg[1]);
- XX return(1);
- XX}
- XX
- XXprenv()
- XX{
- XX int i;
- XX int mal1;
- XX
- XX /* print an environment variable or all of them */
- XX
- XX /* if one arg print whole environment */
- XX if(sh.shrgn == 1 ) {
- XX /* print all occupied environment space */
- XX for(i =0; i < SHENV; i++) {
- XX if(sh.shenv[i])
- XX if(*sh.shenv[i])
- XX printf("%s\n",sh.shenv[i]);
- XX }
- XX return(0);
- XX } else {
- XX /* search for the named variable and print it */
- XX
- XX /* get the length */
- XX mal1 = strlen(sh.sharg[1]);
- XX for(i = 0; i < SHENV; i++) {
- XX if(!strncmp(sh.shenv[i],sh.sharg[1],mal1)) {
- XX if(sh.shenv[i][mal1 + 1] == '=') {
- XX printf("%s\n",sh.shenv[i]);
- XX return(0);
- XX }
- XX }
- XX }
- XX }
- XX fprintf(stderr,"printenv: no environment variable %s\n",sh.sharg[1]);
- XX return(1);
- XX}
- XX
- XXbye()
- XX{
- XX /* if exit number given */
- XX if(sh.shrgn >= 2 )
- XX exit(atoi(sh.sharg[1]));
- XX
- XX /* exit with 0 */
- XX exit(0);
- XX}
- XX
- XXcd()
- XX{
- XX /* change current working directory */
- XX /* if no args use home */
- XX if(sh.shrgn == 1) {
- XX if(chdir(home)) {
- XX perror(home);
- XX return(1);
- XX }
- XX return(0);
- XX }
- XX
- XX /* see if args is right and all */
- XX if(sh.shrgn != 2 ) {
- XX fprintf(stderr,"syntax: cd [directory]\n");
- XX return(1);
- XX }
- XX
- XX if(chdir(sh.sharg[1])) {
- XX perror(sh.sharg[1]);
- XX return(1);
- XX }
- XX return(0);
- XX}
- XX
- XXpwd()
- XX{
- XX
- XX /* print current working directory */
- XX
- XX /* see if args is right and all */
- XX if(sh.shrgn > 1 ) {
- XX fprintf(stderr,"syntax: pwd\n");
- XX return(1);
- XX }
- XX printf("%s\n",getwd("."));
- XX
- XX return(0);
- XX}
- XX
- XXsource()
- XX{
- XX FILE *sourcin;
- XX int savttyin = isttyin;
- XX
- XX if(sh.shrgn != 2) {
- XX fprintf(stderr,"syntax: source file\n");
- XX return(1);
- XX }
- XX if((sourcin = fopen(sh.sharg[1], "r")) == NULL) {
- XX perror(sh.sharg[1]);
- XX } else {
- XX isttyin = 0;
- XX (void)doinput(sourcin);
- XX (void)fclose(sourcin);
- XX isttyin = savttyin;
- XX }
- XX return(0);
- XX}
- SHAR_EOF
- if test 5541 -ne "`wc -c sushfunc.c`"
- then
- echo shar: error transmitting sushfunc.c '(should have been 5541 characters)'
- fi
- echo shar: extracting sushhelp.c '(631 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushhelp.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "3:$Header: sushhelp.c,v 1.2 87/11/19 14:23:13 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushhelp.c,v $
- XX * Revision 1.2 87/11/19 14:23:13 mjr
- XX * added clearer help messages
- XX *
- XX * Revision 1.1 87/11/08 18:19:20 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX
- XXhelp()
- XX{
- XX struct cmdtab *dptr;
- XX
- XX fprintf(stderr,"Internal Commands Are:\n");
- XX dptr = cm;
- XX while(dptr -> func) {
- XX fprintf(stderr,"%s\n",dptr->mnem);
- XX dptr++;
- XX }
- XX fprintf(stderr,"Note - I/O redirection is not supported, nor are ");
- XX fprintf(stderr,"filename expansion or history.\n");
- XX return(0);
- XX}
- SHAR_EOF
- if test 631 -ne "`wc -c sushhelp.c`"
- then
- echo shar: error transmitting sushhelp.c '(should have been 631 characters)'
- fi
- echo shar: extracting sushlex.c '(3455 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushlex.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "4:$Header: sushlex.c,v 1.3 87/11/24 16:19:12 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushlex.c,v $
- XX * Revision 1.3 87/11/24 16:19:12 mjr
- XX * added inline macro expansion in command line
- XX *
- XX * Revision 1.2 87/11/19 14:23:33 mjr
- XX * cleaned up parser code a bit.
- XX *
- XX * Revision 1.1 87/11/08 18:19:21 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX#include <ctype.h>
- XX
- XXstatic char *copymac();
- XX
- XXlex(str)
- XXchar *str;
- XX{
- XX char *bufptr;
- XX
- XX /* analyze input string - break it into tokens */
- XX sh.shrgn =0;
- XX bufptr = str;
- XX
- XX /* actually perform the parse */
- XX while(bufptr = wordparse(bufptr,sh.sharg[sh.shrgn],0)) {
- XX
- XX /* set the token pointers to token - this sucks */
- XX sh.shtok[sh.shrgn] = sh.sharg[sh.shrgn];
- XX
- XX /* increment token number */
- XX sh.shrgn++;
- XX }
- XX sh.shtok[sh.shrgn] = NULL;
- XX return(0);
- XX}
- XX
- XXchar *
- XXwordparse(line,word,delim)
- XXchar *line, *word;
- XXint delim;
- XX{
- XX int quot =0;
- XX
- XX /* skip whitespace or delims */
- XX while (*line && (isspace(*line) || *line == delim))
- XX line++;
- XX
- XX if(*line == '\n')
- XX line++;
- XX
- XX /* if end of string, return */
- XX if (!*line) {
- XX *word = '\0';
- XX return(0);
- XX }
- XX
- XX while (*line)
- XX {
- XX /* if its a quote character and we are not in a quoted */
- XX /* string we then set the quote character to match this */
- XX /* one (or end of line) */
- XX if(!quot && (*line == '\"' || *line == '\''))
- XX quot = *line++;
- XX
- XX /* spaces get skipped unless were in a quoted string */
- XX /* if the current character is a matching quote we unset */
- XX /* the quotation and keep parsing */
- XX if((isspace(*line) || *line == delim) && !quot) {
- XX break;
- XX } else {
- XX if(quot && *line == quot) {
- XX quot = 0;
- XX line++;
- XX } else {
- XX *word++ = *line++;
- XX }
- XX }
- XX }
- XX /* null the end of the word and return an ptr to where we are */
- XX *word = '\0';
- XX return(line);
- XX}
- XX
- XXexpline(line,retline,vars)
- XXchar *line;
- XXchar *retline;
- XXchar **vars;
- XX{
- XX
- XX /* expline - expand macros in a string and place the expanded */
- XX /* string in retline. retline is assumed to be long enough. */
- XX /* vars is assumed to be an array of strings that are in the */
- XX /* form of: thing=thing - note - recursion not supported yet */
- XX /* function returns nonzero in event of error */
- XX
- XX char *pti = line;
- XX char *pto = retline;
- XX char vbuf[400];
- XX char *vbpt;
- XX
- XX if(!pti)
- XX return(0);
- XX
- XX while(*pti) {
- XX /* $ indicates start of possible macro */
- XX if(*pti != '$') {
- XX *pto++ = *pti++;
- XX } else {
- XX if(*++pti != '\(') {
- XX /* not a macro */
- XX *pto++ = *pti++;
- XX } else {
- XX /* get macroname into vbuf */
- XX vbpt = vbuf;
- XX ++pti;
- XX while(*pti != '\)') {
- XX if(pti) {
- XX *vbpt++ = *pti++;
- XX } else {
- XX return(-1);
- XX }
- XX }
- XX *vbpt = '\0';
- XX /* increment past last paren */
- XX pti++;
- XX if((pto = copymac(vbuf,pto,vars)) == '\0')
- XX return(-1);
- XX }
- XX }
- XX }
- XX *pto = '\0';
- XX return(0);
- XX}
- XX
- XXstatic char *
- XXcopymac(mac,out,varlist)
- XXchar *mac;
- XXchar *out;
- XXchar **varlist;
- XX{
- XX /* copy the identified macro into the string we are handed */
- XX /* return a pointer to where we leave off, or NULL if we fail */
- XX char **vpt = varlist;
- XX char *ptr;
- XX int lng;
- XX
- XX
- XX /* return if no macros defined */
- XX if(!*vpt)
- XX return(out);
- XX
- XX /* save time if empty macro */
- XX if((lng = strlen(mac)) ==0)
- XX return(out);
- XX
- XX while(vpt) {
- XX if((strncmp(*vpt,mac,lng) ==0) && ((*vpt)[lng] == '=')) {
- XX /* copy contents of macro into string */
- XX ptr = *vpt + lng +1;
- XX while(*ptr)
- XX *out++ = *ptr++;
- XX break;
- XX }
- XX vpt++;
- XX }
- XX return(out);
- XX}
- SHAR_EOF
- if test 3455 -ne "`wc -c sushlex.c`"
- then
- echo shar: error transmitting sushlex.c '(should have been 3455 characters)'
- fi
- echo shar: extracting sushmain.c '(3164 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushmain.c
- XX#ifndef lint
- XXstatic char RCSid[] = "5:$Header: sushmain.c,v 1.5 87/11/24 17:34:43 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushmain.c,v $
- XX * Revision 1.5 87/11/24 17:34:43 mjr
- XX * added the source() feature and .sushrc
- XX *
- XX * Revision 1.4 87/11/24 16:18:50 mjr
- XX * added inline macro expansion in command line.
- XX *
- XX * Revision 1.3 87/11/19 14:22:21 mjr
- XX * dropped newline off the end of input buffer before logging it.
- XX *
- XX * Revision 1.2 87/11/19 14:10:43 mjr
- XX * fixed interrupt handling so shell wouldn't exit on ^C from tty
- XX *
- XX * Revision 1.1 87/11/08 18:19:22 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#define NOEXTERN
- XX#include "sush.h"
- XX#include <stdio.h>
- XX#include <syslog.h>
- XX#include <sys/signal.h>
- XX
- XXextern char **environ;
- XX
- XXmain()
- XX{
- XX register char **ep;
- XX
- XX (void)signal(SIGINT,SIG_IGN);
- XX if(getuser())
- XX exit(1);
- XX
- XX if(loadperm())
- XX exit(1);
- XX
- XX /* make a copy of our environment - actually just point to it */
- XX if (environ) {
- XX int ind = 0;
- XX for (ep = environ; *ep; ep++, ind++)
- XX sh.shenv[ind] = *ep;
- XX path = getenv("PATH");
- XX }
- XX
- XX /* if not a tty, dont print prompt */
- XX if(!isatty(fileno(stdin)))
- XX isttyin = 0;
- XX
- XX /* set default prompt */
- XX prompt = "xsh> ";
- XX
- XX#ifdef ROOTRC
- XX /* 'source' a static .sushrc file if any */
- XX /* we pass a fmt string to userrc to allow this. */
- XX /* later sprintf() is used to build the path */
- XX /* by adding 'home' in. This is possibly gross */
- XX (void)userrc("/etc/.sushrc");
- XX#endif
- XX
- XX /* 'source' a user's .sushrc file if any */
- XX (void)userrc("%s/.sushrc");
- XX
- XX /* 'source' the standard input */
- XX exit(doinput(stdin));
- XX}
- XX
- XXdoinput(inp)
- XXFILE *inp;
- XX{
- XX int (*ptr)();
- XX char *bptr;
- XX struct cmdtab *dptr;
- XX
- XX /* loop forever reading from input FILE */
- XX while(1) {
- XX if(isttyin)
- XX printf("%s",prompt);
- XX if((fgets(sh.shbuf,SHBUF,inp)) == NULL)
- XX return(0);
- XX
- XX /* perform macro expansion if needed */
- XX if(expline(sh.shbuf,sh.shexb,sh.shenv)) {
- XX fprintf(stderr,"INTERNAL error in macro expansion\n");
- XX }
- XX
- XX /* parse it - use the expanded buffer */
- XX if(lex(sh.shexb)) {
- XX fprintf(stderr,"INTERNAL error in lexical analysis\n");
- XX break;
- XX }
- XX
- XX /* if no tokens, skip to read */
- XX if(sh.shrgn == 0)
- XX continue;
- XX
- XX /* in case of verbosity, be verbose */
- XX if(verbose)
- XX fprintf(stderr,"%s",sh.shexb);
- XX
- XX /* drop the last newline from input buffer */
- XX if(bptr = rindex(sh.shexb,'\n'))
- XX *bptr = '\0';
- XX
- XX /* log the input buffer */
- XX (void)syslog(LOG_NOTICE,"sush:<%s> %s",user,sh.shexb);
- XX
- XX /* set dispatch function pointer */
- XX dptr = cm;
- XX
- XX while(dptr -> func) {
- XX if(!strcmp(dptr->mnem,sh.sharg[0])) {
- XX ptr = dptr->func;
- XX break;
- XX }
- XX dptr++;
- XX }
- XX if(!dptr->mnem) {
- XX (void)dopath();
- XX } else {
- XX (void)((*ptr)());
- XX }
- XX }
- XXreturn(0);
- XX}
- XX
- XXuserrc(fmt)
- XXchar *fmt;
- XX{
- XX char pathbuf[900];
- XX int savttyin = isttyin;
- XX FILE *rcp;
- XX
- XX /* source a file if user's home dir has a .sushrc file */
- XX /* note fmt is passed to us - this is grotty but can */
- XX /* be used to pass a default .sushrc also. */
- XX /* see comment where userrc is called. */
- XX
- XX (void)sprintf(pathbuf,fmt,home);
- XX if((rcp = fopen(pathbuf, "r")) == NULL)
- XX return(1);
- XX
- XX isttyin = 0;
- XX (void)doinput(rcp);
- XX (void)fclose(rcp);
- XX isttyin = savttyin;
- XX
- XXreturn(0);
- XX}
- SHAR_EOF
- if test 3164 -ne "`wc -c sushmain.c`"
- then
- echo shar: error transmitting sushmain.c '(should have been 3164 characters)'
- fi
- echo shar: extracting sushpath.c '(2369 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushpath.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "6:$Header: sushpath.c,v 1.2 87/11/19 14:10:26 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushpath.c,v $
- XX * Revision 1.2 87/11/19 14:10:26 mjr
- XX * fixed interrupt handling so shell wouldn't exit on ^C from tty
- XX *
- XX * Revision 1.1 87/11/08 18:19:23 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX#include <syslog.h>
- XX#include <sys/types.h>
- XX#include <sys/stat.h>
- XX#include <sys/wait.h>
- XX#include <sys/signal.h>
- XX
- XXdopath()
- XX{
- XX char *todo;
- XX char **alist = sh.shtok;
- XX char **envptr = sh.shenv;
- XX int child, ret;
- XX union wait status;
- XX
- XX todo = xpath(sh.sharg[0]);
- XX if(!todo) {
- XX fprintf(stderr,"\"%s\" not found\n",sh.sharg[0]);
- XX return(1);
- XX }
- XX
- XX if(!search(top,todo)) {
- XX (void)syslog(LOG_NOTICE,"sush:%s FAILED permission %s",user,todo);
- XX fprintf(stderr,"\"%s\" permission denied\n",todo);
- XX return(1);
- XX }
- XX
- XX /* do it */
- XX if ((child = vfork()) == 0) {
- XX (void)signal(SIGINT,SIG_DFL);
- XX execve(todo,alist,envptr);
- XX perror(todo);
- XX _exit(127);
- XX }
- XX
- XX if(child < 0) {
- XX perror("vfork");
- XX }
- XX
- XX while ((ret = wait(&status)) != child && ret != -1);
- XX
- XX if(verbose && status.w_T.w_Retcode)
- XX fprintf(stderr,"\"%s\" returns %d\n",todo,status.w_T.w_Retcode);
- XX
- XX /* done it */
- XX return(0);
- XX}
- XX
- XXchar *
- XXxpath(exe)
- XXchar *exe;
- XX{
- XX char *ptr;
- XX char *p;
- XX static char pbuf[SHENV]; /* thing to build path in */
- XX static struct stat stbuf; /* stat buffer */
- XX
- XX /* read the path and search for the first thing that matches */
- XX /* the name of the program */
- XX
- XX /* first check if absolut path */
- XX if(exe[0] == '/') {
- XX /* if stat(2) fails return NULL */
- XX if(stat(exe,&stbuf)) {
- XX return((char *)NULL);
- XX } else {
- XX return(exe);
- XX }
- XX }
- XX
- XX /* check to see if pathname is a relative path or not */
- XX /* IE - it has a '/' in it */
- XX if((p = index(exe,'/')) != 0) {
- XX (void)strcpy(pbuf,".");
- XX if((p = getwd(pbuf)) == 0) {
- XX perror(p);
- XX return((char *)NULL);
- XX }
- XX (void)strcat(pbuf,"/");
- XX (void)strcat(pbuf,exe);
- XX if(stat(pbuf,&stbuf)) {
- XX return((char *)NULL);
- XX } else {
- XX return(pbuf);
- XX }
- XX }
- XX
- XX /* last but not least, search the PATH */
- XX ptr = path;
- XX p = pbuf;
- XX
- XX /* somewhat gnarly */
- XX while(*ptr) {
- XX p = pbuf;
- XX while(*ptr && *ptr != ':') {
- XX *p++ = *ptr++;
- XX }
- XX *p++ = '\0';
- XX (void)strcat(pbuf,"/");
- XX (void)strcat(pbuf,exe);
- XX if(!stat(pbuf,&stbuf)) {
- XX return(pbuf);
- XX }
- XX if(*ptr = ':')
- XX ptr++;
- XX }
- XX return((char *)NULL);
- XX}
- SHAR_EOF
- if test 2369 -ne "`wc -c sushpath.c`"
- then
- echo shar: error transmitting sushpath.c '(should have been 2369 characters)'
- fi
- echo shar: extracting sushperm.c '(2594 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushperm.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "7:$Header: sushperm.c,v 1.2 87/11/19 14:21:41 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushperm.c,v $
- XX * Revision 1.2 87/11/19 14:21:41 mjr
- XX * cleaner logging format and more specific messages for error conditions.
- XX *
- XX * Revision 1.1 87/11/08 18:19:24 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX#include <syslog.h>
- XX#include <grp.h>
- XX
- XXloadperm()
- XX{
- XX char inbuf[BUFSIZ];
- XX FILE *fp;
- XX int linenum =0;
- XX
- XX if((fp = fopen(PERMFILE,"r")) == NULL) {
- XX perror(PERMFILE);
- XX return(1);
- XX }
- XX while(fgets(inbuf,BUFSIZ,fp) != NULL) {
- XX linenum++;
- XX /* skip comments */
- XX if(inbuf[0] != '#') {
- XX if(tokenperm(inbuf,linenum))
- XX return(1);
- XX }
- XX }
- XX return(0);
- XX}
- XX
- XXtokenperm(str,linenum)
- XXchar *str;
- XXint linenum;
- XX{
- XX static char cmbuf[SHTOK];
- XX char *bptr;
- XX
- XX bptr = str;
- XX /* tokenize - or is it tokenate ? */
- XX if(bptr = wordparse(bptr,cmbuf,',')) {
- XX
- XX /* parse it as a group */
- XX if(!strcmp(cmbuf,"group")) {
- XX return(addgroup(bptr,linenum));
- XX }
- XX
- XX /* parse it as a user */
- XX if(!strcmp(cmbuf,"user")) {
- XX return(adduser(bptr,linenum));
- XX }
- XX
- XX /* puke */
- XX fprintf(stderr,"bad \"%s\" %s line %d\n",str,PERMFILE,linenum);
- XX (void)syslog(LOG_NOTICE,"sush:sushperm line %d bad",linenum);
- XX return(1);
- XX }
- XXreturn(0);
- XX}
- XX
- XXadduser(str,lineno)
- XXchar *str;
- XXint lineno;
- XX{
- XX static char buf[SHTOK];
- XX char *bptr;
- XX
- XX bptr = str;
- XX
- XX /* this should be the username */
- XX if((bptr = wordparse(bptr,buf,',')) == '\0') {
- XX fprintf(stderr,"bad user in %s line %d\n",PERMFILE,lineno);
- XX (void)syslog(LOG_NOTICE,"sush:sushperm line %d user bad",lineno);
- XX return(1);
- XX }
- XX
- XX /* not us - dont add the files */
- XX if(strcmp(user,buf))
- XX return(0);
- XX
- XX while((bptr = wordparse(bptr,buf,','))!= '\0') {
- XX /* link it in */
- XX if(insert(&top,buf))
- XX return(1);
- XX }
- XXreturn(0);
- XX}
- XX
- XXaddgroup(str,lineno)
- XXchar *str;
- XXint lineno;
- XX{
- XX static char buf[SHTOK];
- XX char *bptr;
- XX struct group *gpt;
- XX int ok =0;
- XX char **gpmem;
- XX
- XX bptr = str;
- XX
- XX /* this should be the group name */
- XX if((bptr = wordparse(bptr,buf,',')) == '\0') {
- XX fprintf(stderr,"bad group in %s line %d\n",PERMFILE,lineno);
- XX (void)syslog(LOG_NOTICE,"sush:sushperm line %d group bad",lineno);
- XX return(1);
- XX }
- XX
- XX if((gpt = getgrnam(buf)) == NULL) {
- XX fprintf(stderr,"vapor group in %s line %d\n",PERMFILE,lineno);
- XX (void)syslog(LOG_NOTICE,"sush:sushperm line %d group bad",lineno);
- XX return(0);
- XX }
- XX gpmem = gpt->gr_mem;
- XX while(*gpmem++) {
- XX if(!strcmp(user,*gpmem))
- XX ok++;
- XX }
- XX
- XX /* auth failed - return */
- XX if(!ok)
- XX return(0);
- XX
- XX while(bptr = wordparse(bptr,buf,',')) {
- XX if(insert(&top,buf))
- XX return(1);
- XX }
- XXreturn(0);
- XX}
- SHAR_EOF
- if test 2594 -ne "`wc -c sushperm.c`"
- then
- echo shar: error transmitting sushperm.c '(should have been 2594 characters)'
- fi
- echo shar: extracting sushtree.c '(1681 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushtree.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "8:$Header: sushtree.c,v 1.2 87/11/19 14:23:57 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushtree.c,v $
- XX * Revision 1.2 87/11/19 14:23:57 mjr
- XX * cleaned up parser code a bit.
- XX *
- XX * Revision 1.1 87/11/08 18:19:25 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX
- XXinsert(curr,newcom)
- XXstruct leaf **curr;
- XXchar *newcom;
- XX{
- XX int ret;
- XX
- XX /* current leaf is empty */
- XX if(*curr == NULL) {
- XX /* add-a-leaf */
- XX *curr = (struct leaf *)malloc((unsigned)sizeof(struct leaf));
- XX if(*curr == NULL) {
- XX perror("malloc");
- XX return(1);
- XX }
- XX (*curr)->cmd = malloc((unsigned)(strlen(newcom)+1));
- XX if((*curr)->cmd == NULL) {
- XX perror("malloc");
- XX return(1);
- XX }
- XX (void)strcpy((*curr)->cmd,newcom);
- XX (*curr)->lptr = NULL;
- XX (*curr)->rptr = NULL;
- XX return(0);
- XX }
- XX
- XX /* fall through if match - no need to save */
- XX ret = strcmp((*curr)->cmd,newcom);
- XX if(ret >0)
- XX return(insert(&(*curr)->rptr,newcom));
- XX if(ret <0)
- XX return(insert(&(*curr)->lptr,newcom));
- XX
- XXreturn(0);
- XX}
- XX
- XXsearch(curr,newcom)
- XXstruct leaf *curr;
- XXchar *newcom;
- XX{
- XX
- XX int ret;
- XX
- XX /* current leaf is empty - not found */
- XX if(curr == NULL) {
- XX return(0);
- XX }
- XX
- XX /* if ! match - search appropriate branch */
- XX ret = strcmp(curr->cmd,newcom);
- XX if(ret >0)
- XX return(search(curr->rptr,newcom));
- XX if(ret <0)
- XX return(search(curr->lptr,newcom));
- XX
- XX return(1);
- XX}
- XX
- XXshopriv()
- XX{
- XX fprintf(stderr,"You are privileged to execute the following:\n");
- XX return(leafdump(top));
- XX}
- XX
- XXleafdump(curr)
- XXstruct leaf *curr;
- XX{
- XX /* current leaf is empty - not found */
- XX if(curr == NULL) {
- XX return(0);
- XX }
- XX (void)leafdump(curr->rptr);
- XX (void)leafdump(curr->lptr);
- XX printf("%s\n",curr->cmd);
- XX
- XX return(0);
- XX}
- SHAR_EOF
- if test 1681 -ne "`wc -c sushtree.c`"
- then
- echo shar: error transmitting sushtree.c '(should have been 1681 characters)'
- fi
- echo shar: extracting sushuser.c '(1315 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushuser.c
- XX
- XX#ifndef lint
- XXstatic char *RCSid = "9:$Header: sushuser.c,v 1.3 87/11/24 17:36:24 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sushuser.c,v $
- XX * Revision 1.3 87/11/24 17:36:24 mjr
- XX * added code to preserve home external envir variable
- XX *
- XX * Revision 1.2 87/11/19 14:24:03 mjr
- XX * improved calls to syslog - dropped newlines
- XX *
- XX * Revision 1.1 87/11/08 18:19:27 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX#include "sush.h"
- XX#include <stdio.h>
- XX#include <pwd.h>
- XX#include <syslog.h>
- XX
- XXchar *crypt();
- XXchar *getpass();
- XX
- XXstruct passwd *getpwuid();
- XX
- XXgetuser()
- XX{
- XX struct passwd *pwt; /* passwd struct */
- XX char *uspass; /* user password */
- XX char *crpass; /* crypted password */
- XX int cleared =3; /* cleared to fly */
- XX
- XX if((pwt = getpwuid(getuid())) == NULL) {
- XX fprintf(stderr,"WHO ARE YOU! !!!\n");
- XX exit(1);
- XX }
- XX
- XX /* we assume your version of getpwent preserves the */
- XX /* stuff it returns. Ours does. */
- XX user = pwt->pw_name;
- XX home = pwt->pw_dir;
- XX
- XX /* validate login */
- XX while(1 == 1) {
- XX uspass = getpass("Your Login Password:");
- XX crpass = crypt(uspass,pwt->pw_passwd);
- XX if(strcmp(crpass,pwt->pw_passwd)) {
- XX fprintf(stderr,"incorrect.\n");
- XX if(!--cleared)
- XX (void)syslog(LOG_NOTICE,"sush:BADlog %s",user);
- XX exit(4);
- XX } else {
- XX break;
- XX }
- XX }
- XX (void)syslog(LOG_NOTICE,"sush:login %s",user);
- XX
- XXreturn(0);
- XX}
- SHAR_EOF
- if test 1315 -ne "`wc -c sushuser.c`"
- then
- echo shar: error transmitting sushuser.c '(should have been 1315 characters)'
- fi
- echo shar: extracting sush.h '(2328 characters)'
- sed 's/^XX//' << \SHAR_EOF > sush.h
- XX
- XX#ifndef lint
- XXstatic char *RCSidG = "1:$Header: sush.h,v 1.3 87/11/24 17:36:45 mjr Exp $";
- XX#endif
- XX
- XX/*
- XX * $Author: mjr $
- XX * $Log: sush.h,v $
- XX * Revision 1.3 87/11/24 17:36:45 mjr
- XX * added code to preserve home external envir variable
- XX *
- XX * Revision 1.2 87/11/24 16:19:04 mjr
- XX * added inline macro expansion in command line.
- XX *
- XX * Revision 1.1 87/11/08 18:19:17 mjr
- XX * Initial revision
- XX *
- XX*/
- XX
- XX
- XX/* should be adequate for basic shell - not heavy-duty */
- XX#define SHBUF 2048
- XX#define SHTOK 64
- XX#define SHARG 40
- XX#define SHENV 1024
- XX
- XXstruct shglob {
- XX char shbuf[SHBUF]; /* general scratch mem */
- XX char shexb[SHBUF]; /* macro expansion buffer */
- XX char *shprm[SHTOK]; /* pointers to permitted progs */
- XX char *shtok[SHTOK]; /* pointers to tokens */
- XX char *shenv[SHENV]; /* pointers to environment variables */
- XX char sharg[SHTOK][SHARG]; /* strings of shell args */
- XX int shrgn; /* number of shell args */
- XX};
- XX
- XXstruct cmdtab {
- XX char *mnem; /* command name */
- XX int (*func)(); /* pointer to func */
- XX};
- XX
- XXstruct leaf {
- XX char *cmd;
- XX struct leaf *lptr;
- XX struct leaf *rptr;
- XX};
- XX
- XX
- XX/* function definitions */
- XXextern int set(), unset(), prenv(), bye();
- XXextern int cd(), pwd(), help(), shopriv();
- XXextern int source();
- XXextern char *malloc();
- XXextern char *wordparse();
- XXextern char *strcpy();
- XXextern char *strcat();
- XXextern char *getenv();
- XXextern char *xpath();
- XXextern char *index();
- XXextern char *rindex();
- XXextern char *getwd();
- XXextern struct group *getgrnam();
- XX
- XX#ifdef NOEXTERN
- XX
- XX/* this version actually allocates memory */
- XX/* only the main() module should define NOEXTERN */
- XXchar *prompt; /* pointer to user prompt */
- XXchar *path; /* pointer to user path */
- XXchar *user; /* pointer to user name */
- XXchar *home; /* pointer to user home dir */
- XXchar verbose =0; /* set -x */
- XXchar isttyin =1; /* is input from a tty ? */
- XXstruct shglob sh; /* shell global struct */
- XXstruct leaf *top = 0; /* permissions list tree */
- XXstruct cmdtab cm[] = {
- XX "set", set,
- XX "cd", cd,
- XX "pwd", pwd,
- XX "unset", unset,
- XX "exit", bye,
- XX "printenv", prenv,
- XX "?", help,
- XX "help", help,
- XX "source", source,
- XX "showpriv", shopriv,
- XX 0, 0
- XX };
- XX
- XX#else
- XX
- XXextern char *path;
- XXextern char *user;
- XXextern char *home;
- XXextern struct leaf *top;
- XXextern struct shglob sh;
- XXextern struct cmdtab cm[];
- XXextern char *prompt;
- XXextern char verbose;
- XXextern char isttyin;
- XX
- XX#endif
- SHAR_EOF
- if test 2328 -ne "`wc -c sush.h`"
- then
- echo shar: error transmitting sush.h '(should have been 2328 characters)'
- fi
- echo shar: extracting Makefile '(1744 characters)'
- sed 's/^XX//' << \SHAR_EOF > Makefile
- XX
- XX#static char *RCSid = "$Header: Makefile,v 1.7 87/11/24 17:35:04 mjr Exp $";
- XX#/*
- XX# $Author: mjr $
- XX# $Log: Makefile,v $
- XX# Revision 1.7 87/11/24 17:35:04 mjr
- XX# added more detail on define options
- XX#
- XX# Revision 1.6 87/11/19 14:46:02 mjr
- XX# final tweeks(?) .
- XX#
- XX# Revision 1.5 87/11/19 14:42:28 mjr
- XX# more futzing around.
- XX#
- XX# Revision 1.4 87/11/19 14:37:26 mjr
- XX# added doc into make dependencies.
- XX#
- XX# Revision 1.3 87/11/19 14:33:00 mjr
- XX# added make install.
- XX#
- XX# Revision 1.2 87/11/19 14:27:33 mjr
- XX# forgot to put Makefile in dependency list !!
- XX#
- XX# Revision 1.1 87/11/08 18:19:15 mjr
- XX# Initial revision
- XX#
- XX#*/
- XX
- XX.SUFFIXES:
- XX.SUFFIXES: .c .o
- XX
- XX.DEFAULT:
- XX co $@
- XX
- XXDEST = /etc/local
- XXDOC = sushperm.l sush.l
- XX
- XX#must be defined as pathname to permissions file.
- XX#DEFINES= -DPERMFILE=\"/etc/local/sushperm\" -DROOTRC
- XX
- XXDEFINES= -DPERMFILE=\"/u1/mjr/hacks/sh/myperm\"
- XX
- XXCFLAGS= -OG -s -n $(DEFINES)
- XX#CFLAGS= -gx $(DEFINES)
- XX
- XXOBJ= sushmain.o\
- XX sushlex.o\
- XX sushpath.o\
- XX sushperm.o\
- XX sushuser.o\
- XX sushtree.o\
- XX sushhelp.o\
- XX sushfunc.o
- XX
- XX
- XXsush: $(OBJ)
- XX cc $(CFLAGS) -o sush $(OBJ)
- XX
- XX$(OBJ): sush.h Makefile
- XX
- XXclean:
- XX rm -f *.o sush
- XX
- XXlint:
- XX lint $(DEFINES) *.c
- XX
- XXshar:
- XX shar -a README *.c *.h Makefile sush.8l sushperm.5l > sush.shar
- XX
- XXinstall: $(DOC) sush
- XX cp sush $(DEST)/sush
- XX chown root $(DEST)/sush
- XX chmod 4511 $(DEST)/sush
- XX cp sush.l /usr/man/manl
- XX chmod 744 /usr/man/manl/sush.l
- XX cp sushperm.l /usr/man/manl
- XX chmod 744 /usr/man/manl/sushperm.l
- XX
- XX#documentation !!
- XXsush.l: sush.8l
- XX cp sush.8l sush.l
- XXsushperm.l: sushperm.5l
- XX cp sushperm.5l sushperm.l
- XX
- XX#for RCS
- XXsushlex.o: sushlex.c
- XXsushmain.o: sushmain.c
- XXsushpath.o: sushpath.c
- XXsushperm.o: sushperm.c
- XXsushuser.o: sushuser.c
- XXsushtree.o: sushtree.c
- XXsushhelp.o: sushhelp.c
- XXsushfunc.o: sushfunc.c
- SHAR_EOF
- if test 1744 -ne "`wc -c Makefile`"
- then
- echo shar: error transmitting Makefile '(should have been 1744 characters)'
- fi
- echo shar: extracting sush.8l '(5046 characters)'
- sed 's/^XX//' << \SHAR_EOF > sush.8l
- XX.TH sush 8-local
- XX.SH NAME
- XXsush \- SuperUser shell
- XX.fi
- XX.ad
- XX.hy 0
- XX.SH ORIGIN
- XXmjr@osiris.UUCP
- XX.SH SYNOPSIS
- XX.B sush
- XX.SH DESCRIPTION
- XX.B Sush
- XXis a restricted shell that allows systems administrators to
- XXgrant specific limited priviledges to users. All commands that are
- XXexecuted are logged to the system log, as well as other pertinent
- XXinformation.
- XX.SH AUTHORIZATION
- XX.B Sush
- XXreads an authorization file at start-up time. This file contains a
- XXlist of group and user names, each followed by a list of pathnames
- XXto programs they are allowed to run. The user's password is checked,
- XXto ensure that someone has not broken into that account. Thereafter,
- XXusers are prompted, just as in a "normal" shell, commands are parsed,
- XXand executed if the user has permission to execute them.
- XX.SH "INTERNAL COMMANDS"
- XX.PP
- XX.B set
- XX.B [
- XXvariable
- XX.B ] = [
- XXstring
- XX.B ]
- XX.PP
- XXIf called without arguments, the set command shows a list of currently
- XXdefined environment variables. If called with arguments in the form of
- XXstring = string (spaces necessary) the specified environment variable
- XXis set, or reset.
- XX.PP
- XX.B cd
- XX.PP
- XXThe cd command allows the user to reset the current working directory.
- XX.PP
- XX.B pwd
- XX.PP
- XXThe pwd command will print the current working directory.
- XX.PP
- XX.B unset variable
- XX.PP
- XXUnset, when provided an environment variable name, will unset that
- XXenvironment variable.
- XX.PP
- XX.B exit
- XX.PP
- XXExits from the shell. An EOF will also exit the shell.
- XX.PP
- XX.B source filename
- XX.PP
- XXWill read the file into the shell as commands.
- XX.PP
- XX.B printenv
- XX.PP
- XXThe printenv command lists all current environment variables.
- XX.PP
- XX.B ? or help
- XX.PP
- XXThe "?" and help commands provide a list of shell internals.
- XX.PP
- XX.SH "THE .sushrc FILE"
- XX.PP
- XXAt startup
- XX.I Sush
- XXwill read a
- XX.I .sushrc
- XXfile if there is one in the user's home directory. This functions
- XXexactly like the
- XX.B source
- XXinternal command. If the last line in the
- XX.I .sushrc
- XXis exit, the shell will exit. This can be used to more exactly control a
- XXuser.
- XX.SH "THE ENVIRONMENT"
- XX.I Sush
- XXmaintains a copy of the invocation environment, including the PATH,
- XXTERM and other useful variables. These are passed whenever a command
- XXis invoked, so that programs such as Ingres and Sybase that rely on
- XXenvironment variables will still work properly.
- XX.SH "ENVIRONMENT VARIABLES"
- XX.PP
- XXEnvironment variables are substituted in the command line if they
- XXare surrounded by $(). Thus something like:
- XX.br
- XX\fIecho $(PATH)\fP
- XX.br
- XX.PP
- XXwill echo the contents of PATH. Recursion is not supported - IE:
- XX.nf
- XX.na
- XX.br
- XX\fIset FOO = "this is $(BAR)"\fP
- XX\fIecho $(FOO)\fP
- XX\fBthis is $(BAR)\fP
- XX.fi
- XX.ad
- XX.SH "DIFFERENCES FROM A REAL SHELL"
- XX.I Sush
- XXintentionally does not support many features found in a \fIREAL\fP
- XXUNIX shell, since they allow unauthorized access too easily.
- XX.PP
- XX.I "I/O Redirection:"
- XX.I Bourne
- XXor
- XX.I Csh
- XXconstructs like \fB"ls | more"\fP are not supported, since it entails
- XXan additional level of parsing in the command line. Constructs such
- XXas \fB"ls > foo"\fP are also unsupported, for obvious reasons.
- XX.PP
- XX.I "Globbing:"
- XXGlobbing, or wildcard expansion, is not supported, since it renders it
- XXmore difficult to determine what command a user wants to execute. A
- XXcommand like \fB"/etc/vip*"\fP, which could expand to \fB"/etc/vipw"\fP
- XXso the shell would have to re-parse the command line multiple times.
- XX.SH "COMMAND EXECUTION"
- XXCommands are executed by searching the PATH environment variable for the
- XXcommand that is requested. If the command is found, the complete pathname
- XXis checked against the list of user's permissions. If the filename is in
- XXthe permission list, it is executed, and the execution is logged to the
- XXsystem log file, along with the arguments it was invoked with. The way
- XXin which the path is parsed makes calls like \fB"/bin/../bin/ls"\fP to
- XXbe rejected.
- XX.SH "A SAMPLE RUN"
- XX.nf
- XX\fB
- XXxsh> \fIshowpriv\fP
- XXYou are privileged to execute the following:
- XX/bin/grep
- XX/bin/kill
- XX/bin/echo
- XX/bin/csh
- XX/bin/ls
- XX/ingres/bin/accessdb
- XX/usr/ucb/w
- XX/bin/who
- XX/bin/sh
- XXxsh> \fI?\fP
- XXInternal Commands Are:
- XXset
- XXcd
- XXpwd
- XXunset
- XXexit
- XXprintenv
- XX?
- XXhelp
- XXshowpriv
- XXNote - I/O redirection, filename expansion and history, not supported.
- XXxsh> \fIls\fP
- XXMakefile sush.8l sushhelp.c sushmain.c sushperm.c sushuser.c
- XXRCS sush.h sushhelp.o sushmain.o sushperm.o sushuser.o
- XXxsh> \fIvipw\fP
- XX"/etc/vipw" permission denied
- XXxsh> \fIexit\fP
- XX.fi
- XX\fR
- XX.SH "SEE ALSO"
- XXsyslog(8), sh(1), sushperm(5l)
- XX.SH MESSAGES
- XX.IP "vapor group in /u1/mjr/hacks/sh/myperm line 3" 10
- XX.br
- XX.I Sush
- XXfound a group in the permissions file that does not exist in /etc/group.
- XXThis is logged as a potential security hole.
- XX.SH BUGS
- XX.PP
- XXSignal handling is not perfect.
- XX.PP
- XXAny commands that contain a shell escape (vi, more, ingres editor,
- XXetc, etc) are
- XXa potential loophole. Additionally, there is the problem of a user with the
- XXability to do anything that would alter a security file. IE - someone with
- XXthe ability to chmod /etc/passwd. There is no way around this.
- XX.\" @(#)sush.8l Tue Nov 10 20:52:17 EST 1987
- SHAR_EOF
- if test 5046 -ne "`wc -c sush.8l`"
- then
- echo shar: error transmitting sush.8l '(should have been 5046 characters)'
- fi
- echo shar: extracting sushperm.5l '(1729 characters)'
- sed 's/^XX//' << \SHAR_EOF > sushperm.5l
- XX.TH SUSHPERM 5-local
- XX.SH NAME
- XXsushperm \- suid shell permissions database
- XX.SH SYNOPSIS
- XX/etc/local/sushperm
- XX.SH DESCRIPTION
- XX.I Sushperm
- XXis a data base describing users, groups, and pathnames of programs
- XXthat they are allowed to execute as "root".
- XX.PP
- XXEntries in
- XX.I sushperm
- XXconsist of a number of fields.
- XXThe first entry for each field consists of the word "user" or "group"
- XXto indicate whether the next field is specifying the permissions for
- XXa single user, or a group. The second field is the name of the user
- XXor group in question. User names are expected to be in \fB"/etc/passwd"\fP
- XXand groups are expected to be in \fB"/etc/group"\fP.
- XXThe remainder of the line consists of comma or space separated entries
- XXthat list the complete PATHnames of programs that the user or group
- XXin question is privileged to run.
- XX.PP
- XXUser's permissions are cumulative, so that a user's total permissions
- XXwill be the sum of that user's entries, plus the sum of all groups in
- XXwhich that user is a member. Badly formatted lines in the
- XX.I sushperm
- XXfile are ignored, as are lines beginning with a \fB'#'\fP.
- XX.fi
- XX.PP
- XX.B A Sample Entry
- XX.PP
- XX.nf
- XX
- XX# sample sushperm file
- XXgroup e+o /bin/sh, /bin/ls, /bin/csh
- XXgroup sys /bin/echo, /bin/kill
- XXuser ken /bin/sh, /bin/ls, /bin/cat
- XXuser mjr /bin/kill, /bin/grep, /bin/who, /usr/ucb/w
- XXuser mjr /etc/shutdown, /etc/halt, /etc/reboot
- XX
- XX.fi
- XX.PP
- XXEntries for a particular user may appear on several lines with a cumulative
- XXeffect.
- XX.SH DIAGNOSTICS
- XX.I sush
- XXwill complain of it finds nonexistent groups or user names in the
- XX.I sushperm
- XXfile.
- XX.SH FILES
- XX.DT
- XX/etc/local/sushperm - permissions file.
- XX.SH SEE ALSO
- XXsush(8l)
- XX.br
- XX.SH BUGS
- XXNone known at present.
- XX.\" @(#)sushperm.5l Tue Nov 17 10:02:59 EST 1987
- SHAR_EOF
- if test 1729 -ne "`wc -c sushperm.5l`"
- then
- echo shar: error transmitting sushperm.5l '(should have been 1729 characters)'
- fi
- # End of shell archive
- exit 0
-