1 /* $OpenBSD: auth.c,v 1.30 2003/09/26 06:01:42 pvalchev Exp $ */ 2 3 /* 4 * auth.c - PPP authentication and phase control. 5 * 6 * Copyright (c) 1989-2002 Paul Mackerras. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. The name(s) of the authors of this software must not be used to 21 * endorse or promote products derived from this software without 22 * prior written permission. 23 * 24 * 4. Redistributions of any form whatsoever must retain the following 25 * acknowledgment: 26 * "This product includes software developed by Paul Mackerras 27 * <paulus@samba.org>". 28 * 29 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO 30 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 31 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 32 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 33 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 34 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 35 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 36 * 37 * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in 48 * the documentation and/or other materials provided with the 49 * distribution. 50 * 51 * 3. The name "Carnegie Mellon University" must not be used to 52 * endorse or promote products derived from this software without 53 * prior written permission. For permission or any legal 54 * details, please contact 55 * Office of Technology Transfer 56 * Carnegie Mellon University 57 * 5000 Forbes Avenue 58 * Pittsburgh, PA 15213-3890 59 * (412) 268-4387, fax: (412) 268-7395 60 * tech-transfer@andrew.cmu.edu 61 * 62 * 4. Redistributions of any form whatsoever must retain the following 63 * acknowledgment: 64 * "This product includes software developed by Computing Services 65 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 66 * 67 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO 68 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 69 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 70 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 71 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 72 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 73 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 74 */ 75 76 #ifndef lint 77 #if 0 78 static char rcsid[] = "Id: auth.c,v 1.37 1998/03/26 04:46:03 paulus Exp $"; 79 #else 80 static char rcsid[] = "$OpenBSD: auth.c,v 1.30 2003/09/26 06:01:42 pvalchev Exp $"; 81 #endif 82 #endif 83 84 #include <stdio.h> 85 #include <stddef.h> 86 #include <stdlib.h> 87 #include <unistd.h> 88 #include <syslog.h> 89 #include <pwd.h> 90 #include <string.h> 91 #include <sys/types.h> 92 #include <sys/stat.h> 93 #include <sys/socket.h> 94 #include <utmp.h> 95 #include <fcntl.h> 96 #if defined(_PATH_LASTLOG) && defined(_linux_) 97 #include <lastlog.h> 98 #endif 99 100 #include <netdb.h> 101 #include <netinet/in.h> 102 #include <arpa/inet.h> 103 104 #ifdef USE_PAM 105 #include <security/pam_appl.h> 106 #endif 107 108 #ifdef HAS_SHADOW 109 #include <shadow.h> 110 #ifndef PW_PPP 111 #define PW_PPP PW_LOGIN 112 #endif 113 #endif 114 115 #include "pppd.h" 116 #include "fsm.h" 117 #include "lcp.h" 118 #include "ipcp.h" 119 #include "upap.h" 120 #include "chap.h" 121 #ifdef CBCP_SUPPORT 122 #include "cbcp.h" 123 #endif 124 #include "pathnames.h" 125 126 /* Used for storing a sequence of words. Usually malloced. */ 127 struct wordlist { 128 struct wordlist *next; 129 char word[1]; 130 }; 131 132 /* Bits in scan_authfile return value */ 133 #define NONWILD_SERVER 1 134 #define NONWILD_CLIENT 2 135 136 #define ISWILD(word) (word[0] == '*' && word[1] == 0) 137 138 #define FALSE 0 139 #define TRUE 1 140 141 /* The name by which the peer authenticated itself to us. */ 142 char peer_authname[MAXNAMELEN]; 143 144 /* Records which authentication operations haven't completed yet. */ 145 static int auth_pending[NUM_PPP]; 146 147 /* Set if we have successfully called plogin() */ 148 static int logged_in; 149 150 /* Set if we have run the /etc/ppp/auth-up script. */ 151 static int did_authup; 152 153 /* List of addresses which the peer may use. */ 154 static struct wordlist *addresses[NUM_PPP]; 155 156 /* Number of network protocols which we have opened. */ 157 static int num_np_open; 158 159 /* Number of network protocols which have come up. */ 160 static int num_np_up; 161 162 /* Set if we got the contents of passwd[] from the pap-secrets file. */ 163 static int passwd_from_file; 164 165 /* Bits in auth_pending[] */ 166 #define PAP_WITHPEER 1 167 #define PAP_PEER 2 168 #define CHAP_WITHPEER 4 169 #define CHAP_PEER 8 170 171 extern char *crypt(const char *, const char *); 172 173 /* Prototypes for procedures local to this file. */ 174 175 static void network_phase(int); 176 static void check_idle(void *); 177 static void connect_time_expired(void *); 178 static int plogin(char *, char *, char **, int *); 179 static void plogout(void); 180 static int null_login(int); 181 static int get_pap_passwd(char *); 182 static int have_pap_secret(void); 183 static int have_chap_secret(char *, char *, u_int32_t); 184 static int ip_addr_check(u_int32_t, struct wordlist *); 185 static int scan_authfile(FILE *, char *, char *, u_int32_t, char *, 186 struct wordlist **, char *); 187 static void free_wordlist(struct wordlist *); 188 static void auth_script(char *); 189 static void set_allowed_addrs(int, struct wordlist *); 190 191 /* 192 * An Open on LCP has requested a change from Dead to Establish phase. 193 * Do what's necessary to bring the physical layer up. 194 */ 195 void 196 link_required(unit) 197 int unit; 198 { 199 } 200 201 /* 202 * LCP has terminated the link; go to the Dead phase and take the 203 * physical layer down. 204 */ 205 void 206 link_terminated(unit) 207 int unit; 208 { 209 if (phase == PHASE_DEAD) 210 return; 211 if (logged_in) 212 plogout(); 213 phase = PHASE_DEAD; 214 syslog(LOG_NOTICE, "Connection terminated."); 215 } 216 217 /* 218 * LCP has gone down; it will either die or try to re-establish. 219 */ 220 void 221 link_down(unit) 222 int unit; 223 { 224 int i; 225 struct protent *protp; 226 227 if (did_authup) { 228 auth_script(_PATH_AUTHDOWN); 229 did_authup = 0; 230 } 231 for (i = 0; (protp = protocols[i]) != NULL; ++i) { 232 if (!protp->enabled_flag) 233 continue; 234 if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) 235 (*protp->lowerdown)(unit); 236 if (protp->protocol < 0xC000 && protp->close != NULL) 237 (*protp->close)(unit, "LCP down"); 238 } 239 num_np_open = 0; 240 num_np_up = 0; 241 if (phase != PHASE_DEAD) 242 phase = PHASE_TERMINATE; 243 } 244 245 /* 246 * The link is established. 247 * Proceed to the Dead, Authenticate or Network phase as appropriate. 248 */ 249 void 250 link_established(unit) 251 int unit; 252 { 253 int auth; 254 lcp_options *wo = &lcp_wantoptions[unit]; 255 lcp_options *go = &lcp_gotoptions[unit]; 256 lcp_options *ho = &lcp_hisoptions[unit]; 257 int i; 258 struct protent *protp; 259 260 /* 261 * Tell higher-level protocols that LCP is up. 262 */ 263 for (i = 0; (protp = protocols[i]) != NULL; ++i) 264 if (protp->protocol != PPP_LCP && protp->enabled_flag 265 && protp->lowerup != NULL) 266 (*protp->lowerup)(unit); 267 268 if (auth_required && !(go->neg_chap || go->neg_upap)) { 269 /* 270 * We wanted the peer to authenticate itself, and it refused: 271 * treat it as though it authenticated with PAP using a username 272 * of "" and a password of "". If that's not OK, boot it out. 273 */ 274 if (!wo->neg_upap || !null_login(unit)) { 275 syslog(LOG_WARNING, "peer refused to authenticate"); 276 lcp_close(unit, "peer refused to authenticate"); 277 return; 278 } 279 } 280 281 phase = PHASE_AUTHENTICATE; 282 auth = 0; 283 if (go->neg_chap) { 284 ChapAuthPeer(unit, our_name, go->chap_mdtype); 285 auth |= CHAP_PEER; 286 } else if (go->neg_upap) { 287 upap_authpeer(unit); 288 auth |= PAP_PEER; 289 } 290 if (ho->neg_chap) { 291 ChapAuthWithPeer(unit, user, ho->chap_mdtype); 292 auth |= CHAP_WITHPEER; 293 } else if (ho->neg_upap) { 294 if (passwd[0] == 0) { 295 passwd_from_file = 1; 296 if (!get_pap_passwd(passwd)) 297 syslog(LOG_ERR, "No secret found for PAP login"); 298 } 299 upap_authwithpeer(unit, user, passwd); 300 auth |= PAP_WITHPEER; 301 } 302 auth_pending[unit] = auth; 303 304 if (!auth) 305 network_phase(unit); 306 } 307 308 /* 309 * Proceed to the network phase. 310 */ 311 static void 312 network_phase(unit) 313 int unit; 314 { 315 int i; 316 struct protent *protp; 317 lcp_options *go = &lcp_gotoptions[unit]; 318 319 /* 320 * If the peer had to authenticate, run the auth-up script now. 321 */ 322 if ((go->neg_chap || go->neg_upap) && !did_authup) { 323 auth_script(_PATH_AUTHUP); 324 did_authup = 1; 325 } 326 327 #ifdef CBCP_SUPPORT 328 /* 329 * If we negotiated callback, do it now. 330 */ 331 if (go->neg_cbcp) { 332 phase = PHASE_CALLBACK; 333 (*cbcp_protent.open)(unit); 334 return; 335 } 336 #endif 337 338 phase = PHASE_NETWORK; 339 #if 0 340 if (!demand) 341 set_filters(&pass_filter, &active_filter); 342 #endif 343 for (i = 0; (protp = protocols[i]) != NULL; ++i) 344 if (protp->protocol < 0xC000 && protp->enabled_flag 345 && protp->open != NULL) { 346 (*protp->open)(unit); 347 if (protp->protocol != PPP_CCP) 348 ++num_np_open; 349 } 350 351 if (num_np_open == 0) 352 /* nothing to do */ 353 lcp_close(0, "No network protocols running"); 354 } 355 356 /* 357 * The peer has failed to authenticate himself using `protocol'. 358 */ 359 void 360 auth_peer_fail(unit, protocol) 361 int unit, protocol; 362 { 363 /* 364 * Authentication failure: take the link down 365 */ 366 lcp_close(unit, "Authentication failed"); 367 } 368 369 /* 370 * The peer has been successfully authenticated using `protocol'. 371 */ 372 void 373 auth_peer_success(unit, protocol, name, namelen) 374 int unit, protocol; 375 char *name; 376 int namelen; 377 { 378 int bit; 379 380 switch (protocol) { 381 case PPP_CHAP: 382 bit = CHAP_PEER; 383 break; 384 case PPP_PAP: 385 bit = PAP_PEER; 386 break; 387 default: 388 syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", 389 protocol); 390 return; 391 } 392 393 /* 394 * Save the authenticated name of the peer for later. 395 */ 396 if (namelen > sizeof(peer_authname) - 1) 397 namelen = sizeof(peer_authname) - 1; 398 BCOPY(name, peer_authname, namelen); 399 peer_authname[namelen] = 0; 400 script_setenv("PEERNAME", peer_authname); 401 402 /* 403 * If there is no more authentication still to be done, 404 * proceed to the network (or callback) phase. 405 */ 406 if ((auth_pending[unit] &= ~bit) == 0) 407 network_phase(unit); 408 } 409 410 /* 411 * We have failed to authenticate ourselves to the peer using `protocol'. 412 */ 413 void 414 auth_withpeer_fail(unit, protocol) 415 int unit, protocol; 416 { 417 if (passwd_from_file) 418 BZERO(passwd, MAXSECRETLEN); 419 /* 420 * We've failed to authenticate ourselves to our peer. 421 * He'll probably take the link down, and there's not much 422 * we can do except wait for that. 423 */ 424 } 425 426 /* 427 * We have successfully authenticated ourselves with the peer using `protocol'. 428 */ 429 void 430 auth_withpeer_success(unit, protocol) 431 int unit, protocol; 432 { 433 int bit; 434 435 switch (protocol) { 436 case PPP_CHAP: 437 bit = CHAP_WITHPEER; 438 break; 439 case PPP_PAP: 440 if (passwd_from_file) 441 BZERO(passwd, MAXSECRETLEN); 442 bit = PAP_WITHPEER; 443 break; 444 default: 445 syslog(LOG_WARNING, "auth_peer_success: unknown protocol %x", 446 protocol); 447 bit = 0; 448 } 449 450 /* 451 * If there is no more authentication still being done, 452 * proceed to the network (or callback) phase. 453 */ 454 if ((auth_pending[unit] &= ~bit) == 0) 455 network_phase(unit); 456 } 457 458 459 /* 460 * np_up - a network protocol has come up. 461 */ 462 void 463 np_up(unit, proto) 464 int unit, proto; 465 { 466 if (num_np_up == 0) { 467 /* 468 * At this point we consider that the link has come up successfully. 469 */ 470 need_holdoff = 0; 471 472 if (idle_time_limit > 0) 473 TIMEOUT(check_idle, NULL, idle_time_limit); 474 475 /* 476 * Set a timeout to close the connection once the maximum 477 * connect time has expired. 478 */ 479 if (maxconnect > 0) 480 TIMEOUT(connect_time_expired, 0, maxconnect); 481 482 /* 483 * Detach now, if the updetach option was given. 484 */ 485 if (nodetach == -1) 486 detach(); 487 } 488 ++num_np_up; 489 } 490 491 /* 492 * np_down - a network protocol has gone down. 493 */ 494 void 495 np_down(unit, proto) 496 int unit, proto; 497 { 498 if (--num_np_up == 0 && idle_time_limit > 0) { 499 UNTIMEOUT(check_idle, NULL); 500 } 501 } 502 503 /* 504 * np_finished - a network protocol has finished using the link. 505 */ 506 void 507 np_finished(unit, proto) 508 int unit, proto; 509 { 510 if (--num_np_open <= 0) { 511 /* no further use for the link: shut up shop. */ 512 lcp_close(0, "No network protocols running"); 513 } 514 } 515 516 /* 517 * check_idle - check whether the link has been idle for long 518 * enough that we can shut it down. 519 */ 520 static void 521 check_idle(arg) 522 void *arg; 523 { 524 struct ppp_idle idle; 525 time_t itime; 526 527 if (!get_idle_time(0, &idle)) 528 return; 529 itime = MIN(idle.xmit_idle, idle.recv_idle); 530 if (itime >= idle_time_limit) { 531 /* link is idle: shut it down. */ 532 syslog(LOG_INFO, "Terminating connection due to lack of activity."); 533 lcp_close(0, "Link inactive"); 534 } else { 535 TIMEOUT(check_idle, NULL, idle_time_limit - itime); 536 } 537 } 538 539 /* 540 * connect_time_expired - log a message and close the connection. 541 */ 542 static void 543 connect_time_expired(arg) 544 void *arg; 545 { 546 syslog(LOG_INFO, "Connect time expired"); 547 lcp_close(0, "Connect time expired"); /* Close connection */ 548 } 549 550 /* 551 * auth_check_options - called to check authentication options. 552 */ 553 void 554 auth_check_options() 555 { 556 lcp_options *wo = &lcp_wantoptions[0]; 557 int can_auth; 558 ipcp_options *ipwo = &ipcp_wantoptions[0]; 559 u_int32_t remote; 560 561 /* Default our_name to hostname, and user to our_name */ 562 if (our_name[0] == 0 || usehostname) 563 strlcpy(our_name, hostname, MAXHOSTNAMELEN); 564 if (user[0] == 0) 565 strlcpy(user, our_name, MAXNAMELEN); 566 567 /* If authentication is required, ask peer for CHAP or PAP. */ 568 if (auth_required && !wo->neg_chap && !wo->neg_upap) { 569 wo->neg_chap = 1; 570 wo->neg_upap = 1; 571 } 572 573 /* 574 * Check whether we have appropriate secrets to use 575 * to authenticate the peer. 576 */ 577 can_auth = wo->neg_upap && (uselogin || have_pap_secret()); 578 if (!can_auth && wo->neg_chap) { 579 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 580 can_auth = have_chap_secret(remote_name, our_name, remote); 581 } 582 583 if (auth_required && !can_auth) { 584 option_error("peer authentication required but no suitable secret(s) found\n"); 585 if (remote_name[0] == 0) 586 option_error("for authenticating any peer to us (%s)\n", our_name); 587 else 588 option_error("for authenticating peer %s to us (%s)\n", 589 remote_name, our_name); 590 exit(1); 591 } 592 593 /* 594 * Check whether the user tried to override certain values 595 * set by root. 596 */ 597 if (!auth_required && auth_req_info.priv > 0) { 598 if (!default_device && devnam_info.priv == 0) { 599 option_error("can't override device name when noauth option used"); 600 exit(1); 601 } 602 if ((connector != NULL && connector_info.priv == 0) 603 || (disconnector != NULL && disconnector_info.priv == 0) 604 || (welcomer != NULL && welcomer_info.priv == 0)) { 605 option_error("can't override connect, disconnect or welcome"); 606 option_error("option values when noauth option used"); 607 exit(1); 608 } 609 } 610 } 611 612 /* 613 * auth_reset - called when LCP is starting negotiations to recheck 614 * authentication options, i.e. whether we have appropriate secrets 615 * to use for authenticating ourselves and/or the peer. 616 */ 617 void 618 auth_reset(unit) 619 int unit; 620 { 621 lcp_options *go = &lcp_gotoptions[unit]; 622 lcp_options *ao = &lcp_allowoptions[0]; 623 ipcp_options *ipwo = &ipcp_wantoptions[0]; 624 u_int32_t remote; 625 626 ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); 627 ao->neg_chap = !refuse_chap 628 && have_chap_secret(user, remote_name, (u_int32_t)0); 629 630 if (go->neg_upap && !uselogin && !have_pap_secret()) 631 go->neg_upap = 0; 632 if (go->neg_chap) { 633 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 634 if (!have_chap_secret(remote_name, our_name, remote)) 635 go->neg_chap = 0; 636 } 637 } 638 639 640 /* 641 * check_passwd - Check the user name and passwd against the PAP secrets 642 * file. If requested, also check against the system password database, 643 * and login the user if OK. 644 * 645 * returns: 646 * UPAP_AUTHNAK: Authentication failed. 647 * UPAP_AUTHACK: Authentication succeeded. 648 * In either case, msg points to an appropriate message. 649 */ 650 int 651 check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) 652 int unit; 653 char *auser; 654 int userlen; 655 char *apasswd; 656 int passwdlen; 657 char **msg; 658 int *msglen; 659 { 660 int ret; 661 char *filename; 662 FILE *f; 663 struct wordlist *addrs; 664 u_int32_t remote; 665 ipcp_options *ipwo = &ipcp_wantoptions[unit]; 666 char passwd[256], user[256]; 667 char secret[MAXWORDLEN]; 668 static int attempts = 0; 669 670 /* 671 * Make copies of apasswd and auser, then null-terminate them. 672 */ 673 BCOPY(apasswd, passwd, passwdlen); 674 passwd[passwdlen] = '\0'; 675 BCOPY(auser, user, userlen); 676 user[userlen] = '\0'; 677 *msg = (char *) 0; 678 679 /* 680 * Open the file of pap secrets and scan for a suitable secret 681 * for authenticating this user. 682 */ 683 filename = _PATH_UPAPFILE; 684 addrs = NULL; 685 ret = UPAP_AUTHACK; 686 f = fopen(filename, "r"); 687 if (f == NULL) { 688 syslog(LOG_ERR, "Can't open PAP password file %s: %m", filename); 689 ret = UPAP_AUTHNAK; 690 } else { 691 check_access(f, filename); 692 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 693 if (scan_authfile(f, user, our_name, remote, 694 secret, &addrs, filename) < 0 695 || (secret[0] != 0 && (cryptpap || strcmp(passwd, secret) != 0) 696 && strcmp(crypt(passwd, secret), secret) != 0)) { 697 syslog(LOG_WARNING, "PAP authentication failure for %s", user); 698 ret = UPAP_AUTHNAK; 699 } 700 fclose(f); 701 } 702 703 if (uselogin && ret == UPAP_AUTHACK) { 704 ret = plogin(user, passwd, msg, msglen); 705 if (ret == UPAP_AUTHNAK) { 706 syslog(LOG_WARNING, "PAP login failure for %s", user); 707 } 708 } 709 710 if (ret == UPAP_AUTHNAK) { 711 if (*msg == (char *) 0) 712 *msg = "Login incorrect"; 713 *msglen = strlen(*msg); 714 /* 715 * Frustrate passwd stealer programs. 716 * Allow 10 tries, but start backing off after 3 (stolen from login). 717 * On 10'th, drop the connection. 718 */ 719 if (attempts++ >= 10) { 720 syslog(LOG_WARNING, "%d LOGIN FAILURES ON %s, %s", 721 attempts, devnam, user); 722 quit(); 723 } 724 if (attempts > 3) 725 sleep((u_int) (attempts - 3) * 5); 726 if (addrs != NULL) 727 free_wordlist(addrs); 728 729 } else { 730 attempts = 0; /* Reset count */ 731 if (*msg == (char *) 0) 732 *msg = "Login ok"; 733 *msglen = strlen(*msg); 734 set_allowed_addrs(unit, addrs); 735 } 736 737 BZERO(passwd, sizeof(passwd)); 738 BZERO(secret, sizeof(secret)); 739 740 return ret; 741 } 742 743 /* 744 * This function is needed for PAM. 745 */ 746 747 #ifdef USE_PAM 748 static char *PAM_username = ""; 749 static char *PAM_password = ""; 750 751 #ifdef PAM_ESTABLISH_CRED /* new PAM defines :(^ */ 752 #define MY_PAM_STRERROR(err_code) (char *) pam_strerror(pamh,err_code) 753 #else 754 #define MY_PAM_STRERROR(err_code) (char *) pam_strerror(err_code) 755 #endif 756 757 static int pam_conv (int num_msg, 758 const struct pam_message **msg, 759 struct pam_response **resp, 760 void *appdata_ptr) 761 { 762 int count = 0, replies = 0; 763 struct pam_response *reply = NULL; 764 int size = 0; 765 766 for (count = 0; count < num_msg; count++) 767 { 768 struct pam_response *newreply; 769 int newsize = size + sizeof (struct pam_response); 770 newreply = realloc (reply, newsize); /* ANSI: is malloc() if reply==NULL */ 771 if (!newreply) { 772 free(reply); 773 reply = NULL; 774 return PAM_CONV_ERR; 775 } 776 reply = newreply; 777 size = newsize; 778 779 switch (msg[count]->msg_style) 780 { 781 case PAM_PROMPT_ECHO_ON: 782 reply[replies].resp_retcode = PAM_SUCCESS; 783 reply[replies++].resp = strdup(PAM_username); /* never NULL */ 784 break; 785 786 case PAM_PROMPT_ECHO_OFF: 787 reply[replies].resp_retcode = PAM_SUCCESS; 788 reply[replies++].resp = strdup(PAM_password); /* never NULL */ 789 break; 790 791 case PAM_TEXT_INFO: 792 reply[replies].resp_retcode = PAM_SUCCESS; 793 reply[replies++].resp = NULL; 794 break; 795 796 case PAM_ERROR_MSG: 797 default: 798 free (reply); 799 return PAM_CONV_ERR; 800 } 801 } 802 803 if (resp) 804 *resp = reply; 805 else 806 free (reply); 807 808 return PAM_SUCCESS; 809 } 810 #endif 811 812 /* 813 * plogin - Check the user name and password against the system 814 * password database, and login the user if OK. 815 * 816 * returns: 817 * UPAP_AUTHNAK: Login failed. 818 * UPAP_AUTHACK: Login succeeded. 819 * In either case, msg points to an appropriate message. 820 */ 821 822 static int 823 plogin(user, passwd, msg, msglen) 824 char *user; 825 char *passwd; 826 char **msg; 827 int *msglen; 828 { 829 830 #ifdef USE_PAM 831 832 struct pam_conv pam_conversation; 833 pam_handle_t *pamh; 834 int pam_error; 835 /* 836 * Fill the pam_conversion structure 837 */ 838 memset (&pam_conversation, '\0', sizeof (struct pam_conv)); 839 pam_conversation.conv = &pam_conv; 840 841 pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); 842 843 if (pam_error != PAM_SUCCESS) { 844 *msg = MY_PAM_STRERROR (pam_error); 845 return UPAP_AUTHNAK; 846 } 847 /* 848 * Define the fields for the credential validation 849 */ 850 (void) pam_set_item (pamh, PAM_TTY, devnam); 851 PAM_username = user; 852 PAM_password = passwd; 853 /* 854 * Validate the user 855 */ 856 pam_error = pam_authenticate (pamh, PAM_SILENT); 857 if (pam_error == PAM_SUCCESS) { 858 pam_error = pam_acct_mgmt (pamh, PAM_SILENT); 859 860 /* start a session for this user. Session closed when link ends. */ 861 if (pam_error == PAM_SUCCESS) 862 (void) pam_open_session (pamh, PAM_SILENT); 863 } 864 865 *msg = MY_PAM_STRERROR (pam_error); 866 867 PAM_username = 868 PAM_password = ""; 869 /* 870 * Clean up the mess 871 */ 872 (void) pam_end (pamh, pam_error); 873 874 if (pam_error != PAM_SUCCESS) 875 return UPAP_AUTHNAK; 876 /* 877 * Use the non-PAM methods directly 878 */ 879 #else /* #ifdef USE_PAM */ 880 881 struct passwd *pw; 882 char *tty; 883 884 #ifdef HAS_SHADOW 885 struct spwd *spwd; 886 struct spwd *getspnam(); 887 #endif 888 889 pw = getpwnam(user); 890 endpwent(); 891 if (pw == NULL) { 892 return (UPAP_AUTHNAK); 893 } 894 895 #ifdef HAS_SHADOW 896 spwd = getspnam(user); 897 endspent(); 898 if (spwd) { 899 /* check the age of the password entry */ 900 long now = time(NULL) / 86400L; 901 902 if ((spwd->sp_expire > 0 && now >= spwd->sp_expire) 903 || ((spwd->sp_max >= 0 && spwd->sp_max < 10000) 904 && spwd->sp_lstchg >= 0 905 && now >= spwd->sp_lstchg + spwd->sp_max)) { 906 syslog(LOG_WARNING, "Password for %s has expired", user); 907 return (UPAP_AUTHNAK); 908 } 909 pw->pw_passwd = spwd->sp_pwdp; 910 } 911 #endif 912 913 /* 914 * If no passwd, don't let them login. 915 */ 916 if (pw->pw_passwd == NULL || *pw->pw_passwd == '\0' 917 || strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) != 0) 918 return (UPAP_AUTHNAK); 919 920 /* These functions are not enabled for PAM. The reason for this is that */ 921 /* there is not necessarily a "passwd" entry for this user. That is */ 922 /* real purpose of 'PAM' -- to virtualize the account data from the */ 923 /* application. If you want to do the same thing, write the entry in */ 924 /* the 'session' hook. */ 925 926 /* 927 * Write a wtmp entry for this user. 928 */ 929 930 tty = devnam; 931 if (strncmp(tty, "/dev/", 5) == 0) 932 tty += 5; 933 logwtmp(tty, user, remote_name); /* Add wtmp login entry */ 934 935 #if defined(_PATH_LASTLOG) 936 { 937 struct lastlog ll; 938 int fd; 939 940 if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { 941 (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); 942 memset((void *)&ll, 0, sizeof(ll)); 943 (void)time(&ll.ll_time); 944 (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 945 (void)write(fd, (char *)&ll, sizeof(ll)); 946 (void)close(fd); 947 } 948 } 949 #endif 950 951 #endif /* #ifdef USE_PAM */ 952 953 syslog(LOG_INFO, "user %s logged in", user); 954 logged_in = TRUE; 955 956 return (UPAP_AUTHACK); 957 } 958 959 /* 960 * plogout - Logout the user. 961 */ 962 static void 963 plogout() 964 { 965 #ifdef USE_PAM 966 struct pam_conv pam_conversation; 967 pam_handle_t *pamh; 968 int pam_error; 969 /* 970 * Fill the pam_conversion structure. The PAM specification states that the 971 * session must be able to be closed by a totally different handle from which 972 * it was created. Hold the PAM group to their own specification! 973 */ 974 memset (&pam_conversation, '\0', sizeof (struct pam_conv)); 975 pam_conversation.conv = &pam_conv; 976 977 pam_error = pam_start ("ppp", user, &pam_conversation, &pamh); 978 if (pam_error == PAM_SUCCESS) { 979 (void) pam_set_item (pamh, PAM_TTY, devnam); 980 (void) pam_close_session (pamh, PAM_SILENT); 981 (void) pam_end (pamh, PAM_SUCCESS); 982 } 983 984 #else 985 char *tty; 986 987 tty = devnam; 988 if (strncmp(tty, "/dev/", 5) == 0) 989 tty += 5; 990 logwtmp(tty, "", ""); /* Wipe out utmp logout entry */ 991 #endif 992 993 logged_in = FALSE; 994 } 995 996 997 /* 998 * null_login - Check if a username of "" and a password of "" are 999 * acceptable, and iff so, set the list of acceptable IP addresses 1000 * and return 1. 1001 */ 1002 static int 1003 null_login(unit) 1004 int unit; 1005 { 1006 char *filename; 1007 FILE *f; 1008 int i, ret; 1009 struct wordlist *addrs; 1010 char secret[MAXWORDLEN]; 1011 1012 /* 1013 * Open the file of pap secrets and scan for a suitable secret. 1014 * We don't accept a wildcard client. 1015 */ 1016 filename = _PATH_UPAPFILE; 1017 addrs = NULL; 1018 f = fopen(filename, "r"); 1019 if (f == NULL) 1020 return 0; 1021 check_access(f, filename); 1022 1023 i = scan_authfile(f, "", our_name, (u_int32_t)0, secret, &addrs, filename); 1024 ret = i >= 0 && (i & NONWILD_CLIENT) != 0 && secret[0] == 0; 1025 BZERO(secret, sizeof(secret)); 1026 1027 if (ret) 1028 set_allowed_addrs(unit, addrs); 1029 else 1030 free_wordlist(addrs); 1031 1032 fclose(f); 1033 return ret; 1034 } 1035 1036 1037 /* 1038 * get_pap_passwd - get a password for authenticating ourselves with 1039 * our peer using PAP. Returns 1 on success, 0 if no suitable password 1040 * could be found. 1041 */ 1042 static int 1043 get_pap_passwd(passwd) 1044 char *passwd; 1045 { 1046 char *filename; 1047 FILE *f; 1048 int ret; 1049 struct wordlist *addrs; 1050 char secret[MAXWORDLEN]; 1051 1052 filename = _PATH_UPAPFILE; 1053 addrs = NULL; 1054 f = fopen(filename, "r"); 1055 if (f == NULL) 1056 return 0; 1057 check_access(f, filename); 1058 ret = scan_authfile(f, user, 1059 remote_name[0]? remote_name: NULL, 1060 (u_int32_t)0, secret, NULL, filename); 1061 fclose(f); 1062 if (ret < 0) 1063 return 0; 1064 if (passwd != NULL) 1065 strlcpy(passwd, secret, MAXSECRETLEN); 1066 BZERO(secret, sizeof(secret)); 1067 return 1; 1068 } 1069 1070 1071 /* 1072 * have_pap_secret - check whether we have a PAP file with any 1073 * secrets that we could possibly use for authenticating the peer. 1074 */ 1075 static int 1076 have_pap_secret() 1077 { 1078 FILE *f; 1079 int ret; 1080 char *filename; 1081 ipcp_options *ipwo = &ipcp_wantoptions[0]; 1082 u_int32_t remote; 1083 1084 filename = _PATH_UPAPFILE; 1085 f = fopen(filename, "r"); 1086 if (f == NULL) 1087 return 0; 1088 1089 remote = ipwo->accept_remote? 0: ipwo->hisaddr; 1090 ret = scan_authfile(f, NULL, our_name, remote, NULL, NULL, filename); 1091 fclose(f); 1092 if (ret < 0) 1093 return 0; 1094 1095 return 1; 1096 } 1097 1098 1099 /* 1100 * have_chap_secret - check whether we have a CHAP file with a 1101 * secret that we could possibly use for authenticating `client' 1102 * on `server'. Either can be the null string, meaning we don't 1103 * know the identity yet. 1104 */ 1105 static int 1106 have_chap_secret(client, server, remote) 1107 char *client; 1108 char *server; 1109 u_int32_t remote; 1110 { 1111 FILE *f; 1112 int ret; 1113 char *filename; 1114 1115 filename = _PATH_CHAPFILE; 1116 f = fopen(filename, "r"); 1117 if (f == NULL) 1118 return 0; 1119 1120 if (client[0] == 0) 1121 client = NULL; 1122 else if (server[0] == 0) 1123 server = NULL; 1124 1125 ret = scan_authfile(f, client, server, remote, NULL, NULL, filename); 1126 fclose(f); 1127 if (ret < 0) 1128 return 0; 1129 1130 return 1; 1131 } 1132 1133 1134 /* 1135 * get_secret - open the CHAP secret file and return the secret 1136 * for authenticating the given client on the given server. 1137 * (We could be either client or server). 1138 */ 1139 int 1140 get_secret(unit, client, server, secret, secret_len, save_addrs) 1141 int unit; 1142 char *client; 1143 char *server; 1144 char *secret; 1145 int *secret_len; 1146 int save_addrs; 1147 { 1148 FILE *f; 1149 int ret, len; 1150 char *filename; 1151 struct wordlist *addrs; 1152 char secbuf[MAXWORDLEN]; 1153 1154 filename = _PATH_CHAPFILE; 1155 addrs = NULL; 1156 secbuf[0] = 0; 1157 1158 f = fopen(filename, "r"); 1159 if (f == NULL) { 1160 syslog(LOG_ERR, "Can't open chap secret file %s: %m", filename); 1161 return 0; 1162 } 1163 check_access(f, filename); 1164 1165 ret = scan_authfile(f, client, server, (u_int32_t)0, 1166 secbuf, &addrs, filename); 1167 fclose(f); 1168 if (ret < 0) 1169 return 0; 1170 1171 if (save_addrs) 1172 set_allowed_addrs(unit, addrs); 1173 1174 len = strlen(secbuf); 1175 if (len > MAXSECRETLEN) { 1176 syslog(LOG_ERR, "Secret for %s on %s is too long", client, server); 1177 len = MAXSECRETLEN; 1178 } 1179 BCOPY(secbuf, secret, len); 1180 BZERO(secbuf, sizeof(secbuf)); 1181 *secret_len = len; 1182 1183 return 1; 1184 } 1185 1186 /* 1187 * set_allowed_addrs() - set the list of allowed addresses. 1188 */ 1189 static void 1190 set_allowed_addrs(unit, addrs) 1191 int unit; 1192 struct wordlist *addrs; 1193 { 1194 if (addresses[unit] != NULL) 1195 free_wordlist(addresses[unit]); 1196 addresses[unit] = addrs; 1197 1198 /* 1199 * If there's only one authorized address we might as well 1200 * ask our peer for that one right away 1201 */ 1202 if (addrs != NULL && addrs->next == NULL) { 1203 char *p = addrs->word; 1204 struct ipcp_options *wo = &ipcp_wantoptions[unit]; 1205 struct in_addr ina; 1206 struct hostent *hp; 1207 1208 if (*p != '!' && *p != '-' && !ISWILD(p) && strchr(p, '/') == NULL) { 1209 hp = gethostbyname(p); 1210 if (hp != NULL && hp->h_addrtype == AF_INET) 1211 wo->hisaddr = *(u_int32_t *)hp->h_addr; 1212 else if (inet_aton(p, &ina) == 1) 1213 wo->hisaddr = ina.s_addr; 1214 } 1215 } 1216 } 1217 1218 /* 1219 * auth_ip_addr - check whether the peer is authorized to use 1220 * a given IP address. Returns 1 if authorized, 0 otherwise. 1221 */ 1222 int 1223 auth_ip_addr(unit, addr) 1224 int unit; 1225 u_int32_t addr; 1226 { 1227 return ip_addr_check(addr, addresses[unit]); 1228 } 1229 1230 static int 1231 ip_addr_check(addr, addrs) 1232 u_int32_t addr; 1233 struct wordlist *addrs; 1234 { 1235 u_int32_t mask, ah; 1236 struct in_addr ina; 1237 int accept, r = 1; 1238 char *ptr_word, *ptr_mask; 1239 struct hostent *hp; 1240 struct netent *np; 1241 1242 /* don't allow loopback or multicast address */ 1243 if (bad_ip_adrs(addr)) 1244 return 0; 1245 1246 if (addrs == NULL) 1247 return !auth_required; /* no addresses authorized */ 1248 1249 for (; addrs != NULL; addrs = addrs->next) { 1250 /* "-" means no addresses authorized, "*" means any address allowed */ 1251 ptr_word = addrs->word; 1252 if (strcmp(ptr_word, "-") == 0) 1253 break; 1254 if (strcmp(ptr_word, "*") == 0) 1255 return 1; 1256 1257 accept = 1; 1258 if (*ptr_word == '!') { 1259 accept = 0; 1260 ++ptr_word; 1261 } 1262 1263 mask = ~ (u_int32_t) 0; 1264 ptr_mask = strchr (ptr_word, '/'); 1265 if (ptr_mask != NULL) { 1266 int bit_count; 1267 1268 bit_count = (int) strtol (ptr_mask+1, (char **) 0, 10); 1269 if (bit_count <= 0 || bit_count > 32) { 1270 syslog (LOG_WARNING, 1271 "invalid address length %s in auth. address list", 1272 ptr_mask); 1273 continue; 1274 } 1275 *ptr_mask = '\0'; 1276 mask <<= 32 - bit_count; 1277 } 1278 1279 hp = gethostbyname(ptr_word); 1280 if (hp != NULL && hp->h_addrtype == AF_INET) { 1281 ina.s_addr = *(u_int32_t *)hp->h_addr; 1282 } else { 1283 np = getnetbyname (ptr_word); 1284 if (np != NULL && np->n_addrtype == AF_INET) 1285 ina.s_addr = htonl (np->n_net); 1286 else 1287 r = inet_aton (ptr_word, &ina); 1288 if (ptr_mask == NULL) { 1289 /* calculate appropriate mask for net */ 1290 ah = ntohl(ina.s_addr); 1291 if (IN_CLASSA(ah)) 1292 mask = IN_CLASSA_NET; 1293 else if (IN_CLASSB(ah)) 1294 mask = IN_CLASSB_NET; 1295 else if (IN_CLASSC(ah)) 1296 mask = IN_CLASSC_NET; 1297 } 1298 } 1299 1300 if (ptr_mask != NULL) 1301 *ptr_mask = '/'; 1302 1303 if (r == 0) 1304 syslog (LOG_WARNING, 1305 "unknown host %s in auth. address list", 1306 addrs->word); 1307 else 1308 /* Here ina.s_addr and addr are in network byte order, 1309 and mask is in host order. */ 1310 if (((addr ^ ina.s_addr) & htonl(mask)) == 0) 1311 return accept; 1312 } 1313 return 0; /* not in list => can't have it */ 1314 } 1315 1316 /* 1317 * bad_ip_adrs - return 1 if the IP address is one we don't want 1318 * to use, such as an address in the loopback net or a multicast address. 1319 * addr is in network byte order. 1320 */ 1321 int 1322 bad_ip_adrs(addr) 1323 u_int32_t addr; 1324 { 1325 addr = ntohl(addr); 1326 return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET 1327 || IN_MULTICAST(addr) || IN_BADCLASS(addr); 1328 } 1329 1330 /* 1331 * check_access - complain if a secret file has too-liberal permissions. 1332 */ 1333 void 1334 check_access(f, filename) 1335 FILE *f; 1336 char *filename; 1337 { 1338 struct stat sbuf; 1339 1340 if (fstat(fileno(f), &sbuf) < 0) { 1341 syslog(LOG_WARNING, "cannot stat secret file %s: %m", filename); 1342 } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { 1343 syslog(LOG_WARNING, "Warning - secret file %s has world and/or group access", filename); 1344 } 1345 } 1346 1347 1348 /* 1349 * scan_authfile - Scan an authorization file for a secret suitable 1350 * for authenticating `client' on `server'. The return value is -1 1351 * if no secret is found, otherwise >= 0. The return value has 1352 * NONWILD_CLIENT set if the secret didn't have "*" for the client, and 1353 * NONWILD_SERVER set if the secret didn't have "*" for the server. 1354 * Any following words on the line (i.e. address authorization 1355 * info) are placed in a wordlist and returned in *addrs. 1356 */ 1357 static int 1358 scan_authfile(f, client, server, ipaddr, secret, addrs, filename) 1359 FILE *f; 1360 char *client; 1361 char *server; 1362 u_int32_t ipaddr; 1363 char *secret; 1364 struct wordlist **addrs; 1365 char *filename; 1366 { 1367 int newline, xxx; 1368 int got_flag, best_flag; 1369 FILE *sf; 1370 struct wordlist *ap, *addr_list, *alist, *alast; 1371 char word[MAXWORDLEN]; 1372 char atfile[MAXWORDLEN]; 1373 char lsecret[MAXWORDLEN]; 1374 1375 if (addrs != NULL) 1376 *addrs = NULL; 1377 addr_list = NULL; 1378 if (!getword(f, word, &newline, filename)) 1379 return -1; /* file is empty??? */ 1380 newline = 1; 1381 best_flag = -1; 1382 for (;;) { 1383 /* 1384 * Skip until we find a word at the start of a line. 1385 */ 1386 while (!newline && getword(f, word, &newline, filename)) 1387 ; 1388 if (!newline) 1389 break; /* got to end of file */ 1390 1391 /* 1392 * Got a client - check if it's a match or a wildcard. 1393 */ 1394 got_flag = 0; 1395 if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { 1396 newline = 0; 1397 continue; 1398 } 1399 if (!ISWILD(word)) 1400 got_flag = NONWILD_CLIENT; 1401 1402 /* 1403 * Now get a server and check if it matches. 1404 */ 1405 if (!getword(f, word, &newline, filename)) 1406 break; 1407 if (newline) 1408 continue; 1409 if (server != NULL && strcmp(word, server) != 0 && !ISWILD(word)) 1410 continue; 1411 if (!ISWILD(word)) 1412 got_flag |= NONWILD_SERVER; 1413 1414 /* 1415 * Got some sort of a match - see if it's better than what 1416 * we have already. 1417 */ 1418 if (got_flag <= best_flag) 1419 continue; 1420 1421 /* 1422 * Get the secret. 1423 */ 1424 if (!getword(f, word, &newline, filename)) 1425 break; 1426 if (newline) 1427 continue; 1428 1429 /* 1430 * Special syntax: @filename means read secret from file. 1431 */ 1432 if (word[0] == '@') { 1433 strlcpy(atfile, word+1, sizeof atfile); 1434 if ((sf = fopen(atfile, "r")) == NULL) { 1435 syslog(LOG_WARNING, "can't open indirect secret file %s", 1436 atfile); 1437 continue; 1438 } 1439 check_access(sf, atfile); 1440 if (!getword(sf, word, &xxx, atfile)) { 1441 syslog(LOG_WARNING, "no secret in indirect secret file %s", 1442 atfile); 1443 fclose(sf); 1444 continue; 1445 } 1446 fclose(sf); 1447 } 1448 if (secret != NULL) 1449 strlcpy(lsecret, word, sizeof lsecret); 1450 1451 /* 1452 * Now read address authorization info and make a wordlist. 1453 */ 1454 alist = alast = NULL; 1455 for (;;) { 1456 size_t wordlen; 1457 1458 if (!getword(f, word, &newline, filename) || newline) 1459 break; 1460 wordlen = strlen(word); /* NUL in struct wordlist */ 1461 ap = (struct wordlist *) malloc(sizeof(struct wordlist) + 1462 wordlen); 1463 1464 if (ap == NULL) 1465 novm("authorized addresses"); 1466 ap->next = NULL; 1467 strlcpy(ap->word, word, wordlen + 1); 1468 if (alist == NULL) 1469 alist = ap; 1470 else 1471 alast->next = ap; 1472 alast = ap; 1473 } 1474 1475 /* 1476 * Check if the given IP address is allowed by the wordlist. 1477 */ 1478 if (ipaddr != 0 && !ip_addr_check(ipaddr, alist)) { 1479 free_wordlist(alist); 1480 continue; 1481 } 1482 1483 /* 1484 * This is the best so far; remember it. 1485 */ 1486 best_flag = got_flag; 1487 if (addr_list) 1488 free_wordlist(addr_list); 1489 addr_list = alist; 1490 if (secret != NULL) 1491 strlcpy(secret, lsecret, MAXWORDLEN); 1492 1493 if (!newline) 1494 break; 1495 } 1496 1497 if (addrs != NULL) 1498 *addrs = addr_list; 1499 else if (addr_list != NULL) 1500 free_wordlist(addr_list); 1501 1502 return best_flag; 1503 } 1504 1505 /* 1506 * free_wordlist - release memory allocated for a wordlist. 1507 */ 1508 static void 1509 free_wordlist(wp) 1510 struct wordlist *wp; 1511 { 1512 struct wordlist *next; 1513 1514 while (wp != NULL) { 1515 next = wp->next; 1516 free(wp); 1517 wp = next; 1518 } 1519 } 1520 1521 /* 1522 * auth_script - execute a script with arguments 1523 * interface-name peer-name real-user tty speed 1524 */ 1525 static void 1526 auth_script(script) 1527 char *script; 1528 { 1529 char strspeed[32]; 1530 struct passwd *pw; 1531 char struid[32]; 1532 char *user_name; 1533 char *argv[8]; 1534 1535 if ((pw = getpwuid(getuid())) != NULL && pw->pw_name != NULL) 1536 user_name = pw->pw_name; 1537 else { 1538 snprintf(struid, sizeof struid, "%u", getuid()); 1539 user_name = struid; 1540 } 1541 snprintf(strspeed, sizeof strspeed, "%d", baud_rate); 1542 1543 argv[0] = script; 1544 argv[1] = ifname; 1545 argv[2] = peer_authname; 1546 argv[3] = user_name; 1547 argv[4] = devnam; 1548 argv[5] = strspeed; 1549 argv[6] = NULL; 1550 1551 run_program(script, argv, 0); 1552 } 1553