home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume1 / 8712 / 3 < prev    next >
Internet Message Format  |  1990-07-13  |  39KB

  1. Path: uunet!husc6!necntc!ncoast!allbery
  2. From: mjr@osiris.UUCP (Marcus J. Ranum)
  3. Newsgroups: comp.sources.misc
  4. Subject: submission to source.misc - setuid shell...
  5. Message-ID: <6381@ncoast.UUCP>
  6. Date: 8 Dec 87 23:51:59 GMT
  7. Sender: smith@ncoast.UUCP
  8. Lines: 1625
  9. Approved: allbery@ncoast.UUCP
  10. X-Archive: comp.sources.misc/8712/3
  11.  
  12. #    This is a shell archive.
  13. #    Remove everything above and including the cut line.
  14. #    Then run the rest of the file through sh.
  15. -----cut here-----cut here-----cut here-----cut here-----
  16. #!/bin/sh
  17. # shar:    Shell Archiver
  18. #    Run the following text with /bin/sh to create:
  19. #    README
  20. #    sushfunc.c
  21. #    sushhelp.c
  22. #    sushlex.c
  23. #    sushmain.c
  24. #    sushpath.c
  25. #    sushperm.c
  26. #    sushtree.c
  27. #    sushuser.c
  28. #    sush.h
  29. #    Makefile
  30. #    sush.8l
  31. #    sushperm.5l
  32. # This archive created: Fri Dec  4 09:11:33 1987
  33. echo shar: extracting README '(794 characters)'
  34. sed 's/^XX//' << \SHAR_EOF > README
  35. XX#static char *RCSid = "$Header: README,v 1.1 87/11/24 17:35:24 mjr Exp $"
  36. XX#    $Author: mjr $
  37. XX#    $Log:    README,v $
  38. XX# Revision 1.1  87/11/24  17:35:24  mjr
  39. XX# Initial revision
  40. XX# 
  41. XX
  42. XX    This is the source code and existing documentation for a 
  43. XXprivileged shell. Typically it's more useful on development systems
  44. XXand in trusted environments. It allows a systems admin to 'grant'
  45. XXthe power to run certain programs as root on a user/group basis.
  46. XXThe problem of shell escapes in the granted programs renders sush
  47. XXless than 100% secure :-)
  48. XX
  49. XX    Some stylistic flaws:
  50. XXLots of global variables. All the globals are listed in sush.h
  51. XXUnfortunately, this makes it hard to run recursive 'sources'.
  52. XX
  53. XX    Options:
  54. XXif ROOTRC is defined, it will add code in sushmain.c that tries to
  55. XXsource a root owned .sushrc file.
  56. XX
  57. XX--mjr();
  58. SHAR_EOF
  59. if test 794 -ne "`wc -c README`"
  60. then
  61. echo shar: error transmitting README '(should have been 794 characters)'
  62. fi
  63. echo shar: extracting sushfunc.c '(5541 characters)'
  64. sed 's/^XX//' << \SHAR_EOF > sushfunc.c
  65. XX
  66. XX#ifndef lint
  67. XXstatic char *RCSid = "2:$Header: sushfunc.c,v 1.3 87/11/24 17:35:45 mjr Exp $";
  68. XX#endif
  69. XX
  70. XX/*
  71. XX *     $Author: mjr $
  72. XX *     $Log:    sushfunc.c,v $
  73. XX * Revision 1.3  87/11/24  17:35:45  mjr
  74. XX * fixed the source() function as well as the cd() to home if no args
  75. XX * 
  76. XX * Revision 1.2  87/11/19  14:22:47  mjr
  77. XX * improved functionality of the environment variables.
  78. XX * 
  79. XX * Revision 1.1  87/11/08  18:19:18  mjr
  80. XX * Initial revision
  81. XX * 
  82. XX*/
  83. XX
  84. XX#include "sush.h"
  85. XX#include <stdio.h>
  86. XX
  87. XXset()
  88. XX{
  89. XX    int    ind =0;
  90. XX    int    lng;
  91. XX    unsigned    mal1;
  92. XX    unsigned    mal2;
  93. XX
  94. XX    /* set an environment variable */
  95. XX    /* we assume the args are parsed (they must be to get here) */
  96. XX    /* and flip through the envir stack looking for a blank slot*/
  97. XX    /* when we find one we malloc the memory and copy into it. */
  98. XX
  99. XX    if(sh.shrgn == 1)
  100. XX        return(prenv());
  101. XX
  102. XX    /* is the thing verbose? - if so set it */
  103. XX    /* and immediately return */
  104. XX    if((!strcmp(sh.sharg[1],"verbose")) || !(strcmp(sh.sharg[1],"-x"))) {
  105. XX        verbose++;
  106. XX        return(0);
  107. XX    }
  108. XX
  109. XX    
  110. XX    /* see if args is right and all */
  111. XX    if((sh.shrgn != 4) || (strcmp(sh.sharg[2],"="))) {
  112. XX        fprintf(stderr,"syntax: set string = string\n");
  113. XX        return(1);
  114. XX    } 
  115. XX
  116. XX    lng = strlen(sh.sharg[1]);
  117. XX
  118. XX    /* otherwise OK */
  119. XX    /* search for the victim and free its memory space */
  120. XX    for(ind = 0; ind < SHENV; ind++) { 
  121. XX        if(!strncmp(sh.shenv[ind],sh.sharg[1],lng)) {
  122. XX            /* next thing must be an = sign */
  123. XX            if(sh.shenv[ind][lng] == '=') {
  124. XX                if(sh.shenv[ind])
  125. XX                    (void)free(sh.shenv[ind]);
  126. XX                sh.shenv[ind] = '\0';
  127. XX            }
  128. XX        }
  129. XX    }
  130. XX
  131. XX    /* skip occupied environment space */
  132. XX    ind = 0;
  133. XX    while((sh.shenv[ind]) && (ind < SHENV))
  134. XX        ind++;
  135. XX
  136. XX    /* if there is room for another shell var */
  137. XX    if(ind < SHENV) {
  138. XX        mal1 = (unsigned)(strlen(sh.sharg[1]));
  139. XX        mal2 = (unsigned)(strlen(sh.sharg[3]));
  140. XX        /* allocate the memory and make the name copy */
  141. XX        if((sh.shenv[ind] = malloc(mal1 + mal2 + 3)) == NULL) {
  142. XX            perror("set");
  143. XX            return(1);
  144. XX        }
  145. XX        (void)strcpy(sh.shenv[ind],sh.sharg[1]);
  146. XX        (void)strcat(sh.shenv[ind],"=");
  147. XX        (void)strcat(sh.shenv[ind],sh.sharg[3]);
  148. XX
  149. XX    } else {
  150. XX        fprintf(stderr,"set: out of environment space\n");
  151. XX        return(1);
  152. XX    }
  153. XX
  154. XX    /* is the thing the prompt ? - if so reset it */
  155. XX    if(!strcmp(sh.sharg[1],"prompt")) {
  156. XX        prompt = &sh.shenv[ind][mal1+1];
  157. XX        return(0);
  158. XX    }
  159. XX
  160. XX    /* is the thing the PATH ? - if so reset it */
  161. XX    if(!strcmp(sh.sharg[1],"PATH")) {
  162. XX        path = &sh.shenv[ind][mal1+1];
  163. XX        return(0);
  164. XX    }
  165. XX
  166. XX    /* otherwise OK */
  167. XX    if(verbose)
  168. XX        fprintf(stderr,"%s set\n",sh.sharg[1]);
  169. XX    return(0);
  170. XX}
  171. XX
  172. XXunset()
  173. XX{
  174. XX    int    ind;
  175. XX    int     mal1;
  176. XX    int    ind2;
  177. XX
  178. XX    /* unset an environment variable */
  179. XX    /* we assume the args are parsed (they must be to get here) */
  180. XX    /* and flip through the envir stack looking for the named slot*/
  181. XX    /* when we find it we free the memory and zero it. */
  182. XX    
  183. XX    /* is the thing verbose? - if so set it */
  184. XX    /* and immediately return */
  185. XX    if((!strcmp(sh.sharg[1],"verbose")) || !(strcmp(sh.sharg[1],"-x"))) {
  186. XX        verbose =0;
  187. XX        return(0);
  188. XX    }
  189. XX
  190. XX    /* see if args is right and all */
  191. XX    if(sh.shrgn != 2 ) {
  192. XX        fprintf(stderr,"syntax: unset string\n");
  193. XX        return(1);
  194. XX    } 
  195. XX
  196. XX    /* is the thing the PATH ? - if so complain */
  197. XX    if(!strcmp(sh.sharg[1],"PATH")) {
  198. XX        fprintf(stderr,"why unset PATH?\n");
  199. XX        return(1);
  200. XX    }
  201. XX
  202. XX    /* used for length of search */
  203. XX    mal1 = strlen(sh.sharg[1]);
  204. XX
  205. XX    /* otherwise OK */
  206. XX    /* search for the victim and free its memory space */
  207. XX    for(ind = 0; ind < SHENV; ind++) { 
  208. XX        if(!strncmp(sh.shenv[ind],sh.sharg[1],mal1)) {
  209. XX            /* next thing must be an = sign */
  210. XX            if(sh.shenv[ind][mal1] == '=') {
  211. XX                (void)free(sh.shenv[ind]);
  212. XX                sh.shenv[ind] = '\0';
  213. XX            }
  214. XX            for (ind2 = 0; sh.shenv[ind + ind2 + 1]; ind2++) {
  215. XX                sh.shenv[ind + ind2] = sh.shenv[ind + ind2 + 1];
  216. XX                sh.shenv[ind + ind2 + 1] = '\0';
  217. XX            }
  218. XX            if(verbose)
  219. XX                fprintf(stderr,"%s unset\n",sh.sharg[1]);
  220. XX            return(0);
  221. XX        }
  222. XX    }
  223. XX    
  224. XX    fprintf(stderr,"unset: no environment variable %s\n",sh.sharg[1]);
  225. XX    return(1);
  226. XX}
  227. XX
  228. XXprenv()
  229. XX{
  230. XX    int    i;
  231. XX    int    mal1;
  232. XX
  233. XX    /* print an environment variable or all of them */
  234. XX    
  235. XX    /* if one arg print whole environment */
  236. XX    if(sh.shrgn == 1 ) {
  237. XX        /* print all occupied environment space */
  238. XX        for(i =0; i < SHENV; i++) {
  239. XX            if(sh.shenv[i])
  240. XX                if(*sh.shenv[i])
  241. XX                    printf("%s\n",sh.shenv[i]);
  242. XX        }
  243. XX        return(0);
  244. XX    } else {
  245. XX        /* search for the named variable and print it */
  246. XX
  247. XX        /* get the length */
  248. XX        mal1 = strlen(sh.sharg[1]);
  249. XX        for(i = 0; i < SHENV; i++) { 
  250. XX            if(!strncmp(sh.shenv[i],sh.sharg[1],mal1)) {
  251. XX                if(sh.shenv[i][mal1 + 1] == '=') {
  252. XX                    printf("%s\n",sh.shenv[i]);
  253. XX                    return(0);
  254. XX                }
  255. XX            }
  256. XX        }
  257. XX    }
  258. XX    fprintf(stderr,"printenv: no environment variable %s\n",sh.sharg[1]);
  259. XX    return(1);
  260. XX}
  261. XX
  262. XXbye()
  263. XX{
  264. XX    /* if exit number given */
  265. XX    if(sh.shrgn >= 2 )
  266. XX        exit(atoi(sh.sharg[1]));
  267. XX
  268. XX    /* exit with 0 */
  269. XX    exit(0);
  270. XX}
  271. XX
  272. XXcd()
  273. XX{
  274. XX    /* change current working directory */
  275. XX    /* if no args use home */
  276. XX    if(sh.shrgn == 1) {
  277. XX        if(chdir(home)) {
  278. XX            perror(home);
  279. XX            return(1);
  280. XX        }
  281. XX        return(0);
  282. XX    }
  283. XX    
  284. XX    /* see if args is right and all */
  285. XX    if(sh.shrgn != 2 ) {
  286. XX        fprintf(stderr,"syntax: cd [directory]\n");
  287. XX        return(1);
  288. XX    }
  289. XX
  290. XX    if(chdir(sh.sharg[1])) {
  291. XX        perror(sh.sharg[1]);
  292. XX        return(1);
  293. XX    }
  294. XX    return(0);
  295. XX}
  296. XX
  297. XXpwd()
  298. XX{
  299. XX
  300. XX    /* print current working directory */
  301. XX    
  302. XX    /* see if args is right and all */
  303. XX    if(sh.shrgn > 1 ) {
  304. XX        fprintf(stderr,"syntax: pwd\n");
  305. XX        return(1);
  306. XX    }
  307. XX    printf("%s\n",getwd(".")); 
  308. XX        
  309. XX    return(0);
  310. XX}
  311. XX
  312. XXsource()
  313. XX{
  314. XX    FILE    *sourcin;
  315. XX    int    savttyin = isttyin;
  316. XX    
  317. XX    if(sh.shrgn != 2) {
  318. XX        fprintf(stderr,"syntax: source file\n");
  319. XX        return(1);
  320. XX    }
  321. XX    if((sourcin = fopen(sh.sharg[1], "r")) == NULL) {
  322. XX        perror(sh.sharg[1]);
  323. XX    } else {
  324. XX        isttyin = 0;
  325. XX        (void)doinput(sourcin);
  326. XX        (void)fclose(sourcin);
  327. XX        isttyin = savttyin;
  328. XX    }
  329. XX    return(0);
  330. XX}
  331. SHAR_EOF
  332. if test 5541 -ne "`wc -c sushfunc.c`"
  333. then
  334. echo shar: error transmitting sushfunc.c '(should have been 5541 characters)'
  335. fi
  336. echo shar: extracting sushhelp.c '(631 characters)'
  337. sed 's/^XX//' << \SHAR_EOF > sushhelp.c
  338. XX
  339. XX#ifndef lint
  340. XXstatic char *RCSid = "3:$Header: sushhelp.c,v 1.2 87/11/19 14:23:13 mjr Exp $";
  341. XX#endif
  342. XX
  343. XX/*
  344. XX *     $Author: mjr $
  345. XX *     $Log:    sushhelp.c,v $
  346. XX * Revision 1.2  87/11/19  14:23:13  mjr
  347. XX * added clearer help messages
  348. XX * 
  349. XX * Revision 1.1  87/11/08  18:19:20  mjr
  350. XX * Initial revision
  351. XX * 
  352. XX*/
  353. XX
  354. XX#include "sush.h"
  355. XX#include <stdio.h>
  356. XX
  357. XXhelp()
  358. XX{
  359. XX    struct    cmdtab    *dptr;
  360. XX
  361. XX    fprintf(stderr,"Internal Commands Are:\n");
  362. XX    dptr = cm;
  363. XX    while(dptr -> func) {
  364. XX        fprintf(stderr,"%s\n",dptr->mnem);
  365. XX        dptr++;
  366. XX    }
  367. XX    fprintf(stderr,"Note - I/O redirection is not supported, nor are ");
  368. XX    fprintf(stderr,"filename expansion or history.\n");
  369. XX    return(0);
  370. XX}
  371. SHAR_EOF
  372. if test 631 -ne "`wc -c sushhelp.c`"
  373. then
  374. echo shar: error transmitting sushhelp.c '(should have been 631 characters)'
  375. fi
  376. echo shar: extracting sushlex.c '(3455 characters)'
  377. sed 's/^XX//' << \SHAR_EOF > sushlex.c
  378. XX
  379. XX#ifndef lint
  380. XXstatic char *RCSid = "4:$Header: sushlex.c,v 1.3 87/11/24 16:19:12 mjr Exp $";
  381. XX#endif
  382. XX
  383. XX/*
  384. XX *     $Author: mjr $
  385. XX *     $Log:    sushlex.c,v $
  386. XX * Revision 1.3  87/11/24  16:19:12  mjr
  387. XX * added inline macro expansion in command line
  388. XX * 
  389. XX * Revision 1.2  87/11/19  14:23:33  mjr
  390. XX * cleaned up parser code a bit.
  391. XX * 
  392. XX * Revision 1.1  87/11/08  18:19:21  mjr
  393. XX * Initial revision
  394. XX * 
  395. XX*/
  396. XX
  397. XX#include "sush.h"
  398. XX#include <stdio.h>
  399. XX#include <ctype.h>
  400. XX
  401. XXstatic    char    *copymac();
  402. XX
  403. XXlex(str)
  404. XXchar    *str;
  405. XX{
  406. XX    char    *bufptr;
  407. XX
  408. XX    /* analyze input string - break it into tokens */
  409. XX    sh.shrgn =0;
  410. XX    bufptr = str;
  411. XX
  412. XX    /* actually perform the parse */
  413. XX    while(bufptr = wordparse(bufptr,sh.sharg[sh.shrgn],0)) {
  414. XX
  415. XX        /* set the token pointers to token - this sucks */
  416. XX        sh.shtok[sh.shrgn] = sh.sharg[sh.shrgn];
  417. XX
  418. XX        /* increment token number */
  419. XX        sh.shrgn++;
  420. XX    }
  421. XX    sh.shtok[sh.shrgn] = NULL;
  422. XX    return(0);
  423. XX}
  424. XX
  425. XXchar *
  426. XXwordparse(line,word,delim)
  427. XXchar    *line,    *word;
  428. XXint    delim;
  429. XX{
  430. XX    int    quot =0;
  431. XX
  432. XX    /* skip whitespace or delims */
  433. XX    while (*line && (isspace(*line) || *line == delim))
  434. XX        line++;
  435. XX
  436. XX    if(*line == '\n')
  437. XX        line++;
  438. XX
  439. XX    /* if end of string, return */
  440. XX    if (!*line) {
  441. XX        *word = '\0';
  442. XX        return(0);
  443. XX    }
  444. XX
  445. XX    while (*line)
  446. XX    {
  447. XX        /* if its a quote character and we are not in a quoted */
  448. XX        /* string we then set the quote character to match this */
  449. XX        /* one (or end of line) */
  450. XX        if(!quot && (*line == '\"' || *line == '\''))
  451. XX            quot = *line++;
  452. XX
  453. XX        /* spaces get skipped unless were in a quoted string */ 
  454. XX        /* if the current character is a matching quote we unset */
  455. XX        /* the quotation and keep parsing */
  456. XX        if((isspace(*line) || *line == delim) && !quot) {
  457. XX            break;
  458. XX        } else {
  459. XX            if(quot && *line == quot) {
  460. XX                quot = 0;
  461. XX                line++;
  462. XX            } else {
  463. XX                *word++ = *line++;
  464. XX            }
  465. XX        }
  466. XX    }
  467. XX    /* null the end of the word and return an ptr to where we are */
  468. XX    *word = '\0';
  469. XX    return(line);
  470. XX}
  471. XX
  472. XXexpline(line,retline,vars)
  473. XXchar    *line;
  474. XXchar    *retline;
  475. XXchar    **vars;
  476. XX{
  477. XX
  478. XX    /* expline - expand macros in a string and place the expanded */
  479. XX    /* string in retline. retline is assumed to be long enough. */
  480. XX    /* vars is assumed to be an array of strings that are in the */
  481. XX    /* form of: thing=thing  - note - recursion not supported yet */
  482. XX    /* function returns nonzero in event of error */
  483. XX    
  484. XX    char    *pti = line;
  485. XX    char    *pto = retline;
  486. XX    char    vbuf[400];
  487. XX    char    *vbpt;
  488. XX
  489. XX    if(!pti)
  490. XX        return(0);
  491. XX
  492. XX    while(*pti) {
  493. XX        /* $ indicates start of possible macro */
  494. XX        if(*pti != '$') {
  495. XX            *pto++ = *pti++;
  496. XX        } else {
  497. XX            if(*++pti != '\(') {
  498. XX                /* not a macro */
  499. XX                *pto++ = *pti++;
  500. XX            } else {
  501. XX                /* get macroname into vbuf */
  502. XX                vbpt = vbuf;
  503. XX                ++pti;
  504. XX                while(*pti != '\)') { 
  505. XX                    if(pti) {
  506. XX                        *vbpt++ = *pti++;
  507. XX                    } else {    
  508. XX                        return(-1);
  509. XX                    } 
  510. XX                }
  511. XX                *vbpt = '\0';
  512. XX                /* increment past last paren */
  513. XX                pti++;
  514. XX                if((pto = copymac(vbuf,pto,vars)) == '\0')
  515. XX                    return(-1);
  516. XX            }
  517. XX        }
  518. XX    }
  519. XX    *pto = '\0';
  520. XX    return(0);
  521. XX}
  522. XX
  523. XXstatic    char    *
  524. XXcopymac(mac,out,varlist)
  525. XXchar    *mac;
  526. XXchar    *out;
  527. XXchar    **varlist;
  528. XX{
  529. XX    /* copy the identified macro into the string we are handed */
  530. XX    /* return a pointer to where we leave off, or NULL if we fail */ 
  531. XX    char    **vpt = varlist;
  532. XX    char    *ptr;
  533. XX    int    lng;
  534. XX
  535. XX
  536. XX    /* return if no macros defined */
  537. XX    if(!*vpt)
  538. XX        return(out);
  539. XX
  540. XX    /* save time if empty macro */
  541. XX    if((lng = strlen(mac)) ==0)
  542. XX        return(out);
  543. XX
  544. XX    while(vpt) {
  545. XX        if((strncmp(*vpt,mac,lng) ==0) && ((*vpt)[lng] == '=')) {
  546. XX        /* copy contents of macro into string */
  547. XX            ptr = *vpt + lng +1;
  548. XX            while(*ptr)
  549. XX                *out++ = *ptr++;
  550. XX            break;
  551. XX        }
  552. XX    vpt++;
  553. XX    }
  554. XX    return(out);
  555. XX}
  556. SHAR_EOF
  557. if test 3455 -ne "`wc -c sushlex.c`"
  558. then
  559. echo shar: error transmitting sushlex.c '(should have been 3455 characters)'
  560. fi
  561. echo shar: extracting sushmain.c '(3164 characters)'
  562. sed 's/^XX//' << \SHAR_EOF > sushmain.c
  563. XX#ifndef lint
  564. XXstatic char RCSid[] = "5:$Header: sushmain.c,v 1.5 87/11/24 17:34:43 mjr Exp $";
  565. XX#endif
  566. XX
  567. XX/*
  568. XX *    $Author: mjr $
  569. XX *    $Log:    sushmain.c,v $
  570. XX * Revision 1.5  87/11/24  17:34:43  mjr
  571. XX * added the source() feature and .sushrc
  572. XX * 
  573. XX * Revision 1.4  87/11/24  16:18:50  mjr
  574. XX * added inline macro expansion in command line.
  575. XX * 
  576. XX * Revision 1.3  87/11/19  14:22:21  mjr
  577. XX * dropped newline off the end of input buffer before logging it.
  578. XX * 
  579. XX * Revision 1.2  87/11/19  14:10:43  mjr
  580. XX * fixed interrupt handling so shell wouldn't exit on ^C from tty
  581. XX * 
  582. XX * Revision 1.1  87/11/08  18:19:22  mjr
  583. XX * Initial revision
  584. XX * 
  585. XX*/
  586. XX
  587. XX#define    NOEXTERN
  588. XX#include "sush.h"
  589. XX#include <stdio.h>
  590. XX#include <syslog.h>
  591. XX#include <sys/signal.h>
  592. XX
  593. XXextern char **environ;
  594. XX
  595. XXmain()
  596. XX{
  597. XX    register char **ep;
  598. XX
  599. XX    (void)signal(SIGINT,SIG_IGN);
  600. XX    if(getuser())
  601. XX        exit(1);
  602. XX
  603. XX    if(loadperm())
  604. XX        exit(1);
  605. XX
  606. XX    /* make a copy of our environment - actually just point to it */
  607. XX    if (environ) {
  608. XX        int ind = 0;
  609. XX        for (ep = environ; *ep; ep++, ind++)
  610. XX            sh.shenv[ind] = *ep;
  611. XX        path = getenv("PATH");
  612. XX    }
  613. XX
  614. XX    /* if not a tty, dont print prompt */
  615. XX    if(!isatty(fileno(stdin)))
  616. XX        isttyin = 0;
  617. XX    
  618. XX    /* set default prompt */
  619. XX    prompt = "xsh> ";
  620. XX
  621. XX#ifdef ROOTRC
  622. XX    /* 'source' a static .sushrc file if any */
  623. XX    /* we pass a fmt string to userrc to allow this. */
  624. XX    /* later sprintf() is used to build the path */
  625. XX    /* by adding 'home' in. This is possibly gross */
  626. XX    (void)userrc("/etc/.sushrc");
  627. XX#endif
  628. XX
  629. XX    /* 'source' a user's .sushrc file if any */
  630. XX    (void)userrc("%s/.sushrc");
  631. XX
  632. XX    /* 'source' the standard input */ 
  633. XX    exit(doinput(stdin));
  634. XX}
  635. XX
  636. XXdoinput(inp)
  637. XXFILE *inp;
  638. XX{
  639. XX    int    (*ptr)();
  640. XX    char    *bptr;
  641. XX    struct    cmdtab    *dptr;
  642. XX
  643. XX    /* loop forever reading from input FILE */
  644. XX    while(1) {
  645. XX        if(isttyin)
  646. XX            printf("%s",prompt);
  647. XX        if((fgets(sh.shbuf,SHBUF,inp)) == NULL) 
  648. XX            return(0);
  649. XX
  650. XX        /* perform macro expansion if needed */
  651. XX        if(expline(sh.shbuf,sh.shexb,sh.shenv)) {
  652. XX            fprintf(stderr,"INTERNAL error in macro expansion\n");
  653. XX        }
  654. XX
  655. XX        /* parse it - use the expanded buffer */
  656. XX        if(lex(sh.shexb)) { 
  657. XX            fprintf(stderr,"INTERNAL error in lexical analysis\n");
  658. XX            break;
  659. XX        }
  660. XX        
  661. XX        /* if no tokens, skip to read */
  662. XX        if(sh.shrgn == 0)
  663. XX            continue;
  664. XX
  665. XX        /* in case of verbosity, be verbose */
  666. XX        if(verbose)
  667. XX            fprintf(stderr,"%s",sh.shexb);
  668. XX
  669. XX        /* drop the last newline from input buffer */
  670. XX        if(bptr = rindex(sh.shexb,'\n'))
  671. XX            *bptr = '\0';
  672. XX
  673. XX        /* log the input buffer */
  674. XX        (void)syslog(LOG_NOTICE,"sush:<%s> %s",user,sh.shexb);
  675. XX
  676. XX        /* set dispatch function pointer */
  677. XX        dptr = cm;
  678. XX
  679. XX        while(dptr -> func) {
  680. XX            if(!strcmp(dptr->mnem,sh.sharg[0])) {
  681. XX                ptr = dptr->func;
  682. XX                break;
  683. XX            }
  684. XX            dptr++;
  685. XX        }
  686. XX        if(!dptr->mnem) {
  687. XX            (void)dopath();
  688. XX        } else {
  689. XX            (void)((*ptr)());
  690. XX        }
  691. XX    }
  692. XXreturn(0);
  693. XX}
  694. XX
  695. XXuserrc(fmt)
  696. XXchar    *fmt;
  697. XX{
  698. XX    char    pathbuf[900];
  699. XX    int    savttyin = isttyin;
  700. XX    FILE    *rcp;
  701. XX
  702. XX    /* source a file if user's home dir has a .sushrc file */
  703. XX    /* note fmt is passed to us - this is grotty but can */
  704. XX    /* be used to pass a default .sushrc also. */
  705. XX    /* see comment where userrc is called. */
  706. XX
  707. XX    (void)sprintf(pathbuf,fmt,home);
  708. XX    if((rcp = fopen(pathbuf, "r")) == NULL)
  709. XX        return(1);
  710. XX
  711. XX    isttyin = 0;
  712. XX    (void)doinput(rcp);
  713. XX    (void)fclose(rcp);
  714. XX    isttyin = savttyin;
  715. XX
  716. XXreturn(0);
  717. XX}
  718. SHAR_EOF
  719. if test 3164 -ne "`wc -c sushmain.c`"
  720. then
  721. echo shar: error transmitting sushmain.c '(should have been 3164 characters)'
  722. fi
  723. echo shar: extracting sushpath.c '(2369 characters)'
  724. sed 's/^XX//' << \SHAR_EOF > sushpath.c
  725. XX
  726. XX#ifndef lint
  727. XXstatic char *RCSid = "6:$Header: sushpath.c,v 1.2 87/11/19 14:10:26 mjr Exp $";
  728. XX#endif
  729. XX
  730. XX/*
  731. XX *     $Author: mjr $
  732. XX *     $Log:    sushpath.c,v $
  733. XX * Revision 1.2  87/11/19  14:10:26  mjr
  734. XX * fixed interrupt handling so shell wouldn't exit on ^C from tty
  735. XX * 
  736. XX * Revision 1.1  87/11/08  18:19:23  mjr
  737. XX * Initial revision
  738. XX * 
  739. XX*/
  740. XX
  741. XX#include "sush.h"
  742. XX#include <stdio.h>
  743. XX#include <syslog.h>
  744. XX#include <sys/types.h>
  745. XX#include <sys/stat.h>
  746. XX#include <sys/wait.h>
  747. XX#include <sys/signal.h>
  748. XX
  749. XXdopath()
  750. XX{
  751. XX    char    *todo;
  752. XX    char    **alist = sh.shtok;
  753. XX    char    **envptr = sh.shenv;
  754. XX    int    child, ret;
  755. XX    union    wait    status;
  756. XX
  757. XX    todo = xpath(sh.sharg[0]);
  758. XX    if(!todo) {
  759. XX        fprintf(stderr,"\"%s\" not found\n",sh.sharg[0]);
  760. XX        return(1);
  761. XX    }
  762. XX
  763. XX    if(!search(top,todo)) {
  764. XX        (void)syslog(LOG_NOTICE,"sush:%s FAILED permission %s",user,todo);
  765. XX        fprintf(stderr,"\"%s\" permission denied\n",todo);
  766. XX        return(1);
  767. XX    }
  768. XX
  769. XX    /* do it */
  770. XX    if ((child = vfork()) == 0) {
  771. XX        (void)signal(SIGINT,SIG_DFL);
  772. XX        execve(todo,alist,envptr);
  773. XX        perror(todo);
  774. XX        _exit(127);
  775. XX    }
  776. XX
  777. XX    if(child < 0) {
  778. XX        perror("vfork");
  779. XX    }
  780. XX
  781. XX    while ((ret = wait(&status)) != child && ret != -1);
  782. XX
  783. XX    if(verbose && status.w_T.w_Retcode)
  784. XX        fprintf(stderr,"\"%s\" returns %d\n",todo,status.w_T.w_Retcode);
  785. XX
  786. XX    /* done it */
  787. XX    return(0);
  788. XX}
  789. XX
  790. XXchar    *
  791. XXxpath(exe)
  792. XXchar    *exe;
  793. XX{
  794. XX    char    *ptr;
  795. XX    char    *p;
  796. XX    static    char    pbuf[SHENV];    /* thing to build path in */
  797. XX    static    struct    stat    stbuf;    /* stat buffer */
  798. XX
  799. XX    /* read the path and search for the first thing that matches */
  800. XX    /* the name of the program */
  801. XX
  802. XX    /* first check if absolut path */
  803. XX    if(exe[0] == '/') {
  804. XX        /* if stat(2) fails return NULL */
  805. XX        if(stat(exe,&stbuf)) {
  806. XX            return((char *)NULL);
  807. XX        } else {
  808. XX            return(exe);
  809. XX        }
  810. XX    }
  811. XX
  812. XX    /* check to see if pathname is a relative path or not */
  813. XX    /* IE - it has a '/' in it     */
  814. XX    if((p = index(exe,'/')) != 0) {
  815. XX        (void)strcpy(pbuf,".");
  816. XX        if((p = getwd(pbuf)) == 0) {
  817. XX            perror(p);
  818. XX            return((char *)NULL);
  819. XX        }
  820. XX        (void)strcat(pbuf,"/");
  821. XX        (void)strcat(pbuf,exe);
  822. XX        if(stat(pbuf,&stbuf)) {
  823. XX            return((char *)NULL);
  824. XX        } else {
  825. XX            return(pbuf);
  826. XX        }
  827. XX    }
  828. XX
  829. XX    /* last but not least, search the PATH */
  830. XX    ptr = path;
  831. XX    p = pbuf;
  832. XX
  833. XX    /* somewhat gnarly */
  834. XX    while(*ptr) {
  835. XX        p = pbuf;
  836. XX        while(*ptr && *ptr != ':') {
  837. XX            *p++ = *ptr++;
  838. XX        }
  839. XX        *p++ = '\0';
  840. XX        (void)strcat(pbuf,"/");
  841. XX        (void)strcat(pbuf,exe);
  842. XX        if(!stat(pbuf,&stbuf)) {
  843. XX            return(pbuf);
  844. XX        }
  845. XX        if(*ptr = ':')
  846. XX            ptr++;
  847. XX    } 
  848. XX    return((char *)NULL);
  849. XX}
  850. SHAR_EOF
  851. if test 2369 -ne "`wc -c sushpath.c`"
  852. then
  853. echo shar: error transmitting sushpath.c '(should have been 2369 characters)'
  854. fi
  855. echo shar: extracting sushperm.c '(2594 characters)'
  856. sed 's/^XX//' << \SHAR_EOF > sushperm.c
  857. XX
  858. XX#ifndef lint
  859. XXstatic char *RCSid = "7:$Header: sushperm.c,v 1.2 87/11/19 14:21:41 mjr Exp $";
  860. XX#endif
  861. XX
  862. XX/*
  863. XX *     $Author: mjr $
  864. XX *     $Log:    sushperm.c,v $
  865. XX * Revision 1.2  87/11/19  14:21:41  mjr
  866. XX * cleaner logging format and more specific messages for error conditions.
  867. XX * 
  868. XX * Revision 1.1  87/11/08  18:19:24  mjr
  869. XX * Initial revision
  870. XX * 
  871. XX*/
  872. XX
  873. XX#include "sush.h"
  874. XX#include <stdio.h>
  875. XX#include <syslog.h>
  876. XX#include <grp.h>
  877. XX
  878. XXloadperm()
  879. XX{
  880. XX    char    inbuf[BUFSIZ];
  881. XX    FILE    *fp;
  882. XX    int    linenum =0;
  883. XX
  884. XX    if((fp = fopen(PERMFILE,"r")) == NULL) {
  885. XX        perror(PERMFILE);
  886. XX        return(1);
  887. XX    } 
  888. XX    while(fgets(inbuf,BUFSIZ,fp) != NULL) {
  889. XX        linenum++;
  890. XX        /* skip comments */
  891. XX        if(inbuf[0] != '#') {
  892. XX            if(tokenperm(inbuf,linenum))
  893. XX                return(1);
  894. XX        }
  895. XX    }
  896. XX    return(0);
  897. XX}
  898. XX
  899. XXtokenperm(str,linenum)
  900. XXchar    *str;
  901. XXint    linenum;
  902. XX{
  903. XX    static    char    cmbuf[SHTOK];
  904. XX    char    *bptr;
  905. XX
  906. XX    bptr = str;
  907. XX    /* tokenize - or is it tokenate ? */
  908. XX    if(bptr = wordparse(bptr,cmbuf,',')) {
  909. XX
  910. XX        /* parse it as a group */
  911. XX        if(!strcmp(cmbuf,"group")) {
  912. XX            return(addgroup(bptr,linenum)); 
  913. XX        }
  914. XX
  915. XX        /* parse it as a user */
  916. XX        if(!strcmp(cmbuf,"user")) {
  917. XX            return(adduser(bptr,linenum)); 
  918. XX        }
  919. XX
  920. XX        /* puke */
  921. XX        fprintf(stderr,"bad \"%s\" %s line %d\n",str,PERMFILE,linenum);
  922. XX        (void)syslog(LOG_NOTICE,"sush:sushperm line %d bad",linenum);
  923. XX        return(1);
  924. XX    }
  925. XXreturn(0);
  926. XX}
  927. XX
  928. XXadduser(str,lineno)
  929. XXchar    *str;
  930. XXint    lineno;
  931. XX{
  932. XX    static    char    buf[SHTOK];
  933. XX    char    *bptr;
  934. XX
  935. XX    bptr = str;
  936. XX
  937. XX    /* this should be the username */
  938. XX    if((bptr = wordparse(bptr,buf,',')) == '\0') {
  939. XX        fprintf(stderr,"bad user in %s line %d\n",PERMFILE,lineno);
  940. XX        (void)syslog(LOG_NOTICE,"sush:sushperm line %d user bad",lineno);
  941. XX        return(1);
  942. XX    }
  943. XX
  944. XX    /* not us - dont add the files */
  945. XX    if(strcmp(user,buf))
  946. XX        return(0);
  947. XX
  948. XX    while((bptr = wordparse(bptr,buf,','))!= '\0') {
  949. XX        /* link it in */
  950. XX        if(insert(&top,buf)) 
  951. XX            return(1);
  952. XX    }
  953. XXreturn(0);
  954. XX}
  955. XX
  956. XXaddgroup(str,lineno)
  957. XXchar    *str;
  958. XXint    lineno;
  959. XX{
  960. XX    static    char    buf[SHTOK];
  961. XX    char    *bptr;
  962. XX    struct    group    *gpt;
  963. XX    int    ok =0;
  964. XX    char    **gpmem;
  965. XX
  966. XX    bptr = str;
  967. XX
  968. XX    /* this should be the group name */
  969. XX    if((bptr = wordparse(bptr,buf,',')) == '\0') {
  970. XX        fprintf(stderr,"bad group in %s line %d\n",PERMFILE,lineno);
  971. XX        (void)syslog(LOG_NOTICE,"sush:sushperm line %d group bad",lineno);
  972. XX        return(1);
  973. XX    }
  974. XX    
  975. XX    if((gpt = getgrnam(buf)) == NULL) {
  976. XX        fprintf(stderr,"vapor group in %s line %d\n",PERMFILE,lineno);
  977. XX        (void)syslog(LOG_NOTICE,"sush:sushperm line %d group bad",lineno);
  978. XX        return(0);
  979. XX    }
  980. XX    gpmem = gpt->gr_mem;
  981. XX    while(*gpmem++) {
  982. XX        if(!strcmp(user,*gpmem))
  983. XX            ok++;
  984. XX    }
  985. XX
  986. XX    /* auth failed - return */
  987. XX    if(!ok)
  988. XX        return(0);
  989. XX
  990. XX    while(bptr = wordparse(bptr,buf,',')) {
  991. XX        if(insert(&top,buf)) 
  992. XX            return(1);
  993. XX    }
  994. XXreturn(0);
  995. XX}
  996. SHAR_EOF
  997. if test 2594 -ne "`wc -c sushperm.c`"
  998. then
  999. echo shar: error transmitting sushperm.c '(should have been 2594 characters)'
  1000. fi
  1001. echo shar: extracting sushtree.c '(1681 characters)'
  1002. sed 's/^XX//' << \SHAR_EOF > sushtree.c
  1003. XX
  1004. XX#ifndef lint
  1005. XXstatic char *RCSid = "8:$Header: sushtree.c,v 1.2 87/11/19 14:23:57 mjr Exp $";
  1006. XX#endif
  1007. XX
  1008. XX/*
  1009. XX *     $Author: mjr $
  1010. XX *     $Log:    sushtree.c,v $
  1011. XX * Revision 1.2  87/11/19  14:23:57  mjr
  1012. XX * cleaned up parser code a bit.
  1013. XX * 
  1014. XX * Revision 1.1  87/11/08  18:19:25  mjr
  1015. XX * Initial revision
  1016. XX * 
  1017. XX*/
  1018. XX
  1019. XX#include "sush.h"
  1020. XX#include <stdio.h>
  1021. XX
  1022. XXinsert(curr,newcom)
  1023. XXstruct    leaf    **curr;
  1024. XXchar    *newcom;
  1025. XX{
  1026. XX    int ret;
  1027. XX
  1028. XX    /* current leaf is empty */
  1029. XX    if(*curr == NULL) {
  1030. XX        /* add-a-leaf */
  1031. XX        *curr = (struct leaf *)malloc((unsigned)sizeof(struct leaf));
  1032. XX        if(*curr == NULL) {
  1033. XX            perror("malloc");
  1034. XX            return(1);
  1035. XX        }
  1036. XX        (*curr)->cmd = malloc((unsigned)(strlen(newcom)+1));
  1037. XX        if((*curr)->cmd == NULL) {
  1038. XX            perror("malloc");
  1039. XX            return(1);
  1040. XX        }
  1041. XX        (void)strcpy((*curr)->cmd,newcom);
  1042. XX        (*curr)->lptr = NULL;
  1043. XX        (*curr)->rptr = NULL;
  1044. XX        return(0);
  1045. XX    }
  1046. XX
  1047. XX    /* fall through if match - no need to save */
  1048. XX    ret = strcmp((*curr)->cmd,newcom);
  1049. XX    if(ret >0)
  1050. XX        return(insert(&(*curr)->rptr,newcom));
  1051. XX    if(ret <0)
  1052. XX        return(insert(&(*curr)->lptr,newcom));
  1053. XX
  1054. XXreturn(0);
  1055. XX}
  1056. XX
  1057. XXsearch(curr,newcom)
  1058. XXstruct    leaf    *curr;
  1059. XXchar    *newcom;
  1060. XX{
  1061. XX
  1062. XX    int ret;
  1063. XX
  1064. XX    /* current leaf is empty - not found */
  1065. XX    if(curr == NULL) {
  1066. XX        return(0);
  1067. XX    }
  1068. XX
  1069. XX    /* if ! match - search appropriate branch */
  1070. XX    ret = strcmp(curr->cmd,newcom);
  1071. XX    if(ret >0)
  1072. XX        return(search(curr->rptr,newcom));
  1073. XX    if(ret <0)
  1074. XX        return(search(curr->lptr,newcom));
  1075. XX
  1076. XX    return(1);
  1077. XX}
  1078. XX
  1079. XXshopriv()
  1080. XX{
  1081. XX    fprintf(stderr,"You are privileged to execute the following:\n");
  1082. XX    return(leafdump(top));
  1083. XX}
  1084. XX
  1085. XXleafdump(curr)
  1086. XXstruct    leaf    *curr;
  1087. XX{
  1088. XX    /* current leaf is empty - not found */
  1089. XX    if(curr == NULL) {
  1090. XX        return(0);
  1091. XX    }
  1092. XX    (void)leafdump(curr->rptr);
  1093. XX    (void)leafdump(curr->lptr);
  1094. XX    printf("%s\n",curr->cmd);
  1095. XX
  1096. XX    return(0);
  1097. XX}
  1098. SHAR_EOF
  1099. if test 1681 -ne "`wc -c sushtree.c`"
  1100. then
  1101. echo shar: error transmitting sushtree.c '(should have been 1681 characters)'
  1102. fi
  1103. echo shar: extracting sushuser.c '(1315 characters)'
  1104. sed 's/^XX//' << \SHAR_EOF > sushuser.c
  1105. XX
  1106. XX#ifndef lint
  1107. XXstatic char *RCSid = "9:$Header: sushuser.c,v 1.3 87/11/24 17:36:24 mjr Exp $";
  1108. XX#endif
  1109. XX
  1110. XX/*
  1111. XX *     $Author: mjr $
  1112. XX *     $Log:    sushuser.c,v $
  1113. XX * Revision 1.3  87/11/24  17:36:24  mjr
  1114. XX * added code to preserve home external envir variable
  1115. XX * 
  1116. XX * Revision 1.2  87/11/19  14:24:03  mjr
  1117. XX * improved calls to syslog - dropped newlines
  1118. XX * 
  1119. XX * Revision 1.1  87/11/08  18:19:27  mjr
  1120. XX * Initial revision
  1121. XX * 
  1122. XX*/
  1123. XX
  1124. XX#include "sush.h"
  1125. XX#include <stdio.h>
  1126. XX#include <pwd.h>
  1127. XX#include <syslog.h>
  1128. XX
  1129. XXchar    *crypt();
  1130. XXchar    *getpass();
  1131. XX
  1132. XXstruct    passwd    *getpwuid();
  1133. XX
  1134. XXgetuser()
  1135. XX{
  1136. XX    struct    passwd    *pwt;    /* passwd struct */
  1137. XX    char    *uspass;    /* user password */
  1138. XX    char    *crpass;    /* crypted password */
  1139. XX    int    cleared =3;    /* cleared to fly */
  1140. XX
  1141. XX     if((pwt = getpwuid(getuid())) == NULL) {
  1142. XX        fprintf(stderr,"WHO ARE YOU! !!!\n");
  1143. XX        exit(1);
  1144. XX    }
  1145. XX
  1146. XX    /* we assume your version of getpwent preserves the */
  1147. XX    /* stuff it returns. Ours does. */
  1148. XX    user = pwt->pw_name;
  1149. XX    home = pwt->pw_dir;
  1150. XX
  1151. XX    /* validate login */
  1152. XX    while(1 == 1) {
  1153. XX        uspass = getpass("Your Login Password:");
  1154. XX        crpass = crypt(uspass,pwt->pw_passwd);
  1155. XX        if(strcmp(crpass,pwt->pw_passwd)) {
  1156. XX            fprintf(stderr,"incorrect.\n");
  1157. XX            if(!--cleared)
  1158. XX                (void)syslog(LOG_NOTICE,"sush:BADlog %s",user);
  1159. XX                exit(4);
  1160. XX        } else {
  1161. XX            break;
  1162. XX        }
  1163. XX    }
  1164. XX    (void)syslog(LOG_NOTICE,"sush:login %s",user);
  1165. XX
  1166. XXreturn(0);
  1167. XX}
  1168. SHAR_EOF
  1169. if test 1315 -ne "`wc -c sushuser.c`"
  1170. then
  1171. echo shar: error transmitting sushuser.c '(should have been 1315 characters)'
  1172. fi
  1173. echo shar: extracting sush.h '(2328 characters)'
  1174. sed 's/^XX//' << \SHAR_EOF > sush.h
  1175. XX
  1176. XX#ifndef lint
  1177. XXstatic char *RCSidG = "1:$Header: sush.h,v 1.3 87/11/24 17:36:45 mjr Exp $";
  1178. XX#endif
  1179. XX
  1180. XX/*
  1181. XX *     $Author: mjr $
  1182. XX *     $Log:    sush.h,v $
  1183. XX * Revision 1.3  87/11/24  17:36:45  mjr
  1184. XX * added code to preserve home external envir variable
  1185. XX * 
  1186. XX * Revision 1.2  87/11/24  16:19:04  mjr
  1187. XX * added inline macro expansion in command line.
  1188. XX * 
  1189. XX * Revision 1.1  87/11/08  18:19:17  mjr
  1190. XX * Initial revision
  1191. XX * 
  1192. XX*/
  1193. XX
  1194. XX
  1195. XX/* should be adequate for basic shell - not heavy-duty */
  1196. XX#define    SHBUF    2048
  1197. XX#define    SHTOK    64
  1198. XX#define    SHARG    40
  1199. XX#define    SHENV    1024
  1200. XX
  1201. XXstruct    shglob    {
  1202. XX    char    shbuf[SHBUF];        /* general scratch mem */
  1203. XX    char    shexb[SHBUF];        /* macro expansion buffer */
  1204. XX    char    *shprm[SHTOK];        /* pointers to permitted progs */
  1205. XX    char    *shtok[SHTOK];        /* pointers to tokens */
  1206. XX    char    *shenv[SHENV];        /* pointers to environment variables */
  1207. XX    char    sharg[SHTOK][SHARG];    /* strings of shell args */
  1208. XX    int    shrgn;            /* number of shell args */
  1209. XX};
  1210. XX
  1211. XXstruct    cmdtab    {
  1212. XX    char    *mnem;            /* command name */
  1213. XX    int    (*func)();        /* pointer to func */
  1214. XX};
  1215. XX
  1216. XXstruct    leaf    {
  1217. XX    char    *cmd;
  1218. XX    struct    leaf    *lptr;
  1219. XX    struct    leaf    *rptr;
  1220. XX};
  1221. XX
  1222. XX    
  1223. XX/* function definitions */
  1224. XXextern    int    set(), unset(), prenv(), bye();
  1225. XXextern    int    cd(), pwd(), help(), shopriv();
  1226. XXextern    int    source();
  1227. XXextern    char    *malloc();
  1228. XXextern    char    *wordparse();
  1229. XXextern    char    *strcpy();
  1230. XXextern    char    *strcat();
  1231. XXextern    char    *getenv();
  1232. XXextern    char    *xpath();
  1233. XXextern    char    *index();
  1234. XXextern    char    *rindex();
  1235. XXextern    char    *getwd();
  1236. XXextern    struct    group    *getgrnam();
  1237. XX
  1238. XX#ifdef    NOEXTERN
  1239. XX
  1240. XX/* this version actually allocates memory */
  1241. XX/* only the main() module should define NOEXTERN */
  1242. XXchar    *prompt;            /* pointer to user prompt */
  1243. XXchar    *path;                /* pointer to user path */
  1244. XXchar    *user;                /* pointer to user name */
  1245. XXchar    *home;                /* pointer to user home dir */
  1246. XXchar    verbose =0;            /* set -x */
  1247. XXchar    isttyin =1;            /* is input from a tty ? */
  1248. XXstruct    shglob    sh;            /* shell global struct */
  1249. XXstruct    leaf    *top = 0;        /* permissions list tree */
  1250. XXstruct    cmdtab    cm[] = {
  1251. XX    "set",        set,
  1252. XX    "cd",        cd,
  1253. XX    "pwd",        pwd,
  1254. XX    "unset",    unset,
  1255. XX    "exit",        bye,
  1256. XX    "printenv",    prenv,
  1257. XX    "?",        help,
  1258. XX    "help",        help,
  1259. XX    "source",    source,
  1260. XX    "showpriv",    shopriv,
  1261. XX    0,    0
  1262. XX    };
  1263. XX
  1264. XX#else
  1265. XX
  1266. XXextern    char    *path;
  1267. XXextern    char    *user;
  1268. XXextern    char    *home;
  1269. XXextern    struct    leaf    *top;
  1270. XXextern    struct    shglob    sh;
  1271. XXextern    struct    cmdtab    cm[];
  1272. XXextern    char    *prompt;
  1273. XXextern    char    verbose;
  1274. XXextern    char    isttyin;
  1275. XX
  1276. XX#endif
  1277. SHAR_EOF
  1278. if test 2328 -ne "`wc -c sush.h`"
  1279. then
  1280. echo shar: error transmitting sush.h '(should have been 2328 characters)'
  1281. fi
  1282. echo shar: extracting Makefile '(1744 characters)'
  1283. sed 's/^XX//' << \SHAR_EOF > Makefile
  1284. XX
  1285. XX#static char *RCSid = "$Header: Makefile,v 1.7 87/11/24 17:35:04 mjr Exp $";
  1286. XX#/*
  1287. XX#    $Author: mjr $
  1288. XX#    $Log:    Makefile,v $
  1289. XX# Revision 1.7  87/11/24  17:35:04  mjr
  1290. XX# added more detail on define options
  1291. XX# 
  1292. XX# Revision 1.6  87/11/19  14:46:02  mjr
  1293. XX# final tweeks(?) .
  1294. XX# 
  1295. XX# Revision 1.5  87/11/19  14:42:28  mjr
  1296. XX# more futzing around.
  1297. XX# 
  1298. XX# Revision 1.4  87/11/19  14:37:26  mjr
  1299. XX# added doc into make dependencies. 
  1300. XX# 
  1301. XX# Revision 1.3  87/11/19  14:33:00  mjr
  1302. XX# added make install.
  1303. XX# 
  1304. XX# Revision 1.2  87/11/19  14:27:33  mjr
  1305. XX# forgot to put Makefile in dependency list !!
  1306. XX# 
  1307. XX# Revision 1.1  87/11/08  18:19:15  mjr
  1308. XX# Initial revision
  1309. XX# 
  1310. XX#*/
  1311. XX
  1312. XX.SUFFIXES:
  1313. XX.SUFFIXES: .c .o
  1314. XX
  1315. XX.DEFAULT:
  1316. XX    co $@
  1317. XX
  1318. XXDEST = /etc/local
  1319. XXDOC = sushperm.l sush.l
  1320. XX
  1321. XX#must be defined as pathname to permissions file.
  1322. XX#DEFINES= -DPERMFILE=\"/etc/local/sushperm\" -DROOTRC
  1323. XX
  1324. XXDEFINES= -DPERMFILE=\"/u1/mjr/hacks/sh/myperm\"
  1325. XX
  1326. XXCFLAGS= -OG -s -n $(DEFINES)
  1327. XX#CFLAGS= -gx $(DEFINES)
  1328. XX
  1329. XXOBJ=    sushmain.o\
  1330. XX    sushlex.o\
  1331. XX    sushpath.o\
  1332. XX    sushperm.o\
  1333. XX    sushuser.o\
  1334. XX    sushtree.o\
  1335. XX    sushhelp.o\
  1336. XX    sushfunc.o
  1337. XX
  1338. XX
  1339. XXsush:    $(OBJ)
  1340. XX    cc $(CFLAGS) -o sush $(OBJ) 
  1341. XX
  1342. XX$(OBJ): sush.h Makefile
  1343. XX
  1344. XXclean:
  1345. XX    rm -f *.o sush
  1346. XX
  1347. XXlint:
  1348. XX    lint $(DEFINES) *.c
  1349. XX
  1350. XXshar:
  1351. XX    shar -a README *.c *.h Makefile sush.8l sushperm.5l > sush.shar
  1352. XX
  1353. XXinstall: $(DOC) sush
  1354. XX    cp sush $(DEST)/sush
  1355. XX    chown root $(DEST)/sush
  1356. XX    chmod 4511 $(DEST)/sush
  1357. XX    cp sush.l /usr/man/manl
  1358. XX    chmod 744 /usr/man/manl/sush.l
  1359. XX    cp sushperm.l /usr/man/manl
  1360. XX    chmod 744 /usr/man/manl/sushperm.l
  1361. XX
  1362. XX#documentation !!
  1363. XXsush.l:        sush.8l
  1364. XX    cp sush.8l sush.l
  1365. XXsushperm.l:    sushperm.5l
  1366. XX    cp sushperm.5l sushperm.l
  1367. XX
  1368. XX#for RCS
  1369. XXsushlex.o:    sushlex.c
  1370. XXsushmain.o:    sushmain.c
  1371. XXsushpath.o:    sushpath.c
  1372. XXsushperm.o:    sushperm.c
  1373. XXsushuser.o:    sushuser.c
  1374. XXsushtree.o:    sushtree.c
  1375. XXsushhelp.o:    sushhelp.c
  1376. XXsushfunc.o:    sushfunc.c
  1377. SHAR_EOF
  1378. if test 1744 -ne "`wc -c Makefile`"
  1379. then
  1380. echo shar: error transmitting Makefile '(should have been 1744 characters)'
  1381. fi
  1382. echo shar: extracting sush.8l '(5046 characters)'
  1383. sed 's/^XX//' << \SHAR_EOF > sush.8l
  1384. XX.TH sush 8-local
  1385. XX.SH NAME
  1386. XXsush \- SuperUser shell
  1387. XX.fi
  1388. XX.ad
  1389. XX.hy 0
  1390. XX.SH ORIGIN
  1391. XXmjr@osiris.UUCP 
  1392. XX.SH SYNOPSIS
  1393. XX.B sush
  1394. XX.SH DESCRIPTION
  1395. XX.B Sush
  1396. XXis a restricted shell that allows systems administrators to
  1397. XXgrant specific limited priviledges to users.   All commands that are
  1398. XXexecuted are logged to the system log,   as well as other pertinent
  1399. XXinformation.
  1400. XX.SH AUTHORIZATION
  1401. XX.B Sush
  1402. XXreads an authorization file at start-up time.   This file contains a
  1403. XXlist of group and user names,   each followed by a list of pathnames
  1404. XXto programs they are allowed to run.   The user's password is checked,
  1405. XXto ensure that someone has not broken into that account.   Thereafter,
  1406. XXusers are prompted,   just as in a "normal" shell,   commands are parsed,
  1407. XXand executed if the user has permission to execute them.
  1408. XX.SH "INTERNAL COMMANDS"
  1409. XX.PP
  1410. XX.B set 
  1411. XX.B [
  1412. XXvariable
  1413. XX.B ] = [
  1414. XXstring
  1415. XX.B ]
  1416. XX.PP
  1417. XXIf called without arguments,   the set command shows a list of currently
  1418. XXdefined environment variables.   If called with arguments in the form of
  1419. XXstring = string (spaces necessary) the specified environment variable 
  1420. XXis set,   or reset.
  1421. XX.PP
  1422. XX.B cd
  1423. XX.PP
  1424. XXThe cd command allows the user to reset the current working directory.
  1425. XX.PP
  1426. XX.B pwd
  1427. XX.PP
  1428. XXThe pwd command will print the current working directory.
  1429. XX.PP
  1430. XX.B unset variable
  1431. XX.PP
  1432. XXUnset,   when provided an environment variable name,   will unset that 
  1433. XXenvironment variable.
  1434. XX.PP
  1435. XX.B exit
  1436. XX.PP
  1437. XXExits from the shell.   An EOF will also exit the shell.
  1438. XX.PP
  1439. XX.B source filename
  1440. XX.PP
  1441. XXWill read the file into the shell as commands.
  1442. XX.PP
  1443. XX.B printenv
  1444. XX.PP
  1445. XXThe printenv command lists all current environment variables.
  1446. XX.PP
  1447. XX.B ? or help
  1448. XX.PP
  1449. XXThe "?" and help commands provide a list of shell internals.
  1450. XX.PP
  1451. XX.SH "THE .sushrc FILE"
  1452. XX.PP
  1453. XXAt startup
  1454. XX.I Sush
  1455. XXwill read a 
  1456. XX.I .sushrc
  1457. XXfile if there is one in the user's home directory. This functions
  1458. XXexactly like the 
  1459. XX.B source
  1460. XXinternal command. If the last line in the 
  1461. XX.I .sushrc
  1462. XXis exit, the shell will exit. This can be used to more exactly control a 
  1463. XXuser.
  1464. XX.SH "THE ENVIRONMENT"
  1465. XX.I Sush
  1466. XXmaintains a copy of the invocation environment,  including the PATH,
  1467. XXTERM and other useful variables.  These are passed whenever a command
  1468. XXis invoked,  so that programs such as Ingres and Sybase that rely on
  1469. XXenvironment variables will still work properly.
  1470. XX.SH "ENVIRONMENT VARIABLES"
  1471. XX.PP
  1472. XXEnvironment variables are substituted in the command line if they
  1473. XXare surrounded by $().  Thus something like:
  1474. XX.br
  1475. XX\fIecho  $(PATH)\fP
  1476. XX.br
  1477. XX.PP
  1478. XXwill echo the contents of PATH.  Recursion is not supported - IE:
  1479. XX.nf
  1480. XX.na
  1481. XX.br
  1482. XX\fIset FOO = "this is $(BAR)"\fP
  1483. XX\fIecho $(FOO)\fP
  1484. XX\fBthis is $(BAR)\fP
  1485. XX.fi
  1486. XX.ad
  1487. XX.SH "DIFFERENCES FROM A REAL SHELL"
  1488. XX.I Sush 
  1489. XXintentionally does not support many features found in a \fIREAL\fP
  1490. XXUNIX shell,   since they allow unauthorized access too easily.
  1491. XX.PP
  1492. XX.I "I/O Redirection:"
  1493. XX.I Bourne
  1494. XXor
  1495. XX.I Csh 
  1496. XXconstructs like \fB"ls | more"\fP are not supported,   since it entails
  1497. XXan additional level of parsing in the command line.  Constructs such
  1498. XXas \fB"ls > foo"\fP are also unsupported,   for obvious reasons.
  1499. XX.PP
  1500. XX.I "Globbing:"
  1501. XXGlobbing,   or wildcard expansion,   is not supported,   since it renders it
  1502. XXmore difficult to determine what command a user wants to execute.  A
  1503. XXcommand like \fB"/etc/vip*"\fP,   which could expand to \fB"/etc/vipw"\fP
  1504. XXso the shell would have to re-parse the command line multiple times.
  1505. XX.SH "COMMAND EXECUTION"
  1506. XXCommands are executed by searching the PATH environment variable for the
  1507. XXcommand that is requested.  If the command is found,  the complete pathname
  1508. XXis checked against the list of user's permissions.  If the filename is in
  1509. XXthe permission list,  it is executed,  and the execution is logged to the
  1510. XXsystem log file,  along with the arguments it was invoked with.  The way
  1511. XXin which the path is parsed makes calls like \fB"/bin/../bin/ls"\fP to
  1512. XXbe rejected.
  1513. XX.SH "A SAMPLE RUN"
  1514. XX.nf
  1515. XX\fB
  1516. XXxsh> \fIshowpriv\fP
  1517. XXYou are privileged to execute the following:
  1518. XX/bin/grep
  1519. XX/bin/kill
  1520. XX/bin/echo
  1521. XX/bin/csh
  1522. XX/bin/ls
  1523. XX/ingres/bin/accessdb
  1524. XX/usr/ucb/w
  1525. XX/bin/who
  1526. XX/bin/sh
  1527. XXxsh> \fI?\fP
  1528. XXInternal Commands Are:
  1529. XXset
  1530. XXcd
  1531. XXpwd
  1532. XXunset
  1533. XXexit
  1534. XXprintenv
  1535. XX?
  1536. XXhelp
  1537. XXshowpriv
  1538. XXNote - I/O redirection,   filename expansion and history,   not supported.
  1539. XXxsh> \fIls\fP
  1540. XXMakefile    sush.8l     sushhelp.c  sushmain.c  sushperm.c  sushuser.c
  1541. XXRCS         sush.h      sushhelp.o  sushmain.o  sushperm.o  sushuser.o
  1542. XXxsh> \fIvipw\fP
  1543. XX"/etc/vipw" permission denied
  1544. XXxsh> \fIexit\fP
  1545. XX.fi
  1546. XX\fR
  1547. XX.SH "SEE ALSO"
  1548. XXsyslog(8),   sh(1),   sushperm(5l)
  1549. XX.SH MESSAGES
  1550. XX.IP "vapor group in /u1/mjr/hacks/sh/myperm line 3" 10
  1551. XX.br
  1552. XX.I Sush
  1553. XXfound a group in the permissions file that does not exist in /etc/group.
  1554. XXThis is logged as a potential security hole.
  1555. XX.SH BUGS
  1556. XX.PP
  1557. XXSignal handling is not perfect.
  1558. XX.PP
  1559. XXAny commands that contain a shell escape (vi,   more,   ingres editor,   
  1560. XXetc,   etc) are
  1561. XXa potential loophole.   Additionally,   there is the problem of a user with the
  1562. XXability to do anything that would alter a security file.   IE - someone with
  1563. XXthe ability to chmod /etc/passwd.   There is no way around this.
  1564. XX.\"    @(#)sush.8l Tue Nov 10 20:52:17 EST 1987
  1565. SHAR_EOF
  1566. if test 5046 -ne "`wc -c sush.8l`"
  1567. then
  1568. echo shar: error transmitting sush.8l '(should have been 5046 characters)'
  1569. fi
  1570. echo shar: extracting sushperm.5l '(1729 characters)'
  1571. sed 's/^XX//' << \SHAR_EOF > sushperm.5l
  1572. XX.TH SUSHPERM 5-local
  1573. XX.SH NAME
  1574. XXsushperm \- suid shell permissions database
  1575. XX.SH SYNOPSIS
  1576. XX/etc/local/sushperm
  1577. XX.SH DESCRIPTION
  1578. XX.I Sushperm
  1579. XXis a data base describing users,  groups,  and pathnames of programs
  1580. XXthat they are allowed to execute as "root".
  1581. XX.PP
  1582. XXEntries in
  1583. XX.I sushperm
  1584. XXconsist of a number of fields.
  1585. XXThe first entry for each field consists of the word "user" or "group"
  1586. XXto indicate whether the next field is specifying the permissions for
  1587. XXa single user,  or a group.  The second field is the name of the user
  1588. XXor group in question.  User names are expected to be in \fB"/etc/passwd"\fP
  1589. XXand groups are expected to be in \fB"/etc/group"\fP.  
  1590. XXThe remainder of the line consists of comma or space separated entries
  1591. XXthat list the complete PATHnames of programs that the user or group
  1592. XXin question is privileged to run.  
  1593. XX.PP
  1594. XXUser's permissions are cumulative,  so that a user's total permissions 
  1595. XXwill be the sum of that user's entries,  plus the sum of all groups in
  1596. XXwhich that user is a member.  Badly formatted lines in the 
  1597. XX.I sushperm
  1598. XXfile are ignored,  as are lines beginning with a \fB'#'\fP.
  1599. XX.fi
  1600. XX.PP
  1601. XX.B A Sample Entry
  1602. XX.PP
  1603. XX.nf
  1604. XX
  1605. XX# sample sushperm file
  1606. XXgroup e+o /bin/sh, /bin/ls, /bin/csh
  1607. XXgroup sys /bin/echo,  /bin/kill
  1608. XXuser ken /bin/sh, /bin/ls, /bin/cat
  1609. XXuser mjr /bin/kill,  /bin/grep,  /bin/who,  /usr/ucb/w
  1610. XXuser mjr /etc/shutdown,  /etc/halt,  /etc/reboot
  1611. XX
  1612. XX.fi
  1613. XX.PP
  1614. XXEntries for a particular user may appear on several lines with a cumulative
  1615. XXeffect.
  1616. XX.SH DIAGNOSTICS
  1617. XX.I sush
  1618. XXwill complain of it finds nonexistent groups or user names in the
  1619. XX.I sushperm
  1620. XXfile.
  1621. XX.SH FILES
  1622. XX.DT
  1623. XX/etc/local/sushperm - permissions file.
  1624. XX.SH SEE ALSO
  1625. XXsush(8l)
  1626. XX.br
  1627. XX.SH BUGS
  1628. XXNone known at present.
  1629. XX.\"    @(#)sushperm.5l    Tue Nov 17 10:02:59 EST 1987
  1630. SHAR_EOF
  1631. if test 1729 -ne "`wc -c sushperm.5l`"
  1632. then
  1633. echo shar: error transmitting sushperm.5l '(should have been 1729 characters)'
  1634. fi
  1635. #    End of shell archive
  1636. exit 0
  1637.