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

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