diff -ur orig/ppp-2.3.10/pppd/auth.c ppp-2.3.10/pppd/auth.c --- orig/ppp-2.3.10/pppd/auth.c 1999/11/15 21:02:00 +++ ppp-2.3.10/pppd/auth.c 1999/12/08 15:31:10 @@ -96,6 +96,9 @@ /* List of addresses which the peer may use. */ static struct permitted_ip *addresses[NUM_PPP]; +/* List of locked addreses. */ +static u_int32_t locked_addresses[NUM_PPP]; + /* Wordlist giving addresses which the peer may use without authenticating itself. */ static struct wordlist *noauth_addrs; @@ -151,6 +154,7 @@ bool allow_any_ip = 0; /* Allow peer to use any IP address */ bool explicit_remote = 0; /* User specified explicit remote name */ char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ +char pool_dir[MAXDIRNAMELEN]; /* Bits in auth_pending[] */ #define PAP_WITHPEER 1 @@ -172,6 +176,7 @@ static int have_pap_secret __P((int *)); static int have_chap_secret __P((char *, char *, int, int *)); static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); +static int lock_ip_addr __P((int, u_int32_t)); static int scan_authfile __P((FILE *, char *, char *, char *, struct wordlist **, struct wordlist **, char *)); @@ -233,6 +238,9 @@ { "allow-ip", o_special, set_noauth_addr, "Set IP address(es) which can be used without authentication", OPT_PRIV }, + { "pool-dir", o_string, pool_dir, + "Set the address pool directory", + OPT_PRIV|OPT_STATIC, NULL, MAXDIRNAMELEN }, { NULL } }; @@ -1514,7 +1522,8 @@ ip[n].base = a & ip[n].mask; ++n; if (~mask == 0 && suggested_ip == 0) - suggested_ip = a; + if ( lock_ip_addr(unit,a) ) + suggested_ip = a; } ip[n].permit = 0; /* make the last entry forbid all addresses */ @@ -1551,11 +1560,13 @@ if (addresses[unit] != NULL) { ok = ip_addr_check(addr, addresses[unit]); - if (ok >= 0) - return ok; + if (ok > 0) + return lock_ip_addr(unit, addr); } if (auth_required) return 0; /* no addresses authorized */ - return allow_any_ip || !have_route_to(addr); + if ( !allow_any_ip && have_route_to(addr) ) + return 0; + return lock_ip_addr(unit, addr); } static int @@ -1597,6 +1608,73 @@ return 1; /* some IP address is allowed */ } return 0; +} + +/* + * lock_ip_addr - if pool_dir is present try to lock the given address + * (and release old lock, if present) + */ +static int +lock_ip_addr(unit, addr) + int unit; + u_int32_t addr; +{ + int pool_dir_len = strlen(pool_dir); + + if ( !pool_dir_len ) + return 1; + + if ( locked_addresses[unit]!=addr ) { + int lockfd; + FILE* lockf; + char fname[MAXDIRNAMELEN]; + struct in_addr in; + + memcpy(fname,pool_dir,pool_dir_len); + + if ( locked_addresses[unit] ) { + in.s_addr = locked_addresses[unit]; + strcpy(fname+pool_dir_len, inet_ntoa(in)); + unlink(fname); + locked_addresses[unit] = 0; + } + + in.s_addr = addr; + strcpy(fname+pool_dir_len, inet_ntoa(in)); + lockfd = open(fname,O_WRONLY|O_CREAT|O_EXCL,S_IRUSR|S_IWUSR); + if ( lockfd == -1 ) + return 0; + lockf = fdopen(lockfd,"w"); + fprintf(lockf,"%d\n",getpid()); + fclose(lockf); + locked_addresses[unit] = addr; + } + return 1; +} + +/* + * unlock_ip_addrs - remove all locks created by lock_ip_addr + */ +void +unlock_ip_addrs() +{ + int unit; + char fname[MAXDIRNAMELEN]; + int pool_dir_len = strlen(pool_dir); + + if ( !pool_dir_len ) + return; + + memcpy(fname,pool_dir,pool_dir_len); + + for (unit=0;unit