exec.c revision 47461
146686Sbrian/*- 246686Sbrian * Copyright (c) 1999 Brian Somers <brian@Awfulhak.org> 346686Sbrian * All rights reserved. 446686Sbrian * 546686Sbrian * Redistribution and use in source and binary forms, with or without 646686Sbrian * modification, are permitted provided that the following conditions 746686Sbrian * are met: 846686Sbrian * 1. Redistributions of source code must retain the above copyright 946686Sbrian * notice, this list of conditions and the following disclaimer. 1046686Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1146686Sbrian * notice, this list of conditions and the following disclaimer in the 1246686Sbrian * documentation and/or other materials provided with the distribution. 1346686Sbrian * 1446686Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1546686Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1646686Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1746686Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1846686Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1946686Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2046686Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2146686Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2246686Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2346686Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2446686Sbrian * SUCH DAMAGE. 2546686Sbrian * 2647461Sbrian * $Id: exec.c,v 1.2 1999/05/12 09:48:49 brian Exp $ 2746686Sbrian */ 2846686Sbrian 2946686Sbrian#include <sys/param.h> 3046686Sbrian#include <sys/socket.h> 3146686Sbrian#include <netinet/in.h> 3246686Sbrian#include <arpa/inet.h> 3346686Sbrian#include <netdb.h> 3446686Sbrian#include <netinet/in_systm.h> 3546686Sbrian#include <netinet/ip.h> 3646686Sbrian#include <sys/un.h> 3746686Sbrian 3846686Sbrian#include <errno.h> 3946686Sbrian#include <fcntl.h> 4046686Sbrian#include <stdio.h> 4146686Sbrian#include <stdlib.h> 4246686Sbrian#include <string.h> 4346686Sbrian#include <sys/wait.h> 4446686Sbrian#include <termios.h> 4546686Sbrian#include <unistd.h> 4646686Sbrian 4746686Sbrian#include "layer.h" 4846686Sbrian#include "defs.h" 4946686Sbrian#include "mbuf.h" 5046686Sbrian#include "log.h" 5146686Sbrian#include "sync.h" 5246686Sbrian#include "timer.h" 5346686Sbrian#include "lqr.h" 5446686Sbrian#include "hdlc.h" 5546686Sbrian#include "throughput.h" 5646686Sbrian#include "fsm.h" 5746686Sbrian#include "lcp.h" 5846686Sbrian#include "ccp.h" 5946686Sbrian#include "link.h" 6046686Sbrian#include "async.h" 6146686Sbrian#include "slcompress.h" 6246686Sbrian#include "iplist.h" 6346686Sbrian#include "ipcp.h" 6446686Sbrian#include "filter.h" 6546686Sbrian#include "descriptor.h" 6646686Sbrian#include "physical.h" 6746686Sbrian#include "mp.h" 6846686Sbrian#ifndef NORADIUS 6946686Sbrian#include "radius.h" 7046686Sbrian#endif 7146686Sbrian#include "chat.h" 7246686Sbrian#include "command.h" 7346686Sbrian#include "bundle.h" 7446686Sbrian#include "prompt.h" 7546686Sbrian#include "auth.h" 7646686Sbrian#include "chap.h" 7746686Sbrian#include "cbcp.h" 7846686Sbrian#include "datalink.h" 7946686Sbrian#include "exec.h" 8046686Sbrian 8147061Sbrianstatic struct device execdevice = { 8247061Sbrian EXEC_DEVICE, 8347061Sbrian "exec", 8447061Sbrian NULL, 8547061Sbrian NULL, 8647061Sbrian NULL, 8747061Sbrian NULL, 8847061Sbrian NULL, 8947061Sbrian NULL, 9047061Sbrian NULL, 9147061Sbrian NULL, 9247061Sbrian NULL, 9347061Sbrian NULL 9447061Sbrian}; 9547061Sbrian 9647061Sbrianstruct device * 9747061Sbrianexec_iov2device(int type, struct physical *p, struct iovec *iov, 9847061Sbrian int *niov, int maxiov) 9946686Sbrian{ 10047461Sbrian if (type == EXEC_DEVICE) { 10147461Sbrian physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC); 10247061Sbrian return &execdevice; 10347461Sbrian } 10447061Sbrian 10547061Sbrian return NULL; 10647061Sbrian} 10747061Sbrian 10847061Sbrianstruct device * 10947061Sbrianexec_Create(struct physical *p) 11047061Sbrian{ 11147061Sbrian if (p->fd < 0 && *p->name.full == '!') { 11246686Sbrian int fids[2]; 11346686Sbrian 11446686Sbrian if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0) 11546686Sbrian log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", 11646686Sbrian strerror(errno)); 11746686Sbrian else { 11846686Sbrian int stat, argc; 11946686Sbrian pid_t pid; 12046686Sbrian char *argv[MAXARGS]; 12146686Sbrian 12246686Sbrian stat = fcntl(fids[0], F_GETFL, 0); 12346686Sbrian if (stat > 0) { 12446686Sbrian stat |= O_NONBLOCK; 12546686Sbrian fcntl(fids[0], F_SETFL, stat); 12646686Sbrian } 12746686Sbrian switch ((pid = fork())) { 12846686Sbrian case -1: 12946686Sbrian log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n", 13046686Sbrian strerror(errno)); 13146686Sbrian break; 13246686Sbrian 13346686Sbrian case 0: 13446686Sbrian close(fids[0]); 13546686Sbrian timer_TermService(); 13646686Sbrian setuid(geteuid()); 13746686Sbrian 13846686Sbrian switch (fork()) { 13946686Sbrian case 0: 14046686Sbrian break; 14146686Sbrian 14246686Sbrian case -1: 14346686Sbrian log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n", 14446686Sbrian strerror(errno)); 14546686Sbrian default: 14646686Sbrian _exit(127); 14746686Sbrian } 14846686Sbrian 14946686Sbrian fids[1] = fcntl(fids[1], F_DUPFD, 3); 15046686Sbrian dup2(fids[1], STDIN_FILENO); 15146686Sbrian dup2(fids[1], STDOUT_FILENO); 15246686Sbrian dup2(fids[1], STDERR_FILENO); 15346686Sbrian 15446686Sbrian argc = MakeArgs(p->name.base, argv, VECSIZE(argv)); 15546686Sbrian command_Expand(argv, argc, (char const *const *)argv, 15646686Sbrian p->dl->bundle, 0); 15746686Sbrian execvp(*argv, argv); 15846686Sbrian fprintf(stderr, "execvp failed: %s: %s\r\n", *argv, strerror(errno)); 15946686Sbrian _exit(127); 16046686Sbrian break; 16146686Sbrian 16246686Sbrian default: 16346686Sbrian close(fids[1]); 16446686Sbrian p->fd = fids[0]; 16546686Sbrian waitpid(pid, &stat, 0); 16646686Sbrian log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd); 16747461Sbrian physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC); 16847061Sbrian return &execdevice; 16946686Sbrian } 17046686Sbrian } 17146686Sbrian } 17246686Sbrian 17347061Sbrian return NULL; 17446686Sbrian} 175