15d9e6103SBrian Somers /*- 25d9e6103SBrian Somers * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org> 35d9e6103SBrian Somers * All rights reserved. 45d9e6103SBrian Somers * 55d9e6103SBrian Somers * Redistribution and use in source and binary forms, with or without 65d9e6103SBrian Somers * modification, are permitted provided that the following conditions 75d9e6103SBrian Somers * are met: 85d9e6103SBrian Somers * 1. Redistributions of source code must retain the above copyright 95d9e6103SBrian Somers * notice, this list of conditions and the following disclaimer. 105d9e6103SBrian Somers * 2. Redistributions in binary form must reproduce the above copyright 115d9e6103SBrian Somers * notice, this list of conditions and the following disclaimer in the 125d9e6103SBrian Somers * documentation and/or other materials provided with the distribution. 135d9e6103SBrian Somers * 145d9e6103SBrian Somers * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 155d9e6103SBrian Somers * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165d9e6103SBrian Somers * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 175d9e6103SBrian Somers * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 185d9e6103SBrian Somers * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 195d9e6103SBrian Somers * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 205d9e6103SBrian Somers * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 215d9e6103SBrian Somers * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 225d9e6103SBrian Somers * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 235d9e6103SBrian Somers * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 245d9e6103SBrian Somers * SUCH DAMAGE. 255d9e6103SBrian Somers * 2644e73c12SBrian Somers * $Id: exec.c,v 1.7 1999/08/06 20:04:03 brian Exp $ 275d9e6103SBrian Somers */ 285d9e6103SBrian Somers 295d9e6103SBrian Somers #include <sys/param.h> 305d9e6103SBrian Somers #include <sys/socket.h> 315d9e6103SBrian Somers #include <sys/un.h> 325d9e6103SBrian Somers 335d9e6103SBrian Somers #include <errno.h> 345d9e6103SBrian Somers #include <fcntl.h> 355d9e6103SBrian Somers #include <stdio.h> 365d9e6103SBrian Somers #include <stdlib.h> 375d9e6103SBrian Somers #include <string.h> 385d9e6103SBrian Somers #include <sys/wait.h> 39f5a99677SBrian Somers #include <sys/uio.h> 405d9e6103SBrian Somers #include <termios.h> 415d9e6103SBrian Somers #include <unistd.h> 425d9e6103SBrian Somers 435d9e6103SBrian Somers #include "layer.h" 445d9e6103SBrian Somers #include "defs.h" 455d9e6103SBrian Somers #include "mbuf.h" 465d9e6103SBrian Somers #include "log.h" 475d9e6103SBrian Somers #include "timer.h" 485d9e6103SBrian Somers #include "lqr.h" 495d9e6103SBrian Somers #include "hdlc.h" 505d9e6103SBrian Somers #include "throughput.h" 515d9e6103SBrian Somers #include "fsm.h" 525d9e6103SBrian Somers #include "lcp.h" 535d9e6103SBrian Somers #include "ccp.h" 545d9e6103SBrian Somers #include "link.h" 555d9e6103SBrian Somers #include "async.h" 565d9e6103SBrian Somers #include "descriptor.h" 575d9e6103SBrian Somers #include "physical.h" 585d9e6103SBrian Somers #include "mp.h" 595d9e6103SBrian Somers #include "chat.h" 605d9e6103SBrian Somers #include "command.h" 615d9e6103SBrian Somers #include "auth.h" 625d9e6103SBrian Somers #include "chap.h" 635d9e6103SBrian Somers #include "cbcp.h" 645d9e6103SBrian Somers #include "datalink.h" 655d9e6103SBrian Somers #include "exec.h" 665d9e6103SBrian Somers 676815097bSBrian Somers static struct device execdevice = { 686815097bSBrian Somers EXEC_DEVICE, 696815097bSBrian Somers "exec", 706815097bSBrian Somers NULL, 716815097bSBrian Somers NULL, 726815097bSBrian Somers NULL, 736815097bSBrian Somers NULL, 746815097bSBrian Somers NULL, 756815097bSBrian Somers NULL, 766815097bSBrian Somers NULL, 776815097bSBrian Somers NULL, 786815097bSBrian Somers NULL, 79eb6e5e05SBrian Somers NULL, 806815097bSBrian Somers NULL 816815097bSBrian Somers }; 826815097bSBrian Somers 836815097bSBrian Somers struct device * 846815097bSBrian Somers exec_iov2device(int type, struct physical *p, struct iovec *iov, 856815097bSBrian Somers int *niov, int maxiov) 865d9e6103SBrian Somers { 87acbd1f00SBrian Somers if (type == EXEC_DEVICE) { 88f5a99677SBrian Somers free(iov[(*niov)++].iov_base); 89acbd1f00SBrian Somers physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC); 906815097bSBrian Somers return &execdevice; 91acbd1f00SBrian Somers } 926815097bSBrian Somers 936815097bSBrian Somers return NULL; 946815097bSBrian Somers } 956815097bSBrian Somers 966815097bSBrian Somers struct device * 976815097bSBrian Somers exec_Create(struct physical *p) 986815097bSBrian Somers { 996815097bSBrian Somers if (p->fd < 0 && *p->name.full == '!') { 1005d9e6103SBrian Somers int fids[2]; 1015d9e6103SBrian Somers 1025d9e6103SBrian Somers if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0) 1035d9e6103SBrian Somers log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", 1045d9e6103SBrian Somers strerror(errno)); 1055d9e6103SBrian Somers else { 10644e73c12SBrian Somers int stat, argc, i; 1078fb106c6SBrian Somers pid_t pid, realpid; 1085d9e6103SBrian Somers char *argv[MAXARGS]; 1095d9e6103SBrian Somers 1105d9e6103SBrian Somers stat = fcntl(fids[0], F_GETFL, 0); 1115d9e6103SBrian Somers if (stat > 0) { 1125d9e6103SBrian Somers stat |= O_NONBLOCK; 1135d9e6103SBrian Somers fcntl(fids[0], F_SETFL, stat); 1145d9e6103SBrian Somers } 1158fb106c6SBrian Somers realpid = getpid(); 1165d9e6103SBrian Somers switch ((pid = fork())) { 1175d9e6103SBrian Somers case -1: 1185d9e6103SBrian Somers log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", 1195d9e6103SBrian Somers strerror(errno)); 1205d9e6103SBrian Somers break; 1215d9e6103SBrian Somers 1225d9e6103SBrian Somers case 0: 1235d9e6103SBrian Somers close(fids[0]); 1245d9e6103SBrian Somers timer_TermService(); 1255d9e6103SBrian Somers setuid(geteuid()); 1265d9e6103SBrian Somers 1275d9e6103SBrian Somers switch (fork()) { 1285d9e6103SBrian Somers case 0: 1295d9e6103SBrian Somers break; 1305d9e6103SBrian Somers 1315d9e6103SBrian Somers case -1: 1325d9e6103SBrian Somers log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n", 1335d9e6103SBrian Somers strerror(errno)); 1345d9e6103SBrian Somers default: 1355d9e6103SBrian Somers _exit(127); 1365d9e6103SBrian Somers } 1375d9e6103SBrian Somers 13844e73c12SBrian Somers log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base); 13944e73c12SBrian Somers 1405d9e6103SBrian Somers dup2(fids[1], STDIN_FILENO); 1415d9e6103SBrian Somers dup2(fids[1], STDOUT_FILENO); 1425d9e6103SBrian Somers dup2(fids[1], STDERR_FILENO); 14344e73c12SBrian Somers for (i = getdtablesize(); i > STDERR_FILENO; i--) 14444e73c12SBrian Somers fcntl(i, F_SETFD, 1); 1455d9e6103SBrian Somers 1465d9e6103SBrian Somers argc = MakeArgs(p->name.base, argv, VECSIZE(argv)); 1475d9e6103SBrian Somers command_Expand(argv, argc, (char const *const *)argv, 1488fb106c6SBrian Somers p->dl->bundle, 0, realpid); 1495d9e6103SBrian Somers execvp(*argv, argv); 15044e73c12SBrian Somers printf("execvp failed: %s: %s\r\n", *argv, strerror(errno)); 1515d9e6103SBrian Somers _exit(127); 1525d9e6103SBrian Somers break; 1535d9e6103SBrian Somers 1545d9e6103SBrian Somers default: 1555d9e6103SBrian Somers close(fids[1]); 1565d9e6103SBrian Somers p->fd = fids[0]; 1575d9e6103SBrian Somers waitpid(pid, &stat, 0); 1585d9e6103SBrian Somers log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); 159acbd1f00SBrian Somers physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC); 1606815097bSBrian Somers return &execdevice; 1615d9e6103SBrian Somers } 1625d9e6103SBrian Somers } 1635d9e6103SBrian Somers } 1645d9e6103SBrian Somers 1656815097bSBrian Somers return NULL; 1665d9e6103SBrian Somers } 167