X-Git-Url: https://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fauth.c;h=3b0e24341292050657c63d99d37d70aab0989c9b;hp=2f763c11aef515bc273942ca816fcbed4a7db371;hb=7a4dc0ff500aaa176a41965d8d4ad15a97a70904;hpb=a00baab063b349591289cbde22ab40cf80b8f0af diff --git a/pppd/auth.c b/pppd/auth.c index 2f763c1..3b0e243 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -33,15 +33,15 @@ */ #ifndef lint -static char rcsid[] = "$Id: auth.c,v 1.43 1999/03/06 11:28:10 paulus Exp $"; +static char rcsid[] = "$Id: auth.c,v 1.46 1999/03/16 03:15:12 paulus Exp $"; #endif #include #include #include #include -#include #include +#include #include #include #include @@ -81,7 +81,7 @@ static char rcsid[] = "$Id: auth.c,v 1.43 1999/03/06 11:28:10 paulus Exp $"; /* Used for storing a sequence of words. Usually malloced. */ struct wordlist { struct wordlist *next; - char word[1]; + char *word; }; /* Bits in scan_authfile return value */ @@ -154,7 +154,8 @@ static int scan_authfile __P((FILE *, char *, char *, u_int32_t, char *, static void free_wordlist __P((struct wordlist *)); static void auth_script __P((char *)); static void set_allowed_addrs __P((int, struct wordlist *)); -static int setupapfile __P((char **)); +static int setupapfile __P((char **)); +static int privgroup __P((char **)); /* * Authentication-related options. @@ -195,6 +196,8 @@ option_t auth_options[] = { "PAP passwords are encrypted", 1 }, { "+ua", o_special, setupapfile, "Get PAP user and password from file" }, + { "privgroup", o_special, privgroup, + "Allow group members to use privileged options", OPT_PRIV }, { NULL } }; @@ -246,6 +249,31 @@ setupapfile(argv) } +/* + * privgroup - allow members of the group to have privileged access. + */ +static int +privgroup(argv) + char **argv; +{ + struct group *g; + int i; + + g = getgrnam(*argv); + if (g == 0) { + option_error("group %s is unknown", *argv); + return 0; + } + for (i = 0; i < ngroups; ++i) { + if (groups[i] == g->gr_gid) { + privileged = 1; + break; + } + } + return 1; +} + + /* * An Open on LCP has requested a change from Dead to Establish phase. * Do what's necessary to bring the physical layer up. @@ -269,7 +297,7 @@ link_terminated(unit) if (logged_in) plogout(); phase = PHASE_DEAD; - syslog(LOG_NOTICE, "Connection terminated."); + notice("Connection terminated."); } /* @@ -330,7 +358,7 @@ link_established(unit) * of "" and a password of "". If that's not OK, boot it out. */ if (!wo->neg_upap || !null_login(unit)) { - syslog(LOG_WARNING, "peer refused to authenticate"); + warn("peer refused to authenticate: terminating link"); lcp_close(unit, "peer refused to authenticate"); return; } @@ -352,7 +380,7 @@ link_established(unit) if (passwd[0] == 0) { passwd_from_file = 1; if (!get_pap_passwd(passwd)) - syslog(LOG_ERR, "No secret found for PAP login"); + error("No secret found for PAP login"); } upap_authwithpeer(unit, user, passwd); auth |= PAP_WITHPEER; @@ -443,8 +471,7 @@ auth_peer_success(unit, protocol, name, namelen) bit = PAP_PEER; break; default: - syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", - protocol); + warn("auth_peer_success: unknown protocol %x", protocol); return; } @@ -500,8 +527,7 @@ auth_withpeer_success(unit, protocol) bit = PAP_WITHPEER; break; default: - syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", - protocol); + warn("auth_withpeer_success: unknown protocol %x", protocol); bit = 0; } @@ -587,7 +613,7 @@ check_idle(arg) itime = MIN(idle.xmit_idle, idle.recv_idle); if (itime >= idle_time_limit) { /* link is idle: shut it down. */ - syslog(LOG_INFO, "Terminating connection due to lack of activity."); + info("Terminating connection due to lack of activity."); lcp_close(0, "Link inactive"); } else { TIMEOUT(check_idle, NULL, idle_time_limit - itime); @@ -601,7 +627,7 @@ static void connect_time_expired(arg) void *arg; { - syslog(LOG_INFO, "Connect time expired"); + info("Connect time expired"); lcp_close(0, "Connect time expired"); /* Close connection */ } @@ -618,9 +644,9 @@ auth_check_options() /* Default our_name to hostname, and user to our_name */ if (our_name[0] == 0 || usehostname) - strcpy(our_name, hostname); + strlcpy(our_name, sizeof(our_name), hostname); if (user[0] == 0) - strcpy(user, our_name); + strlcpy(user, sizeof(user), our_name); /* If authentication is required, ask peer for CHAP or PAP. */ if (auth_required) { @@ -659,20 +685,6 @@ auth_check_options() remote_name, our_name); exit(1); } - - /* - * Check whether the user tried to override certain values - * set by root. - */ - if (allow_any_ip) { - if ((connector != NULL && connector_info.priv == 0) - || (disconnector != NULL && disconnector_info.priv == 0) - || (welcomer != NULL && welcomer_info.priv == 0)) { - option_error("connect, disconnect and welcome options"); - option_error("are privileged when noauth option is used"); - exit(1); - } - } } /* @@ -751,7 +763,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) ret = UPAP_AUTHACK; f = fopen(filename, "r"); if (f == NULL) { - syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename); + error("Can't open PAP password file %s: %m", filename); ret = UPAP_AUTHNAK; } else { @@ -761,7 +773,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) secret, &addrs, filename) < 0 || (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0) && strcmp(crypt(passwd, secret), secret) != 0)) { - syslog(LOG_WARNING, "PAP authentication failure for %s", user); + warn("PAP authentication failure for %s", user); ret = UPAP_AUTHNAK; } fclose(f); @@ -770,7 +782,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) if (uselogin && ret == UPAP_AUTHACK) { ret = plogin(user, passwd, msg, msglen); if (ret == UPAP_AUTHNAK) { - syslog(LOG_WARNING, "PAP login failure for %s", user); + warn("PAP login failure for %s", user); } } @@ -784,8 +796,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) * On 10'th, drop the connection. */ if (attempts++ >= 10) { - syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s", - attempts, devnam, user); + warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); quit(); } if (attempts > 3) @@ -964,7 +975,7 @@ plogin(user, passwd, msg, msglen) || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) && spwd->sp_lstchg >= 0 && now >= spwd->sp_lstchg + spwd->sp_max)) { - syslog(LOG_WARNING, "Password for %s has expired", user); + warn("Password for %s has expired", user); return (UPAP_AUTHNAK); } pw->pw_passwd = spwd->sp_pwdp; @@ -1002,7 +1013,7 @@ plogin(user, passwd, msg, msglen) (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); memset((void *)&ll, 0, sizeof(ll)); (void)time(&ll.ll_time); - (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); + (void)strlcpy(ll.ll_line, sizeof(ll.ll_line), tty); (void)write(fd, (char *)&ll, sizeof(ll)); (void)close(fd); } @@ -1011,7 +1022,7 @@ plogin(user, passwd, msg, msglen) #endif /* #ifdef USE_PAM */ - syslog(LOG_INFO, "user %s logged in", user); + info("user %s logged in", user); logged_in = TRUE; return (UPAP_AUTHACK); @@ -1099,6 +1110,7 @@ null_login(unit) * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password * could be found. + * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). */ static int get_pap_passwd(passwd) @@ -1122,10 +1134,8 @@ get_pap_passwd(passwd) fclose(f); if (ret < 0) return 0; - if (passwd != NULL) { - strncpy(passwd, secret, MAXSECRETLEN); - passwd[MAXSECRETLEN-1] = 0; - } + if (passwd != NULL) + strlcpy(passwd, MAXSECRETLEN, secret); BZERO(secret, sizeof(secret)); return 1; } @@ -1220,7 +1230,7 @@ get_secret(unit, client, server, secret, secret_len, save_addrs) f = fopen(filename, "r"); if (f == NULL) { - syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename); + error("Can't open chap secret file %s: %m", filename); return 0; } check_access(f, filename); @@ -1236,7 +1246,7 @@ get_secret(unit, client, server, secret, secret_len, save_addrs) len = strlen(secbuf); if (len > MAXSECRETLEN) { - syslog(LOG_ERR, "Secret for %s on %s is too long", client, server); + error("Secret for %s on %s is too long", client, server); len = MAXSECRETLEN; } BCOPY(secbuf, secret, len); @@ -1289,6 +1299,12 @@ auth_ip_addr(unit, addr) int unit; u_int32_t addr; { + + if (addresses[unit] == NULL) { + if (auth_required) + return 0; /* no addresses authorized */ + return allow_any_ip || !have_route_to(addr); + } return ip_addr_check(addr, addresses[unit]); } @@ -1307,11 +1323,8 @@ ip_addr_check(addr, addrs) if (bad_ip_adrs(addr)) return 0; - if (addrs == NULL) { - if (auth_required) - return 0; /* no addresses authorized */ - return allow_any_ip || !have_route_to(addr); - } + if (addrs == NULL) + return 0; /* no addresses authorized */ for (; addrs != NULL; addrs = addrs->next) { /* "-" means no addresses authorized, "*" means any address allowed */ @@ -1334,9 +1347,8 @@ ip_addr_check(addr, addrs) bit_count = (int) strtol (ptr_mask+1, (char **) 0, 10); if (bit_count <= 0 || bit_count > 32) { - syslog (LOG_WARNING, - "invalid address length %s in auth. address list", - ptr_mask); + warn("invalid address length %v in auth. address list", + ptr_mask); continue; } *ptr_mask = '\0'; @@ -1369,9 +1381,7 @@ ip_addr_check(addr, addrs) *ptr_mask = '/'; if (a == (u_int32_t)-1L) - syslog (LOG_WARNING, - "unknown host %s in auth. address list", - addrs->word); + warn("unknown host %s in auth. address list", addrs->word); else /* Here a and addr are in network byte order, and mask is in host order. */ @@ -1406,9 +1416,10 @@ check_access(f, filename) struct stat sbuf; if (fstat(fileno(f), &sbuf) < 0) { - syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename); + warn("cannot stat secret file %s: %m", filename); } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename); + warn("Warning - secret file %s has world and/or group access", + filename); } } @@ -1420,7 +1431,8 @@ check_access(f, filename) * NONWILD_CLIENT set if the secret didn't have "*" for the client, and * NONWILD_SERVER set if the secret didn't have "*" for the server. * Any following words on the line (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. + * info) are placed in a wordlist and returned in *addrs. + * We assume secret is NULL or points to MAXWORDLEN bytes of space. */ static int scan_authfile(f, client, server, ipaddr, secret, addrs, filename) @@ -1498,23 +1510,21 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) * Special syntax: @filename means read secret from file. */ if (word[0] == '@') { - strcpy(atfile, word+1); + strlcpy(atfile, sizeof(atfile), word+1); if ((sf = fopen(atfile, "r")) == NULL) { - syslog(LOG_WARNING, "can't open indirect secret file %s", - atfile); + warn("can't open indirect secret file %s", atfile); continue; } check_access(sf, atfile); if (!getword(sf, word, &xxx, atfile)) { - syslog(LOG_WARNING, "no secret in indirect secret file %s", - atfile); + warn("no secret in indirect secret file %s", atfile); fclose(sf); continue; } fclose(sf); } if (secret != NULL) - strcpy(lsecret, word); + strlcpy(lsecret, sizeof(lsecret), word); /* * Now read address authorization info and make a wordlist. @@ -1523,12 +1533,13 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) for (;;) { if (!getword(f, word, &newline, filename) || newline) break; - ap = (struct wordlist *) malloc(sizeof(struct wordlist) - + strlen(word)); + ap = (struct wordlist *) malloc(sizeof(struct wordlist)); if (ap == NULL) novm("authorized addresses"); ap->next = NULL; - strcpy(ap->word, word); + ap->word = strdup(word); + if (ap->word == NULL) + novm("authorized address"); if (alist == NULL) alist = ap; else @@ -1554,7 +1565,7 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) free_wordlist(addr_list); addr_list = alist; if (secret != NULL) - strcpy(secret, lsecret); + strlcpy(secret, MAXWORDLEN, lsecret); if (!newline) break; @@ -1601,10 +1612,10 @@ auth_script(script) if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) user_name = pw->pw_name; else { - sprintf(struid, "%d", getuid()); + slprintf(struid, sizeof(struid), "%d", getuid()); user_name = struid; } - sprintf(strspeed, "%d", baud_rate); + slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); argv[0] = script; argv[1] = ifname;