home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / sxt-sh-jobs / part02 / sxtalloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-22  |  5.7 KB  |  265 lines

  1. /*
  2.  *    Allocate a sxt-channel for a non-priveliged user, by
  3.  *    chowning an unused one, so the user can pick it up later.
  4.  *    Probably needs locks to prevent races, but too much effort to do that.
  5.  *
  6.  *    MUST BE SET-USER-ID "root".
  7.  *
  8.  *    Used by the "ssh" shell to do job-control.
  9.  *
  10.  *    Usage:
  11.  *        sxtalloc         - allocate sxt, print old ttyname on 
  12.  *                      stdout;
  13.  *                      exit status: 0=success, 1=failure.
  14.  *        sxtalloc realtty status - de-allocate sxt, change utmp entry
  15.  *                      back to "realtty";
  16.  *                      exit status: "status"."
  17.  *    Copyright (c) S. Brown, 1987
  18.  */
  19.  
  20. #include <errno.h>
  21. #include <sys/types.h>
  22. #include <sys/tty.h>
  23. #include <sys/sxt.h>
  24. #include <fcntl.h>
  25. #include <utmp.h>
  26. #include <sys/stat.h>
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include <pwd.h>
  30.  
  31. char sxt[] = "/dev/sxt/000";    /* virtual tty devices, channel 0 */
  32. #define SXT_CHAN 9
  33. char devsxt[] = "sxt000";    /* utmp dummy */
  34. char devreal[50];
  35. extern struct utmp *getutline();
  36. extern char *ttyname();
  37. extern char *strrchr();
  38. char *getuser();
  39. char *progname;
  40.  
  41. /*
  42.  *    The "allow/deny" files, a la cron/at.
  43.  */
  44. #define ALLOW    "/usr/lib/ssh/sxt.allow"
  45. #define DENY    "/usr/lib/ssh/sxt.deny"
  46.  
  47. #define UNAMESIZE 64    /* FAR too big! */
  48.  
  49. /*
  50.  *    Verbose mode
  51.  */
  52. /*#define VERBOSE*/
  53.  
  54.  
  55. main(argc,argv)
  56. char **argv;
  57. {
  58.     int exitstat;
  59.  
  60.     progname = argv[0];
  61.     if (argc==3){
  62.         release(argv[1]);
  63.         exitstat = atoi(argv[2]);
  64.     } else if (argc==1)
  65.         exitstat = allocate();
  66.     else {
  67.         fprintf(stderr, "%s: usage\n", argv[0]);
  68.         exitstat = -1;
  69.     }
  70.     exit(exitstat);
  71.     /*NOTREACHED*/
  72. }
  73.  
  74.  
  75. allocate()
  76. {
  77.     int fd;
  78.     int chan = 0;
  79.     int uid, gid;
  80.     char *tty;
  81.     int mode;
  82.     struct utmp *u_entry;
  83.     struct utmp u_start;
  84.     register int i;
  85.     struct stat statb;
  86.     char *username;
  87.  
  88.     uid=getuid();
  89.     username = getuser(uid);
  90.     if (username==NULL){    /* you don't exist! */
  91. #ifdef VERBOSE
  92.         fprintf(stderr,"You don't exist. go away!\n");
  93. #endif
  94.         return(1);
  95.     }
  96.     if (allowed(username,ALLOW,DENY)==0){
  97. #ifdef VERBOSE
  98.         fprintf(stderr,"You are not allowed to use sxt devices\n");
  99. #endif
  100.         return(2);    /* 2 means "not permitted" */
  101.     }
  102.     do {
  103.         fd = open(sxt,O_RDONLY|O_EXCL);
  104.         if (fd==-1){
  105.             if (errno!=EBUSY){
  106.                 fprintf(stderr,"%s: sxt failure on %s (errno %d)\n", progname, sxt,errno);
  107.                 return(1);    /* some strange error, like no chans unused */
  108.             }
  109.             chan++;        /* try next device */
  110.             sxt[SXT_CHAN] = (chan/10)+'0';
  111.             sxt[SXT_CHAN+1] = (chan%10)+'0';
  112.         }
  113.     } while (fd==-1);    /* continue until found an unused dev */
  114.  
  115.     gid=getgid();
  116.     tty=ttyname(0);
  117.     if (tty && stat(tty,&statb)==0){
  118.         mode = statb.st_mode&0777;
  119.         tty = strrchr(tty,'/');
  120.         if (tty){
  121.             tty++;
  122.             strcpy(u_start.ut_line,tty);
  123.             if ((u_entry=getutline(&u_start))!=(struct utmp *)0){
  124.                 strcpy(&devsxt[3], &sxt[SXT_CHAN]);
  125.                 devsxt[5] = '1';    /* chan 1 is control */
  126.                 strcpy(devreal, u_entry->ut_line);
  127.                 strcpy(u_entry->ut_line, devsxt);
  128.                 pututline(u_entry);
  129.                 endutent();
  130.             } 
  131. #ifdef VERBOSE
  132.             else fprintf(stderr,"%s: can't change utmp\n", progname); 
  133. #endif
  134.         } else fprintf(stderr,"%s: tty has silly name\n", progname);
  135.     } else {
  136.         fprintf(stderr,"%s: warning - can't seem to find tty name\n", progname);
  137.         mode = 0622;
  138.     }
  139.  
  140.     for (i=0; i<MAXPCHAN; i++){    /* chown all the channels for that dev */
  141.  
  142.         sxt[SXT_CHAN+2] = i+'0';
  143.         if (chown(sxt,uid,gid) != 0){    /* "real" id's */
  144.             fprintf(stderr,"%s: chown failure on %s (errno %d)\n", progname, sxt, errno);
  145.             return(1);    /* no point haning about */
  146.         }
  147.         if (chmod(sxt,mode) != 0){
  148.             fprintf(stderr,"%s: chmod failure on %s (errno %d)\n", progname, sxt, errno);
  149.             return(1);    /* no point haning about */
  150.         }
  151.     }
  152.     printf("%s\n", devreal);
  153.     return(0);
  154. }
  155.  
  156.  
  157.  
  158. release(realtty)
  159. char *realtty;
  160. {
  161.     char *tty;
  162.     int mode;
  163.     struct utmp u_start;
  164.     struct utmp *u_entry;
  165.     struct stat statb;
  166.     int uid;
  167.  
  168.     uid=getuid();
  169.     strcpy(devreal,"/dev/");
  170.     if (realtty && *realtty){
  171.         strcat(devreal,realtty);
  172.         if (stat(devreal,&statb)!=0
  173.                  || statb.st_uid!=uid
  174.                  || (statb.st_mode&S_IFMT)!=S_IFCHR){
  175.             fprintf(stderr,"%s: %s is not a tty belonging to you!\n",
  176.                 progname, realtty);
  177.             return;
  178.         }
  179.     } else {
  180.         fprintf(stderr,"%s: null tty name given\n", progname);
  181.         return;
  182.     }
  183.     tty=ttyname(0);
  184.     if (tty && stat(tty,&statb)==0){
  185.         mode = statb.st_mode&0777;
  186.         tty = strrchr(tty,'/');
  187.         if (tty){
  188.             tty++;
  189.             strcpy(u_start.ut_line,tty);
  190.             if ((u_entry=getutline(&u_start))!=(struct utmp *)0){
  191.                 strcpy(u_entry->ut_line, realtty);
  192.                 pututline(u_entry);
  193.                 endutent();
  194.             } else fprintf(stderr,"%s: can't restore utmp\n", progname);
  195.         } else fprintf(stderr,"%s: tty has silly name\n",progname); 
  196.     } else {
  197.         fprintf(stderr,"%s: warning - can't seem to find tty name\n", progname);
  198.         mode = 0622;
  199.     }
  200.     if (chmod(devreal,mode)!=0)
  201.         fprintf(stderr,"%s: cannot reset mode of real tty\n", progname);}
  202.  
  203.  
  204. /*
  205.  *    --------------------------------------------------------
  206.  *
  207.  *    The following stuff checks in the files
  208.  *    sxt.allow and sxt.deny files to control access
  209.  *
  210.  */
  211.  
  212.  
  213.  
  214. struct stat globstat;
  215. #define    exists(file)    (stat(file,&globstat) == 0)
  216.  
  217. char *getuser(uid)
  218. int uid;
  219. {
  220.     struct passwd *nptr,*getpwuid();
  221.  
  222.     if ((nptr=getpwuid(uid)) == NULL) {
  223.         return(NULL); 
  224.     }
  225.     return(nptr->pw_name);
  226. }
  227.  
  228.  
  229. allowed(user,allow,deny)
  230. char *user,*allow,*deny;
  231. {
  232.     if (getuid() == 0) return(1);    /* root is a good guy */
  233.     if ( exists(allow) ) {
  234.         if ( within(user,allow) ) return(1);
  235.     } else if ( exists(deny) ) {
  236.         if ( within(user,deny) ) return(0);
  237.         else return(1); 
  238.     } else return(1);
  239.     return(0);
  240. }
  241.  
  242.  
  243. within(username,filename)
  244. char *username,*filename;
  245. {
  246.     char line[UNAMESIZE];
  247.     FILE *cap;
  248.     int i;
  249.  
  250.     if((cap = fopen(filename,"r")) == NULL)
  251.         return(0);
  252.     while ( fgets(line,UNAMESIZE,cap) != NULL ) {
  253.         for ( i=0 ; line[i] != '\0' ; i++ ) {
  254.             if ( isspace(line[i]) ) {
  255.                 line[i] = '\0';
  256.                 break; }
  257.         }
  258.         if ( strcmp(line,username)==0 ) {
  259.             fclose(cap);
  260.             return(1); }
  261.     }
  262.     fclose(cap);
  263.     return(0);
  264. }
  265.