1 /*
2 * main.c - Point-to-Point Protocol main module
3 *
4 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The name "Carnegie Mellon University" must not be used to
19 * endorse or promote products derived from this software without
20 * prior written permission. For permission or any legal
21 * details, please contact
22 * Office of Technology Transfer
23 * Carnegie Mellon University
24 * 5000 Forbes Avenue
25 * Pittsburgh, PA 15213-3890
26 * (412) 268-4387, fax: (412) 268-7395
27 * tech-transfer@andrew.cmu.edu
28 *
29 * 4. Redistributions of any form whatsoever must retain the following
30 * acknowledgment:
31 * "This product includes software developed by Computing Services
32 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
33 *
34 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
35 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
37 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
38 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
39 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
40 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
41 *
42 * Copyright (c) 1999-2004 Paul Mackerras. All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 *
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 *
51 * 2. The name(s) of the authors of this software must not be used to
52 * endorse or promote products derived from this software without
53 * prior written permission.
54 *
55 * 3. Redistributions of any form whatsoever must retain the following
56 * acknowledgment:
57 * "This product includes software developed by Paul Mackerras
58 * <paulus@samba.org>".
59 *
60 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
61 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
62 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
63 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
64 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
65 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
66 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
67 */
68
69 #define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $"
70
71 #include <stdio.h>
72 #include <ctype.h>
73 #include <stdlib.h>
74 #include <string.h>
75 #include <unistd.h>
76 #include <signal.h>
77 #include <errno.h>
78 #include <fcntl.h>
79 #include <syslog.h>
80 #include <netdb.h>
81 #include <utmp.h>
82 #include <pwd.h>
83 #include <setjmp.h>
84 #include <sys/param.h>
85 #include <sys/types.h>
86 #include <sys/wait.h>
87 #include <sys/time.h>
88 #include <sys/resource.h>
89 #include <sys/stat.h>
90 #include <sys/socket.h>
91 #include <netinet/in.h>
92 #include <arpa/inet.h>
93
94 #include "pppd.h"
95 #include "magic.h"
96 #include "fsm.h"
97 #include "lcp.h"
98 #include "ipcp.h"
99 #ifdef INET6
100 #include "ipv6cp.h"
101 #endif
102 #include "upap.h"
103 #include "chap-new.h"
104 #include "eap.h"
105 #include "ccp.h"
106 #include "ecp.h"
107 #include "pathnames.h"
108
109 #ifdef USE_TDB
110 #include "tdb.h"
111 #endif
112
113 #ifdef CBCP_SUPPORT
114 #include "cbcp.h"
115 #endif
116
117 #ifdef IPX_CHANGE
118 #include "ipxcp.h"
119 #endif /* IPX_CHANGE */
120 #ifdef AT_CHANGE
121 #include "atcp.h"
122 #endif
123
124 static const char rcsid[] = RCSID;
125
126 /* interface vars */
127 char ifname[32]; /* Interface name */
128 int ifunit; /* Interface unit number */
129
130 struct channel *the_channel;
131
132 char *progname; /* Name of this program */
133 char hostname[MAXNAMELEN]; /* Our hostname */
134 static char pidfilename[MAXPATHLEN]; /* name of pid file */
135 static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */
136 char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */
137 uid_t uid; /* Our real user-id */
138 struct notifier *pidchange = NULL;
139 struct notifier *phasechange = NULL;
140 struct notifier *exitnotify = NULL;
141 struct notifier *sigreceived = NULL;
142 struct notifier *fork_notifier = NULL;
143
144 int hungup; /* terminal has been hung up */
145 int privileged; /* we're running as real uid root */
146 int need_holdoff; /* need holdoff period before restarting */
147 int detached; /* have detached from terminal */
148 volatile int status; /* exit status for pppd */
149 int unsuccess; /* # unsuccessful connection attempts */
150 int do_callback; /* != 0 if we should do callback next */
151 int doing_callback; /* != 0 if we are doing callback */
152 int ppp_session_number; /* Session number, for channels with such a
153 concept (eg PPPoE) */
154 int childwait_done; /* have timed out waiting for children */
155
156 #ifdef USE_TDB
157 TDB_CONTEXT *pppdb; /* database for storing status etc. */
158 #endif
159
160 char db_key[32];
161
162 int (*holdoff_hook) __P((void)) = NULL;
163 int (*new_phase_hook) __P((int)) = NULL;
164 void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL;
165 void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL;
166
167 static int conn_running; /* we have a [dis]connector running */
168 static int fd_loop; /* fd for getting demand-dial packets */
169
170 int fd_devnull; /* fd for /dev/null */
171 int devfd = -1; /* fd of underlying device */
172 int fd_ppp = -1; /* fd for talking PPP */
173 int phase; /* where the link is at */
174 int kill_link;
175 int asked_to_quit;
176 int open_ccp_flag;
177 int listen_time;
178 int got_sigusr2;
179 int got_sigterm;
180 int got_sighup;
181
182 static sigset_t signals_handled;
183 static int waiting;
184 static sigjmp_buf sigjmp;
185
186 char **script_env; /* Env. variable values for scripts */
187 int s_env_nalloc; /* # words avail at script_env */
188
189 u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
190 u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
191
192 static int n_children; /* # child processes still running */
193 static int got_sigchld; /* set if we have received a SIGCHLD */
194
195 int privopen; /* don't lock, open device as root */
196
197 char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
198
199 GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */
200 int ngroups; /* How many groups valid in groups */
201
202 static struct timeval start_time; /* Time when link was started. */
203
204 static struct pppd_stats old_link_stats;
205 struct pppd_stats link_stats;
206 unsigned link_connect_time;
207 int link_stats_valid;
208
209 int error_count;
210
211 bool bundle_eof;
212 bool bundle_terminating;
213
214 /*
215 * We maintain a list of child process pids and
216 * functions to call when they exit.
217 */
218 struct subprocess {
219 pid_t pid;
220 char *prog;
221 void (*done) __P((void *));
222 void *arg;
223 int killable;
224 struct subprocess *next;
225 };
226
227 static struct subprocess *children;
228
229 /* Prototypes for procedures local to this file. */
230
231 static void setup_signals __P((void));
232 static void create_pidfile __P((int pid));
233 static void create_linkpidfile __P((int pid));
234 static void cleanup __P((void));
235 static void get_input __P((void));
236 static void calltimeout __P((void));
237 static struct timeval *timeleft __P((struct timeval *));
238 static void kill_my_pg __P((int));
239 static void hup __P((int));
240 static void term __P((int));
241 static void chld __P((int));
242 static void toggle_debug __P((int));
243 static void open_ccp __P((int));
244 static void bad_signal __P((int));
245 static void holdoff_end __P((void *));
246 static void forget_child __P((int pid, int status));
247 static int reap_kids __P((void));
248 static void childwait_end __P((void *));
249
250 #ifdef USE_TDB
251 static void update_db_entry __P((void));
252 static void add_db_key __P((const char *));
253 static void delete_db_key __P((const char *));
254 static void cleanup_db __P((void));
255 #endif
256
257 static void handle_events __P((void));
258 void print_link_stats __P((void));
259
260 extern char *ttyname __P((int));
261 extern char *getlogin __P((void));
262 int main __P((int, char *[]));
263
264 #ifdef ultrix
265 #undef O_NONBLOCK
266 #define O_NONBLOCK O_NDELAY
267 #endif
268
269 #ifdef ULTRIX
270 #define setlogmask(x)
271 #endif
272
273 /*
274 * PPP Data Link Layer "protocol" table.
275 * One entry per supported protocol.
276 * The last entry must be NULL.
277 */
278 struct protent *protocols[] = {
279 &lcp_protent,
280 &pap_protent,
281 &chap_protent,
282 #ifdef CBCP_SUPPORT
283 &cbcp_protent,
284 #endif
285 &ipcp_protent,
286 #ifdef INET6
287 &ipv6cp_protent,
288 #endif
289 &ccp_protent,
290 &ecp_protent,
291 #ifdef IPX_CHANGE
292 &ipxcp_protent,
293 #endif
294 #ifdef AT_CHANGE
295 &atcp_protent,
296 #endif
297 &eap_protent,
298 NULL
299 };
300
301 /*
302 * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name.
303 */
304 #if !defined(PPP_DRV_NAME)
305 #define PPP_DRV_NAME "ppp"
306 #endif /* !defined(PPP_DRV_NAME) */
307
308 int
main(argc,argv)309 main(argc, argv)
310 int argc;
311 char *argv[];
312 {
313 int i, t;
314 char *p;
315 struct passwd *pw;
316 struct protent *protp;
317 char numbuf[16];
318
319 link_stats_valid = 0;
320 new_phase(PHASE_INITIALIZE);
321
322 script_env = NULL;
323
324 /* Initialize syslog facilities */
325 reopen_log();
326
327 if (gethostname(hostname, MAXNAMELEN) < 0 ) {
328 option_error("Couldn't get hostname: %m");
329 exit(1);
330 }
331 hostname[MAXNAMELEN-1] = 0;
332
333 /* make sure we don't create world or group writable files. */
334 umask(umask(0777) | 022);
335
336 uid = getuid();
337 privileged = uid == 0;
338 slprintf(numbuf, sizeof(numbuf), "%d", uid);
339 script_setenv("ORIG_UID", numbuf, 0);
340
341 ngroups = getgroups(NGROUPS_MAX, groups);
342
343 /*
344 * Initialize magic number generator now so that protocols may
345 * use magic numbers in initialization.
346 */
347 magic_init();
348
349 /*
350 * Initialize each protocol.
351 */
352 for (i = 0; (protp = protocols[i]) != NULL; ++i)
353 (*protp->init)(0);
354
355 /*
356 * Initialize the default channel.
357 */
358 tty_init();
359
360 progname = *argv;
361
362 #if defined(__ANDROID__)
363 {
364 extern void pppox_init();
365 pppox_init();
366 privileged = 1;
367 }
368 {
369 char *envargs = getenv("envargs");
370 if (envargs) {
371 int i;
372 /* Decode the arguments in-place and count the number of them.
373 * They were hex encoded using [A-P] instead of [0-9A-F]. */
374 for (argc = 0, i = 0; envargs[i] && envargs[i + 1]; i += 2) {
375 char c = ((envargs[i] - 'A') << 4) + (envargs[i + 1] - 'A');
376 if (c == 0) {
377 ++argc;
378 }
379 envargs[i / 2 + 1] = c;
380 }
381 if (argc == 0 || (argv = malloc(sizeof(char *) * argc)) == NULL) {
382 fatal("Failed to parse envargs!");
383 }
384 for (envargs[0] = 0, i = 0; i < argc; ++envargs) {
385 if (envargs[0] == 0) {
386 argv[i++] = &envargs[1];
387 }
388 }
389 }
390 }
391 #endif
392
393 /*
394 * Parse, in order, the system options file, the user's options file,
395 * and the command line arguments.
396 */
397 #if defined(__ANDROID__)
398 /* Android: only take options from commandline */
399 if (!parse_args(argc-1, argv+1))
400 exit(EXIT_OPTION_ERROR);
401
402 #else
403 if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1)
404 || !options_from_user()
405 || !parse_args(argc-1, argv+1))
406 exit(EXIT_OPTION_ERROR);
407
408 #endif
409
410 devnam_fixed = 1; /* can no longer change device name */
411
412 /*
413 * Work out the device name, if it hasn't already been specified,
414 * and parse the tty's options file.
415 */
416 if (the_channel->process_extra_options)
417 (*the_channel->process_extra_options)();
418
419 if (debug)
420 setlogmask(LOG_UPTO(LOG_DEBUG));
421
422 #if !defined(__ANDROID__)
423 /*
424 * Check that we are running as root.
425 */
426 if (geteuid() != 0) {
427 option_error("must be root to run %s, since it is not setuid-root",
428 argv[0]);
429 exit(EXIT_NOT_ROOT);
430 }
431 #endif
432
433 if (!ppp_available()) {
434 option_error("%s", no_ppp_msg);
435 exit(EXIT_NO_KERNEL_SUPPORT);
436 }
437
438 /*
439 * Check that the options given are valid and consistent.
440 */
441 check_options();
442 if (!sys_check_options())
443 exit(EXIT_OPTION_ERROR);
444 auth_check_options();
445 #ifdef HAVE_MULTILINK
446 mp_check_options();
447 #endif
448 for (i = 0; (protp = protocols[i]) != NULL; ++i)
449 if (protp->check_options != NULL)
450 (*protp->check_options)();
451 if (the_channel->check_options)
452 (*the_channel->check_options)();
453
454
455 if (dump_options || dryrun) {
456 init_pr_log(NULL, LOG_INFO);
457 print_options(pr_log, NULL);
458 end_pr_log();
459 }
460
461 if (dryrun)
462 die(0);
463
464 /* Make sure fds 0, 1, 2 are open to somewhere. */
465 fd_devnull = open(_PATH_DEVNULL, O_RDWR);
466 if (fd_devnull < 0)
467 fatal("Couldn't open %s: %m", _PATH_DEVNULL);
468 while (fd_devnull <= 2) {
469 i = dup(fd_devnull);
470 if (i < 0)
471 fatal("Critical shortage of file descriptors: dup failed: %m");
472 fd_devnull = i;
473 }
474
475 /*
476 * Initialize system-dependent stuff.
477 */
478 sys_init();
479 #ifdef USE_TDB
480 pppdb = tdb_open(_PATH_PPPDB, 0, 0, O_RDWR|O_CREAT, 0644);
481 if (pppdb != NULL) {
482 slprintf(db_key, sizeof(db_key), "pppd%d", getpid());
483 update_db_entry();
484 } else {
485 warn("Warning: couldn't open ppp database %s", _PATH_PPPDB);
486 if (multilink) {
487 warn("Warning: disabling multilink");
488 multilink = 0;
489 }
490 }
491 #endif
492
493 /*
494 * Detach ourselves from the terminal, if required,
495 * and identify who is running us.
496 */
497 if (!nodetach && !updetach)
498 detach();
499 p = getlogin();
500 if (p == NULL) {
501 pw = getpwuid(uid);
502 if (pw != NULL && pw->pw_name != NULL)
503 p = pw->pw_name;
504 else
505 p = "(unknown)";
506 }
507 syslog(LOG_NOTICE, "pppd %s started by %s, uid %d", VERSION, p, uid);
508 script_setenv("PPPLOGNAME", p, 0);
509
510 if (devnam[0])
511 script_setenv("DEVICE", devnam, 1);
512 slprintf(numbuf, sizeof(numbuf), "%d", getpid());
513 script_setenv("PPPD_PID", numbuf, 1);
514
515 setup_signals();
516
517 create_linkpidfile(getpid());
518
519 waiting = 0;
520
521 /*
522 * If we're doing dial-on-demand, set up the interface now.
523 */
524 if (demand) {
525 /*
526 * Open the loopback channel and set it up to be the ppp interface.
527 */
528 fd_loop = open_ppp_loopback();
529 set_ifunit(1);
530 /*
531 * Configure the interface and mark it up, etc.
532 */
533 demand_conf();
534 }
535
536 do_callback = 0;
537 for (;;) {
538
539 bundle_eof = 0;
540 bundle_terminating = 0;
541 listen_time = 0;
542 need_holdoff = 1;
543 devfd = -1;
544 status = EXIT_OK;
545 ++unsuccess;
546 doing_callback = do_callback;
547 do_callback = 0;
548
549 if (demand && !doing_callback) {
550 /*
551 * Don't do anything until we see some activity.
552 */
553 new_phase(PHASE_DORMANT);
554 demand_unblock();
555 add_fd(fd_loop);
556 for (;;) {
557 handle_events();
558 if (asked_to_quit)
559 break;
560 if (get_loop_output())
561 break;
562 }
563 remove_fd(fd_loop);
564 if (asked_to_quit)
565 break;
566
567 /*
568 * Now we want to bring up the link.
569 */
570 demand_block();
571 info("Starting link");
572 }
573
574 gettimeofday(&start_time, NULL);
575 script_unsetenv("CONNECT_TIME");
576 script_unsetenv("BYTES_SENT");
577 script_unsetenv("BYTES_RCVD");
578
579 lcp_open(0); /* Start protocol */
580 start_link(0);
581 while (phase != PHASE_DEAD) {
582 handle_events();
583 get_input();
584 if (kill_link)
585 lcp_close(0, "User request");
586 if (asked_to_quit) {
587 bundle_terminating = 1;
588 if (phase == PHASE_MASTER)
589 mp_bundle_terminated();
590 }
591 if (open_ccp_flag) {
592 if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) {
593 ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
594 (*ccp_protent.open)(0);
595 }
596 }
597 }
598 /* restore FSMs to original state */
599 lcp_close(0, "");
600
601 if (!persist || asked_to_quit || (maxfail > 0 && unsuccess >= maxfail))
602 break;
603
604 if (demand)
605 demand_discard();
606 t = need_holdoff? holdoff: 0;
607 if (holdoff_hook)
608 t = (*holdoff_hook)();
609 if (t > 0) {
610 new_phase(PHASE_HOLDOFF);
611 TIMEOUT(holdoff_end, NULL, t);
612 do {
613 handle_events();
614 if (kill_link)
615 new_phase(PHASE_DORMANT); /* allow signal to end holdoff */
616 } while (phase == PHASE_HOLDOFF);
617 if (!persist)
618 break;
619 }
620 }
621
622 /* Wait for scripts to finish */
623 reap_kids();
624 if (n_children > 0) {
625 if (child_wait > 0)
626 TIMEOUT(childwait_end, NULL, child_wait);
627 if (debug) {
628 struct subprocess *chp;
629 dbglog("Waiting for %d child processes...", n_children);
630 for (chp = children; chp != NULL; chp = chp->next)
631 dbglog(" script %s, pid %d", chp->prog, chp->pid);
632 }
633 while (n_children > 0 && !childwait_done) {
634 handle_events();
635 if (kill_link && !childwait_done)
636 childwait_end(NULL);
637 }
638 }
639
640 die(status);
641 return 0;
642 }
643
644 /*
645 * handle_events - wait for something to happen and respond to it.
646 */
647 static void
handle_events()648 handle_events()
649 {
650 struct timeval timo;
651
652 kill_link = open_ccp_flag = 0;
653 if (sigsetjmp(sigjmp, 1) == 0) {
654 sigprocmask(SIG_BLOCK, &signals_handled, NULL);
655 if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) {
656 sigprocmask(SIG_UNBLOCK, &signals_handled, NULL);
657 } else {
658 waiting = 1;
659 sigprocmask(SIG_UNBLOCK, &signals_handled, NULL);
660 wait_input(timeleft(&timo));
661 }
662 }
663 waiting = 0;
664 calltimeout();
665 if (got_sighup) {
666 info("Hangup (SIGHUP)");
667 kill_link = 1;
668 got_sighup = 0;
669 if (status != EXIT_HANGUP)
670 status = EXIT_USER_REQUEST;
671 }
672 if (got_sigterm) {
673 info("Terminating on signal %d", got_sigterm);
674 kill_link = 1;
675 asked_to_quit = 1;
676 persist = 0;
677 status = EXIT_USER_REQUEST;
678 got_sigterm = 0;
679 }
680 if (got_sigchld) {
681 got_sigchld = 0;
682 reap_kids(); /* Don't leave dead kids lying around */
683 }
684 if (got_sigusr2) {
685 open_ccp_flag = 1;
686 got_sigusr2 = 0;
687 }
688 }
689
690 /*
691 * setup_signals - initialize signal handling.
692 */
693 static void
setup_signals()694 setup_signals()
695 {
696 struct sigaction sa;
697
698 /*
699 * Compute mask of all interesting signals and install signal handlers
700 * for each. Only one signal handler may be active at a time. Therefore,
701 * all other signals should be masked when any handler is executing.
702 */
703 sigemptyset(&signals_handled);
704 sigaddset(&signals_handled, SIGHUP);
705 sigaddset(&signals_handled, SIGINT);
706 sigaddset(&signals_handled, SIGTERM);
707 sigaddset(&signals_handled, SIGCHLD);
708 sigaddset(&signals_handled, SIGUSR2);
709
710 #define SIGNAL(s, handler) do { \
711 sa.sa_handler = handler; \
712 if (sigaction(s, &sa, NULL) < 0) \
713 fatal("Couldn't establish signal handler (%d): %m", s); \
714 } while (0)
715
716 sa.sa_mask = signals_handled;
717 sa.sa_flags = 0;
718 SIGNAL(SIGHUP, hup); /* Hangup */
719 SIGNAL(SIGINT, term); /* Interrupt */
720 SIGNAL(SIGTERM, term); /* Terminate */
721 SIGNAL(SIGCHLD, chld);
722
723 SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */
724 SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */
725
726 /*
727 * Install a handler for other signals which would otherwise
728 * cause pppd to exit without cleaning up.
729 */
730 SIGNAL(SIGABRT, bad_signal);
731 SIGNAL(SIGALRM, bad_signal);
732 SIGNAL(SIGFPE, bad_signal);
733 SIGNAL(SIGILL, bad_signal);
734 SIGNAL(SIGPIPE, bad_signal);
735 SIGNAL(SIGQUIT, bad_signal);
736 SIGNAL(SIGSEGV, bad_signal);
737 #ifdef SIGBUS
738 SIGNAL(SIGBUS, bad_signal);
739 #endif
740 #ifdef SIGEMT
741 SIGNAL(SIGEMT, bad_signal);
742 #endif
743 #ifdef SIGPOLL
744 SIGNAL(SIGPOLL, bad_signal);
745 #endif
746 #ifdef SIGPROF
747 SIGNAL(SIGPROF, bad_signal);
748 #endif
749 #ifdef SIGSYS
750 SIGNAL(SIGSYS, bad_signal);
751 #endif
752 #ifdef SIGTRAP
753 SIGNAL(SIGTRAP, bad_signal);
754 #endif
755 #ifdef SIGVTALRM
756 SIGNAL(SIGVTALRM, bad_signal);
757 #endif
758 #ifdef SIGXCPU
759 SIGNAL(SIGXCPU, bad_signal);
760 #endif
761 #ifdef SIGXFSZ
762 SIGNAL(SIGXFSZ, bad_signal);
763 #endif
764
765 /*
766 * Apparently we can get a SIGPIPE when we call syslog, if
767 * syslogd has died and been restarted. Ignoring it seems
768 * be sufficient.
769 */
770 signal(SIGPIPE, SIG_IGN);
771 }
772
773 /*
774 * set_ifunit - do things we need to do once we know which ppp
775 * unit we are using.
776 */
777 void
set_ifunit(iskey)778 set_ifunit(iskey)
779 int iskey;
780 {
781 info("Using interface %s%d", PPP_DRV_NAME, ifunit);
782 slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit);
783 script_setenv("IFNAME", ifname, iskey);
784 if (iskey) {
785 create_pidfile(getpid()); /* write pid to file */
786 create_linkpidfile(getpid());
787 }
788 }
789
790 /*
791 * detach - detach us from the controlling terminal.
792 */
793 void
detach()794 detach()
795 {
796 int pid;
797 char numbuf[16];
798 int pipefd[2];
799
800 if (detached)
801 return;
802 if (pipe(pipefd) == -1)
803 pipefd[0] = pipefd[1] = -1;
804 if ((pid = fork()) < 0) {
805 error("Couldn't detach (fork failed: %m)");
806 die(1); /* or just return? */
807 }
808 if (pid != 0) {
809 /* parent */
810 notify(pidchange, pid);
811 /* update pid files if they have been written already */
812 if (pidfilename[0])
813 create_pidfile(pid);
814 if (linkpidfile[0])
815 create_linkpidfile(pid);
816 exit(0); /* parent dies */
817 }
818 setsid();
819 chdir("/");
820 dup2(fd_devnull, 0);
821 dup2(fd_devnull, 1);
822 dup2(fd_devnull, 2);
823 detached = 1;
824 if (log_default)
825 log_to_fd = -1;
826 slprintf(numbuf, sizeof(numbuf), "%d", getpid());
827 script_setenv("PPPD_PID", numbuf, 1);
828
829 /* wait for parent to finish updating pid & lock files and die */
830 close(pipefd[1]);
831 complete_read(pipefd[0], numbuf, 1);
832 close(pipefd[0]);
833 }
834
835 /*
836 * reopen_log - (re)open our connection to syslog.
837 */
838 void
reopen_log()839 reopen_log()
840 {
841 openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
842 setlogmask(LOG_UPTO(LOG_INFO));
843 }
844
845 /*
846 * Create a file containing our process ID.
847 */
848 static void
create_pidfile(pid)849 create_pidfile(pid)
850 int pid;
851 {
852 #if !defined(__ANDROID__)
853 FILE *pidfile;
854
855 slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
856 _PATH_VARRUN, ifname);
857 if ((pidfile = fopen(pidfilename, "w")) != NULL) {
858 fprintf(pidfile, "%d\n", pid);
859 (void) fclose(pidfile);
860 } else {
861 error("Failed to create pid file %s: %m", pidfilename);
862 pidfilename[0] = 0;
863 }
864 #endif
865 }
866
867 void
create_linkpidfile(pid)868 create_linkpidfile(pid)
869 int pid;
870 {
871 #if !defined(__ANDROID__)
872 FILE *pidfile;
873
874 if (linkname[0] == 0)
875 return;
876 script_setenv("LINKNAME", linkname, 1);
877 slprintf(linkpidfile, sizeof(linkpidfile), "%sppp-%s.pid",
878 _PATH_VARRUN, linkname);
879 if ((pidfile = fopen(linkpidfile, "w")) != NULL) {
880 fprintf(pidfile, "%d\n", pid);
881 if (ifname[0])
882 fprintf(pidfile, "%s\n", ifname);
883 (void) fclose(pidfile);
884 } else {
885 error("Failed to create pid file %s: %m", linkpidfile);
886 linkpidfile[0] = 0;
887 }
888 #endif
889 }
890
891 /*
892 * remove_pidfile - remove our pid files
893 */
remove_pidfiles()894 void remove_pidfiles()
895 {
896 #if !defined(__ANDROID__)
897 if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT)
898 warn("unable to delete pid file %s: %m", pidfilename);
899 pidfilename[0] = 0;
900 if (linkpidfile[0] != 0 && unlink(linkpidfile) < 0 && errno != ENOENT)
901 warn("unable to delete pid file %s: %m", linkpidfile);
902 linkpidfile[0] = 0;
903 #endif
904 }
905
906 /*
907 * holdoff_end - called via a timeout when the holdoff period ends.
908 */
909 static void
holdoff_end(arg)910 holdoff_end(arg)
911 void *arg;
912 {
913 new_phase(PHASE_DORMANT);
914 }
915
916 /* List of protocol names, to make our messages a little more informative. */
917 struct protocol_list {
918 u_short proto;
919 const char *name;
920 } protocol_list[] = {
921 { 0x21, "IP" },
922 { 0x23, "OSI Network Layer" },
923 { 0x25, "Xerox NS IDP" },
924 { 0x27, "DECnet Phase IV" },
925 { 0x29, "Appletalk" },
926 { 0x2b, "Novell IPX" },
927 { 0x2d, "VJ compressed TCP/IP" },
928 { 0x2f, "VJ uncompressed TCP/IP" },
929 { 0x31, "Bridging PDU" },
930 { 0x33, "Stream Protocol ST-II" },
931 { 0x35, "Banyan Vines" },
932 { 0x39, "AppleTalk EDDP" },
933 { 0x3b, "AppleTalk SmartBuffered" },
934 { 0x3d, "Multi-Link" },
935 { 0x3f, "NETBIOS Framing" },
936 { 0x41, "Cisco Systems" },
937 { 0x43, "Ascom Timeplex" },
938 { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" },
939 { 0x47, "DCA Remote Lan" },
940 { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" },
941 { 0x4b, "SNA over 802.2" },
942 { 0x4d, "SNA" },
943 { 0x4f, "IP6 Header Compression" },
944 { 0x51, "KNX Bridging Data" },
945 { 0x53, "Encryption" },
946 { 0x55, "Individual Link Encryption" },
947 { 0x57, "IPv6" },
948 { 0x59, "PPP Muxing" },
949 { 0x5b, "Vendor-Specific Network Protocol" },
950 { 0x61, "RTP IPHC Full Header" },
951 { 0x63, "RTP IPHC Compressed TCP" },
952 { 0x65, "RTP IPHC Compressed non-TCP" },
953 { 0x67, "RTP IPHC Compressed UDP 8" },
954 { 0x69, "RTP IPHC Compressed RTP 8" },
955 { 0x6f, "Stampede Bridging" },
956 { 0x73, "MP+" },
957 { 0xc1, "NTCITS IPI" },
958 { 0xfb, "single-link compression" },
959 { 0xfd, "Compressed Datagram" },
960 { 0x0201, "802.1d Hello Packets" },
961 { 0x0203, "IBM Source Routing BPDU" },
962 { 0x0205, "DEC LANBridge100 Spanning Tree" },
963 { 0x0207, "Cisco Discovery Protocol" },
964 { 0x0209, "Netcs Twin Routing" },
965 { 0x020b, "STP - Scheduled Transfer Protocol" },
966 { 0x020d, "EDP - Extreme Discovery Protocol" },
967 { 0x0211, "Optical Supervisory Channel Protocol" },
968 { 0x0213, "Optical Supervisory Channel Protocol" },
969 { 0x0231, "Luxcom" },
970 { 0x0233, "Sigma Network Systems" },
971 { 0x0235, "Apple Client Server Protocol" },
972 { 0x0281, "MPLS Unicast" },
973 { 0x0283, "MPLS Multicast" },
974 { 0x0285, "IEEE p1284.4 standard - data packets" },
975 { 0x0287, "ETSI TETRA Network Protocol Type 1" },
976 { 0x0289, "Multichannel Flow Treatment Protocol" },
977 { 0x2063, "RTP IPHC Compressed TCP No Delta" },
978 { 0x2065, "RTP IPHC Context State" },
979 { 0x2067, "RTP IPHC Compressed UDP 16" },
980 { 0x2069, "RTP IPHC Compressed RTP 16" },
981 { 0x4001, "Cray Communications Control Protocol" },
982 { 0x4003, "CDPD Mobile Network Registration Protocol" },
983 { 0x4005, "Expand accelerator protocol" },
984 { 0x4007, "ODSICP NCP" },
985 { 0x4009, "DOCSIS DLL" },
986 { 0x400B, "Cetacean Network Detection Protocol" },
987 { 0x4021, "Stacker LZS" },
988 { 0x4023, "RefTek Protocol" },
989 { 0x4025, "Fibre Channel" },
990 { 0x4027, "EMIT Protocols" },
991 { 0x405b, "Vendor-Specific Protocol (VSP)" },
992 { 0x8021, "Internet Protocol Control Protocol" },
993 { 0x8023, "OSI Network Layer Control Protocol" },
994 { 0x8025, "Xerox NS IDP Control Protocol" },
995 { 0x8027, "DECnet Phase IV Control Protocol" },
996 { 0x8029, "Appletalk Control Protocol" },
997 { 0x802b, "Novell IPX Control Protocol" },
998 { 0x8031, "Bridging NCP" },
999 { 0x8033, "Stream Protocol Control Protocol" },
1000 { 0x8035, "Banyan Vines Control Protocol" },
1001 { 0x803d, "Multi-Link Control Protocol" },
1002 { 0x803f, "NETBIOS Framing Control Protocol" },
1003 { 0x8041, "Cisco Systems Control Protocol" },
1004 { 0x8043, "Ascom Timeplex" },
1005 { 0x8045, "Fujitsu LBLB Control Protocol" },
1006 { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" },
1007 { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
1008 { 0x804b, "SNA over 802.2 Control Protocol" },
1009 { 0x804d, "SNA Control Protocol" },
1010 { 0x804f, "IP6 Header Compression Control Protocol" },
1011 { 0x8051, "KNX Bridging Control Protocol" },
1012 { 0x8053, "Encryption Control Protocol" },
1013 { 0x8055, "Individual Link Encryption Control Protocol" },
1014 { 0x8057, "IPv6 Control Protocol" },
1015 { 0x8059, "PPP Muxing Control Protocol" },
1016 { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" },
1017 { 0x806f, "Stampede Bridging Control Protocol" },
1018 { 0x8073, "MP+ Control Protocol" },
1019 { 0x80c1, "NTCITS IPI Control Protocol" },
1020 { 0x80fb, "Single Link Compression Control Protocol" },
1021 { 0x80fd, "Compression Control Protocol" },
1022 { 0x8207, "Cisco Discovery Protocol Control" },
1023 { 0x8209, "Netcs Twin Routing" },
1024 { 0x820b, "STP - Control Protocol" },
1025 { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" },
1026 { 0x8235, "Apple Client Server Protocol Control" },
1027 { 0x8281, "MPLSCP" },
1028 { 0x8285, "IEEE p1284.4 standard - Protocol Control" },
1029 { 0x8287, "ETSI TETRA TNP1 Control Protocol" },
1030 { 0x8289, "Multichannel Flow Treatment Protocol" },
1031 { 0xc021, "Link Control Protocol" },
1032 { 0xc023, "Password Authentication Protocol" },
1033 { 0xc025, "Link Quality Report" },
1034 { 0xc027, "Shiva Password Authentication Protocol" },
1035 { 0xc029, "CallBack Control Protocol (CBCP)" },
1036 { 0xc02b, "BACP Bandwidth Allocation Control Protocol" },
1037 { 0xc02d, "BAP" },
1038 { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" },
1039 { 0xc081, "Container Control Protocol" },
1040 { 0xc223, "Challenge Handshake Authentication Protocol" },
1041 { 0xc225, "RSA Authentication Protocol" },
1042 { 0xc227, "Extensible Authentication Protocol" },
1043 { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" },
1044 { 0xc26f, "Stampede Bridging Authorization Protocol" },
1045 { 0xc281, "Proprietary Authentication Protocol" },
1046 { 0xc283, "Proprietary Authentication Protocol" },
1047 { 0xc481, "Proprietary Node ID Authentication Protocol" },
1048 { 0, NULL },
1049 };
1050
1051 /*
1052 * protocol_name - find a name for a PPP protocol.
1053 */
1054 const char *
protocol_name(proto)1055 protocol_name(proto)
1056 int proto;
1057 {
1058 struct protocol_list *lp;
1059
1060 for (lp = protocol_list; lp->proto != 0; ++lp)
1061 if (proto == lp->proto)
1062 return lp->name;
1063 return NULL;
1064 }
1065
1066 /*
1067 * get_input - called when incoming data is available.
1068 */
1069 static void
get_input()1070 get_input()
1071 {
1072 int len, i;
1073 u_char *p;
1074 u_short protocol;
1075 struct protent *protp;
1076
1077 p = inpacket_buf; /* point to beginning of packet buffer */
1078
1079 len = read_packet(inpacket_buf);
1080 if (len < 0)
1081 return;
1082
1083 if (len == 0) {
1084 if (bundle_eof && multilink_master) {
1085 notice("Last channel has disconnected");
1086 mp_bundle_terminated();
1087 return;
1088 }
1089 notice("Modem hangup");
1090 hungup = 1;
1091 status = EXIT_HANGUP;
1092 lcp_lowerdown(0); /* serial link is no longer available */
1093 link_terminated(0);
1094 return;
1095 }
1096
1097 if (len < PPP_HDRLEN) {
1098 dbglog("received short packet:%.*B", len, p);
1099 return;
1100 }
1101
1102 dump_packet("rcvd", p, len);
1103 if (snoop_recv_hook) snoop_recv_hook(p, len);
1104
1105 p += 2; /* Skip address and control */
1106 GETSHORT(protocol, p);
1107 len -= PPP_HDRLEN;
1108
1109 /*
1110 * Toss all non-LCP packets unless LCP is OPEN.
1111 */
1112 if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
1113 dbglog("Discarded non-LCP packet when LCP not open");
1114 return;
1115 }
1116
1117 /*
1118 * Until we get past the authentication phase, toss all packets
1119 * except LCP, LQR and authentication packets.
1120 */
1121 if (phase <= PHASE_AUTHENTICATE
1122 && !(protocol == PPP_LCP || protocol == PPP_LQR
1123 || protocol == PPP_PAP || protocol == PPP_CHAP ||
1124 protocol == PPP_EAP)) {
1125 dbglog("discarding proto 0x%x in phase %d",
1126 protocol, phase);
1127 return;
1128 }
1129
1130 /*
1131 * Upcall the proper protocol input routine.
1132 */
1133 for (i = 0; (protp = protocols[i]) != NULL; ++i) {
1134 if (protp->protocol == protocol && protp->enabled_flag) {
1135 (*protp->input)(0, p, len);
1136 return;
1137 }
1138 if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
1139 && protp->datainput != NULL) {
1140 (*protp->datainput)(0, p, len);
1141 return;
1142 }
1143 }
1144
1145 if (debug) {
1146 const char *pname = protocol_name(protocol);
1147 if (pname != NULL)
1148 warn("Unsupported protocol '%s' (0x%x) received", pname, protocol);
1149 else
1150 warn("Unsupported protocol 0x%x received", protocol);
1151 }
1152 lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
1153 }
1154
1155 /*
1156 * ppp_send_config - configure the transmit-side characteristics of
1157 * the ppp interface. Returns -1, indicating an error, if the channel
1158 * send_config procedure called error() (or incremented error_count
1159 * itself), otherwise 0.
1160 */
1161 int
ppp_send_config(unit,mtu,accm,pcomp,accomp)1162 ppp_send_config(unit, mtu, accm, pcomp, accomp)
1163 int unit, mtu;
1164 u_int32_t accm;
1165 int pcomp, accomp;
1166 {
1167 int errs;
1168
1169 if (the_channel->send_config == NULL)
1170 return 0;
1171 errs = error_count;
1172 (*the_channel->send_config)(mtu, accm, pcomp, accomp);
1173 return (error_count != errs)? -1: 0;
1174 }
1175
1176 /*
1177 * ppp_recv_config - configure the receive-side characteristics of
1178 * the ppp interface. Returns -1, indicating an error, if the channel
1179 * recv_config procedure called error() (or incremented error_count
1180 * itself), otherwise 0.
1181 */
1182 int
ppp_recv_config(unit,mru,accm,pcomp,accomp)1183 ppp_recv_config(unit, mru, accm, pcomp, accomp)
1184 int unit, mru;
1185 u_int32_t accm;
1186 int pcomp, accomp;
1187 {
1188 int errs;
1189
1190 if (the_channel->recv_config == NULL)
1191 return 0;
1192 errs = error_count;
1193 (*the_channel->recv_config)(mru, accm, pcomp, accomp);
1194 return (error_count != errs)? -1: 0;
1195 }
1196
1197 /*
1198 * new_phase - signal the start of a new phase of pppd's operation.
1199 */
1200 void
new_phase(p)1201 new_phase(p)
1202 int p;
1203 {
1204 phase = p;
1205 if (new_phase_hook)
1206 (*new_phase_hook)(p);
1207 notify(phasechange, p);
1208 }
1209
1210 /*
1211 * die - clean up state and exit with the specified status.
1212 */
1213 void
die(status)1214 die(status)
1215 int status;
1216 {
1217 if (!doing_multilink || multilink_master)
1218 print_link_stats();
1219 cleanup();
1220 notify(exitnotify, status);
1221 syslog(LOG_INFO, "Exit.");
1222 exit(status);
1223 }
1224
1225 /*
1226 * cleanup - restore anything which needs to be restored before we exit
1227 */
1228 /* ARGSUSED */
1229 static void
cleanup()1230 cleanup()
1231 {
1232 sys_cleanup();
1233
1234 if (fd_ppp >= 0)
1235 the_channel->disestablish_ppp(devfd);
1236 if (the_channel->cleanup)
1237 (*the_channel->cleanup)();
1238 remove_pidfiles();
1239
1240 #ifdef USE_TDB
1241 if (pppdb != NULL)
1242 cleanup_db();
1243 #endif
1244
1245 }
1246
1247 void
print_link_stats()1248 print_link_stats()
1249 {
1250 /*
1251 * Print connect time and statistics.
1252 */
1253 if (link_stats_valid) {
1254 int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */
1255 info("Connect time %d.%d minutes.", t/10, t%10);
1256 info("Sent %u bytes, received %u bytes.",
1257 link_stats.bytes_out, link_stats.bytes_in);
1258 link_stats_valid = 0;
1259 }
1260 }
1261
1262 /*
1263 * reset_link_stats - "reset" stats when link goes up.
1264 */
1265 void
reset_link_stats(u)1266 reset_link_stats(u)
1267 int u;
1268 {
1269 if (!get_ppp_stats(u, &old_link_stats))
1270 return;
1271 gettimeofday(&start_time, NULL);
1272 }
1273
1274 /*
1275 * update_link_stats - get stats at link termination.
1276 */
1277 void
update_link_stats(u)1278 update_link_stats(u)
1279 int u;
1280 {
1281 struct timeval now;
1282 char numbuf[32];
1283
1284 if (!get_ppp_stats(u, &link_stats)
1285 || gettimeofday(&now, NULL) < 0)
1286 return;
1287 link_connect_time = now.tv_sec - start_time.tv_sec;
1288 link_stats_valid = 1;
1289
1290 link_stats.bytes_in -= old_link_stats.bytes_in;
1291 link_stats.bytes_out -= old_link_stats.bytes_out;
1292 link_stats.pkts_in -= old_link_stats.pkts_in;
1293 link_stats.pkts_out -= old_link_stats.pkts_out;
1294
1295 slprintf(numbuf, sizeof(numbuf), "%u", link_connect_time);
1296 script_setenv("CONNECT_TIME", numbuf, 0);
1297 slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_out);
1298 script_setenv("BYTES_SENT", numbuf, 0);
1299 slprintf(numbuf, sizeof(numbuf), "%u", link_stats.bytes_in);
1300 script_setenv("BYTES_RCVD", numbuf, 0);
1301 }
1302
1303
1304 struct callout {
1305 struct timeval c_time; /* time at which to call routine */
1306 void *c_arg; /* argument to routine */
1307 void (*c_func) __P((void *)); /* routine */
1308 struct callout *c_next;
1309 };
1310
1311 static struct callout *callout = NULL; /* Callout list */
1312 static struct timeval timenow; /* Current time */
1313
1314 /*
1315 * timeout - Schedule a timeout.
1316 */
1317 void
1318 timeout(func, arg, secs, usecs)
1319 void (*func) __P((void *));
1320 void *arg;
1321 int secs, usecs;
1322 {
1323 struct callout *newp, *p, **pp;
1324
1325 /*
1326 * Allocate timeout.
1327 */
1328 if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
1329 fatal("Out of memory in timeout()!");
1330 newp->c_arg = arg;
1331 newp->c_func = func;
1332 gettimeofday(&timenow, NULL);
1333 newp->c_time.tv_sec = timenow.tv_sec + secs;
1334 newp->c_time.tv_usec = timenow.tv_usec + usecs;
1335 if (newp->c_time.tv_usec >= 1000000) {
1336 newp->c_time.tv_sec += newp->c_time.tv_usec / 1000000;
1337 newp->c_time.tv_usec %= 1000000;
1338 }
1339
1340 /*
1341 * Find correct place and link it in.
1342 */
1343 for (pp = &callout; (p = *pp); pp = &p->c_next)
1344 if (newp->c_time.tv_sec < p->c_time.tv_sec
1345 || (newp->c_time.tv_sec == p->c_time.tv_sec
1346 && newp->c_time.tv_usec < p->c_time.tv_usec))
1347 break;
1348 newp->c_next = p;
1349 *pp = newp;
1350 }
1351
1352
1353 /*
1354 * untimeout - Unschedule a timeout.
1355 */
1356 void
1357 untimeout(func, arg)
1358 void (*func) __P((void *));
1359 void *arg;
1360 {
1361 struct callout **copp, *freep;
1362
1363 /*
1364 * Find first matching timeout and remove it from the list.
1365 */
1366 for (copp = &callout; (freep = *copp); copp = &freep->c_next)
1367 if (freep->c_func == func && freep->c_arg == arg) {
1368 *copp = freep->c_next;
1369 free((char *) freep);
1370 break;
1371 }
1372 }
1373
1374
1375 /*
1376 * calltimeout - Call any timeout routines which are now due.
1377 */
1378 static void
calltimeout()1379 calltimeout()
1380 {
1381 struct callout *p;
1382
1383 while (callout != NULL) {
1384 p = callout;
1385
1386 if (gettimeofday(&timenow, NULL) < 0)
1387 fatal("Failed to get time of day: %m");
1388 if (!(p->c_time.tv_sec < timenow.tv_sec
1389 || (p->c_time.tv_sec == timenow.tv_sec
1390 && p->c_time.tv_usec <= timenow.tv_usec)))
1391 break; /* no, it's not time yet */
1392
1393 callout = p->c_next;
1394 (*p->c_func)(p->c_arg);
1395
1396 free((char *) p);
1397 }
1398 }
1399
1400
1401 /*
1402 * timeleft - return the length of time until the next timeout is due.
1403 */
1404 static struct timeval *
timeleft(tvp)1405 timeleft(tvp)
1406 struct timeval *tvp;
1407 {
1408 if (callout == NULL)
1409 return NULL;
1410
1411 gettimeofday(&timenow, NULL);
1412 tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
1413 tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
1414 if (tvp->tv_usec < 0) {
1415 tvp->tv_usec += 1000000;
1416 tvp->tv_sec -= 1;
1417 }
1418 if (tvp->tv_sec < 0)
1419 tvp->tv_sec = tvp->tv_usec = 0;
1420
1421 return tvp;
1422 }
1423
1424
1425 /*
1426 * kill_my_pg - send a signal to our process group, and ignore it ourselves.
1427 * We assume that sig is currently blocked.
1428 */
1429 static void
kill_my_pg(sig)1430 kill_my_pg(sig)
1431 int sig;
1432 {
1433 struct sigaction act, oldact;
1434 struct subprocess *chp;
1435
1436 if (!detached) {
1437 /*
1438 * There might be other things in our process group that we
1439 * didn't start that would get hit if we did a kill(0), so
1440 * just send the signal individually to our children.
1441 */
1442 for (chp = children; chp != NULL; chp = chp->next)
1443 if (chp->killable)
1444 kill(chp->pid, sig);
1445 return;
1446 }
1447
1448 /* We've done a setsid(), so we can just use a kill(0) */
1449 sigemptyset(&act.sa_mask); /* unnecessary in fact */
1450 act.sa_handler = SIG_IGN;
1451 act.sa_flags = 0;
1452 kill(0, sig);
1453 /*
1454 * The kill() above made the signal pending for us, as well as
1455 * the rest of our process group, but we don't want it delivered
1456 * to us. It is blocked at the moment. Setting it to be ignored
1457 * will cause the pending signal to be discarded. If we did the
1458 * kill() after setting the signal to be ignored, it is unspecified
1459 * (by POSIX) whether the signal is immediately discarded or left
1460 * pending, and in fact Linux would leave it pending, and so it
1461 * would be delivered after the current signal handler exits,
1462 * leading to an infinite loop.
1463 */
1464 sigaction(sig, &act, &oldact);
1465 sigaction(sig, &oldact, NULL);
1466 }
1467
1468
1469 /*
1470 * hup - Catch SIGHUP signal.
1471 *
1472 * Indicates that the physical layer has been disconnected.
1473 * We don't rely on this indication; if the user has sent this
1474 * signal, we just take the link down.
1475 */
1476 static void
hup(sig)1477 hup(sig)
1478 int sig;
1479 {
1480 /* can't log a message here, it can deadlock */
1481 got_sighup = 1;
1482 if (conn_running)
1483 /* Send the signal to the [dis]connector process(es) also */
1484 kill_my_pg(sig);
1485 notify(sigreceived, sig);
1486 if (waiting)
1487 siglongjmp(sigjmp, 1);
1488 }
1489
1490
1491 /*
1492 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
1493 *
1494 * Indicates that we should initiate a graceful disconnect and exit.
1495 */
1496 /*ARGSUSED*/
1497 static void
term(sig)1498 term(sig)
1499 int sig;
1500 {
1501 /* can't log a message here, it can deadlock */
1502 got_sigterm = sig;
1503 if (conn_running)
1504 /* Send the signal to the [dis]connector process(es) also */
1505 kill_my_pg(sig);
1506 notify(sigreceived, sig);
1507 if (waiting)
1508 siglongjmp(sigjmp, 1);
1509 }
1510
1511
1512 /*
1513 * chld - Catch SIGCHLD signal.
1514 * Sets a flag so we will call reap_kids in the mainline.
1515 */
1516 static void
chld(sig)1517 chld(sig)
1518 int sig;
1519 {
1520 got_sigchld = 1;
1521 if (waiting)
1522 siglongjmp(sigjmp, 1);
1523 }
1524
1525
1526 /*
1527 * toggle_debug - Catch SIGUSR1 signal.
1528 *
1529 * Toggle debug flag.
1530 */
1531 /*ARGSUSED*/
1532 static void
toggle_debug(sig)1533 toggle_debug(sig)
1534 int sig;
1535 {
1536 debug = !debug;
1537 if (debug) {
1538 setlogmask(LOG_UPTO(LOG_DEBUG));
1539 } else {
1540 setlogmask(LOG_UPTO(LOG_WARNING));
1541 }
1542 }
1543
1544
1545 /*
1546 * open_ccp - Catch SIGUSR2 signal.
1547 *
1548 * Try to (re)negotiate compression.
1549 */
1550 /*ARGSUSED*/
1551 static void
open_ccp(sig)1552 open_ccp(sig)
1553 int sig;
1554 {
1555 got_sigusr2 = 1;
1556 if (waiting)
1557 siglongjmp(sigjmp, 1);
1558 }
1559
1560
1561 /*
1562 * bad_signal - We've caught a fatal signal. Clean up state and exit.
1563 */
1564 static void
bad_signal(sig)1565 bad_signal(sig)
1566 int sig;
1567 {
1568 static int crashed = 0;
1569
1570 if (crashed)
1571 _exit(127);
1572 crashed = 1;
1573 error("Fatal signal %d", sig);
1574 if (conn_running)
1575 kill_my_pg(SIGTERM);
1576 notify(sigreceived, sig);
1577 die(127);
1578 }
1579
1580 /*
1581 * safe_fork - Create a child process. The child closes all the
1582 * file descriptors that we don't want to leak to a script.
1583 * The parent waits for the child to do this before returning.
1584 * This also arranges for the specified fds to be dup'd to
1585 * fds 0, 1, 2 in the child.
1586 */
1587 pid_t
safe_fork(int infd,int outfd,int errfd)1588 safe_fork(int infd, int outfd, int errfd)
1589 {
1590 pid_t pid;
1591 int fd, pipefd[2];
1592 char buf[1];
1593
1594 /* make sure fds 0, 1, 2 are occupied (probably not necessary) */
1595 while ((fd = dup(fd_devnull)) >= 0) {
1596 if (fd > 2) {
1597 close(fd);
1598 break;
1599 }
1600 }
1601
1602 if (pipe(pipefd) == -1)
1603 pipefd[0] = pipefd[1] = -1;
1604 pid = fork();
1605 if (pid < 0) {
1606 error("fork failed: %m");
1607 return -1;
1608 }
1609 if (pid > 0) {
1610 /* parent */
1611 close(pipefd[1]);
1612 /* this read() blocks until the close(pipefd[1]) below */
1613 complete_read(pipefd[0], buf, 1);
1614 close(pipefd[0]);
1615 return pid;
1616 }
1617
1618 /* Executing in the child */
1619 sys_close();
1620 #ifdef USE_TDB
1621 tdb_close(pppdb);
1622 #endif
1623
1624 /* make sure infd, outfd and errfd won't get tromped on below */
1625 if (infd == 1 || infd == 2)
1626 infd = dup(infd);
1627 if (outfd == 0 || outfd == 2)
1628 outfd = dup(outfd);
1629 if (errfd == 0 || errfd == 1)
1630 errfd = dup(errfd);
1631
1632 closelog();
1633
1634 /* dup the in, out, err fds to 0, 1, 2 */
1635 if (infd != 0)
1636 dup2(infd, 0);
1637 if (outfd != 1)
1638 dup2(outfd, 1);
1639 if (errfd != 2)
1640 dup2(errfd, 2);
1641
1642 if (log_to_fd > 2)
1643 close(log_to_fd);
1644 if (the_channel->close)
1645 (*the_channel->close)();
1646 else
1647 close(devfd); /* some plugins don't have a close function */
1648 close(fd_ppp);
1649 close(fd_devnull);
1650 if (infd != 0)
1651 close(infd);
1652 if (outfd != 1)
1653 close(outfd);
1654 if (errfd != 2)
1655 close(errfd);
1656
1657 notify(fork_notifier, 0);
1658 close(pipefd[0]);
1659 /* this close unblocks the read() call above in the parent */
1660 close(pipefd[1]);
1661
1662 return 0;
1663 }
1664
1665 static bool
add_script_env(pos,newstring)1666 add_script_env(pos, newstring)
1667 int pos;
1668 char *newstring;
1669 {
1670 if (pos + 1 >= s_env_nalloc) {
1671 int new_n = pos + 17;
1672 char **newenv = realloc(script_env, new_n * sizeof(char *));
1673 if (newenv == NULL) {
1674 free(newstring - 1);
1675 return 0;
1676 }
1677 script_env = newenv;
1678 s_env_nalloc = new_n;
1679 }
1680 script_env[pos] = newstring;
1681 script_env[pos + 1] = NULL;
1682 return 1;
1683 }
1684
1685 static void
remove_script_env(pos)1686 remove_script_env(pos)
1687 int pos;
1688 {
1689 free(script_env[pos] - 1);
1690 while ((script_env[pos] = script_env[pos + 1]) != NULL)
1691 pos++;
1692 }
1693
1694 /*
1695 * update_system_environment - process the list of set/unset options
1696 * and update the system environment.
1697 */
1698 static void
update_system_environment()1699 update_system_environment()
1700 {
1701 struct userenv *uep;
1702
1703 for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
1704 if (uep->ue_isset)
1705 setenv(uep->ue_name, uep->ue_value, 1);
1706 else
1707 unsetenv(uep->ue_name);
1708 }
1709 }
1710
1711 /*
1712 * device_script - run a program to talk to the specified fds
1713 * (e.g. to run the connector or disconnector script).
1714 * stderr gets connected to the log fd or to the _PATH_CONNERRS file.
1715 */
1716 int
device_script(program,in,out,dont_wait)1717 device_script(program, in, out, dont_wait)
1718 char *program;
1719 int in, out;
1720 int dont_wait;
1721 {
1722 int pid;
1723 int status = -1;
1724 int errfd;
1725
1726 if (log_to_fd >= 0)
1727 errfd = log_to_fd;
1728 else
1729 errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600);
1730
1731 ++conn_running;
1732 pid = safe_fork(in, out, errfd);
1733
1734 if (pid != 0 && log_to_fd < 0)
1735 close(errfd);
1736
1737 if (pid < 0) {
1738 --conn_running;
1739 error("Failed to create child process: %m");
1740 return -1;
1741 }
1742
1743 if (pid != 0) {
1744 record_child(pid, program, NULL, NULL, 1);
1745 status = 0;
1746 if (!dont_wait) {
1747 while (waitpid(pid, &status, 0) < 0) {
1748 if (errno == EINTR)
1749 continue;
1750 fatal("error waiting for (dis)connection process: %m");
1751 }
1752 forget_child(pid, status);
1753 --conn_running;
1754 }
1755 return (status == 0 ? 0 : -1);
1756 }
1757
1758 /* here we are executing in the child */
1759
1760 setgid(getgid());
1761 setuid(uid);
1762 if (getuid() != uid) {
1763 fprintf(stderr, "pppd: setuid failed\n");
1764 exit(1);
1765 }
1766 update_system_environment();
1767 #if defined(__ANDROID__)
1768 execl("/system/bin/sh", "sh", "-c", program, NULL);
1769 #else
1770 execl("/bin/sh", "sh", "-c", program, (char *)0);
1771 #endif
1772 perror("pppd: could not exec /bin/sh");
1773 _exit(99);
1774 /* NOTREACHED */
1775 }
1776
1777
1778 /*
1779 * update_script_environment - process the list of set/unset options
1780 * and update the script environment. Note that we intentionally do
1781 * not update the TDB. These changes are layered on top right before
1782 * exec. It is not possible to use script_setenv() or
1783 * script_unsetenv() safely after this routine is run.
1784 */
1785 static void
update_script_environment()1786 update_script_environment()
1787 {
1788 struct userenv *uep;
1789
1790 for (uep = userenv_list; uep != NULL; uep = uep->ue_next) {
1791 int i;
1792 char *p, *newstring;
1793 int nlen = strlen(uep->ue_name);
1794
1795 for (i = 0; (p = script_env[i]) != NULL; i++) {
1796 if (strncmp(p, uep->ue_name, nlen) == 0 && p[nlen] == '=')
1797 break;
1798 }
1799 if (uep->ue_isset) {
1800 nlen += strlen(uep->ue_value) + 2;
1801 newstring = malloc(nlen + 1);
1802 if (newstring == NULL)
1803 continue;
1804 *newstring++ = 0;
1805 slprintf(newstring, nlen, "%s=%s", uep->ue_name, uep->ue_value);
1806 if (p != NULL)
1807 script_env[i] = newstring;
1808 else
1809 add_script_env(i, newstring);
1810 } else {
1811 remove_script_env(i);
1812 }
1813 }
1814 }
1815
1816 /*
1817 * run_program - execute a program with given arguments,
1818 * but don't wait for it unless wait is non-zero.
1819 * If the program can't be executed, logs an error unless
1820 * must_exist is 0 and the program file doesn't exist.
1821 * Returns -1 if it couldn't fork, 0 if the file doesn't exist
1822 * or isn't an executable plain file, or the process ID of the child.
1823 * If done != NULL, (*done)(arg) will be called later (within
1824 * reap_kids) iff the return value is > 0.
1825 */
1826 pid_t
run_program(prog,args,must_exist,done,arg,wait)1827 run_program(prog, args, must_exist, done, arg, wait)
1828 char *prog;
1829 char **args;
1830 int must_exist;
1831 void (*done) __P((void *));
1832 void *arg;
1833 int wait;
1834 {
1835 int pid, status;
1836 struct stat sbuf;
1837
1838 #if defined(__ANDROID__)
1839 /* Originally linkname is used to create named pid files, which is
1840 * meaningless to android. Here we use it as a suffix of program names,
1841 * so different users can run their own program by specifying it. For
1842 * example, "/etc/ppp/ip-up-vpn" will be executed when IPCP is up and
1843 * linkname is "vpn". Note that "/" is not allowed for security reasons. */
1844 char file[MAXPATHLEN];
1845
1846 if (linkname[0] && !strchr(linkname, '/')) {
1847 snprintf(file, MAXPATHLEN, "%s-%s", prog, linkname);
1848 file[MAXPATHLEN - 1] = '\0';
1849 prog = file;
1850 }
1851 #endif
1852
1853 /*
1854 * First check if the file exists and is executable.
1855 * We don't use access() because that would use the
1856 * real user-id, which might not be root, and the script
1857 * might be accessible only to root.
1858 */
1859 errno = EINVAL;
1860 if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode)
1861 || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
1862 if (must_exist || errno != ENOENT)
1863 warn("Can't execute %s: %m", prog);
1864 return 0;
1865 }
1866
1867 pid = safe_fork(fd_devnull, fd_devnull, fd_devnull);
1868 if (pid == -1) {
1869 error("Failed to create child process for %s: %m", prog);
1870 return -1;
1871 }
1872 if (pid != 0) {
1873 if (debug)
1874 dbglog("Script %s started (pid %d)", prog, pid);
1875 record_child(pid, prog, done, arg, 0);
1876 if (wait) {
1877 while (waitpid(pid, &status, 0) < 0) {
1878 if (errno == EINTR)
1879 continue;
1880 fatal("error waiting for script %s: %m", prog);
1881 }
1882 forget_child(pid, status);
1883 }
1884 return pid;
1885 }
1886
1887 /* Leave the current location */
1888 (void) setsid(); /* No controlling tty. */
1889 (void) umask (S_IRWXG|S_IRWXO);
1890 (void) chdir ("/"); /* no current directory. */
1891 setuid(0); /* set real UID = root */
1892 setgid(getegid());
1893
1894 #ifdef BSD
1895 /* Force the priority back to zero if pppd is running higher. */
1896 if (setpriority (PRIO_PROCESS, 0, 0) < 0)
1897 warn("can't reset priority to 0: %m");
1898 #endif
1899
1900 /* run the program */
1901 update_script_environment();
1902 execve(prog, args, script_env);
1903 if (must_exist || errno != ENOENT) {
1904 /* have to reopen the log, there's nowhere else
1905 for the message to go. */
1906 reopen_log();
1907 syslog(LOG_ERR, "Can't execute %s: %m", prog);
1908 closelog();
1909 }
1910 _exit(99);
1911 }
1912
1913
1914 /*
1915 * record_child - add a child process to the list for reap_kids
1916 * to use.
1917 */
1918 void
record_child(pid,prog,done,arg,killable)1919 record_child(pid, prog, done, arg, killable)
1920 int pid;
1921 char *prog;
1922 void (*done) __P((void *));
1923 void *arg;
1924 int killable;
1925 {
1926 struct subprocess *chp;
1927
1928 ++n_children;
1929
1930 chp = (struct subprocess *) malloc(sizeof(struct subprocess));
1931 if (chp == NULL) {
1932 warn("losing track of %s process", prog);
1933 } else {
1934 chp->pid = pid;
1935 chp->prog = prog;
1936 chp->done = done;
1937 chp->arg = arg;
1938 chp->next = children;
1939 chp->killable = killable;
1940 children = chp;
1941 }
1942 }
1943
1944 /*
1945 * childwait_end - we got fed up waiting for the child processes to
1946 * exit, send them all a SIGTERM.
1947 */
1948 static void
childwait_end(arg)1949 childwait_end(arg)
1950 void *arg;
1951 {
1952 struct subprocess *chp;
1953
1954 for (chp = children; chp != NULL; chp = chp->next) {
1955 if (debug)
1956 dbglog("sending SIGTERM to process %d", chp->pid);
1957 kill(chp->pid, SIGTERM);
1958 }
1959 childwait_done = 1;
1960 }
1961
1962 /*
1963 * forget_child - clean up after a dead child
1964 */
1965 static void
forget_child(pid,status)1966 forget_child(pid, status)
1967 int pid, status;
1968 {
1969 struct subprocess *chp, **prevp;
1970
1971 for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) {
1972 if (chp->pid == pid) {
1973 --n_children;
1974 *prevp = chp->next;
1975 break;
1976 }
1977 }
1978 if (WIFSIGNALED(status)) {
1979 warn("Child process %s (pid %d) terminated with signal %d",
1980 (chp? chp->prog: "??"), pid, WTERMSIG(status));
1981 } else if (debug)
1982 dbglog("Script %s finished (pid %d), status = 0x%x",
1983 (chp? chp->prog: "??"), pid,
1984 WIFEXITED(status) ? WEXITSTATUS(status) : status);
1985 if (chp && chp->done)
1986 (*chp->done)(chp->arg);
1987 if (chp)
1988 free(chp);
1989 }
1990
1991 /*
1992 * reap_kids - get status from any dead child processes,
1993 * and log a message for abnormal terminations.
1994 */
1995 static int
reap_kids()1996 reap_kids()
1997 {
1998 int pid, status;
1999
2000 if (n_children == 0)
2001 return 0;
2002 while ((pid = waitpid(-1, &status, WNOHANG)) != -1 && pid != 0) {
2003 forget_child(pid, status);
2004 }
2005 if (pid == -1) {
2006 if (errno == ECHILD)
2007 return -1;
2008 if (errno != EINTR)
2009 error("Error waiting for child process: %m");
2010 }
2011 return 0;
2012 }
2013
2014 /*
2015 * add_notifier - add a new function to be called when something happens.
2016 */
2017 void
add_notifier(notif,func,arg)2018 add_notifier(notif, func, arg)
2019 struct notifier **notif;
2020 notify_func func;
2021 void *arg;
2022 {
2023 struct notifier *np;
2024
2025 np = malloc(sizeof(struct notifier));
2026 if (np == 0)
2027 novm("notifier struct");
2028 np->next = *notif;
2029 np->func = func;
2030 np->arg = arg;
2031 *notif = np;
2032 }
2033
2034 /*
2035 * remove_notifier - remove a function from the list of things to
2036 * be called when something happens.
2037 */
2038 void
remove_notifier(notif,func,arg)2039 remove_notifier(notif, func, arg)
2040 struct notifier **notif;
2041 notify_func func;
2042 void *arg;
2043 {
2044 struct notifier *np;
2045
2046 for (; (np = *notif) != 0; notif = &np->next) {
2047 if (np->func == func && np->arg == arg) {
2048 *notif = np->next;
2049 free(np);
2050 break;
2051 }
2052 }
2053 }
2054
2055 /*
2056 * notify - call a set of functions registered with add_notifier.
2057 */
2058 void
notify(notif,val)2059 notify(notif, val)
2060 struct notifier *notif;
2061 int val;
2062 {
2063 struct notifier *np;
2064
2065 while ((np = notif) != 0) {
2066 notif = np->next;
2067 (*np->func)(np->arg, val);
2068 }
2069 }
2070
2071 /*
2072 * novm - log an error message saying we ran out of memory, and die.
2073 */
2074 void
novm(msg)2075 novm(msg)
2076 char *msg;
2077 {
2078 fatal("Virtual memory exhausted allocating %s\n", msg);
2079 }
2080
2081 /*
2082 * script_setenv - set an environment variable value to be used
2083 * for scripts that we run (e.g. ip-up, auth-up, etc.)
2084 */
2085 void
script_setenv(var,value,iskey)2086 script_setenv(var, value, iskey)
2087 char *var, *value;
2088 int iskey;
2089 {
2090 size_t varl = strlen(var);
2091 size_t vl = varl + strlen(value) + 2;
2092 int i;
2093 char *p, *newstring;
2094
2095 newstring = (char *) malloc(vl+1);
2096 if (newstring == 0)
2097 return;
2098 *newstring++ = iskey;
2099 slprintf(newstring, vl, "%s=%s", var, value);
2100
2101 /* check if this variable is already set */
2102 if (script_env != 0) {
2103 for (i = 0; (p = script_env[i]) != 0; ++i) {
2104 if (strncmp(p, var, varl) == 0 && p[varl] == '=') {
2105 #ifdef USE_TDB
2106 if (p[-1] && pppdb != NULL)
2107 delete_db_key(p);
2108 #endif
2109 free(p-1);
2110 script_env[i] = newstring;
2111 #ifdef USE_TDB
2112 if (pppdb != NULL) {
2113 if (iskey)
2114 add_db_key(newstring);
2115 update_db_entry();
2116 }
2117 #endif
2118 return;
2119 }
2120 }
2121 } else {
2122 /* no space allocated for script env. ptrs. yet */
2123 i = 0;
2124 script_env = malloc(16 * sizeof(char *));
2125 if (script_env == 0) {
2126 free(newstring - 1);
2127 return;
2128 }
2129 s_env_nalloc = 16;
2130 }
2131
2132 if (!add_script_env(i, newstring))
2133 return;
2134
2135 #ifdef USE_TDB
2136 if (pppdb != NULL) {
2137 if (iskey)
2138 add_db_key(newstring);
2139 update_db_entry();
2140 }
2141 #endif
2142 }
2143
2144 /*
2145 * script_unsetenv - remove a variable from the environment
2146 * for scripts.
2147 */
2148 void
script_unsetenv(var)2149 script_unsetenv(var)
2150 char *var;
2151 {
2152 int vl = strlen(var);
2153 int i;
2154 char *p;
2155
2156 if (script_env == 0)
2157 return;
2158 for (i = 0; (p = script_env[i]) != 0; ++i) {
2159 if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
2160 #ifdef USE_TDB
2161 if (p[-1] && pppdb != NULL)
2162 delete_db_key(p);
2163 #endif
2164 remove_script_env(i);
2165 break;
2166 }
2167 }
2168 #ifdef USE_TDB
2169 if (pppdb != NULL)
2170 update_db_entry();
2171 #endif
2172 }
2173
2174 /*
2175 * Any arbitrary string used as a key for locking the database.
2176 * It doesn't matter what it is as long as all pppds use the same string.
2177 */
2178 #define PPPD_LOCK_KEY "pppd lock"
2179
2180 /*
2181 * lock_db - get an exclusive lock on the TDB database.
2182 * Used to ensure atomicity of various lookup/modify operations.
2183 */
lock_db()2184 void lock_db()
2185 {
2186 #ifdef USE_TDB
2187 TDB_DATA key;
2188
2189 key.dptr = PPPD_LOCK_KEY;
2190 key.dsize = strlen(key.dptr);
2191 tdb_chainlock(pppdb, key);
2192 #endif
2193 }
2194
2195 /*
2196 * unlock_db - remove the exclusive lock obtained by lock_db.
2197 */
unlock_db()2198 void unlock_db()
2199 {
2200 #ifdef USE_TDB
2201 TDB_DATA key;
2202
2203 key.dptr = PPPD_LOCK_KEY;
2204 key.dsize = strlen(key.dptr);
2205 tdb_chainunlock(pppdb, key);
2206 #endif
2207 }
2208
2209 #ifdef USE_TDB
2210 /*
2211 * update_db_entry - update our entry in the database.
2212 */
2213 static void
update_db_entry()2214 update_db_entry()
2215 {
2216 TDB_DATA key, dbuf;
2217 int vlen, i;
2218 char *p, *q, *vbuf;
2219
2220 if (script_env == NULL)
2221 return;
2222 vlen = 0;
2223 for (i = 0; (p = script_env[i]) != 0; ++i)
2224 vlen += strlen(p) + 1;
2225 vbuf = malloc(vlen + 1);
2226 if (vbuf == 0)
2227 novm("database entry");
2228 q = vbuf;
2229 for (i = 0; (p = script_env[i]) != 0; ++i)
2230 q += slprintf(q, vbuf + vlen - q, "%s;", p);
2231
2232 key.dptr = db_key;
2233 key.dsize = strlen(db_key);
2234 dbuf.dptr = vbuf;
2235 dbuf.dsize = vlen;
2236 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
2237 error("tdb_store failed: %s", tdb_errorstr(pppdb));
2238
2239 if (vbuf)
2240 free(vbuf);
2241
2242 }
2243
2244 /*
2245 * add_db_key - add a key that we can use to look up our database entry.
2246 */
2247 static void
add_db_key(str)2248 add_db_key(str)
2249 const char *str;
2250 {
2251 TDB_DATA key, dbuf;
2252
2253 key.dptr = (char *) str;
2254 key.dsize = strlen(str);
2255 dbuf.dptr = db_key;
2256 dbuf.dsize = strlen(db_key);
2257 if (tdb_store(pppdb, key, dbuf, TDB_REPLACE))
2258 error("tdb_store key failed: %s", tdb_errorstr(pppdb));
2259 }
2260
2261 /*
2262 * delete_db_key - delete a key for looking up our database entry.
2263 */
2264 static void
delete_db_key(str)2265 delete_db_key(str)
2266 const char *str;
2267 {
2268 TDB_DATA key;
2269
2270 key.dptr = (char *) str;
2271 key.dsize = strlen(str);
2272 tdb_delete(pppdb, key);
2273 }
2274
2275 /*
2276 * cleanup_db - delete all the entries we put in the database.
2277 */
2278 static void
cleanup_db()2279 cleanup_db()
2280 {
2281 TDB_DATA key;
2282 int i;
2283 char *p;
2284
2285 key.dptr = db_key;
2286 key.dsize = strlen(db_key);
2287 tdb_delete(pppdb, key);
2288 for (i = 0; (p = script_env[i]) != 0; ++i)
2289 if (p[-1])
2290 delete_db_key(p);
2291 }
2292 #endif /* USE_TDB */
2293