* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RCSID "$Id: auth.c,v 1.113 2007/06/19 02:08:35 carlsonj Exp $"
+#define RCSID "$Id: auth.c,v 1.117 2008/07/01 12:27:56 paulus Exp $"
#include <stdio.h>
#include <stddef.h>
#endif
#include <time.h>
+#ifdef SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
#include "pppd.h"
#include "fsm.h"
#include "lcp.h"
int (*allowed_address_hook) __P((u_int32_t addr)) = NULL;
+#ifdef HAVE_MULTILINK
+/* Hook for plugin to hear when an interface joins a multilink bundle */
+void (*multilink_join_hook) __P((void)) = NULL;
+#endif
+
/* A notifier for when the peer has authenticated itself,
and we are proceeding to the network phase. */
struct notifier *auth_up_notifier = NULL;
bool auth_required = 0; /* Always require authentication from peer */
bool allow_any_ip = 0; /* Allow peer to use any IP address */
bool explicit_remote = 0; /* User specified explicit remote name */
+bool explicit_user = 0; /* Set if "user" option supplied */
+bool explicit_passwd = 0; /* Set if "password" option supplied */
char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
static char *uafname; /* name of most recent +ua file */
OPT_PRIO | OPT_A2STRVAL, &uafname },
{ "user", o_string, user,
- "Set name for auth with peer", OPT_PRIO | OPT_STATIC, NULL, MAXNAMELEN },
+ "Set name for auth with peer", OPT_PRIO | OPT_STATIC,
+ &explicit_user, MAXNAMELEN },
{ "password", o_string, passwd,
"Password for authenticating us to the peer",
- OPT_PRIO | OPT_STATIC | OPT_HIDE, NULL, MAXSECRETLEN },
+ OPT_PRIO | OPT_STATIC | OPT_HIDE,
+ &explicit_passwd, MAXSECRETLEN },
{ "usehostname", o_bool, &usehostname,
"Must use hostname for authentication", 1 },
euid = geteuid();
if (seteuid(getuid()) == -1) {
option_error("unable to reset uid before opening %s: %m", fname);
+ free(fname);
return 0;
}
ufile = fopen(fname, "r");
fatal("unable to regain privileges: %m");
if (ufile == NULL) {
option_error("unable to open user login data file %s", fname);
+ free(fname);
return 0;
}
check_access(ufile, fname);
|| fgets(p, MAXSECRETLEN - 1, ufile) == NULL) {
fclose(ufile);
option_error("unable to read user login data file %s", fname);
+ free(fname);
return 0;
}
fclose(ufile);
if (l > 0 && p[l-1] == '\n')
p[l-1] = 0;
- if (override_value("user", option_priority, fname))
+ if (override_value("user", option_priority, fname)) {
strlcpy(user, u, sizeof(user));
- if (override_value("passwd", option_priority, fname))
+ explicit_user = 1;
+ }
+ if (override_value("passwd", option_priority, fname)) {
strlcpy(passwd, p, sizeof(passwd));
+ explicit_passwd = 1;
+ }
+ free(fname);
return (1);
}
void start_link(unit)
int unit;
{
- char *msg;
-
+ status = EXIT_CONNECT_FAILED;
new_phase(PHASE_SERIALCONN);
+ hungup = 0;
devfd = the_channel->connect();
- msg = "Connect script failed";
if (devfd < 0)
goto fail;
* 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;
(*the_channel->cleanup)();
if (doing_multilink && multilink_master) {
- if (!bundle_terminating)
+ if (!bundle_terminating) {
new_phase(PHASE_MASTER);
- else
+ if (master_detach && !detached)
+ detach();
+ } else
mp_bundle_terminated();
} else
new_phase(PHASE_DEAD);
chap_auth_with_peer(unit, user, CHAP_DIGEST(ho->chap_mdtype));
auth |= CHAP_WITHPEER;
} else if (ho->neg_upap) {
- if (passwd[0] == 0) {
+ /* If a blank password was explicitly given as an option, trust
+ the user and don't try to look up one. */
+ if (passwd[0] == 0 && !explicit_passwd) {
passwd_from_file = 1;
if (!get_pap_passwd(passwd))
error("No secret found for PAP login");
#ifdef HAVE_MULTILINK
if (multilink) {
if (mp_join_bundle()) {
+ if (multilink_join_hook)
+ (*multilink_join_hook)();
if (updetach && !nodetach)
detach();
return;
/*
* Detach now, if the updetach option was given.
*/
- if (updetach && !nodetach)
+ if (updetach && !nodetach) {
+ dbglog("updetach is set. Now detaching.");
detach();
+#ifdef SYSTEMD
+ } else if (nodetach && up_sdnotify) {
+ dbglog("up_sdnotify is set. Now notifying systemd: READY=1");
+ sd_notify(0, "READY=1");
+#endif
+ }
}
++num_np_up;
}
check_maxoctets(arg)
void *arg;
{
- int diff;
unsigned int used;
update_link_stats(ifunit);
used = link_stats.bytes_in+link_stats.bytes_out;
break;
}
- diff = maxoctets - used;
- if(diff < 0) {
+ if (used > maxoctets) {
notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used);
status = EXIT_TRAFFIC_LIMIT;
lcp_close(0, "Traffic limit");
/* Default our_name to hostname, and user to our_name */
if (our_name[0] == 0 || usehostname)
strlcpy(our_name, hostname, sizeof(our_name));
- if (user[0] == 0)
+ /* If a blank username was explicitly given as an option, trust
+ the user and don't use our_name */
+ if (user[0] == 0 && !explicit_user)
strlcpy(user, our_name, sizeof(user));
/*
}
if (secret[0] != 0 && !login_secret) {
/* password given in pap-secrets - must match */
- if ((cryptpap || strcmp(passwd, secret) != 0)
- && strcmp(crypt(passwd, secret), secret) != 0)
- ret = UPAP_AUTHNAK;
+ if (cryptpap || strcmp(passwd, secret) != 0) {
+ char *cbuf = crypt(passwd, secret);
+ if (!cbuf || strcmp(cbuf, secret) != 0)
+ ret = UPAP_AUTHNAK;
+ }
}
}
fclose(f);