xref: /freebsd/usr.sbin/ppp/exec.c (revision fdc29d54a48f371bfc1c3af8a6dff0450b6523d0)
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  *
2697d92980SPeter Wemm  * $FreeBSD$
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",
70fdc29d54SBrian Somers   { CD_NOTREQUIRED, 0 },
716815097bSBrian Somers   NULL,
726815097bSBrian Somers   NULL,
736815097bSBrian Somers   NULL,
746815097bSBrian Somers   NULL,
756815097bSBrian Somers   NULL,
766815097bSBrian Somers   NULL,
776815097bSBrian Somers   NULL,
786815097bSBrian Somers   NULL,
796815097bSBrian Somers   NULL,
80eb6e5e05SBrian Somers   NULL,
8187c3786eSBrian Somers   NULL,
826815097bSBrian Somers   NULL
836815097bSBrian Somers };
846815097bSBrian Somers 
856815097bSBrian Somers struct device *
866815097bSBrian Somers exec_iov2device(int type, struct physical *p, struct iovec *iov,
8787c3786eSBrian Somers                 int *niov, int maxiov, int *auxfd, int *nauxfd)
885d9e6103SBrian Somers {
89acbd1f00SBrian Somers   if (type == EXEC_DEVICE) {
90f5a99677SBrian Somers     free(iov[(*niov)++].iov_base);
91acbd1f00SBrian Somers     physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC);
926815097bSBrian Somers     return &execdevice;
93acbd1f00SBrian Somers   }
946815097bSBrian Somers 
956815097bSBrian Somers   return NULL;
966815097bSBrian Somers }
976815097bSBrian Somers 
986815097bSBrian Somers struct device *
996815097bSBrian Somers exec_Create(struct physical *p)
1006815097bSBrian Somers {
1016815097bSBrian Somers   if (p->fd < 0 && *p->name.full == '!') {
1025d9e6103SBrian Somers     int fids[2];
1035d9e6103SBrian Somers 
10487c3786eSBrian Somers     p->fd--;	/* We own the device but maybe can't use it - change fd */
10587c3786eSBrian Somers 
1065d9e6103SBrian Somers     if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0)
1075d9e6103SBrian Somers       log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
1085d9e6103SBrian Somers 	         strerror(errno));
1095d9e6103SBrian Somers     else {
11044e73c12SBrian Somers       int stat, argc, i;
1118fb106c6SBrian Somers       pid_t pid, realpid;
1125d9e6103SBrian Somers       char *argv[MAXARGS];
1135d9e6103SBrian Somers 
1145d9e6103SBrian Somers       stat = fcntl(fids[0], F_GETFL, 0);
1155d9e6103SBrian Somers       if (stat > 0) {
1165d9e6103SBrian Somers         stat |= O_NONBLOCK;
1175d9e6103SBrian Somers         fcntl(fids[0], F_SETFL, stat);
1185d9e6103SBrian Somers       }
1198fb106c6SBrian Somers       realpid = getpid();
1205d9e6103SBrian Somers       switch ((pid = fork())) {
1215d9e6103SBrian Somers         case -1:
1225d9e6103SBrian Somers           log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
1235d9e6103SBrian Somers 	             strerror(errno));
1245d9e6103SBrian Somers           break;
1255d9e6103SBrian Somers 
1265d9e6103SBrian Somers         case  0:
1275d9e6103SBrian Somers           close(fids[0]);
1285d9e6103SBrian Somers           timer_TermService();
1295d9e6103SBrian Somers           setuid(geteuid());
1305d9e6103SBrian Somers 
1315d9e6103SBrian Somers           switch (fork()) {
1325d9e6103SBrian Somers             case 0:
1335d9e6103SBrian Somers               break;
1345d9e6103SBrian Somers 
1355d9e6103SBrian Somers             case -1:
1365d9e6103SBrian Somers               log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n",
1375d9e6103SBrian Somers 	                 strerror(errno));
1385d9e6103SBrian Somers             default:
1395d9e6103SBrian Somers               _exit(127);
1405d9e6103SBrian Somers           }
1415d9e6103SBrian Somers 
14244e73c12SBrian Somers           log_Printf(LogDEBUG, "Exec'ing ``%s''\n", p->name.base);
14344e73c12SBrian Somers 
1445d9e6103SBrian Somers           dup2(fids[1], STDIN_FILENO);
1455d9e6103SBrian Somers           dup2(fids[1], STDOUT_FILENO);
1465d9e6103SBrian Somers           dup2(fids[1], STDERR_FILENO);
14744e73c12SBrian Somers           for (i = getdtablesize(); i > STDERR_FILENO; i--)
14844e73c12SBrian Somers             fcntl(i, F_SETFD, 1);
1495d9e6103SBrian Somers 
1505d9e6103SBrian Somers           argc = MakeArgs(p->name.base, argv, VECSIZE(argv));
1515d9e6103SBrian Somers           command_Expand(argv, argc, (char const *const *)argv,
1528fb106c6SBrian Somers                          p->dl->bundle, 0, realpid);
1535d9e6103SBrian Somers           execvp(*argv, argv);
15444e73c12SBrian Somers           printf("execvp failed: %s: %s\r\n", *argv, strerror(errno));
1555d9e6103SBrian Somers           _exit(127);
1565d9e6103SBrian Somers           break;
1575d9e6103SBrian Somers 
1585d9e6103SBrian Somers         default:
1595d9e6103SBrian Somers           close(fids[1]);
1605d9e6103SBrian Somers           p->fd = fids[0];
1615d9e6103SBrian Somers           waitpid(pid, &stat, 0);
1625d9e6103SBrian Somers           log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd);
163acbd1f00SBrian Somers           physical_SetupStack(p, execdevice.name, PHYSICAL_FORCE_ASYNC);
164fdc29d54SBrian Somers           if (p->cfg.cd.necessity != CD_DEFAULT)
165fdc29d54SBrian Somers             log_Printf(LogWARN, "Carrier settings ignored\n");
1666815097bSBrian Somers           return &execdevice;
1675d9e6103SBrian Somers       }
1685d9e6103SBrian Somers     }
1695d9e6103SBrian Somers   }
1705d9e6103SBrian Somers 
1716815097bSBrian Somers   return NULL;
1725d9e6103SBrian Somers }
173