home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume28 / yapp / part02 / system.c < prev   
Encoding:
C/C++ Source or Header  |  1994-05-29  |  7.7 KB  |  264 lines

  1. /* SYSTEM.C - Dave Thaler 3/1/93
  2.  * This file does secure replacements for popen and system calls 
  3.  */
  4. static    char sccsid[] = "@(#)system.c 1.17 93/06/09 Copyright (c)1993 thalerd";
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <signal.h>
  11. /*
  12. #include <fcntl.h> 
  13. #include <sys/socket.h>
  14. */
  15. #include "config.h"
  16. #include "struct.h"
  17. #include "lib.h"
  18. #include "xalloc.h"
  19. #include "macro.h"
  20. #include "globals.h"
  21. #include "files.h"
  22.  
  23. /******************************************************************************/
  24. /* SECURE popen() - OPEN A PIPE TO A PROCESS                                  */
  25. /******************************************************************************/
  26. FILE *      /* RETURNS: file pointer of pipe */
  27. spopen(cmd) /* ARGUMENTS: */
  28. char *cmd;  /*    Command to pipe to */
  29. {
  30.   int fd[2],s;
  31.   char **argv;
  32.   FILE *fp;
  33.  
  34.   if (status & S_REDIRECT) {
  35.      printf("UNK Error, pipe already open\n");
  36.   }
  37.  
  38.   if (pipe(fd)<0) return NULL;
  39.   if ((fp=fdopen(fd[1],"w"))==NULL) return NULL;
  40.   
  41.   /* The following two lines are not necessary, and even slow the program
  42.    * down, but make seen be more accurate in some cases, since less info is
  43.    * buffered by the pager.
  44.    */
  45. /* fcntl(fd[1], F_SETFL, O_SYNC);
  46.    setsockopt(fd[1],SOL_SOCKET, SO_SNDBUF, 4, 1);
  47.  */
  48.  
  49.   if (s=fork()) { /* parent */
  50.      if (s<0) return NULL; /* error: couldn't fork */
  51.      close(fd[0]);
  52.      status |= S_PIPE|S_REDIRECT;
  53.      madd(fd[1],cmd,O_PIPE);
  54.      return fp;
  55.   } else { /* child */
  56.      setuid(getuid());
  57.      setgid(getgid());
  58.      signal(SIGINT,SIG_DFL);
  59.      signal(SIGPIPE,SIG_DFL);
  60.      close(0);
  61.      dup(fd[0]);
  62.      close(fd[1]);
  63.  
  64.      if (strpbrk(cmd,"<>*?|![]{}~`$&';\\\"") == NULL) {
  65.         argv = explode(cmd," ");
  66.         s    = xsizeof(argv);
  67.         argv = xrealloc(argv, (short)(s+1));
  68.         argv[s]=0;
  69.         execvp(argv[0],argv);
  70.         printf("oops: Can't execute \"%s\"!\n",cmd);
  71.      } else {
  72.         char *shpath,*sh;
  73.  
  74.         shpath = expand("shell",DM_VAR);
  75.         sh = strrchr(shpath,'/');
  76.         if (!sh) sh = shpath;
  77.         else sh++;
  78.         execl(shpath,sh,"-c",cmd,(char *)NULL);
  79.      }
  80.      exit(1);
  81.   }
  82.   return NULL;
  83. }
  84.  
  85. /******************************************************************************/
  86. /* DUMP A STRING TO A SECURE PIPE                                             */
  87. /******************************************************************************/
  88. int            /* RETURNS: # bytes written */
  89. spout(fd,buff) /* ARGUMENTS: */
  90. int fd;        /*    File descriptor of pipe */
  91. char *buff;    /*    String to dump */
  92. {
  93.    return write(fd,buff,strlen(buff));
  94. }
  95.  
  96. /******************************************************************************/
  97. /* CLOSE A SECURE PIPE                                                        */
  98. /******************************************************************************/
  99. int         /* RETURNS: error code */
  100. spclose(pp) /* ARGUMENTS: */
  101. FILE *pp;   /*    File pointer to close */
  102. {
  103.    int i;
  104.    int statusp;
  105.  
  106.    if (!(status & S_REDIRECT)) {
  107.       printf("UNK Error, pipe not open\n");
  108.    }
  109.  
  110.    i=mclose(pp);
  111.    if (status & S_PIPE)
  112.       wait(&statusp);
  113.    status &= ~(S_PIPE|S_REDIRECT|S_INT);
  114.    return i;
  115. }
  116.  
  117. /******************************************************************************/
  118. /* SECURE system() - EXECUTE A UNIX COMMAND                                   */
  119. /******************************************************************************/
  120. int           /* RETURNS: exit status of command */
  121. unix_cmd(cmd) /* ARGUMENTS: */
  122. char *cmd;    /*    Command to execute */
  123. {
  124.    char **argv;
  125.    short s;
  126.    register int cpid,wpid;
  127.    int statusp;
  128.  
  129.    if (cpid=fork()) { /* parent */
  130.       if (cpid<0) return -1; /* error: couldn't fork */
  131.       while ((wpid = wait(&statusp)) != cpid && wpid != -1);
  132.    } else { /* child */
  133.       setuid(getuid());
  134.       setgid(getgid());
  135.       signal(SIGINT,SIG_DFL);
  136.       signal(SIGPIPE,SIG_DFL);
  137.       if (strpbrk(cmd,"<>*?|![]{}~`$&';\\\"") == NULL) {
  138.          argv = explode(cmd," ");
  139.          s    = xsizeof(argv);
  140.          argv = xrealloc(argv, (short)(s+1));
  141.          argv[s]=0;
  142.          execvp(argv[0],argv);
  143.          printf("oops: Can't execute \"%s\"!\n",cmd);
  144.       } else {
  145.          char *shpath,*sh;
  146.  
  147.          shpath = expand("shell",DM_VAR);
  148.          sh = strrchr(shpath,'/');
  149.          if (!sh) sh = shpath;
  150.          else sh++;
  151.          execl(shpath,sh,"-c",cmd,(char *)NULL);
  152.       }
  153.       exit(1);
  154.    }
  155.    return statusp;
  156. }
  157.  
  158. /******************************************************************************/
  159. /* REMOVE A FILE                                                              */
  160. /******************************************************************************/
  161. int                     /* RETURNS: error code */
  162. rm(file,sec)        /* ARGUMENTS: */
  163. char *file;
  164. int   sec;              /*    As owner(0) or user(1)? */
  165. {
  166.    int c;
  167.    register int cpid,wpid;
  168.    int statusp;
  169.  
  170.    if (!sec) {
  171.       statusp=unlink(file);
  172.    } else {
  173.       if (cpid=fork()) { /* parent */
  174.          if (cpid<0) return -1; /* error: couldn't fork */
  175.          while ((wpid = wait(&statusp)) != cpid && wpid != -1);
  176.       } else { /* child */
  177.          setuid(getuid());
  178.          setgid(getgid());
  179.          exit(unlink(file));
  180.       }
  181.    }
  182.    if (statusp) error("removing ",file);
  183.    return statusp;
  184. }
  185.  
  186. /******************************************************************************/
  187. /* SECURELY COPY ONE FILE TO ANOTHER                                          */
  188. /******************************************************************************/
  189. int                     /* RETURNS: error code */
  190. copy_file(src,dest,sec) /* ARGUMENTS: */
  191. char *src;              /*    Source file */
  192. char *dest;             /*    Destination file */
  193. int   sec;              /*    As owner(0) or user(1)? */
  194. {
  195.    FILE *fsrc,*fdest;
  196.    int c;
  197.    register int cpid,wpid;
  198.    int statusp;
  199.    long mod;
  200.  
  201.    if (cpid=fork()) { /* parent */
  202.       if (cpid<0) return -1; /* error: couldn't fork */
  203.       while ((wpid = wait(&statusp)) != cpid && wpid != -1);
  204.    } else { /* child */
  205.  
  206.       mod = O_W;
  207.       if (!sec && (st_glob.c_security & CT_BASIC)) mod |= O_PRIVATE;
  208.  
  209.       if (sec) { /* cfadm to user */
  210.          if ((fsrc=mopen(src,O_R))==NULL) exit(1);
  211.          setuid(getuid());
  212.          setgid(getgid());
  213.          if ((fdest=mopen(dest,mod))==NULL) { 
  214.             mclose(fsrc); 
  215.             exit(1); 
  216.          }
  217.       } else {   /* user to cfadm */
  218.          if ((fdest=mopen(dest,mod))==NULL) exit(1);
  219.          setuid(getuid());
  220.          setgid(getgid());
  221.          if ((fsrc=mopen(src,O_R))==NULL) { 
  222.             mclose(fdest); 
  223.             exit(1); 
  224.          }
  225.       }
  226.  
  227.       while ((c=fgetc(fsrc))!=EOF)
  228.          fputc(c,fdest);
  229.       mclose(fdest);
  230.       mclose(fsrc);
  231.       exit(0);
  232.    }
  233.    return statusp;
  234. }
  235.  
  236. /******************************************************************************/
  237. /* INVOKE EDITOR ON A FILE                                                    */
  238. /******************************************************************************/
  239. int                   /* RETURNS: (nothing)            */
  240. edit(dir,file,visual) /* ARGUMENTS:                   */
  241. char *dir;            /*    Directory containing file */
  242. char *file;           /*    Filename to edit          */
  243. int   visual;         /*    Flag: visual editor?      */
  244. {
  245.    char buff[MAX_LINE_LENGTH];
  246.    char buff2[MAX_LINE_LENGTH];
  247.    char buff3[MAX_LINE_LENGTH];
  248.    struct stat st;
  249.  
  250.    if (file)
  251.       sprintf(buff3,"%s/%s",dir,file);
  252.    else
  253.       strcpy(buff3,dir);
  254.    
  255.    if (status & S_MOTIF) 
  256.       sprintf(buff2,"xterm -j -s -sb -sl 1024 -fn 9x15 -e ");
  257.    else
  258.       buff2[0]=0;
  259.    sprintf(buff,"%s%s %s", buff2, expand((visual)? "visual":"editor", DM_VAR), 
  260.     buff3);
  261.    unix_cmd(buff);
  262.    return !stat(buff3,&st);
  263. }
  264.