| 1 | static char sccsid[] = "@(#)nsh.c 4.3 (Berkeley) %G%"; |
| 2 | |
| 3 | # include "defs.h" |
| 4 | /* |
| 5 | nsh -c "comand to be executed" |
| 6 | |
| 7 | This pseudo-shell is executed over the network |
| 8 | as the login shell of an acount "network", no passwd. |
| 9 | It will only execute certain allowed commands. |
| 10 | |
| 11 | has these exit codes: |
| 12 | EX_USAGE = wrong # arguments to nsh |
| 13 | 9 = command you execute may not take arguments |
| 14 | 10= the execl failed |
| 15 | EX_UNAVAILABLE= could not find full path name for the command |
| 16 | |
| 17 | count is the # of arguments (= argc) allowed. |
| 18 | a count of 0 turns off the command |
| 19 | */ |
| 20 | |
| 21 | struct { |
| 22 | char *app; |
| 23 | char count; |
| 24 | char *full; |
| 25 | char *full1; |
| 26 | } st[] = { |
| 27 | /* I assume these are the same for RAND */ |
| 28 | "mmail", 20, "/usr/net/bin/mmail", "/usr/net/bin/mmail", |
| 29 | "mwrite", 20, "/usr/net/bin/mwrite", "/usr/net/bin/mwrite", |
| 30 | "prmail", 20, "/usr/net/bin/prmail", "/usr/net/bin/prmail", |
| 31 | # ifndef NFREECMD |
| 32 | "finger", 20, "/usr/ucb/finger", "/usr/bin/finger", |
| 33 | "lpq", 20, "/usr/ucb/lpq", "/usr/bin/lpq", |
| 34 | # ifdef FREELPR |
| 35 | "lpr", 20, "/usr/ucb/lpr", "/usr/bin/lpr", |
| 36 | # endif |
| 37 | "netlog", 20, "/usr/bin/netlog", "/usr/ucb/netlog", |
| 38 | "netq", 20, "/usr/bin/netq", "/usr/ucb/netq", |
| 39 | "ps", 20, "/bin/ps", "/usr/bin/ps", |
| 40 | "pstat", 20, "/etc/pstat", "/usr/bin/pstat", |
| 41 | "vpq", 20, "/usr/ucb/vpq", "/usr/bin/vpq", |
| 42 | "w", 20, "/usr/ucb/w", "/usr/bin/w", |
| 43 | "wc", 20, "/usr/bin/wc", "/bin/wc", |
| 44 | "who", 20, "/bin/who", "/usr/bin/who", |
| 45 | "whom", 20, "/usr/ucb/whom", "/usr/bin/whom", |
| 46 | "yank", 20, "/usr/ucb/yank", "/usr/bin/yank", |
| 47 | # endif |
| 48 | 0, 0, 0, 0 |
| 49 | }; |
| 50 | /* nsh -c cmd */ |
| 51 | main(argc,argv) |
| 52 | char **argv; { |
| 53 | char *s, buf[500]; |
| 54 | int i, flg = 0; |
| 55 | if(argc != 3){ |
| 56 | fprintf(stderr,"Wrong number of arguments to nsh.\n"); |
| 57 | exit(EX_USAGE); |
| 58 | } |
| 59 | s = argv[2]; |
| 60 | while (*s) |
| 61 | if (*s == ';' |
| 62 | || *s == '|' |
| 63 | || *s == '&' |
| 64 | || *s == '?' |
| 65 | || *s == '*' |
| 66 | || *s == '[' |
| 67 | || *s == '~' |
| 68 | || *s == '{' |
| 69 | || *s == '<' |
| 70 | || *s == '>' |
| 71 | || *s == '$' |
| 72 | || *s == '`') { |
| 73 | fprintf(stderr, "Illegal shell metacharacter in command.\n"); |
| 74 | exit(9); |
| 75 | } else |
| 76 | ++s; |
| 77 | s = argv[2]; |
| 78 | while(*s && *s != ' ')s++; |
| 79 | if(*s == ' ')flg++; |
| 80 | *s = 0; |
| 81 | if((i = mlookup(argv[2])) < 0){ |
| 82 | fprintf(stderr, |
| 83 | "Command '%s' is not allowed if logged in as 'network'.\n", |
| 84 | argv[2]); |
| 85 | exit(11); |
| 86 | } |
| 87 | if(st[i].count == 0){ |
| 88 | fprintf(stderr, |
| 89 | "The command '%s' is not allowed to have arguments.\n",argv[2]); |
| 90 | exit(9); |
| 91 | } |
| 92 | if(stat(st[i].full,buf) >= 0) |
| 93 | strcpy(buf,st[i].full); |
| 94 | else strcpy(buf,st[i].full1); |
| 95 | if(flg && st[i].count > 1){ /* some cmds don't allow parms */ |
| 96 | *s = ' '; |
| 97 | strcat(buf,s); |
| 98 | } |
| 99 | /* |
| 100 | fprintf(stderr,"%s\n",buf); |
| 101 | */ |
| 102 | execl(Bsh,"sh","-c",buf,0); |
| 103 | fprintf(stderr,"Execute of shell failed.\n"); |
| 104 | exit(EX_UNAVAILABLE); |
| 105 | } |
| 106 | mlookup(s) |
| 107 | char *s; { |
| 108 | int i; |
| 109 | for(i = 0; st[i].app; i++) |
| 110 | if(strcmp(st[i].app,s) == 0 || strcmp(st[i].full,s) == 0 |
| 111 | || strcmp(st[i].full1,s) == 0)return(i); |
| 112 | return(-1); |
| 113 | } |