home *** CD-ROM | disk | FTP | other *** search
- /* SYSTEM.C - Dave Thaler 3/1/93
- * This file does secure replacements for popen and system calls
- */
- static char sccsid[] = "@(#)system.c 1.17 93/06/09 Copyright (c)1993 thalerd";
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <signal.h>
- /*
- #include <fcntl.h>
- #include <sys/socket.h>
- */
- #include "config.h"
- #include "struct.h"
- #include "lib.h"
- #include "xalloc.h"
- #include "macro.h"
- #include "globals.h"
- #include "files.h"
-
- /******************************************************************************/
- /* SECURE popen() - OPEN A PIPE TO A PROCESS */
- /******************************************************************************/
- FILE * /* RETURNS: file pointer of pipe */
- spopen(cmd) /* ARGUMENTS: */
- char *cmd; /* Command to pipe to */
- {
- int fd[2],s;
- char **argv;
- FILE *fp;
-
- if (status & S_REDIRECT) {
- printf("UNK Error, pipe already open\n");
- }
-
- if (pipe(fd)<0) return NULL;
- if ((fp=fdopen(fd[1],"w"))==NULL) return NULL;
-
- /* The following two lines are not necessary, and even slow the program
- * down, but make seen be more accurate in some cases, since less info is
- * buffered by the pager.
- */
- /* fcntl(fd[1], F_SETFL, O_SYNC);
- setsockopt(fd[1],SOL_SOCKET, SO_SNDBUF, 4, 1);
- */
-
- if (s=fork()) { /* parent */
- if (s<0) return NULL; /* error: couldn't fork */
- close(fd[0]);
- status |= S_PIPE|S_REDIRECT;
- madd(fd[1],cmd,O_PIPE);
- return fp;
- } else { /* child */
- setuid(getuid());
- setgid(getgid());
- signal(SIGINT,SIG_DFL);
- signal(SIGPIPE,SIG_DFL);
- close(0);
- dup(fd[0]);
- close(fd[1]);
-
- if (strpbrk(cmd,"<>*?|![]{}~`$&';\\\"") == NULL) {
- argv = explode(cmd," ");
- s = xsizeof(argv);
- argv = xrealloc(argv, (short)(s+1));
- argv[s]=0;
- execvp(argv[0],argv);
- printf("oops: Can't execute \"%s\"!\n",cmd);
- } else {
- char *shpath,*sh;
-
- shpath = expand("shell",DM_VAR);
- sh = strrchr(shpath,'/');
- if (!sh) sh = shpath;
- else sh++;
- execl(shpath,sh,"-c",cmd,(char *)NULL);
- }
- exit(1);
- }
- return NULL;
- }
-
- /******************************************************************************/
- /* DUMP A STRING TO A SECURE PIPE */
- /******************************************************************************/
- int /* RETURNS: # bytes written */
- spout(fd,buff) /* ARGUMENTS: */
- int fd; /* File descriptor of pipe */
- char *buff; /* String to dump */
- {
- return write(fd,buff,strlen(buff));
- }
-
- /******************************************************************************/
- /* CLOSE A SECURE PIPE */
- /******************************************************************************/
- int /* RETURNS: error code */
- spclose(pp) /* ARGUMENTS: */
- FILE *pp; /* File pointer to close */
- {
- int i;
- int statusp;
-
- if (!(status & S_REDIRECT)) {
- printf("UNK Error, pipe not open\n");
- }
-
- i=mclose(pp);
- if (status & S_PIPE)
- wait(&statusp);
- status &= ~(S_PIPE|S_REDIRECT|S_INT);
- return i;
- }
-
- /******************************************************************************/
- /* SECURE system() - EXECUTE A UNIX COMMAND */
- /******************************************************************************/
- int /* RETURNS: exit status of command */
- unix_cmd(cmd) /* ARGUMENTS: */
- char *cmd; /* Command to execute */
- {
- char **argv;
- short s;
- register int cpid,wpid;
- int statusp;
-
- if (cpid=fork()) { /* parent */
- if (cpid<0) return -1; /* error: couldn't fork */
- while ((wpid = wait(&statusp)) != cpid && wpid != -1);
- } else { /* child */
- setuid(getuid());
- setgid(getgid());
- signal(SIGINT,SIG_DFL);
- signal(SIGPIPE,SIG_DFL);
- if (strpbrk(cmd,"<>*?|![]{}~`$&';\\\"") == NULL) {
- argv = explode(cmd," ");
- s = xsizeof(argv);
- argv = xrealloc(argv, (short)(s+1));
- argv[s]=0;
- execvp(argv[0],argv);
- printf("oops: Can't execute \"%s\"!\n",cmd);
- } else {
- char *shpath,*sh;
-
- shpath = expand("shell",DM_VAR);
- sh = strrchr(shpath,'/');
- if (!sh) sh = shpath;
- else sh++;
- execl(shpath,sh,"-c",cmd,(char *)NULL);
- }
- exit(1);
- }
- return statusp;
- }
-
- /******************************************************************************/
- /* REMOVE A FILE */
- /******************************************************************************/
- int /* RETURNS: error code */
- rm(file,sec) /* ARGUMENTS: */
- char *file;
- int sec; /* As owner(0) or user(1)? */
- {
- int c;
- register int cpid,wpid;
- int statusp;
-
- if (!sec) {
- statusp=unlink(file);
- } else {
- if (cpid=fork()) { /* parent */
- if (cpid<0) return -1; /* error: couldn't fork */
- while ((wpid = wait(&statusp)) != cpid && wpid != -1);
- } else { /* child */
- setuid(getuid());
- setgid(getgid());
- exit(unlink(file));
- }
- }
- if (statusp) error("removing ",file);
- return statusp;
- }
-
- /******************************************************************************/
- /* SECURELY COPY ONE FILE TO ANOTHER */
- /******************************************************************************/
- int /* RETURNS: error code */
- copy_file(src,dest,sec) /* ARGUMENTS: */
- char *src; /* Source file */
- char *dest; /* Destination file */
- int sec; /* As owner(0) or user(1)? */
- {
- FILE *fsrc,*fdest;
- int c;
- register int cpid,wpid;
- int statusp;
- long mod;
-
- if (cpid=fork()) { /* parent */
- if (cpid<0) return -1; /* error: couldn't fork */
- while ((wpid = wait(&statusp)) != cpid && wpid != -1);
- } else { /* child */
-
- mod = O_W;
- if (!sec && (st_glob.c_security & CT_BASIC)) mod |= O_PRIVATE;
-
- if (sec) { /* cfadm to user */
- if ((fsrc=mopen(src,O_R))==NULL) exit(1);
- setuid(getuid());
- setgid(getgid());
- if ((fdest=mopen(dest,mod))==NULL) {
- mclose(fsrc);
- exit(1);
- }
- } else { /* user to cfadm */
- if ((fdest=mopen(dest,mod))==NULL) exit(1);
- setuid(getuid());
- setgid(getgid());
- if ((fsrc=mopen(src,O_R))==NULL) {
- mclose(fdest);
- exit(1);
- }
- }
-
- while ((c=fgetc(fsrc))!=EOF)
- fputc(c,fdest);
- mclose(fdest);
- mclose(fsrc);
- exit(0);
- }
- return statusp;
- }
-
- /******************************************************************************/
- /* INVOKE EDITOR ON A FILE */
- /******************************************************************************/
- int /* RETURNS: (nothing) */
- edit(dir,file,visual) /* ARGUMENTS: */
- char *dir; /* Directory containing file */
- char *file; /* Filename to edit */
- int visual; /* Flag: visual editor? */
- {
- char buff[MAX_LINE_LENGTH];
- char buff2[MAX_LINE_LENGTH];
- char buff3[MAX_LINE_LENGTH];
- struct stat st;
-
- if (file)
- sprintf(buff3,"%s/%s",dir,file);
- else
- strcpy(buff3,dir);
-
- if (status & S_MOTIF)
- sprintf(buff2,"xterm -j -s -sb -sl 1024 -fn 9x15 -e ");
- else
- buff2[0]=0;
- sprintf(buff,"%s%s %s", buff2, expand((visual)? "visual":"editor", DM_VAR),
- buff3);
- unix_cmd(buff);
- return !stat(buff3,&st);
- }
-