X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Fauth.c;h=0fbc9b92941293c0da3fc1434c8a8156b13d4346;hb=cb6271cf11b1237286e53124dd7a6ac2e24f6671;hp=c924d7be35bfaf72105a4d8ce288f19a4808a3ff;hpb=bfa20ccde2a70b1252dbb614132f1a4cbee815d4;p=ppp.git diff --git a/pppd/auth.c b/pppd/auth.c index c924d7b..0fbc9b9 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: auth.c,v 1.39 1998/11/07 06:59:25 paulus Exp $"; +static char rcsid[] = "$Id: auth.c,v 1.45 1999/03/12 06:07:14 paulus Exp $"; #endif #include @@ -42,6 +42,7 @@ static char rcsid[] = "$Id: auth.c,v 1.39 1998/11/07 06:59:25 paulus Exp $"; #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ static char rcsid[] = "$Id: auth.c,v 1.39 1998/11/07 06:59:25 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,10 +155,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 *)); - -#ifdef OLD_OPTIONS -static int setupapfile __P((char **)); -#endif +static int setupapfile __P((char **)); +static int privgroup __P((char **)); /* * Authentication-related options. @@ -170,7 +169,7 @@ option_t auth_options[] = { { "refuse-pap", o_bool, &refuse_pap, "Don't agree to auth to peer with PAP", 1 }, { "-pap", o_bool, &refuse_pap, - "Don't allow UPAP authentication with peer", 1 }, + "Don't allow PAP authentication with peer", 1 }, { "require-chap", o_bool, &lcp_wantoptions[0].neg_chap, "Require CHAP authentication from peer", 1, &auth_required }, { "+chap", o_bool, &lcp_wantoptions[0].neg_chap, @@ -196,14 +195,13 @@ option_t auth_options[] = { "Use system password database for PAP", 1 }, { "papcrypt", o_bool, &cryptpap, "PAP passwords are encrypted", 1 }, -#if OLD_OPTIONS { "+ua", o_special, setupapfile, "Get PAP user and password from file" }, -#endif + { "privgroup", o_special, privgroup, + "Allow group members to use privileged options", OPT_PRIV }, { NULL } }; -#if OLD_OPTIONS /* * setupapfile - specifies UPAP info for authenticating with peer. */ @@ -217,14 +215,19 @@ setupapfile(argv) lcp_allowoptions[0].neg_upap = 1; /* open user info file */ - if ((ufile = fopen(*argv, "r")) == NULL) { + seteuid(getuid()); + ufile = fopen(*argv, "r"); + seteuid(0); + if (ufile == NULL) { option_error("unable to open user login data file %s", *argv); return 0; } +#if 0 /* check done by setting effective UID above */ if (!readable(fileno(ufile))) { option_error("%s: access denied", *argv); return 0; } +#endif check_access(ufile, *argv); /* get username */ @@ -245,7 +248,31 @@ setupapfile(argv) return (1); } -#endif + + +/* + * 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; +} /* @@ -620,9 +647,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) { @@ -635,6 +662,13 @@ auth_check_options() wo->neg_upap = 0; } + /* + * If we have a default route, require the peer to authenticate + * unless the noauth option was given. + */ + if (!auth_required && !allow_any_ip && have_route_to(0)) + auth_required = 1; + /* * Check whether we have appropriate secrets to use * to authenticate the peer. @@ -654,24 +688,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 (!default_device && devnam_info.priv == 0) { - option_error("can't override device name when noauth option used"); - exit(1); - } - 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); - } - } } /* @@ -1001,7 +1017,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); } @@ -1098,6 +1114,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) @@ -1121,10 +1138,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; } @@ -1288,6 +1303,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]); } @@ -1306,11 +1327,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 */ @@ -1419,7 +1437,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) @@ -1497,23 +1516,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. @@ -1522,12 +1539,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 @@ -1537,6 +1555,8 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) /* * Check if the given IP address is allowed by the wordlist. + * XXX accepts this entry even if it has no allowed IP addresses + * if they didn't specify a remote IP address. XXX */ if (ipaddr != 0 && !ip_addr_check(ipaddr, alist)) { free_wordlist(alist); @@ -1551,7 +1571,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;