X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fauth.c;h=92fe82d9cac8e56fc64405a4c1f3641ecc951f36;hp=9cc3af78490d9896eab94c7f27e4c54652f5870e;hb=f482dc10721044d7ffe4cbc2e78f7ea93b1040e0;hpb=7977da267649fee17261d0d163a12863f3534b57 diff --git a/pppd/auth.c b/pppd/auth.c index 9cc3af7..92fe82d 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -68,12 +68,13 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: auth.c,v 1.99 2004/11/04 10:02:26 paulus Exp $" +#define RCSID "$Id: auth.c,v 1.104 2005/07/09 05:49:44 paulus Exp $" #include #include #include #include +#include #include #include #include @@ -531,6 +532,58 @@ void link_required(unit) int unit; { + char *msg; + + new_phase(PHASE_SERIALCONN); + + devfd = the_channel->connect(); + msg = "Connect script failed"; + if (devfd < 0) + goto fail; + + /* set up the serial device as a ppp interface */ + /* + * N.B. we used to do tdb_writelock/tdb_writeunlock around this + * (from establish_ppp to set_ifunit). However, we won't be + * doing the set_ifunit in multilink mode, which is the only time + * we need the atomicity that the tdb_writelock/tdb_writeunlock + * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. + */ + fd_ppp = the_channel->establish_ppp(devfd); + msg = "ppp establishment failed"; + if (fd_ppp < 0) { + status = EXIT_FATAL_ERROR; + goto disconnect; + } + + if (!demand && ifunit >= 0) + set_ifunit(1); + + /* + * Start opening the connection and wait for + * incoming events (reply, timeout, etc.). + */ + if (ifunit >= 0) + notice("Connect: %s <--> %s", ifname, ppp_devnam); + else + notice("Starting negotiation on %s", ppp_devnam); + add_fd(fd_ppp); + + status = EXIT_NEGOTIATION_FAILED; + new_phase(PHASE_ESTABLISH); + + lcp_lowerup(0); + return; + + disconnect: + new_phase(PHASE_DISCONNECT); + if (the_channel->disconnect) + the_channel->disconnect(); + + fail: + new_phase(PHASE_DEAD); + if (the_channel->cleanup) + (*the_channel->cleanup)(); } /* @@ -541,16 +594,65 @@ void link_terminated(unit) int unit; { - if (phase == PHASE_DEAD) + if (phase == PHASE_DEAD || phase == PHASE_MASTER) return; + new_phase(PHASE_DISCONNECT); + if (pap_logout_hook) { pap_logout_hook(); } else { if (logged_in) plogout(); } - new_phase(PHASE_DEAD); - notice("Connection terminated."); + + if (!doing_multilink) { + notice("Connection terminated."); + print_link_stats(); + } else + notice("Link terminated."); + + /* + * Delete pid files before disestablishing ppp. Otherwise it + * can happen that another pppd gets the same unit and then + * we delete its pid file. + */ + if (!doing_multilink && !demand) + remove_pidfiles(); + + /* + * If we may want to bring the link up again, transfer + * the ppp unit back to the loopback. Set the + * real serial device back to its normal mode of operation. + */ + if (fd_ppp >= 0) { + remove_fd(fd_ppp); + clean_check(); + the_channel->disestablish_ppp(devfd); + if (doing_multilink) + mp_exit_bundle(); + fd_ppp = -1; + } + if (!hungup) + lcp_lowerdown(0); + if (!doing_multilink && !demand) + script_unsetenv("IFNAME"); + + /* + * Run disconnector script, if requested. + * XXX we may not be able to do this if the line has hung up! + */ + if (devfd >= 0 && the_channel->disconnect) { + the_channel->disconnect(); + devfd = -1; + } + + if (doing_multilink && multilink_master) { + if (!bundle_terminating) + new_phase(PHASE_MASTER); + else + mp_bundle_terminated(); + } else + new_phase(PHASE_DEAD); } /* @@ -559,17 +661,30 @@ link_terminated(unit) void link_down(unit) int unit; +{ + if (auth_state != s_down) { + notify(link_down_notifier, 0); + auth_state = s_down; + if (auth_script_state == s_up && auth_script_pid == 0) { + update_link_stats(unit); + auth_script_state = s_down; + auth_script(_PATH_AUTHDOWN); + } + } + if (!doing_multilink) { + upper_layers_down(unit); + if (phase != PHASE_DEAD && phase != PHASE_MASTER) + new_phase(PHASE_ESTABLISH); + } + /* XXX if doing_multilink, should do something to stop + network-layer traffic on the link */ +} + +void upper_layers_down(int unit) { int i; struct protent *protp; - notify(link_down_notifier, 0); - auth_state = s_down; - if (auth_script_state == s_up && auth_script_pid == 0) { - update_link_stats(unit); - auth_script_state = s_down; - auth_script(_PATH_AUTHDOWN); - } for (i = 0; (protp = protocols[i]) != NULL; ++i) { if (!protp->enabled_flag) continue; @@ -580,8 +695,6 @@ link_down(unit) } num_np_open = 0; num_np_up = 0; - if (phase != PHASE_DEAD) - new_phase(PHASE_ESTABLISH); } /* @@ -602,10 +715,12 @@ link_established(unit) /* * Tell higher-level protocols that LCP is up. */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol != PPP_LCP && protp->enabled_flag - && protp->lowerup != NULL) - (*protp->lowerup)(unit); + if (!doing_multilink) { + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol != PPP_LCP && protp->enabled_flag + && protp->lowerup != NULL) + (*protp->lowerup)(unit); + } if (!auth_required && noauth_addrs != NULL) set_allowed_addrs(unit, NULL, NULL); @@ -1104,7 +1219,7 @@ auth_check_options() if (auth_required) { allow_any_ip = 0; if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) { - wo->neg_chap = 1; + wo->neg_chap = chap_mdtype_all != MDTYPE_NONE; wo->chap_mdtype = chap_mdtype_all; wo->neg_upap = 1; wo->neg_eap = 1; @@ -1536,6 +1651,7 @@ plogin(user, passwd, msg) static void plogout() { + char *tty; #ifdef USE_PAM int pam_error; @@ -1546,14 +1662,12 @@ plogout() } /* Apparently the pam stuff does closelog(). */ reopen_log(); -#else /* ! USE_PAM */ - char *tty; +#endif /* USE_PAM */ tty = devnam; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ -#endif /* ! USE_PAM */ logged_in = 0; }