158#ifndef LIBWRAP_ALLOW_FACILITY 159# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 160#endif 161#ifndef LIBWRAP_ALLOW_SEVERITY 162# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 163#endif 164#ifndef LIBWRAP_DENY_FACILITY 165# define LIBWRAP_DENY_FACILITY LOG_AUTH 166#endif 167#ifndef LIBWRAP_DENY_SEVERITY 168# define LIBWRAP_DENY_SEVERITY LOG_WARNING 169#endif 170 171#define ISWRAP(sep) \ 172 ( ((wrap_ex && !(sep)->se_bi) || (wrap_bi && (sep)->se_bi)) \ 173 && (sep->se_family == AF_INET || sep->se_family == AF_INET6) \ 174 && ( ((sep)->se_accept && (sep)->se_socktype == SOCK_STREAM) \ 175 || (sep)->se_socktype == SOCK_DGRAM)) 176 177#ifdef LOGIN_CAP 178#include <login_cap.h> 179 180/* see init.c */ 181#define RESOURCE_RC "daemon" 182 183#endif 184 185#ifndef MAXCHILD 186#define MAXCHILD -1 /* maximum number of this service 187 < 0 = no limit */ 188#endif 189 190#ifndef MAXCPM 191#define MAXCPM -1 /* rate limit invocations from a 192 single remote address, 193 < 0 = no limit */ 194#endif 195 196#ifndef MAXPERIP 197#define MAXPERIP -1 /* maximum number of this service 198 from a single remote address, 199 < 0 = no limit */ 200#endif 201 202#ifndef TOOMANY 203#define TOOMANY 256 /* don't start more than TOOMANY */ 204#endif 205#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */ 206#define RETRYTIME (60*10) /* retry after bind or server fail */ 207#define MAX_MAXCHLD 32767 /* max allowable max children */ 208 209#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM)) 210 211void close_sep(struct servtab *); 212void flag_signal(int); 213void flag_config(int); 214void config(void); 215int cpmip(const struct servtab *, int); 216void endconfig(void); 217struct servtab *enter(struct servtab *); 218void freeconfig(struct servtab *); 219struct servtab *getconfigent(void); 220int matchservent(const char *, const char *, const char *); 221char *nextline(FILE *); 222void addchild(struct servtab *, int); 223void flag_reapchild(int); 224void reapchild(void); 225void enable(struct servtab *); 226void disable(struct servtab *); 227void flag_retry(int); 228void retry(void); 229int setconfig(void); 230void setup(struct servtab *); 231#ifdef IPSEC 232void ipsecsetup(struct servtab *); 233#endif 234void unregisterrpc(register struct servtab *sep); 235static struct conninfo *search_conn(struct servtab *sep, int ctrl); 236static int room_conn(struct servtab *sep, struct conninfo *conn); 237static void addchild_conn(struct conninfo *conn, pid_t pid); 238static void reapchild_conn(pid_t pid); 239static void free_conn(struct conninfo *conn); 240static void resize_conn(struct servtab *sep, int maxperip); 241static void free_connlist(struct servtab *sep); 242static void free_proc(struct procinfo *); 243static struct procinfo *search_proc(pid_t pid, int add); 244static int hashval(char *p, int len); 245 246int allow_severity; 247int deny_severity; 248int wrap_ex = 0; 249int wrap_bi = 0; 250int debug = 0; 251int dolog = 0; 252int maxsock; /* highest-numbered descriptor */ 253fd_set allsock; 254int options; 255int timingout; 256int toomany = TOOMANY; 257int maxchild = MAXCHILD; 258int maxcpm = MAXCPM; 259int maxperip = MAXPERIP; 260struct servent *sp; 261struct rpcent *rpc; 262char *hostname = NULL; 263struct sockaddr_in *bind_sa4; 264int v4bind_ok = 0; 265#ifdef INET6 266struct sockaddr_in6 *bind_sa6; 267int v6bind_ok = 0; 268#endif 269int signalpipe[2]; 270#ifdef SANITY_CHECK 271int nsock; 272#endif 273uid_t euid; 274gid_t egid; 275mode_t mask; 276 277struct servtab *servtab; 278 279extern struct biltin biltins[]; 280 281const char *CONFIG = _PATH_INETDCONF; 282const char *pid_file = _PATH_INETDPID; 283 284struct netconfig *udpconf, *tcpconf, *udp6conf, *tcp6conf; 285 286static LIST_HEAD(, procinfo) proctable[PERIPSIZE]; 287 288int 289getvalue(const char *arg, int *value, const char *whine) 290{ 291 int tmp; 292 char *p; 293 294 tmp = strtol(arg, &p, 0); 295 if (tmp < 0 || *p) { 296 syslog(LOG_ERR, whine, arg); 297 return 1; /* failure */ 298 } 299 *value = tmp; 300 return 0; /* success */ 301} 302 303static sa_family_t 304whichaf(struct request_info *req) 305{ 306 struct sockaddr *sa; 307 308 sa = (struct sockaddr *)req->client->sin; 309 if (sa == NULL) 310 return AF_UNSPEC; 311 if (sa->sa_family == AF_INET6 && 312 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) 313 return AF_INET; 314 return sa->sa_family; 315} 316 317int 318main(int argc, char **argv) 319{ 320 struct servtab *sep; 321 struct passwd *pwd; 322 struct group *grp; 323 struct sigaction sa, saalrm, sachld, sahup, sapipe; 324 int ch, dofork; 325 pid_t pid; 326 char buf[50]; 327#ifdef LOGIN_CAP 328 login_cap_t *lc = NULL; 329#endif 330 struct request_info req; 331 int denied; 332 char *service = NULL; 333 union { 334 struct sockaddr peer_un; 335 struct sockaddr_in peer_un4; 336 struct sockaddr_in6 peer_un6; 337 struct sockaddr_storage peer_max; 338 } p_un; 339#define peer p_un.peer_un 340#define peer4 p_un.peer_un4 341#define peer6 p_un.peer_un6 342#define peermax p_un.peer_max 343 int i; 344 struct addrinfo hints, *res; 345 const char *servname; 346 int error; 347 struct conninfo *conn; 348 349 openlog("inetd", LOG_PID | LOG_NOWAIT | LOG_PERROR, LOG_DAEMON); 350 351 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:s:")) != -1) 352 switch(ch) { 353 case 'd': 354 debug = 1; 355 options |= SO_DEBUG; 356 break; 357 case 'l': 358 dolog = 1; 359 break; 360 case 'R': 361 getvalue(optarg, &toomany, 362 "-R %s: bad value for service invocation rate"); 363 break; 364 case 'c': 365 getvalue(optarg, &maxchild, 366 "-c %s: bad value for maximum children"); 367 break; 368 case 'C': 369 getvalue(optarg, &maxcpm, 370 "-C %s: bad value for maximum children/minute"); 371 break; 372 case 'a': 373 hostname = optarg; 374 break; 375 case 'p': 376 pid_file = optarg; 377 break; 378 case 's': 379 getvalue(optarg, &maxperip, 380 "-s %s: bad value for maximum children per source address"); 381 break; 382 case 'w': 383 wrap_ex++; 384 break; 385 case 'W': 386 wrap_bi++; 387 break; 388 case '?': 389 default: 390 syslog(LOG_ERR, 391 "usage: inetd [-dlwW] [-a address] [-R rate]" 392 " [-c maximum] [-C rate]" 393 " [-p pidfile] [conf-file]"); 394 exit(EX_USAGE); 395 } 396 /* 397 * Initialize Bind Addrs. 398 * When hostname is NULL, wild card bind addrs are obtained from 399 * getaddrinfo(). But getaddrinfo() requires at least one of 400 * hostname or servname is non NULL. 401 * So when hostname is NULL, set dummy value to servname. 402 * Since getaddrinfo() doesn't accept numeric servname, and 403 * we doesn't use ai_socktype of struct addrinfo returned 404 * from getaddrinfo(), we set dummy value to ai_socktype. 405 */ 406 servname = (hostname == NULL) ? "0" /* dummy */ : NULL; 407 408 bzero(&hints, sizeof(struct addrinfo)); 409 hints.ai_flags = AI_PASSIVE; 410 hints.ai_family = AF_UNSPEC; 411 hints.ai_socktype = SOCK_STREAM; /* dummy */ 412 error = getaddrinfo(hostname, servname, &hints, &res); 413 if (error != 0) { 414 syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error)); 415 if (error == EAI_SYSTEM) 416 syslog(LOG_ERR, "%s", strerror(errno)); 417 exit(EX_USAGE); 418 } 419 do { 420 if (res->ai_addr == NULL) { 421 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname); 422 exit(EX_USAGE); 423 } 424 switch (res->ai_addr->sa_family) { 425 case AF_INET: 426 if (v4bind_ok) 427 continue; 428 bind_sa4 = (struct sockaddr_in *)res->ai_addr; 429 /* init port num in case servname is dummy */ 430 bind_sa4->sin_port = 0; 431 v4bind_ok = 1; 432 continue; 433#ifdef INET6 434 case AF_INET6: 435 if (v6bind_ok) 436 continue; 437 bind_sa6 = (struct sockaddr_in6 *)res->ai_addr; 438 /* init port num in case servname is dummy */ 439 bind_sa6->sin6_port = 0; 440 v6bind_ok = 1; 441 continue; 442#endif 443 } 444 if (v4bind_ok 445#ifdef INET6 446 && v6bind_ok 447#endif 448 ) 449 break; 450 } while ((res = res->ai_next) != NULL); 451 if (!v4bind_ok 452#ifdef INET6 453 && !v6bind_ok 454#endif 455 ) { 456 syslog(LOG_ERR, "-a %s: unknown address family", hostname); 457 exit(EX_USAGE); 458 } 459 460 euid = geteuid(); 461 egid = getegid(); 462 umask(mask = umask(0777)); 463 464 argc -= optind; 465 argv += optind; 466 467 if (argc > 0) 468 CONFIG = argv[0]; 469 if (access(CONFIG, R_OK) < 0) 470 syslog(LOG_ERR, "Accessing %s: %m, continuing anyway.", CONFIG); 471 if (debug == 0) { 472 FILE *fp; 473 if (daemon(0, 0) < 0) { 474 syslog(LOG_WARNING, "daemon(0,0) failed: %m"); 475 } 476 /* From now on we don't want syslog messages going to stderr. */ 477 closelog(); 478 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 479 /* 480 * In case somebody has started inetd manually, we need to 481 * clear the logname, so that old servers run as root do not 482 * get the user's logname.. 483 */ 484 if (setlogin("") < 0) { 485 syslog(LOG_WARNING, "cannot clear logname: %m"); 486 /* no big deal if it fails.. */ 487 } 488 pid = getpid(); 489 fp = fopen(pid_file, "w"); 490 if (fp) { 491 fprintf(fp, "%ld\n", (long)pid); 492 fclose(fp); 493 } else { 494 syslog(LOG_WARNING, "%s: %m", pid_file); 495 } 496 } 497 498 for (i = 0; i < PERIPSIZE; ++i) 499 LIST_INIT(&proctable[i]); 500 501 if (v4bind_ok) { 502 udpconf = getnetconfigent("udp"); 503 tcpconf = getnetconfigent("tcp"); 504 if (udpconf == NULL || tcpconf == NULL) { 505 syslog(LOG_ERR, "unknown rpc/udp or rpc/tcp"); 506 exit(EX_USAGE); 507 } 508 } 509#ifdef INET6 510 if (v6bind_ok) { 511 udp6conf = getnetconfigent("udp6"); 512 tcp6conf = getnetconfigent("tcp6"); 513 if (udp6conf == NULL || tcp6conf == NULL) { 514 syslog(LOG_ERR, "unknown rpc/udp6 or rpc/tcp6"); 515 exit(EX_USAGE); 516 } 517 } 518#endif 519 520 sa.sa_flags = 0; 521 sigemptyset(&sa.sa_mask); 522 sigaddset(&sa.sa_mask, SIGALRM); 523 sigaddset(&sa.sa_mask, SIGCHLD); 524 sigaddset(&sa.sa_mask, SIGHUP); 525 sa.sa_handler = flag_retry; 526 sigaction(SIGALRM, &sa, &saalrm); 527 config(); 528 sa.sa_handler = flag_config; 529 sigaction(SIGHUP, &sa, &sahup); 530 sa.sa_handler = flag_reapchild; 531 sigaction(SIGCHLD, &sa, &sachld); 532 sa.sa_handler = SIG_IGN; 533 sigaction(SIGPIPE, &sa, &sapipe); 534 535 { 536 /* space for daemons to overwrite environment for ps */ 537#define DUMMYSIZE 100 538 char dummy[DUMMYSIZE]; 539 540 (void)memset(dummy, 'x', DUMMYSIZE - 1); 541 dummy[DUMMYSIZE - 1] = '\0'; 542 (void)setenv("inetd_dummy", dummy, 1); 543 } 544 545 if (pipe(signalpipe) != 0) { 546 syslog(LOG_ERR, "pipe: %m"); 547 exit(EX_OSERR); 548 } 549 if (fcntl(signalpipe[0], F_SETFD, FD_CLOEXEC) < 0 || 550 fcntl(signalpipe[1], F_SETFD, FD_CLOEXEC) < 0) { 551 syslog(LOG_ERR, "signalpipe: fcntl (F_SETFD, FD_CLOEXEC): %m"); 552 exit(EX_OSERR); 553 } 554 FD_SET(signalpipe[0], &allsock); 555#ifdef SANITY_CHECK 556 nsock++; 557#endif 558 if (signalpipe[0] > maxsock) 559 maxsock = signalpipe[0]; 560 if (signalpipe[1] > maxsock) 561 maxsock = signalpipe[1]; 562 563 for (;;) { 564 int n, ctrl; 565 fd_set readable; 566 567#ifdef SANITY_CHECK 568 if (nsock == 0) { 569 syslog(LOG_ERR, "%s: nsock=0", __func__); 570 exit(EX_SOFTWARE); 571 } 572#endif 573 readable = allsock; 574 if ((n = select(maxsock + 1, &readable, (fd_set *)0, 575 (fd_set *)0, (struct timeval *)0)) <= 0) { 576 if (n < 0 && errno != EINTR) { 577 syslog(LOG_WARNING, "select: %m"); 578 sleep(1); 579 } 580 continue; 581 } 582 /* handle any queued signal flags */ 583 if (FD_ISSET(signalpipe[0], &readable)) { 584 int nsig; 585 if (ioctl(signalpipe[0], FIONREAD, &nsig) != 0) { 586 syslog(LOG_ERR, "ioctl: %m"); 587 exit(EX_OSERR); 588 } 589 while (--nsig >= 0) { 590 char c; 591 if (read(signalpipe[0], &c, 1) != 1) { 592 syslog(LOG_ERR, "read: %m"); 593 exit(EX_OSERR); 594 } 595 if (debug) 596 warnx("handling signal flag %c", c); 597 switch(c) { 598 case 'A': /* sigalrm */ 599 retry(); 600 break; 601 case 'C': /* sigchld */ 602 reapchild(); 603 break; 604 case 'H': /* sighup */ 605 config(); 606 break; 607 } 608 } 609 } 610 for (sep = servtab; n && sep; sep = sep->se_next) 611 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) { 612 n--; 613 if (debug) 614 warnx("someone wants %s", sep->se_service); 615 dofork = !sep->se_bi || sep->se_bi->bi_fork || ISWRAP(sep); 616 conn = NULL; 617 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) { 618 i = 1; 619 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) 620 syslog(LOG_ERR, "ioctl (FIONBIO, 1): %m"); 621 ctrl = accept(sep->se_fd, (struct sockaddr *)0, 622 (socklen_t *)0); 623 if (debug) 624 warnx("accept, ctrl %d", ctrl); 625 if (ctrl < 0) { 626 if (errno != EINTR) 627 syslog(LOG_WARNING, 628 "accept (for %s): %m", 629 sep->se_service); 630 if (sep->se_accept && 631 sep->se_socktype == SOCK_STREAM) 632 close(ctrl); 633 continue; 634 } 635 i = 0; 636 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) 637 syslog(LOG_ERR, "ioctl1(FIONBIO, 0): %m"); 638 if (ioctl(ctrl, FIONBIO, &i) < 0) 639 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m"); 640 if (cpmip(sep, ctrl) < 0) { 641 close(ctrl); 642 continue; 643 } 644 if (dofork && 645 (conn = search_conn(sep, ctrl)) != NULL && 646 !room_conn(sep, conn)) { 647 close(ctrl); 648 continue; 649 } 650 } else 651 ctrl = sep->se_fd; 652 if (dolog && !ISWRAP(sep)) { 653 char pname[INET6_ADDRSTRLEN] = "unknown"; 654 socklen_t sl; 655 sl = sizeof peermax; 656 if (getpeername(ctrl, (struct sockaddr *) 657 &peermax, &sl)) { 658 sl = sizeof peermax; 659 if (recvfrom(ctrl, buf, sizeof(buf), 660 MSG_PEEK, 661 (struct sockaddr *)&peermax, 662 &sl) >= 0) { 663 getnameinfo((struct sockaddr *)&peermax, 664 peer.sa_len, 665 pname, sizeof(pname),
| 153#ifndef LIBWRAP_ALLOW_FACILITY 154# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 155#endif 156#ifndef LIBWRAP_ALLOW_SEVERITY 157# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 158#endif 159#ifndef LIBWRAP_DENY_FACILITY 160# define LIBWRAP_DENY_FACILITY LOG_AUTH 161#endif 162#ifndef LIBWRAP_DENY_SEVERITY 163# define LIBWRAP_DENY_SEVERITY LOG_WARNING 164#endif 165 166#define ISWRAP(sep) \ 167 ( ((wrap_ex && !(sep)->se_bi) || (wrap_bi && (sep)->se_bi)) \ 168 && (sep->se_family == AF_INET || sep->se_family == AF_INET6) \ 169 && ( ((sep)->se_accept && (sep)->se_socktype == SOCK_STREAM) \ 170 || (sep)->se_socktype == SOCK_DGRAM)) 171 172#ifdef LOGIN_CAP 173#include <login_cap.h> 174 175/* see init.c */ 176#define RESOURCE_RC "daemon" 177 178#endif 179 180#ifndef MAXCHILD 181#define MAXCHILD -1 /* maximum number of this service 182 < 0 = no limit */ 183#endif 184 185#ifndef MAXCPM 186#define MAXCPM -1 /* rate limit invocations from a 187 single remote address, 188 < 0 = no limit */ 189#endif 190 191#ifndef MAXPERIP 192#define MAXPERIP -1 /* maximum number of this service 193 from a single remote address, 194 < 0 = no limit */ 195#endif 196 197#ifndef TOOMANY 198#define TOOMANY 256 /* don't start more than TOOMANY */ 199#endif 200#define CNT_INTVL 60 /* servers in CNT_INTVL sec. */ 201#define RETRYTIME (60*10) /* retry after bind or server fail */ 202#define MAX_MAXCHLD 32767 /* max allowable max children */ 203 204#define SIGBLOCK (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM)) 205 206void close_sep(struct servtab *); 207void flag_signal(int); 208void flag_config(int); 209void config(void); 210int cpmip(const struct servtab *, int); 211void endconfig(void); 212struct servtab *enter(struct servtab *); 213void freeconfig(struct servtab *); 214struct servtab *getconfigent(void); 215int matchservent(const char *, const char *, const char *); 216char *nextline(FILE *); 217void addchild(struct servtab *, int); 218void flag_reapchild(int); 219void reapchild(void); 220void enable(struct servtab *); 221void disable(struct servtab *); 222void flag_retry(int); 223void retry(void); 224int setconfig(void); 225void setup(struct servtab *); 226#ifdef IPSEC 227void ipsecsetup(struct servtab *); 228#endif 229void unregisterrpc(register struct servtab *sep); 230static struct conninfo *search_conn(struct servtab *sep, int ctrl); 231static int room_conn(struct servtab *sep, struct conninfo *conn); 232static void addchild_conn(struct conninfo *conn, pid_t pid); 233static void reapchild_conn(pid_t pid); 234static void free_conn(struct conninfo *conn); 235static void resize_conn(struct servtab *sep, int maxperip); 236static void free_connlist(struct servtab *sep); 237static void free_proc(struct procinfo *); 238static struct procinfo *search_proc(pid_t pid, int add); 239static int hashval(char *p, int len); 240 241int allow_severity; 242int deny_severity; 243int wrap_ex = 0; 244int wrap_bi = 0; 245int debug = 0; 246int dolog = 0; 247int maxsock; /* highest-numbered descriptor */ 248fd_set allsock; 249int options; 250int timingout; 251int toomany = TOOMANY; 252int maxchild = MAXCHILD; 253int maxcpm = MAXCPM; 254int maxperip = MAXPERIP; 255struct servent *sp; 256struct rpcent *rpc; 257char *hostname = NULL; 258struct sockaddr_in *bind_sa4; 259int v4bind_ok = 0; 260#ifdef INET6 261struct sockaddr_in6 *bind_sa6; 262int v6bind_ok = 0; 263#endif 264int signalpipe[2]; 265#ifdef SANITY_CHECK 266int nsock; 267#endif 268uid_t euid; 269gid_t egid; 270mode_t mask; 271 272struct servtab *servtab; 273 274extern struct biltin biltins[]; 275 276const char *CONFIG = _PATH_INETDCONF; 277const char *pid_file = _PATH_INETDPID; 278 279struct netconfig *udpconf, *tcpconf, *udp6conf, *tcp6conf; 280 281static LIST_HEAD(, procinfo) proctable[PERIPSIZE]; 282 283int 284getvalue(const char *arg, int *value, const char *whine) 285{ 286 int tmp; 287 char *p; 288 289 tmp = strtol(arg, &p, 0); 290 if (tmp < 0 || *p) { 291 syslog(LOG_ERR, whine, arg); 292 return 1; /* failure */ 293 } 294 *value = tmp; 295 return 0; /* success */ 296} 297 298static sa_family_t 299whichaf(struct request_info *req) 300{ 301 struct sockaddr *sa; 302 303 sa = (struct sockaddr *)req->client->sin; 304 if (sa == NULL) 305 return AF_UNSPEC; 306 if (sa->sa_family == AF_INET6 && 307 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) 308 return AF_INET; 309 return sa->sa_family; 310} 311 312int 313main(int argc, char **argv) 314{ 315 struct servtab *sep; 316 struct passwd *pwd; 317 struct group *grp; 318 struct sigaction sa, saalrm, sachld, sahup, sapipe; 319 int ch, dofork; 320 pid_t pid; 321 char buf[50]; 322#ifdef LOGIN_CAP 323 login_cap_t *lc = NULL; 324#endif 325 struct request_info req; 326 int denied; 327 char *service = NULL; 328 union { 329 struct sockaddr peer_un; 330 struct sockaddr_in peer_un4; 331 struct sockaddr_in6 peer_un6; 332 struct sockaddr_storage peer_max; 333 } p_un; 334#define peer p_un.peer_un 335#define peer4 p_un.peer_un4 336#define peer6 p_un.peer_un6 337#define peermax p_un.peer_max 338 int i; 339 struct addrinfo hints, *res; 340 const char *servname; 341 int error; 342 struct conninfo *conn; 343 344 openlog("inetd", LOG_PID | LOG_NOWAIT | LOG_PERROR, LOG_DAEMON); 345 346 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:s:")) != -1) 347 switch(ch) { 348 case 'd': 349 debug = 1; 350 options |= SO_DEBUG; 351 break; 352 case 'l': 353 dolog = 1; 354 break; 355 case 'R': 356 getvalue(optarg, &toomany, 357 "-R %s: bad value for service invocation rate"); 358 break; 359 case 'c': 360 getvalue(optarg, &maxchild, 361 "-c %s: bad value for maximum children"); 362 break; 363 case 'C': 364 getvalue(optarg, &maxcpm, 365 "-C %s: bad value for maximum children/minute"); 366 break; 367 case 'a': 368 hostname = optarg; 369 break; 370 case 'p': 371 pid_file = optarg; 372 break; 373 case 's': 374 getvalue(optarg, &maxperip, 375 "-s %s: bad value for maximum children per source address"); 376 break; 377 case 'w': 378 wrap_ex++; 379 break; 380 case 'W': 381 wrap_bi++; 382 break; 383 case '?': 384 default: 385 syslog(LOG_ERR, 386 "usage: inetd [-dlwW] [-a address] [-R rate]" 387 " [-c maximum] [-C rate]" 388 " [-p pidfile] [conf-file]"); 389 exit(EX_USAGE); 390 } 391 /* 392 * Initialize Bind Addrs. 393 * When hostname is NULL, wild card bind addrs are obtained from 394 * getaddrinfo(). But getaddrinfo() requires at least one of 395 * hostname or servname is non NULL. 396 * So when hostname is NULL, set dummy value to servname. 397 * Since getaddrinfo() doesn't accept numeric servname, and 398 * we doesn't use ai_socktype of struct addrinfo returned 399 * from getaddrinfo(), we set dummy value to ai_socktype. 400 */ 401 servname = (hostname == NULL) ? "0" /* dummy */ : NULL; 402 403 bzero(&hints, sizeof(struct addrinfo)); 404 hints.ai_flags = AI_PASSIVE; 405 hints.ai_family = AF_UNSPEC; 406 hints.ai_socktype = SOCK_STREAM; /* dummy */ 407 error = getaddrinfo(hostname, servname, &hints, &res); 408 if (error != 0) { 409 syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error)); 410 if (error == EAI_SYSTEM) 411 syslog(LOG_ERR, "%s", strerror(errno)); 412 exit(EX_USAGE); 413 } 414 do { 415 if (res->ai_addr == NULL) { 416 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname); 417 exit(EX_USAGE); 418 } 419 switch (res->ai_addr->sa_family) { 420 case AF_INET: 421 if (v4bind_ok) 422 continue; 423 bind_sa4 = (struct sockaddr_in *)res->ai_addr; 424 /* init port num in case servname is dummy */ 425 bind_sa4->sin_port = 0; 426 v4bind_ok = 1; 427 continue; 428#ifdef INET6 429 case AF_INET6: 430 if (v6bind_ok) 431 continue; 432 bind_sa6 = (struct sockaddr_in6 *)res->ai_addr; 433 /* init port num in case servname is dummy */ 434 bind_sa6->sin6_port = 0; 435 v6bind_ok = 1; 436 continue; 437#endif 438 } 439 if (v4bind_ok 440#ifdef INET6 441 && v6bind_ok 442#endif 443 ) 444 break; 445 } while ((res = res->ai_next) != NULL); 446 if (!v4bind_ok 447#ifdef INET6 448 && !v6bind_ok 449#endif 450 ) { 451 syslog(LOG_ERR, "-a %s: unknown address family", hostname); 452 exit(EX_USAGE); 453 } 454 455 euid = geteuid(); 456 egid = getegid(); 457 umask(mask = umask(0777)); 458 459 argc -= optind; 460 argv += optind; 461 462 if (argc > 0) 463 CONFIG = argv[0]; 464 if (access(CONFIG, R_OK) < 0) 465 syslog(LOG_ERR, "Accessing %s: %m, continuing anyway.", CONFIG); 466 if (debug == 0) { 467 FILE *fp; 468 if (daemon(0, 0) < 0) { 469 syslog(LOG_WARNING, "daemon(0,0) failed: %m"); 470 } 471 /* From now on we don't want syslog messages going to stderr. */ 472 closelog(); 473 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 474 /* 475 * In case somebody has started inetd manually, we need to 476 * clear the logname, so that old servers run as root do not 477 * get the user's logname.. 478 */ 479 if (setlogin("") < 0) { 480 syslog(LOG_WARNING, "cannot clear logname: %m"); 481 /* no big deal if it fails.. */ 482 } 483 pid = getpid(); 484 fp = fopen(pid_file, "w"); 485 if (fp) { 486 fprintf(fp, "%ld\n", (long)pid); 487 fclose(fp); 488 } else { 489 syslog(LOG_WARNING, "%s: %m", pid_file); 490 } 491 } 492 493 for (i = 0; i < PERIPSIZE; ++i) 494 LIST_INIT(&proctable[i]); 495 496 if (v4bind_ok) { 497 udpconf = getnetconfigent("udp"); 498 tcpconf = getnetconfigent("tcp"); 499 if (udpconf == NULL || tcpconf == NULL) { 500 syslog(LOG_ERR, "unknown rpc/udp or rpc/tcp"); 501 exit(EX_USAGE); 502 } 503 } 504#ifdef INET6 505 if (v6bind_ok) { 506 udp6conf = getnetconfigent("udp6"); 507 tcp6conf = getnetconfigent("tcp6"); 508 if (udp6conf == NULL || tcp6conf == NULL) { 509 syslog(LOG_ERR, "unknown rpc/udp6 or rpc/tcp6"); 510 exit(EX_USAGE); 511 } 512 } 513#endif 514 515 sa.sa_flags = 0; 516 sigemptyset(&sa.sa_mask); 517 sigaddset(&sa.sa_mask, SIGALRM); 518 sigaddset(&sa.sa_mask, SIGCHLD); 519 sigaddset(&sa.sa_mask, SIGHUP); 520 sa.sa_handler = flag_retry; 521 sigaction(SIGALRM, &sa, &saalrm); 522 config(); 523 sa.sa_handler = flag_config; 524 sigaction(SIGHUP, &sa, &sahup); 525 sa.sa_handler = flag_reapchild; 526 sigaction(SIGCHLD, &sa, &sachld); 527 sa.sa_handler = SIG_IGN; 528 sigaction(SIGPIPE, &sa, &sapipe); 529 530 { 531 /* space for daemons to overwrite environment for ps */ 532#define DUMMYSIZE 100 533 char dummy[DUMMYSIZE]; 534 535 (void)memset(dummy, 'x', DUMMYSIZE - 1); 536 dummy[DUMMYSIZE - 1] = '\0'; 537 (void)setenv("inetd_dummy", dummy, 1); 538 } 539 540 if (pipe(signalpipe) != 0) { 541 syslog(LOG_ERR, "pipe: %m"); 542 exit(EX_OSERR); 543 } 544 if (fcntl(signalpipe[0], F_SETFD, FD_CLOEXEC) < 0 || 545 fcntl(signalpipe[1], F_SETFD, FD_CLOEXEC) < 0) { 546 syslog(LOG_ERR, "signalpipe: fcntl (F_SETFD, FD_CLOEXEC): %m"); 547 exit(EX_OSERR); 548 } 549 FD_SET(signalpipe[0], &allsock); 550#ifdef SANITY_CHECK 551 nsock++; 552#endif 553 if (signalpipe[0] > maxsock) 554 maxsock = signalpipe[0]; 555 if (signalpipe[1] > maxsock) 556 maxsock = signalpipe[1]; 557 558 for (;;) { 559 int n, ctrl; 560 fd_set readable; 561 562#ifdef SANITY_CHECK 563 if (nsock == 0) { 564 syslog(LOG_ERR, "%s: nsock=0", __func__); 565 exit(EX_SOFTWARE); 566 } 567#endif 568 readable = allsock; 569 if ((n = select(maxsock + 1, &readable, (fd_set *)0, 570 (fd_set *)0, (struct timeval *)0)) <= 0) { 571 if (n < 0 && errno != EINTR) { 572 syslog(LOG_WARNING, "select: %m"); 573 sleep(1); 574 } 575 continue; 576 } 577 /* handle any queued signal flags */ 578 if (FD_ISSET(signalpipe[0], &readable)) { 579 int nsig; 580 if (ioctl(signalpipe[0], FIONREAD, &nsig) != 0) { 581 syslog(LOG_ERR, "ioctl: %m"); 582 exit(EX_OSERR); 583 } 584 while (--nsig >= 0) { 585 char c; 586 if (read(signalpipe[0], &c, 1) != 1) { 587 syslog(LOG_ERR, "read: %m"); 588 exit(EX_OSERR); 589 } 590 if (debug) 591 warnx("handling signal flag %c", c); 592 switch(c) { 593 case 'A': /* sigalrm */ 594 retry(); 595 break; 596 case 'C': /* sigchld */ 597 reapchild(); 598 break; 599 case 'H': /* sighup */ 600 config(); 601 break; 602 } 603 } 604 } 605 for (sep = servtab; n && sep; sep = sep->se_next) 606 if (sep->se_fd != -1 && FD_ISSET(sep->se_fd, &readable)) { 607 n--; 608 if (debug) 609 warnx("someone wants %s", sep->se_service); 610 dofork = !sep->se_bi || sep->se_bi->bi_fork || ISWRAP(sep); 611 conn = NULL; 612 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) { 613 i = 1; 614 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) 615 syslog(LOG_ERR, "ioctl (FIONBIO, 1): %m"); 616 ctrl = accept(sep->se_fd, (struct sockaddr *)0, 617 (socklen_t *)0); 618 if (debug) 619 warnx("accept, ctrl %d", ctrl); 620 if (ctrl < 0) { 621 if (errno != EINTR) 622 syslog(LOG_WARNING, 623 "accept (for %s): %m", 624 sep->se_service); 625 if (sep->se_accept && 626 sep->se_socktype == SOCK_STREAM) 627 close(ctrl); 628 continue; 629 } 630 i = 0; 631 if (ioctl(sep->se_fd, FIONBIO, &i) < 0) 632 syslog(LOG_ERR, "ioctl1(FIONBIO, 0): %m"); 633 if (ioctl(ctrl, FIONBIO, &i) < 0) 634 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m"); 635 if (cpmip(sep, ctrl) < 0) { 636 close(ctrl); 637 continue; 638 } 639 if (dofork && 640 (conn = search_conn(sep, ctrl)) != NULL && 641 !room_conn(sep, conn)) { 642 close(ctrl); 643 continue; 644 } 645 } else 646 ctrl = sep->se_fd; 647 if (dolog && !ISWRAP(sep)) { 648 char pname[INET6_ADDRSTRLEN] = "unknown"; 649 socklen_t sl; 650 sl = sizeof peermax; 651 if (getpeername(ctrl, (struct sockaddr *) 652 &peermax, &sl)) { 653 sl = sizeof peermax; 654 if (recvfrom(ctrl, buf, sizeof(buf), 655 MSG_PEEK, 656 (struct sockaddr *)&peermax, 657 &sl) >= 0) { 658 getnameinfo((struct sockaddr *)&peermax, 659 peer.sa_len, 660 pname, sizeof(pname),
|
677 } 678 syslog(LOG_INFO,"%s from %s", sep->se_service, pname); 679 } 680 (void) sigblock(SIGBLOCK); 681 pid = 0; 682 /* 683 * Fork for all external services, builtins which need to 684 * fork and anything we're wrapping (as wrapping might 685 * block or use hosts_options(5) twist). 686 */ 687 if (dofork) { 688 if (sep->se_count++ == 0) 689 (void)gettimeofday(&sep->se_time, (struct timezone *)NULL); 690 else if (toomany > 0 && sep->se_count >= toomany) { 691 struct timeval now; 692 693 (void)gettimeofday(&now, (struct timezone *)NULL); 694 if (now.tv_sec - sep->se_time.tv_sec > 695 CNT_INTVL) { 696 sep->se_time = now; 697 sep->se_count = 1; 698 } else { 699 syslog(LOG_ERR, 700 "%s/%s server failing (looping), service terminated", 701 sep->se_service, sep->se_proto); 702 if (sep->se_accept && 703 sep->se_socktype == SOCK_STREAM) 704 close(ctrl); 705 close_sep(sep); 706 free_conn(conn); 707 sigsetmask(0L); 708 if (!timingout) { 709 timingout = 1; 710 alarm(RETRYTIME); 711 } 712 continue; 713 } 714 } 715 pid = fork(); 716 } 717 if (pid < 0) { 718 syslog(LOG_ERR, "fork: %m"); 719 if (sep->se_accept && 720 sep->se_socktype == SOCK_STREAM) 721 close(ctrl); 722 free_conn(conn); 723 sigsetmask(0L); 724 sleep(1); 725 continue; 726 } 727 if (pid) { 728 addchild_conn(conn, pid); 729 addchild(sep, pid); 730 } 731 sigsetmask(0L); 732 if (pid == 0) { 733 if (dofork) { 734 sigaction(SIGALRM, &saalrm, (struct sigaction *)0); 735 sigaction(SIGCHLD, &sachld, (struct sigaction *)0); 736 sigaction(SIGHUP, &sahup, (struct sigaction *)0); 737 /* SIGPIPE reset before exec */ 738 } 739 /* 740 * Call tcpmux to find the real service to exec. 741 */ 742 if (sep->se_bi && 743 sep->se_bi->bi_fn == (bi_fn_t *) tcpmux) { 744 sep = tcpmux(ctrl); 745 if (sep == NULL) { 746 close(ctrl); 747 _exit(0); 748 } 749 } 750 if (ISWRAP(sep)) { 751 inetd_setproctitle("wrapping", ctrl); 752 service = sep->se_server_name ? 753 sep->se_server_name : sep->se_service; 754 request_init(&req, RQ_DAEMON, service, RQ_FILE, ctrl, 0); 755 fromhost(&req); 756 deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 757 allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 758 denied = !hosts_access(&req); 759 if (denied) { 760 syslog(deny_severity, 761 "refused connection from %.500s, service %s (%s%s)", 762 eval_client(&req), service, sep->se_proto, 763 (whichaf(&req) == AF_INET6) ? "6" : ""); 764 if (sep->se_socktype != SOCK_STREAM) 765 recv(ctrl, buf, sizeof (buf), 0); 766 if (dofork) { 767 sleep(1); 768 _exit(0); 769 } 770 } 771 if (dolog) { 772 syslog(allow_severity, 773 "connection from %.500s, service %s (%s%s)", 774 eval_client(&req), service, sep->se_proto, 775 (whichaf(&req) == AF_INET6) ? "6" : ""); 776 } 777 } 778 if (sep->se_bi) { 779 (*sep->se_bi->bi_fn)(ctrl, sep); 780 } else { 781 if (debug) 782 warnx("%d execl %s", 783 getpid(), sep->se_server); 784 /* Clear close-on-exec. */ 785 if (fcntl(ctrl, F_SETFD, 0) < 0) { 786 syslog(LOG_ERR, 787 "%s/%s: fcntl (F_SETFD, 0): %m", 788 sep->se_service, sep->se_proto); 789 _exit(EX_OSERR); 790 } 791 if (ctrl != 0) { 792 dup2(ctrl, 0); 793 close(ctrl); 794 } 795 dup2(0, 1); 796 dup2(0, 2); 797 if ((pwd = getpwnam(sep->se_user)) == NULL) { 798 syslog(LOG_ERR, 799 "%s/%s: %s: no such user", 800 sep->se_service, sep->se_proto, 801 sep->se_user); 802 if (sep->se_socktype != SOCK_STREAM) 803 recv(0, buf, sizeof (buf), 0); 804 _exit(EX_NOUSER); 805 } 806 grp = NULL; 807 if ( sep->se_group != NULL 808 && (grp = getgrnam(sep->se_group)) == NULL 809 ) { 810 syslog(LOG_ERR, 811 "%s/%s: %s: no such group", 812 sep->se_service, sep->se_proto, 813 sep->se_group); 814 if (sep->se_socktype != SOCK_STREAM) 815 recv(0, buf, sizeof (buf), 0); 816 _exit(EX_NOUSER); 817 } 818 if (grp != NULL) 819 pwd->pw_gid = grp->gr_gid; 820#ifdef LOGIN_CAP 821 if ((lc = login_getclass(sep->se_class)) == NULL) { 822 /* error syslogged by getclass */ 823 syslog(LOG_ERR, 824 "%s/%s: %s: login class error", 825 sep->se_service, sep->se_proto, 826 sep->se_class); 827 if (sep->se_socktype != SOCK_STREAM) 828 recv(0, buf, sizeof (buf), 0); 829 _exit(EX_NOUSER); 830 } 831#endif 832 if (setsid() < 0) { 833 syslog(LOG_ERR, 834 "%s: can't setsid(): %m", 835 sep->se_service); 836 /* _exit(EX_OSERR); not fatal yet */ 837 } 838#ifdef LOGIN_CAP 839 if (setusercontext(lc, pwd, pwd->pw_uid, 840 LOGIN_SETALL & ~LOGIN_SETMAC) 841 != 0) { 842 syslog(LOG_ERR, 843 "%s: can't setusercontext(..%s..): %m", 844 sep->se_service, sep->se_user); 845 _exit(EX_OSERR); 846 } 847 login_close(lc); 848#else 849 if (pwd->pw_uid) { 850 if (setlogin(sep->se_user) < 0) { 851 syslog(LOG_ERR, 852 "%s: can't setlogin(%s): %m", 853 sep->se_service, sep->se_user); 854 /* _exit(EX_OSERR); not yet */ 855 } 856 if (setgid(pwd->pw_gid) < 0) { 857 syslog(LOG_ERR, 858 "%s: can't set gid %d: %m", 859 sep->se_service, pwd->pw_gid); 860 _exit(EX_OSERR); 861 } 862 (void) initgroups(pwd->pw_name, 863 pwd->pw_gid); 864 if (setuid(pwd->pw_uid) < 0) { 865 syslog(LOG_ERR, 866 "%s: can't set uid %d: %m", 867 sep->se_service, pwd->pw_uid); 868 _exit(EX_OSERR); 869 } 870 } 871#endif 872 sigaction(SIGPIPE, &sapipe, 873 (struct sigaction *)0); 874 execv(sep->se_server, sep->se_argv); 875 syslog(LOG_ERR, 876 "cannot execute %s: %m", sep->se_server); 877 if (sep->se_socktype != SOCK_STREAM) 878 recv(0, buf, sizeof (buf), 0); 879 } 880 if (dofork) 881 _exit(0); 882 } 883 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) 884 close(ctrl); 885 } 886 } 887} 888 889/* 890 * Add a signal flag to the signal flag queue for later handling 891 */ 892 893void 894flag_signal(int c) 895{ 896 char ch = c; 897 898 if (write(signalpipe[1], &ch, 1) != 1) { 899 syslog(LOG_ERR, "write: %m"); 900 _exit(EX_OSERR); 901 } 902} 903 904/* 905 * Record a new child pid for this service. If we've reached the 906 * limit on children, then stop accepting incoming requests. 907 */ 908 909void 910addchild(struct servtab *sep, pid_t pid) 911{ 912 if (sep->se_maxchild <= 0) 913 return; 914#ifdef SANITY_CHECK 915 if (sep->se_numchild >= sep->se_maxchild) { 916 syslog(LOG_ERR, "%s: %d >= %d", 917 __func__, sep->se_numchild, sep->se_maxchild); 918 exit(EX_SOFTWARE); 919 } 920#endif 921 sep->se_pids[sep->se_numchild++] = pid; 922 if (sep->se_numchild == sep->se_maxchild) 923 disable(sep); 924} 925 926/* 927 * Some child process has exited. See if it's on somebody's list. 928 */ 929 930void 931flag_reapchild(int signo __unused) 932{ 933 flag_signal('C'); 934} 935 936void 937reapchild(void) 938{ 939 int k, status; 940 pid_t pid; 941 struct servtab *sep; 942 943 for (;;) { 944 pid = wait3(&status, WNOHANG, (struct rusage *)0); 945 if (pid <= 0) 946 break; 947 if (debug) 948 warnx("%d reaped, %s %u", pid, 949 WIFEXITED(status) ? "status" : "signal", 950 WIFEXITED(status) ? WEXITSTATUS(status) 951 : WTERMSIG(status)); 952 for (sep = servtab; sep; sep = sep->se_next) { 953 for (k = 0; k < sep->se_numchild; k++) 954 if (sep->se_pids[k] == pid) 955 break; 956 if (k == sep->se_numchild) 957 continue; 958 if (sep->se_numchild == sep->se_maxchild) 959 enable(sep); 960 sep->se_pids[k] = sep->se_pids[--sep->se_numchild]; 961 if (WIFSIGNALED(status) || WEXITSTATUS(status)) 962 syslog(LOG_WARNING, 963 "%s[%d]: exited, %s %u", 964 sep->se_server, pid, 965 WIFEXITED(status) ? "status" : "signal", 966 WIFEXITED(status) ? WEXITSTATUS(status) 967 : WTERMSIG(status)); 968 break; 969 } 970 reapchild_conn(pid); 971 } 972} 973 974void 975flag_config(int signo __unused) 976{ 977 flag_signal('H'); 978} 979 980void 981config(void) 982{ 983 struct servtab *sep, *new, **sepp; 984 long omask; 985 int new_nomapped; 986#ifdef LOGIN_CAP 987 login_cap_t *lc = NULL; 988#endif 989 990 if (!setconfig()) { 991 syslog(LOG_ERR, "%s: %m", CONFIG); 992 return; 993 } 994 for (sep = servtab; sep; sep = sep->se_next) 995 sep->se_checked = 0; 996 while ((new = getconfigent())) { 997 if (getpwnam(new->se_user) == NULL) { 998 syslog(LOG_ERR, 999 "%s/%s: no such user '%s', service ignored", 1000 new->se_service, new->se_proto, new->se_user); 1001 continue; 1002 } 1003 if (new->se_group && getgrnam(new->se_group) == NULL) { 1004 syslog(LOG_ERR, 1005 "%s/%s: no such group '%s', service ignored", 1006 new->se_service, new->se_proto, new->se_group); 1007 continue; 1008 } 1009#ifdef LOGIN_CAP 1010 if ((lc = login_getclass(new->se_class)) == NULL) { 1011 /* error syslogged by getclass */ 1012 syslog(LOG_ERR, 1013 "%s/%s: %s: login class error, service ignored", 1014 new->se_service, new->se_proto, new->se_class); 1015 continue; 1016 } 1017 login_close(lc); 1018#endif 1019 new_nomapped = new->se_nomapped; 1020 for (sep = servtab; sep; sep = sep->se_next) 1021 if (strcmp(sep->se_service, new->se_service) == 0 && 1022 strcmp(sep->se_proto, new->se_proto) == 0 && 1023 sep->se_rpc == new->se_rpc && 1024 sep->se_socktype == new->se_socktype && 1025 sep->se_family == new->se_family) 1026 break; 1027 if (sep != 0) { 1028 int i; 1029 1030#define SWAP(t,a, b) { t c = a; a = b; b = c; } 1031 omask = sigblock(SIGBLOCK); 1032 if (sep->se_nomapped != new->se_nomapped) { 1033 /* for rpc keep old nommaped till unregister */ 1034 if (!sep->se_rpc) 1035 sep->se_nomapped = new->se_nomapped; 1036 sep->se_reset = 1; 1037 } 1038 /* copy over outstanding child pids */ 1039 if (sep->se_maxchild > 0 && new->se_maxchild > 0) { 1040 new->se_numchild = sep->se_numchild; 1041 if (new->se_numchild > new->se_maxchild) 1042 new->se_numchild = new->se_maxchild; 1043 memcpy(new->se_pids, sep->se_pids, 1044 new->se_numchild * sizeof(*new->se_pids)); 1045 } 1046 SWAP(pid_t *, sep->se_pids, new->se_pids); 1047 sep->se_maxchild = new->se_maxchild; 1048 sep->se_numchild = new->se_numchild; 1049 sep->se_maxcpm = new->se_maxcpm; 1050 resize_conn(sep, new->se_maxperip); 1051 sep->se_maxperip = new->se_maxperip; 1052 sep->se_bi = new->se_bi; 1053 /* might need to turn on or off service now */ 1054 if (sep->se_fd >= 0) { 1055 if (sep->se_maxchild > 0 1056 && sep->se_numchild == sep->se_maxchild) { 1057 if (FD_ISSET(sep->se_fd, &allsock)) 1058 disable(sep); 1059 } else { 1060 if (!FD_ISSET(sep->se_fd, &allsock)) 1061 enable(sep); 1062 } 1063 } 1064 sep->se_accept = new->se_accept; 1065 SWAP(char *, sep->se_user, new->se_user); 1066 SWAP(char *, sep->se_group, new->se_group); 1067#ifdef LOGIN_CAP 1068 SWAP(char *, sep->se_class, new->se_class); 1069#endif 1070 SWAP(char *, sep->se_server, new->se_server); 1071 SWAP(char *, sep->se_server_name, new->se_server_name); 1072 for (i = 0; i < MAXARGV; i++) 1073 SWAP(char *, sep->se_argv[i], new->se_argv[i]); 1074#ifdef IPSEC 1075 SWAP(char *, sep->se_policy, new->se_policy); 1076 ipsecsetup(sep); 1077#endif 1078 sigsetmask(omask); 1079 freeconfig(new); 1080 if (debug) 1081 print_service("REDO", sep); 1082 } else { 1083 sep = enter(new); 1084 if (debug) 1085 print_service("ADD ", sep); 1086 } 1087 sep->se_checked = 1; 1088 if (ISMUX(sep)) { 1089 sep->se_fd = -1; 1090 continue; 1091 } 1092 switch (sep->se_family) { 1093 case AF_INET: 1094 if (!v4bind_ok) { 1095 sep->se_fd = -1; 1096 continue; 1097 } 1098 break; 1099#ifdef INET6 1100 case AF_INET6: 1101 if (!v6bind_ok) { 1102 sep->se_fd = -1; 1103 continue; 1104 } 1105 break; 1106#endif 1107 } 1108 if (!sep->se_rpc) { 1109 if (sep->se_family != AF_UNIX) { 1110 sp = getservbyname(sep->se_service, sep->se_proto); 1111 if (sp == 0) { 1112 syslog(LOG_ERR, "%s/%s: unknown service", 1113 sep->se_service, sep->se_proto); 1114 sep->se_checked = 0; 1115 continue; 1116 } 1117 } 1118 switch (sep->se_family) { 1119 case AF_INET: 1120 if (sp->s_port != sep->se_ctrladdr4.sin_port) { 1121 sep->se_ctrladdr4.sin_port = 1122 sp->s_port; 1123 sep->se_reset = 1; 1124 } 1125 break; 1126#ifdef INET6 1127 case AF_INET6: 1128 if (sp->s_port != 1129 sep->se_ctrladdr6.sin6_port) { 1130 sep->se_ctrladdr6.sin6_port = 1131 sp->s_port; 1132 sep->se_reset = 1; 1133 } 1134 break; 1135#endif 1136 } 1137 if (sep->se_reset != 0 && sep->se_fd >= 0) 1138 close_sep(sep); 1139 } else { 1140 rpc = getrpcbyname(sep->se_service); 1141 if (rpc == 0) { 1142 syslog(LOG_ERR, "%s/%s unknown RPC service", 1143 sep->se_service, sep->se_proto); 1144 if (sep->se_fd != -1) 1145 (void) close(sep->se_fd); 1146 sep->se_fd = -1; 1147 continue; 1148 } 1149 if (sep->se_reset != 0 || 1150 rpc->r_number != sep->se_rpc_prog) { 1151 if (sep->se_rpc_prog) 1152 unregisterrpc(sep); 1153 sep->se_rpc_prog = rpc->r_number; 1154 if (sep->se_fd != -1) 1155 (void) close(sep->se_fd); 1156 sep->se_fd = -1; 1157 } 1158 sep->se_nomapped = new_nomapped; 1159 } 1160 sep->se_reset = 0; 1161 if (sep->se_fd == -1) 1162 setup(sep); 1163 } 1164 endconfig(); 1165 /* 1166 * Purge anything not looked at above. 1167 */ 1168 omask = sigblock(SIGBLOCK); 1169 sepp = &servtab; 1170 while ((sep = *sepp)) { 1171 if (sep->se_checked) { 1172 sepp = &sep->se_next; 1173 continue; 1174 } 1175 *sepp = sep->se_next; 1176 if (sep->se_fd >= 0) 1177 close_sep(sep); 1178 if (debug) 1179 print_service("FREE", sep); 1180 if (sep->se_rpc && sep->se_rpc_prog > 0) 1181 unregisterrpc(sep); 1182 freeconfig(sep); 1183 free(sep); 1184 } 1185 (void) sigsetmask(omask); 1186} 1187 1188void 1189unregisterrpc(struct servtab *sep) 1190{ 1191 u_int i; 1192 struct servtab *sepp; 1193 long omask; 1194 struct netconfig *netid4, *netid6; 1195 1196 omask = sigblock(SIGBLOCK); 1197 netid4 = sep->se_socktype == SOCK_DGRAM ? udpconf : tcpconf; 1198 netid6 = sep->se_socktype == SOCK_DGRAM ? udp6conf : tcp6conf; 1199 if (sep->se_family == AF_INET) 1200 netid6 = NULL; 1201 else if (sep->se_nomapped) 1202 netid4 = NULL; 1203 /* 1204 * Conflict if same prog and protocol - In that case one should look 1205 * to versions, but it is not interesting: having separate servers for 1206 * different versions does not work well. 1207 * Therefore one do not unregister if there is a conflict. 1208 * There is also transport conflict if destroying INET when INET46 1209 * exists, or destroying INET46 when INET exists 1210 */ 1211 for (sepp = servtab; sepp; sepp = sepp->se_next) { 1212 if (sepp == sep) 1213 continue; 1214 if (sepp->se_checked == 0 || 1215 !sepp->se_rpc || 1216 strcmp(sep->se_proto, sepp->se_proto) != 0 || 1217 sep->se_rpc_prog != sepp->se_rpc_prog) 1218 continue; 1219 if (sepp->se_family == AF_INET) 1220 netid4 = NULL; 1221 if (sepp->se_family == AF_INET6) { 1222 netid6 = NULL; 1223 if (!sep->se_nomapped) 1224 netid4 = NULL; 1225 } 1226 if (netid4 == NULL && netid6 == NULL) 1227 return; 1228 } 1229 if (debug) 1230 print_service("UNREG", sep); 1231 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1232 if (netid4) 1233 rpcb_unset(sep->se_rpc_prog, i, netid4); 1234 if (netid6) 1235 rpcb_unset(sep->se_rpc_prog, i, netid6); 1236 } 1237 if (sep->se_fd != -1) 1238 (void) close(sep->se_fd); 1239 sep->se_fd = -1; 1240 (void) sigsetmask(omask); 1241} 1242 1243void 1244flag_retry(int signo __unused) 1245{ 1246 flag_signal('A'); 1247} 1248 1249void 1250retry(void) 1251{ 1252 struct servtab *sep; 1253 1254 timingout = 0; 1255 for (sep = servtab; sep; sep = sep->se_next) 1256 if (sep->se_fd == -1 && !ISMUX(sep)) 1257 setup(sep); 1258} 1259 1260void 1261setup(struct servtab *sep) 1262{ 1263 int on = 1; 1264 1265 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { 1266 if (debug) 1267 warn("socket failed on %s/%s", 1268 sep->se_service, sep->se_proto); 1269 syslog(LOG_ERR, "%s/%s: socket: %m", 1270 sep->se_service, sep->se_proto); 1271 return; 1272 } 1273 /* Set all listening sockets to close-on-exec. */ 1274 if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) { 1275 syslog(LOG_ERR, "%s/%s: fcntl (F_SETFD, FD_CLOEXEC): %m", 1276 sep->se_service, sep->se_proto); 1277 close(sep->se_fd); 1278 return; 1279 } 1280#define turnon(fd, opt) \ 1281setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) 1282 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 1283 turnon(sep->se_fd, SO_DEBUG) < 0) 1284 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 1285 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 1286 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 1287#ifdef SO_PRIVSTATE 1288 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0) 1289 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m"); 1290#endif 1291 /* tftpd opens a new connection then needs more infos */ 1292 if ((sep->se_family == AF_INET6) && 1293 (strcmp(sep->se_proto, "udp") == 0) && 1294 (sep->se_accept == 0) && 1295 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1296 (char *)&on, sizeof (on)) < 0)) 1297 syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m"); 1298 if (sep->se_family == AF_INET6) { 1299 int flag = sep->se_nomapped ? 1 : 0; 1300 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_V6ONLY, 1301 (char *)&flag, sizeof (flag)) < 0) 1302 syslog(LOG_ERR, "setsockopt (IPV6_V6ONLY): %m"); 1303 } 1304#undef turnon 1305 if (sep->se_type == TTCP_TYPE) 1306 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH, 1307 (char *)&on, sizeof (on)) < 0) 1308 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m"); 1309#ifdef IPV6_FAITH 1310 if (sep->se_type == FAITH_TYPE) { 1311 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on, 1312 sizeof(on)) < 0) { 1313 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); 1314 } 1315 } 1316#endif 1317#ifdef IPSEC 1318 ipsecsetup(sep); 1319#endif 1320 if (sep->se_family == AF_UNIX) { 1321 (void) unlink(sep->se_ctrladdr_un.sun_path); 1322 umask(0777); /* Make socket with conservative permissions */ 1323 } 1324 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, 1325 sep->se_ctrladdr_size) < 0) { 1326 if (debug) 1327 warn("bind failed on %s/%s", 1328 sep->se_service, sep->se_proto); 1329 syslog(LOG_ERR, "%s/%s: bind: %m", 1330 sep->se_service, sep->se_proto); 1331 (void) close(sep->se_fd); 1332 sep->se_fd = -1; 1333 if (!timingout) { 1334 timingout = 1; 1335 alarm(RETRYTIME); 1336 } 1337 if (sep->se_family == AF_UNIX) 1338 umask(mask); 1339 return; 1340 } 1341 if (sep->se_family == AF_UNIX) { 1342 /* Ick - fch{own,mod} don't work on Unix domain sockets */ 1343 if (chown(sep->se_service, sep->se_sockuid, sep->se_sockgid) < 0) 1344 syslog(LOG_ERR, "chown socket: %m"); 1345 if (chmod(sep->se_service, sep->se_sockmode) < 0) 1346 syslog(LOG_ERR, "chmod socket: %m"); 1347 umask(mask); 1348 } 1349 if (sep->se_rpc) { 1350 u_int i; 1351 socklen_t len = sep->se_ctrladdr_size; 1352 struct netconfig *netid, *netid2 = NULL; 1353 struct sockaddr_in sock; 1354 struct netbuf nbuf, nbuf2; 1355 1356 if (getsockname(sep->se_fd, 1357 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){ 1358 syslog(LOG_ERR, "%s/%s: getsockname: %m", 1359 sep->se_service, sep->se_proto); 1360 (void) close(sep->se_fd); 1361 sep->se_fd = -1; 1362 return; 1363 } 1364 nbuf.buf = &sep->se_ctrladdr; 1365 nbuf.len = sep->se_ctrladdr.sa_len; 1366 if (sep->se_family == AF_INET) 1367 netid = sep->se_socktype==SOCK_DGRAM? udpconf:tcpconf; 1368 else { 1369 netid = sep->se_socktype==SOCK_DGRAM? udp6conf:tcp6conf; 1370 if (!sep->se_nomapped) { /* INET and INET6 */ 1371 netid2 = netid==udp6conf? udpconf:tcpconf; 1372 memset(&sock, 0, sizeof sock); /* ADDR_ANY */ 1373 nbuf2.buf = &sock; 1374 nbuf2.len = sock.sin_len = sizeof sock; 1375 sock.sin_family = AF_INET; 1376 sock.sin_port = sep->se_ctrladdr6.sin6_port; 1377 } 1378 } 1379 if (debug) 1380 print_service("REG ", sep); 1381 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1382 rpcb_unset(sep->se_rpc_prog, i, netid); 1383 rpcb_set(sep->se_rpc_prog, i, netid, &nbuf); 1384 if (netid2) { 1385 rpcb_unset(sep->se_rpc_prog, i, netid2); 1386 rpcb_set(sep->se_rpc_prog, i, netid2, &nbuf2); 1387 } 1388 } 1389 } 1390 if (sep->se_socktype == SOCK_STREAM) 1391 listen(sep->se_fd, 64); 1392 enable(sep); 1393 if (debug) { 1394 warnx("registered %s on %d", 1395 sep->se_server, sep->se_fd); 1396 } 1397} 1398 1399#ifdef IPSEC 1400void 1401ipsecsetup(sep) 1402 struct servtab *sep; 1403{ 1404 char *buf; 1405 char *policy_in = NULL; 1406 char *policy_out = NULL; 1407 int level; 1408 int opt; 1409 1410 switch (sep->se_family) { 1411 case AF_INET: 1412 level = IPPROTO_IP; 1413 opt = IP_IPSEC_POLICY; 1414 break; 1415#ifdef INET6 1416 case AF_INET6: 1417 level = IPPROTO_IPV6; 1418 opt = IPV6_IPSEC_POLICY; 1419 break; 1420#endif 1421 default: 1422 return; 1423 } 1424 1425 if (!sep->se_policy || sep->se_policy[0] == '\0') { 1426 static char def_in[] = "in entrust", def_out[] = "out entrust"; 1427 policy_in = def_in; 1428 policy_out = def_out; 1429 } else { 1430 if (!strncmp("in", sep->se_policy, 2)) 1431 policy_in = sep->se_policy; 1432 else if (!strncmp("out", sep->se_policy, 3)) 1433 policy_out = sep->se_policy; 1434 else { 1435 syslog(LOG_ERR, "invalid security policy \"%s\"", 1436 sep->se_policy); 1437 return; 1438 } 1439 } 1440 1441 if (policy_in != NULL) { 1442 buf = ipsec_set_policy(policy_in, strlen(policy_in)); 1443 if (buf != NULL) { 1444 if (setsockopt(sep->se_fd, level, opt, 1445 buf, ipsec_get_policylen(buf)) < 0 && 1446 debug != 0) 1447 warnx("%s/%s: ipsec initialization failed; %s", 1448 sep->se_service, sep->se_proto, 1449 policy_in); 1450 free(buf); 1451 } else 1452 syslog(LOG_ERR, "invalid security policy \"%s\"", 1453 policy_in); 1454 } 1455 if (policy_out != NULL) { 1456 buf = ipsec_set_policy(policy_out, strlen(policy_out)); 1457 if (buf != NULL) { 1458 if (setsockopt(sep->se_fd, level, opt, 1459 buf, ipsec_get_policylen(buf)) < 0 && 1460 debug != 0) 1461 warnx("%s/%s: ipsec initialization failed; %s", 1462 sep->se_service, sep->se_proto, 1463 policy_out); 1464 free(buf); 1465 } else 1466 syslog(LOG_ERR, "invalid security policy \"%s\"", 1467 policy_out); 1468 } 1469} 1470#endif 1471 1472/* 1473 * Finish with a service and its socket. 1474 */ 1475void 1476close_sep(struct servtab *sep) 1477{ 1478 if (sep->se_fd >= 0) { 1479 if (FD_ISSET(sep->se_fd, &allsock)) 1480 disable(sep); 1481 (void) close(sep->se_fd); 1482 sep->se_fd = -1; 1483 } 1484 sep->se_count = 0; 1485 sep->se_numchild = 0; /* forget about any existing children */ 1486} 1487 1488int 1489matchservent(const char *name1, const char *name2, const char *proto) 1490{ 1491 char **alias, *p; 1492 struct servent *se; 1493 1494 if (strcmp(proto, "unix") == 0) { 1495 if ((p = strrchr(name1, '/')) != NULL) 1496 name1 = p + 1; 1497 if ((p = strrchr(name2, '/')) != NULL) 1498 name2 = p + 1; 1499 } 1500 if (strcmp(name1, name2) == 0) 1501 return(1); 1502 if ((se = getservbyname(name1, proto)) != NULL) { 1503 if (strcmp(name2, se->s_name) == 0) 1504 return(1); 1505 for (alias = se->s_aliases; *alias; alias++) 1506 if (strcmp(name2, *alias) == 0) 1507 return(1); 1508 } 1509 return(0); 1510} 1511 1512struct servtab * 1513enter(struct servtab *cp) 1514{ 1515 struct servtab *sep; 1516 long omask; 1517 1518 sep = (struct servtab *)malloc(sizeof (*sep)); 1519 if (sep == (struct servtab *)0) { 1520 syslog(LOG_ERR, "malloc: %m"); 1521 exit(EX_OSERR); 1522 } 1523 *sep = *cp; 1524 sep->se_fd = -1; 1525 omask = sigblock(SIGBLOCK); 1526 sep->se_next = servtab; 1527 servtab = sep; 1528 sigsetmask(omask); 1529 return (sep); 1530} 1531 1532void 1533enable(struct servtab *sep) 1534{ 1535 if (debug) 1536 warnx( 1537 "enabling %s, fd %d", sep->se_service, sep->se_fd); 1538#ifdef SANITY_CHECK 1539 if (sep->se_fd < 0) { 1540 syslog(LOG_ERR, 1541 "%s: %s: bad fd", __func__, sep->se_service); 1542 exit(EX_SOFTWARE); 1543 } 1544 if (ISMUX(sep)) { 1545 syslog(LOG_ERR, 1546 "%s: %s: is mux", __func__, sep->se_service); 1547 exit(EX_SOFTWARE); 1548 } 1549 if (FD_ISSET(sep->se_fd, &allsock)) { 1550 syslog(LOG_ERR, 1551 "%s: %s: not off", __func__, sep->se_service); 1552 exit(EX_SOFTWARE); 1553 } 1554 nsock++; 1555#endif 1556 FD_SET(sep->se_fd, &allsock); 1557 if (sep->se_fd > maxsock) 1558 maxsock = sep->se_fd; 1559} 1560 1561void 1562disable(struct servtab *sep) 1563{ 1564 if (debug) 1565 warnx( 1566 "disabling %s, fd %d", sep->se_service, sep->se_fd); 1567#ifdef SANITY_CHECK 1568 if (sep->se_fd < 0) { 1569 syslog(LOG_ERR, 1570 "%s: %s: bad fd", __func__, sep->se_service); 1571 exit(EX_SOFTWARE); 1572 } 1573 if (ISMUX(sep)) { 1574 syslog(LOG_ERR, 1575 "%s: %s: is mux", __func__, sep->se_service); 1576 exit(EX_SOFTWARE); 1577 } 1578 if (!FD_ISSET(sep->se_fd, &allsock)) { 1579 syslog(LOG_ERR, 1580 "%s: %s: not on", __func__, sep->se_service); 1581 exit(EX_SOFTWARE); 1582 } 1583 if (nsock == 0) { 1584 syslog(LOG_ERR, "%s: nsock=0", __func__); 1585 exit(EX_SOFTWARE); 1586 } 1587 nsock--; 1588#endif 1589 FD_CLR(sep->se_fd, &allsock); 1590 if (sep->se_fd == maxsock) 1591 maxsock--; 1592} 1593 1594FILE *fconfig = NULL; 1595struct servtab serv; 1596char line[LINE_MAX]; 1597 1598int 1599setconfig(void) 1600{ 1601 1602 if (fconfig != NULL) { 1603 fseek(fconfig, 0L, SEEK_SET); 1604 return (1); 1605 } 1606 fconfig = fopen(CONFIG, "r"); 1607 return (fconfig != NULL); 1608} 1609 1610void 1611endconfig(void) 1612{ 1613 if (fconfig) { 1614 (void) fclose(fconfig); 1615 fconfig = NULL; 1616 } 1617} 1618 1619struct servtab * 1620getconfigent(void) 1621{ 1622 struct servtab *sep = &serv; 1623 int argc; 1624 char *cp, *arg, *s; 1625 char *versp; 1626 static char TCPMUX_TOKEN[] = "tcpmux/"; 1627#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) 1628#ifdef IPSEC 1629 char *policy; 1630#endif 1631 int v4bind; 1632#ifdef INET6 1633 int v6bind; 1634#endif 1635 int i; 1636 1637#ifdef IPSEC 1638 policy = NULL; 1639#endif 1640more: 1641 v4bind = 0; 1642#ifdef INET6 1643 v6bind = 0; 1644#endif 1645 while ((cp = nextline(fconfig)) != NULL) { 1646#ifdef IPSEC 1647 /* lines starting with #@ is not a comment, but the policy */ 1648 if (cp[0] == '#' && cp[1] == '@') { 1649 char *p; 1650 for (p = cp + 2; p && *p && isspace(*p); p++) 1651 ; 1652 if (*p == '\0') { 1653 if (policy) 1654 free(policy); 1655 policy = NULL; 1656 } else if (ipsec_get_policylen(p) >= 0) { 1657 if (policy) 1658 free(policy); 1659 policy = newstr(p); 1660 } else { 1661 syslog(LOG_ERR, 1662 "%s: invalid ipsec policy \"%s\"", 1663 CONFIG, p); 1664 exit(EX_CONFIG); 1665 } 1666 } 1667#endif 1668 if (*cp == '#' || *cp == '\0') 1669 continue; 1670 break; 1671 } 1672 if (cp == NULL) 1673 return ((struct servtab *)0); 1674 /* 1675 * clear the static buffer, since some fields (se_ctrladdr, 1676 * for example) don't get initialized here. 1677 */ 1678 memset(sep, 0, sizeof *sep); 1679 arg = skip(&cp); 1680 if (cp == NULL) { 1681 /* got an empty line containing just blanks/tabs. */ 1682 goto more; 1683 } 1684 if (arg[0] == ':') { /* :user:group:perm: */ 1685 char *user, *group, *perm; 1686 struct passwd *pw; 1687 struct group *gr; 1688 user = arg+1; 1689 if ((group = strchr(user, ':')) == NULL) { 1690 syslog(LOG_ERR, "no group after user '%s'", user); 1691 goto more; 1692 } 1693 *group++ = '\0'; 1694 if ((perm = strchr(group, ':')) == NULL) { 1695 syslog(LOG_ERR, "no mode after group '%s'", group); 1696 goto more; 1697 } 1698 *perm++ = '\0'; 1699 if ((pw = getpwnam(user)) == NULL) { 1700 syslog(LOG_ERR, "no such user '%s'", user); 1701 goto more; 1702 } 1703 sep->se_sockuid = pw->pw_uid; 1704 if ((gr = getgrnam(group)) == NULL) { 1705 syslog(LOG_ERR, "no such user '%s'", group); 1706 goto more; 1707 } 1708 sep->se_sockgid = gr->gr_gid; 1709 sep->se_sockmode = strtol(perm, &arg, 8); 1710 if (*arg != ':') { 1711 syslog(LOG_ERR, "bad mode '%s'", perm); 1712 goto more; 1713 } 1714 *arg++ = '\0'; 1715 } else { 1716 sep->se_sockuid = euid; 1717 sep->se_sockgid = egid; 1718 sep->se_sockmode = 0200; 1719 } 1720 if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) { 1721 char *c = arg + MUX_LEN; 1722 if (*c == '+') { 1723 sep->se_type = MUXPLUS_TYPE; 1724 c++; 1725 } else 1726 sep->se_type = MUX_TYPE; 1727 sep->se_service = newstr(c); 1728 } else { 1729 sep->se_service = newstr(arg); 1730 sep->se_type = NORM_TYPE; 1731 } 1732 arg = sskip(&cp); 1733 if (strcmp(arg, "stream") == 0) 1734 sep->se_socktype = SOCK_STREAM; 1735 else if (strcmp(arg, "dgram") == 0) 1736 sep->se_socktype = SOCK_DGRAM; 1737 else if (strcmp(arg, "rdm") == 0) 1738 sep->se_socktype = SOCK_RDM; 1739 else if (strcmp(arg, "seqpacket") == 0) 1740 sep->se_socktype = SOCK_SEQPACKET; 1741 else if (strcmp(arg, "raw") == 0) 1742 sep->se_socktype = SOCK_RAW; 1743 else 1744 sep->se_socktype = -1; 1745 1746 arg = sskip(&cp); 1747 if (strncmp(arg, "tcp", 3) == 0) { 1748 sep->se_proto = newstr(strsep(&arg, "/")); 1749 if (arg != NULL) { 1750 if (strcmp(arg, "ttcp") == 0) 1751 sep->se_type = TTCP_TYPE; 1752 else if (strcmp(arg, "faith") == 0) 1753 sep->se_type = FAITH_TYPE; 1754 } 1755 } else { 1756 if (sep->se_type == NORM_TYPE && 1757 strncmp(arg, "faith/", 6) == 0) { 1758 arg += 6; 1759 sep->se_type = FAITH_TYPE; 1760 } 1761 sep->se_proto = newstr(arg); 1762 } 1763 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { 1764 memmove(sep->se_proto, sep->se_proto + 4, 1765 strlen(sep->se_proto) + 1 - 4); 1766 sep->se_rpc = 1; 1767 sep->se_rpc_prog = sep->se_rpc_lowvers = 1768 sep->se_rpc_lowvers = 0; 1769 memcpy(&sep->se_ctrladdr4, bind_sa4, 1770 sizeof(sep->se_ctrladdr4)); 1771 if ((versp = rindex(sep->se_service, '/'))) { 1772 *versp++ = '\0'; 1773 switch (sscanf(versp, "%u-%u", 1774 &sep->se_rpc_lowvers, 1775 &sep->se_rpc_highvers)) { 1776 case 2: 1777 break; 1778 case 1: 1779 sep->se_rpc_highvers = 1780 sep->se_rpc_lowvers; 1781 break; 1782 default: 1783 syslog(LOG_ERR, 1784 "bad RPC version specifier; %s", 1785 sep->se_service); 1786 freeconfig(sep); 1787 goto more; 1788 } 1789 } 1790 else { 1791 sep->se_rpc_lowvers = 1792 sep->se_rpc_highvers = 1; 1793 } 1794 } 1795 sep->se_nomapped = 0; 1796 if (strcmp(sep->se_proto, "unix") == 0) { 1797 sep->se_family = AF_UNIX; 1798 } else { 1799 while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) { 1800#ifdef INET6 1801 if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') { 1802 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1803 v6bind = 1; 1804 continue; 1805 } 1806#endif 1807 if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') { 1808 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1809 v4bind = 1; 1810 continue; 1811 } 1812 /* illegal version num */ 1813 syslog(LOG_ERR, "bad IP version for %s", sep->se_proto); 1814 freeconfig(sep); 1815 goto more; 1816 } 1817#ifdef INET6 1818 if (v6bind && !v6bind_ok) { 1819 syslog(LOG_INFO, "IPv6 bind is ignored for %s", 1820 sep->se_service); 1821 if (v4bind && v4bind_ok) 1822 v6bind = 0; 1823 else { 1824 freeconfig(sep); 1825 goto more; 1826 } 1827 } 1828 if (v6bind) { 1829 sep->se_family = AF_INET6; 1830 if (!v4bind || !v4bind_ok) 1831 sep->se_nomapped = 1; 1832 } else 1833#endif 1834 { /* default to v4 bind if not v6 bind */ 1835 if (!v4bind_ok) { 1836 syslog(LOG_NOTICE, "IPv4 bind is ignored for %s", 1837 sep->se_service); 1838 freeconfig(sep); 1839 goto more; 1840 } 1841 sep->se_family = AF_INET; 1842 } 1843 } 1844 /* init ctladdr */ 1845 switch(sep->se_family) { 1846 case AF_INET: 1847 memcpy(&sep->se_ctrladdr4, bind_sa4, 1848 sizeof(sep->se_ctrladdr4)); 1849 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr4); 1850 break; 1851#ifdef INET6 1852 case AF_INET6: 1853 memcpy(&sep->se_ctrladdr6, bind_sa6, 1854 sizeof(sep->se_ctrladdr6)); 1855 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr6); 1856 break; 1857#endif 1858 case AF_UNIX: 1859 if (strlen(sep->se_service) >= sizeof(sep->se_ctrladdr_un.sun_path)) { 1860 syslog(LOG_ERR, 1861 "domain socket pathname too long for service %s", 1862 sep->se_service); 1863 goto more; 1864 } 1865 memset(&sep->se_ctrladdr, 0, sizeof(sep->se_ctrladdr)); 1866 sep->se_ctrladdr_un.sun_family = sep->se_family; 1867 sep->se_ctrladdr_un.sun_len = strlen(sep->se_service); 1868 strcpy(sep->se_ctrladdr_un.sun_path, sep->se_service); 1869 sep->se_ctrladdr_size = SUN_LEN(&sep->se_ctrladdr_un); 1870 } 1871 arg = sskip(&cp); 1872 if (!strncmp(arg, "wait", 4)) 1873 sep->se_accept = 0; 1874 else if (!strncmp(arg, "nowait", 6)) 1875 sep->se_accept = 1; 1876 else { 1877 syslog(LOG_ERR, 1878 "%s: bad wait/nowait for service %s", 1879 CONFIG, sep->se_service); 1880 goto more; 1881 } 1882 sep->se_maxchild = -1; 1883 sep->se_maxcpm = -1; 1884 sep->se_maxperip = -1; 1885 if ((s = strchr(arg, '/')) != NULL) { 1886 char *eptr; 1887 u_long val; 1888 1889 val = strtoul(s + 1, &eptr, 10); 1890 if (eptr == s + 1 || val > MAX_MAXCHLD) { 1891 syslog(LOG_ERR, 1892 "%s: bad max-child for service %s", 1893 CONFIG, sep->se_service); 1894 goto more; 1895 } 1896 if (debug) 1897 if (!sep->se_accept && val != 1) 1898 warnx("maxchild=%lu for wait service %s" 1899 " not recommended", val, sep->se_service); 1900 sep->se_maxchild = val; 1901 if (*eptr == '/') 1902 sep->se_maxcpm = strtol(eptr + 1, &eptr, 10); 1903 if (*eptr == '/') 1904 sep->se_maxperip = strtol(eptr + 1, &eptr, 10); 1905 /* 1906 * explicitly do not check for \0 for future expansion / 1907 * backwards compatibility 1908 */ 1909 } 1910 if (ISMUX(sep)) { 1911 /* 1912 * Silently enforce "nowait" mode for TCPMUX services 1913 * since they don't have an assigned port to listen on. 1914 */ 1915 sep->se_accept = 1; 1916 if (strcmp(sep->se_proto, "tcp")) { 1917 syslog(LOG_ERR, 1918 "%s: bad protocol for tcpmux service %s", 1919 CONFIG, sep->se_service); 1920 goto more; 1921 } 1922 if (sep->se_socktype != SOCK_STREAM) { 1923 syslog(LOG_ERR, 1924 "%s: bad socket type for tcpmux service %s", 1925 CONFIG, sep->se_service); 1926 goto more; 1927 } 1928 } 1929 sep->se_user = newstr(sskip(&cp)); 1930#ifdef LOGIN_CAP 1931 if ((s = strrchr(sep->se_user, '/')) != NULL) { 1932 *s = '\0'; 1933 sep->se_class = newstr(s + 1); 1934 } else 1935 sep->se_class = newstr(RESOURCE_RC); 1936#endif 1937 if ((s = strrchr(sep->se_user, ':')) != NULL) { 1938 *s = '\0'; 1939 sep->se_group = newstr(s + 1); 1940 } else 1941 sep->se_group = NULL; 1942 sep->se_server = newstr(sskip(&cp)); 1943 if ((sep->se_server_name = rindex(sep->se_server, '/'))) 1944 sep->se_server_name++; 1945 if (strcmp(sep->se_server, "internal") == 0) { 1946 struct biltin *bi; 1947 1948 for (bi = biltins; bi->bi_service; bi++) 1949 if (bi->bi_socktype == sep->se_socktype && 1950 matchservent(bi->bi_service, sep->se_service, 1951 sep->se_proto)) 1952 break; 1953 if (bi->bi_service == 0) { 1954 syslog(LOG_ERR, "internal service %s unknown", 1955 sep->se_service); 1956 goto more; 1957 } 1958 sep->se_accept = 1; /* force accept mode for built-ins */ 1959 sep->se_bi = bi; 1960 } else 1961 sep->se_bi = NULL; 1962 if (sep->se_maxperip < 0) 1963 sep->se_maxperip = maxperip; 1964 if (sep->se_maxcpm < 0) 1965 sep->se_maxcpm = maxcpm; 1966 if (sep->se_maxchild < 0) { /* apply default max-children */ 1967 if (sep->se_bi && sep->se_bi->bi_maxchild >= 0) 1968 sep->se_maxchild = sep->se_bi->bi_maxchild; 1969 else if (sep->se_accept) 1970 sep->se_maxchild = maxchild > 0 ? maxchild : 0; 1971 else 1972 sep->se_maxchild = 1; 1973 } 1974 if (sep->se_maxchild > 0) { 1975 sep->se_pids = malloc(sep->se_maxchild * sizeof(*sep->se_pids)); 1976 if (sep->se_pids == NULL) { 1977 syslog(LOG_ERR, "malloc: %m"); 1978 exit(EX_OSERR); 1979 } 1980 } 1981 argc = 0; 1982 for (arg = skip(&cp); cp; arg = skip(&cp)) 1983 if (argc < MAXARGV) { 1984 sep->se_argv[argc++] = newstr(arg); 1985 } else { 1986 syslog(LOG_ERR, 1987 "%s: too many arguments for service %s", 1988 CONFIG, sep->se_service); 1989 goto more; 1990 } 1991 while (argc <= MAXARGV) 1992 sep->se_argv[argc++] = NULL; 1993 for (i = 0; i < PERIPSIZE; ++i) 1994 LIST_INIT(&sep->se_conn[i]); 1995#ifdef IPSEC 1996 sep->se_policy = policy ? newstr(policy) : NULL; 1997#endif 1998 return (sep); 1999} 2000 2001void 2002freeconfig(struct servtab *cp) 2003{ 2004 int i; 2005 2006 if (cp->se_service) 2007 free(cp->se_service); 2008 if (cp->se_proto) 2009 free(cp->se_proto); 2010 if (cp->se_user) 2011 free(cp->se_user); 2012 if (cp->se_group) 2013 free(cp->se_group); 2014#ifdef LOGIN_CAP 2015 if (cp->se_class) 2016 free(cp->se_class); 2017#endif 2018 if (cp->se_server) 2019 free(cp->se_server); 2020 if (cp->se_pids) 2021 free(cp->se_pids); 2022 for (i = 0; i < MAXARGV; i++) 2023 if (cp->se_argv[i]) 2024 free(cp->se_argv[i]); 2025 free_connlist(cp); 2026#ifdef IPSEC 2027 if (cp->se_policy) 2028 free(cp->se_policy); 2029#endif 2030} 2031 2032 2033/* 2034 * Safe skip - if skip returns null, log a syntax error in the 2035 * configuration file and exit. 2036 */ 2037char * 2038sskip(char **cpp) 2039{ 2040 char *cp; 2041 2042 cp = skip(cpp); 2043 if (cp == NULL) { 2044 syslog(LOG_ERR, "%s: syntax error", CONFIG); 2045 exit(EX_DATAERR); 2046 } 2047 return (cp); 2048} 2049 2050char * 2051skip(char **cpp) 2052{ 2053 char *cp = *cpp; 2054 char *start; 2055 char quote = '\0'; 2056 2057again: 2058 while (*cp == ' ' || *cp == '\t') 2059 cp++; 2060 if (*cp == '\0') { 2061 int c; 2062 2063 c = getc(fconfig); 2064 (void) ungetc(c, fconfig); 2065 if (c == ' ' || c == '\t') 2066 if ((cp = nextline(fconfig))) 2067 goto again; 2068 *cpp = (char *)0; 2069 return ((char *)0); 2070 } 2071 if (*cp == '"' || *cp == '\'') 2072 quote = *cp++; 2073 start = cp; 2074 if (quote) 2075 while (*cp && *cp != quote) 2076 cp++; 2077 else 2078 while (*cp && *cp != ' ' && *cp != '\t') 2079 cp++; 2080 if (*cp != '\0') 2081 *cp++ = '\0'; 2082 *cpp = cp; 2083 return (start); 2084} 2085 2086char * 2087nextline(FILE *fd) 2088{ 2089 char *cp; 2090 2091 if (fgets(line, sizeof (line), fd) == NULL) 2092 return ((char *)0); 2093 cp = strchr(line, '\n'); 2094 if (cp) 2095 *cp = '\0'; 2096 return (line); 2097} 2098 2099char * 2100newstr(const char *cp) 2101{ 2102 char *cr; 2103 2104 if ((cr = strdup(cp != NULL ? cp : ""))) 2105 return (cr); 2106 syslog(LOG_ERR, "strdup: %m"); 2107 exit(EX_OSERR); 2108} 2109 2110void 2111inetd_setproctitle(const char *a, int s) 2112{ 2113 socklen_t size; 2114 struct sockaddr_storage ss; 2115 char buf[80], pbuf[INET6_ADDRSTRLEN]; 2116 2117 size = sizeof(ss); 2118 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) { 2119 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf),
| 668 } 669 syslog(LOG_INFO,"%s from %s", sep->se_service, pname); 670 } 671 (void) sigblock(SIGBLOCK); 672 pid = 0; 673 /* 674 * Fork for all external services, builtins which need to 675 * fork and anything we're wrapping (as wrapping might 676 * block or use hosts_options(5) twist). 677 */ 678 if (dofork) { 679 if (sep->se_count++ == 0) 680 (void)gettimeofday(&sep->se_time, (struct timezone *)NULL); 681 else if (toomany > 0 && sep->se_count >= toomany) { 682 struct timeval now; 683 684 (void)gettimeofday(&now, (struct timezone *)NULL); 685 if (now.tv_sec - sep->se_time.tv_sec > 686 CNT_INTVL) { 687 sep->se_time = now; 688 sep->se_count = 1; 689 } else { 690 syslog(LOG_ERR, 691 "%s/%s server failing (looping), service terminated", 692 sep->se_service, sep->se_proto); 693 if (sep->se_accept && 694 sep->se_socktype == SOCK_STREAM) 695 close(ctrl); 696 close_sep(sep); 697 free_conn(conn); 698 sigsetmask(0L); 699 if (!timingout) { 700 timingout = 1; 701 alarm(RETRYTIME); 702 } 703 continue; 704 } 705 } 706 pid = fork(); 707 } 708 if (pid < 0) { 709 syslog(LOG_ERR, "fork: %m"); 710 if (sep->se_accept && 711 sep->se_socktype == SOCK_STREAM) 712 close(ctrl); 713 free_conn(conn); 714 sigsetmask(0L); 715 sleep(1); 716 continue; 717 } 718 if (pid) { 719 addchild_conn(conn, pid); 720 addchild(sep, pid); 721 } 722 sigsetmask(0L); 723 if (pid == 0) { 724 if (dofork) { 725 sigaction(SIGALRM, &saalrm, (struct sigaction *)0); 726 sigaction(SIGCHLD, &sachld, (struct sigaction *)0); 727 sigaction(SIGHUP, &sahup, (struct sigaction *)0); 728 /* SIGPIPE reset before exec */ 729 } 730 /* 731 * Call tcpmux to find the real service to exec. 732 */ 733 if (sep->se_bi && 734 sep->se_bi->bi_fn == (bi_fn_t *) tcpmux) { 735 sep = tcpmux(ctrl); 736 if (sep == NULL) { 737 close(ctrl); 738 _exit(0); 739 } 740 } 741 if (ISWRAP(sep)) { 742 inetd_setproctitle("wrapping", ctrl); 743 service = sep->se_server_name ? 744 sep->se_server_name : sep->se_service; 745 request_init(&req, RQ_DAEMON, service, RQ_FILE, ctrl, 0); 746 fromhost(&req); 747 deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY; 748 allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY; 749 denied = !hosts_access(&req); 750 if (denied) { 751 syslog(deny_severity, 752 "refused connection from %.500s, service %s (%s%s)", 753 eval_client(&req), service, sep->se_proto, 754 (whichaf(&req) == AF_INET6) ? "6" : ""); 755 if (sep->se_socktype != SOCK_STREAM) 756 recv(ctrl, buf, sizeof (buf), 0); 757 if (dofork) { 758 sleep(1); 759 _exit(0); 760 } 761 } 762 if (dolog) { 763 syslog(allow_severity, 764 "connection from %.500s, service %s (%s%s)", 765 eval_client(&req), service, sep->se_proto, 766 (whichaf(&req) == AF_INET6) ? "6" : ""); 767 } 768 } 769 if (sep->se_bi) { 770 (*sep->se_bi->bi_fn)(ctrl, sep); 771 } else { 772 if (debug) 773 warnx("%d execl %s", 774 getpid(), sep->se_server); 775 /* Clear close-on-exec. */ 776 if (fcntl(ctrl, F_SETFD, 0) < 0) { 777 syslog(LOG_ERR, 778 "%s/%s: fcntl (F_SETFD, 0): %m", 779 sep->se_service, sep->se_proto); 780 _exit(EX_OSERR); 781 } 782 if (ctrl != 0) { 783 dup2(ctrl, 0); 784 close(ctrl); 785 } 786 dup2(0, 1); 787 dup2(0, 2); 788 if ((pwd = getpwnam(sep->se_user)) == NULL) { 789 syslog(LOG_ERR, 790 "%s/%s: %s: no such user", 791 sep->se_service, sep->se_proto, 792 sep->se_user); 793 if (sep->se_socktype != SOCK_STREAM) 794 recv(0, buf, sizeof (buf), 0); 795 _exit(EX_NOUSER); 796 } 797 grp = NULL; 798 if ( sep->se_group != NULL 799 && (grp = getgrnam(sep->se_group)) == NULL 800 ) { 801 syslog(LOG_ERR, 802 "%s/%s: %s: no such group", 803 sep->se_service, sep->se_proto, 804 sep->se_group); 805 if (sep->se_socktype != SOCK_STREAM) 806 recv(0, buf, sizeof (buf), 0); 807 _exit(EX_NOUSER); 808 } 809 if (grp != NULL) 810 pwd->pw_gid = grp->gr_gid; 811#ifdef LOGIN_CAP 812 if ((lc = login_getclass(sep->se_class)) == NULL) { 813 /* error syslogged by getclass */ 814 syslog(LOG_ERR, 815 "%s/%s: %s: login class error", 816 sep->se_service, sep->se_proto, 817 sep->se_class); 818 if (sep->se_socktype != SOCK_STREAM) 819 recv(0, buf, sizeof (buf), 0); 820 _exit(EX_NOUSER); 821 } 822#endif 823 if (setsid() < 0) { 824 syslog(LOG_ERR, 825 "%s: can't setsid(): %m", 826 sep->se_service); 827 /* _exit(EX_OSERR); not fatal yet */ 828 } 829#ifdef LOGIN_CAP 830 if (setusercontext(lc, pwd, pwd->pw_uid, 831 LOGIN_SETALL & ~LOGIN_SETMAC) 832 != 0) { 833 syslog(LOG_ERR, 834 "%s: can't setusercontext(..%s..): %m", 835 sep->se_service, sep->se_user); 836 _exit(EX_OSERR); 837 } 838 login_close(lc); 839#else 840 if (pwd->pw_uid) { 841 if (setlogin(sep->se_user) < 0) { 842 syslog(LOG_ERR, 843 "%s: can't setlogin(%s): %m", 844 sep->se_service, sep->se_user); 845 /* _exit(EX_OSERR); not yet */ 846 } 847 if (setgid(pwd->pw_gid) < 0) { 848 syslog(LOG_ERR, 849 "%s: can't set gid %d: %m", 850 sep->se_service, pwd->pw_gid); 851 _exit(EX_OSERR); 852 } 853 (void) initgroups(pwd->pw_name, 854 pwd->pw_gid); 855 if (setuid(pwd->pw_uid) < 0) { 856 syslog(LOG_ERR, 857 "%s: can't set uid %d: %m", 858 sep->se_service, pwd->pw_uid); 859 _exit(EX_OSERR); 860 } 861 } 862#endif 863 sigaction(SIGPIPE, &sapipe, 864 (struct sigaction *)0); 865 execv(sep->se_server, sep->se_argv); 866 syslog(LOG_ERR, 867 "cannot execute %s: %m", sep->se_server); 868 if (sep->se_socktype != SOCK_STREAM) 869 recv(0, buf, sizeof (buf), 0); 870 } 871 if (dofork) 872 _exit(0); 873 } 874 if (sep->se_accept && sep->se_socktype == SOCK_STREAM) 875 close(ctrl); 876 } 877 } 878} 879 880/* 881 * Add a signal flag to the signal flag queue for later handling 882 */ 883 884void 885flag_signal(int c) 886{ 887 char ch = c; 888 889 if (write(signalpipe[1], &ch, 1) != 1) { 890 syslog(LOG_ERR, "write: %m"); 891 _exit(EX_OSERR); 892 } 893} 894 895/* 896 * Record a new child pid for this service. If we've reached the 897 * limit on children, then stop accepting incoming requests. 898 */ 899 900void 901addchild(struct servtab *sep, pid_t pid) 902{ 903 if (sep->se_maxchild <= 0) 904 return; 905#ifdef SANITY_CHECK 906 if (sep->se_numchild >= sep->se_maxchild) { 907 syslog(LOG_ERR, "%s: %d >= %d", 908 __func__, sep->se_numchild, sep->se_maxchild); 909 exit(EX_SOFTWARE); 910 } 911#endif 912 sep->se_pids[sep->se_numchild++] = pid; 913 if (sep->se_numchild == sep->se_maxchild) 914 disable(sep); 915} 916 917/* 918 * Some child process has exited. See if it's on somebody's list. 919 */ 920 921void 922flag_reapchild(int signo __unused) 923{ 924 flag_signal('C'); 925} 926 927void 928reapchild(void) 929{ 930 int k, status; 931 pid_t pid; 932 struct servtab *sep; 933 934 for (;;) { 935 pid = wait3(&status, WNOHANG, (struct rusage *)0); 936 if (pid <= 0) 937 break; 938 if (debug) 939 warnx("%d reaped, %s %u", pid, 940 WIFEXITED(status) ? "status" : "signal", 941 WIFEXITED(status) ? WEXITSTATUS(status) 942 : WTERMSIG(status)); 943 for (sep = servtab; sep; sep = sep->se_next) { 944 for (k = 0; k < sep->se_numchild; k++) 945 if (sep->se_pids[k] == pid) 946 break; 947 if (k == sep->se_numchild) 948 continue; 949 if (sep->se_numchild == sep->se_maxchild) 950 enable(sep); 951 sep->se_pids[k] = sep->se_pids[--sep->se_numchild]; 952 if (WIFSIGNALED(status) || WEXITSTATUS(status)) 953 syslog(LOG_WARNING, 954 "%s[%d]: exited, %s %u", 955 sep->se_server, pid, 956 WIFEXITED(status) ? "status" : "signal", 957 WIFEXITED(status) ? WEXITSTATUS(status) 958 : WTERMSIG(status)); 959 break; 960 } 961 reapchild_conn(pid); 962 } 963} 964 965void 966flag_config(int signo __unused) 967{ 968 flag_signal('H'); 969} 970 971void 972config(void) 973{ 974 struct servtab *sep, *new, **sepp; 975 long omask; 976 int new_nomapped; 977#ifdef LOGIN_CAP 978 login_cap_t *lc = NULL; 979#endif 980 981 if (!setconfig()) { 982 syslog(LOG_ERR, "%s: %m", CONFIG); 983 return; 984 } 985 for (sep = servtab; sep; sep = sep->se_next) 986 sep->se_checked = 0; 987 while ((new = getconfigent())) { 988 if (getpwnam(new->se_user) == NULL) { 989 syslog(LOG_ERR, 990 "%s/%s: no such user '%s', service ignored", 991 new->se_service, new->se_proto, new->se_user); 992 continue; 993 } 994 if (new->se_group && getgrnam(new->se_group) == NULL) { 995 syslog(LOG_ERR, 996 "%s/%s: no such group '%s', service ignored", 997 new->se_service, new->se_proto, new->se_group); 998 continue; 999 } 1000#ifdef LOGIN_CAP 1001 if ((lc = login_getclass(new->se_class)) == NULL) { 1002 /* error syslogged by getclass */ 1003 syslog(LOG_ERR, 1004 "%s/%s: %s: login class error, service ignored", 1005 new->se_service, new->se_proto, new->se_class); 1006 continue; 1007 } 1008 login_close(lc); 1009#endif 1010 new_nomapped = new->se_nomapped; 1011 for (sep = servtab; sep; sep = sep->se_next) 1012 if (strcmp(sep->se_service, new->se_service) == 0 && 1013 strcmp(sep->se_proto, new->se_proto) == 0 && 1014 sep->se_rpc == new->se_rpc && 1015 sep->se_socktype == new->se_socktype && 1016 sep->se_family == new->se_family) 1017 break; 1018 if (sep != 0) { 1019 int i; 1020 1021#define SWAP(t,a, b) { t c = a; a = b; b = c; } 1022 omask = sigblock(SIGBLOCK); 1023 if (sep->se_nomapped != new->se_nomapped) { 1024 /* for rpc keep old nommaped till unregister */ 1025 if (!sep->se_rpc) 1026 sep->se_nomapped = new->se_nomapped; 1027 sep->se_reset = 1; 1028 } 1029 /* copy over outstanding child pids */ 1030 if (sep->se_maxchild > 0 && new->se_maxchild > 0) { 1031 new->se_numchild = sep->se_numchild; 1032 if (new->se_numchild > new->se_maxchild) 1033 new->se_numchild = new->se_maxchild; 1034 memcpy(new->se_pids, sep->se_pids, 1035 new->se_numchild * sizeof(*new->se_pids)); 1036 } 1037 SWAP(pid_t *, sep->se_pids, new->se_pids); 1038 sep->se_maxchild = new->se_maxchild; 1039 sep->se_numchild = new->se_numchild; 1040 sep->se_maxcpm = new->se_maxcpm; 1041 resize_conn(sep, new->se_maxperip); 1042 sep->se_maxperip = new->se_maxperip; 1043 sep->se_bi = new->se_bi; 1044 /* might need to turn on or off service now */ 1045 if (sep->se_fd >= 0) { 1046 if (sep->se_maxchild > 0 1047 && sep->se_numchild == sep->se_maxchild) { 1048 if (FD_ISSET(sep->se_fd, &allsock)) 1049 disable(sep); 1050 } else { 1051 if (!FD_ISSET(sep->se_fd, &allsock)) 1052 enable(sep); 1053 } 1054 } 1055 sep->se_accept = new->se_accept; 1056 SWAP(char *, sep->se_user, new->se_user); 1057 SWAP(char *, sep->se_group, new->se_group); 1058#ifdef LOGIN_CAP 1059 SWAP(char *, sep->se_class, new->se_class); 1060#endif 1061 SWAP(char *, sep->se_server, new->se_server); 1062 SWAP(char *, sep->se_server_name, new->se_server_name); 1063 for (i = 0; i < MAXARGV; i++) 1064 SWAP(char *, sep->se_argv[i], new->se_argv[i]); 1065#ifdef IPSEC 1066 SWAP(char *, sep->se_policy, new->se_policy); 1067 ipsecsetup(sep); 1068#endif 1069 sigsetmask(omask); 1070 freeconfig(new); 1071 if (debug) 1072 print_service("REDO", sep); 1073 } else { 1074 sep = enter(new); 1075 if (debug) 1076 print_service("ADD ", sep); 1077 } 1078 sep->se_checked = 1; 1079 if (ISMUX(sep)) { 1080 sep->se_fd = -1; 1081 continue; 1082 } 1083 switch (sep->se_family) { 1084 case AF_INET: 1085 if (!v4bind_ok) { 1086 sep->se_fd = -1; 1087 continue; 1088 } 1089 break; 1090#ifdef INET6 1091 case AF_INET6: 1092 if (!v6bind_ok) { 1093 sep->se_fd = -1; 1094 continue; 1095 } 1096 break; 1097#endif 1098 } 1099 if (!sep->se_rpc) { 1100 if (sep->se_family != AF_UNIX) { 1101 sp = getservbyname(sep->se_service, sep->se_proto); 1102 if (sp == 0) { 1103 syslog(LOG_ERR, "%s/%s: unknown service", 1104 sep->se_service, sep->se_proto); 1105 sep->se_checked = 0; 1106 continue; 1107 } 1108 } 1109 switch (sep->se_family) { 1110 case AF_INET: 1111 if (sp->s_port != sep->se_ctrladdr4.sin_port) { 1112 sep->se_ctrladdr4.sin_port = 1113 sp->s_port; 1114 sep->se_reset = 1; 1115 } 1116 break; 1117#ifdef INET6 1118 case AF_INET6: 1119 if (sp->s_port != 1120 sep->se_ctrladdr6.sin6_port) { 1121 sep->se_ctrladdr6.sin6_port = 1122 sp->s_port; 1123 sep->se_reset = 1; 1124 } 1125 break; 1126#endif 1127 } 1128 if (sep->se_reset != 0 && sep->se_fd >= 0) 1129 close_sep(sep); 1130 } else { 1131 rpc = getrpcbyname(sep->se_service); 1132 if (rpc == 0) { 1133 syslog(LOG_ERR, "%s/%s unknown RPC service", 1134 sep->se_service, sep->se_proto); 1135 if (sep->se_fd != -1) 1136 (void) close(sep->se_fd); 1137 sep->se_fd = -1; 1138 continue; 1139 } 1140 if (sep->se_reset != 0 || 1141 rpc->r_number != sep->se_rpc_prog) { 1142 if (sep->se_rpc_prog) 1143 unregisterrpc(sep); 1144 sep->se_rpc_prog = rpc->r_number; 1145 if (sep->se_fd != -1) 1146 (void) close(sep->se_fd); 1147 sep->se_fd = -1; 1148 } 1149 sep->se_nomapped = new_nomapped; 1150 } 1151 sep->se_reset = 0; 1152 if (sep->se_fd == -1) 1153 setup(sep); 1154 } 1155 endconfig(); 1156 /* 1157 * Purge anything not looked at above. 1158 */ 1159 omask = sigblock(SIGBLOCK); 1160 sepp = &servtab; 1161 while ((sep = *sepp)) { 1162 if (sep->se_checked) { 1163 sepp = &sep->se_next; 1164 continue; 1165 } 1166 *sepp = sep->se_next; 1167 if (sep->se_fd >= 0) 1168 close_sep(sep); 1169 if (debug) 1170 print_service("FREE", sep); 1171 if (sep->se_rpc && sep->se_rpc_prog > 0) 1172 unregisterrpc(sep); 1173 freeconfig(sep); 1174 free(sep); 1175 } 1176 (void) sigsetmask(omask); 1177} 1178 1179void 1180unregisterrpc(struct servtab *sep) 1181{ 1182 u_int i; 1183 struct servtab *sepp; 1184 long omask; 1185 struct netconfig *netid4, *netid6; 1186 1187 omask = sigblock(SIGBLOCK); 1188 netid4 = sep->se_socktype == SOCK_DGRAM ? udpconf : tcpconf; 1189 netid6 = sep->se_socktype == SOCK_DGRAM ? udp6conf : tcp6conf; 1190 if (sep->se_family == AF_INET) 1191 netid6 = NULL; 1192 else if (sep->se_nomapped) 1193 netid4 = NULL; 1194 /* 1195 * Conflict if same prog and protocol - In that case one should look 1196 * to versions, but it is not interesting: having separate servers for 1197 * different versions does not work well. 1198 * Therefore one do not unregister if there is a conflict. 1199 * There is also transport conflict if destroying INET when INET46 1200 * exists, or destroying INET46 when INET exists 1201 */ 1202 for (sepp = servtab; sepp; sepp = sepp->se_next) { 1203 if (sepp == sep) 1204 continue; 1205 if (sepp->se_checked == 0 || 1206 !sepp->se_rpc || 1207 strcmp(sep->se_proto, sepp->se_proto) != 0 || 1208 sep->se_rpc_prog != sepp->se_rpc_prog) 1209 continue; 1210 if (sepp->se_family == AF_INET) 1211 netid4 = NULL; 1212 if (sepp->se_family == AF_INET6) { 1213 netid6 = NULL; 1214 if (!sep->se_nomapped) 1215 netid4 = NULL; 1216 } 1217 if (netid4 == NULL && netid6 == NULL) 1218 return; 1219 } 1220 if (debug) 1221 print_service("UNREG", sep); 1222 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1223 if (netid4) 1224 rpcb_unset(sep->se_rpc_prog, i, netid4); 1225 if (netid6) 1226 rpcb_unset(sep->se_rpc_prog, i, netid6); 1227 } 1228 if (sep->se_fd != -1) 1229 (void) close(sep->se_fd); 1230 sep->se_fd = -1; 1231 (void) sigsetmask(omask); 1232} 1233 1234void 1235flag_retry(int signo __unused) 1236{ 1237 flag_signal('A'); 1238} 1239 1240void 1241retry(void) 1242{ 1243 struct servtab *sep; 1244 1245 timingout = 0; 1246 for (sep = servtab; sep; sep = sep->se_next) 1247 if (sep->se_fd == -1 && !ISMUX(sep)) 1248 setup(sep); 1249} 1250 1251void 1252setup(struct servtab *sep) 1253{ 1254 int on = 1; 1255 1256 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { 1257 if (debug) 1258 warn("socket failed on %s/%s", 1259 sep->se_service, sep->se_proto); 1260 syslog(LOG_ERR, "%s/%s: socket: %m", 1261 sep->se_service, sep->se_proto); 1262 return; 1263 } 1264 /* Set all listening sockets to close-on-exec. */ 1265 if (fcntl(sep->se_fd, F_SETFD, FD_CLOEXEC) < 0) { 1266 syslog(LOG_ERR, "%s/%s: fcntl (F_SETFD, FD_CLOEXEC): %m", 1267 sep->se_service, sep->se_proto); 1268 close(sep->se_fd); 1269 return; 1270 } 1271#define turnon(fd, opt) \ 1272setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) 1273 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 1274 turnon(sep->se_fd, SO_DEBUG) < 0) 1275 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 1276 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 1277 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 1278#ifdef SO_PRIVSTATE 1279 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0) 1280 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m"); 1281#endif 1282 /* tftpd opens a new connection then needs more infos */ 1283 if ((sep->se_family == AF_INET6) && 1284 (strcmp(sep->se_proto, "udp") == 0) && 1285 (sep->se_accept == 0) && 1286 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1287 (char *)&on, sizeof (on)) < 0)) 1288 syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m"); 1289 if (sep->se_family == AF_INET6) { 1290 int flag = sep->se_nomapped ? 1 : 0; 1291 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_V6ONLY, 1292 (char *)&flag, sizeof (flag)) < 0) 1293 syslog(LOG_ERR, "setsockopt (IPV6_V6ONLY): %m"); 1294 } 1295#undef turnon 1296 if (sep->se_type == TTCP_TYPE) 1297 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH, 1298 (char *)&on, sizeof (on)) < 0) 1299 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m"); 1300#ifdef IPV6_FAITH 1301 if (sep->se_type == FAITH_TYPE) { 1302 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on, 1303 sizeof(on)) < 0) { 1304 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); 1305 } 1306 } 1307#endif 1308#ifdef IPSEC 1309 ipsecsetup(sep); 1310#endif 1311 if (sep->se_family == AF_UNIX) { 1312 (void) unlink(sep->se_ctrladdr_un.sun_path); 1313 umask(0777); /* Make socket with conservative permissions */ 1314 } 1315 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, 1316 sep->se_ctrladdr_size) < 0) { 1317 if (debug) 1318 warn("bind failed on %s/%s", 1319 sep->se_service, sep->se_proto); 1320 syslog(LOG_ERR, "%s/%s: bind: %m", 1321 sep->se_service, sep->se_proto); 1322 (void) close(sep->se_fd); 1323 sep->se_fd = -1; 1324 if (!timingout) { 1325 timingout = 1; 1326 alarm(RETRYTIME); 1327 } 1328 if (sep->se_family == AF_UNIX) 1329 umask(mask); 1330 return; 1331 } 1332 if (sep->se_family == AF_UNIX) { 1333 /* Ick - fch{own,mod} don't work on Unix domain sockets */ 1334 if (chown(sep->se_service, sep->se_sockuid, sep->se_sockgid) < 0) 1335 syslog(LOG_ERR, "chown socket: %m"); 1336 if (chmod(sep->se_service, sep->se_sockmode) < 0) 1337 syslog(LOG_ERR, "chmod socket: %m"); 1338 umask(mask); 1339 } 1340 if (sep->se_rpc) { 1341 u_int i; 1342 socklen_t len = sep->se_ctrladdr_size; 1343 struct netconfig *netid, *netid2 = NULL; 1344 struct sockaddr_in sock; 1345 struct netbuf nbuf, nbuf2; 1346 1347 if (getsockname(sep->se_fd, 1348 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){ 1349 syslog(LOG_ERR, "%s/%s: getsockname: %m", 1350 sep->se_service, sep->se_proto); 1351 (void) close(sep->se_fd); 1352 sep->se_fd = -1; 1353 return; 1354 } 1355 nbuf.buf = &sep->se_ctrladdr; 1356 nbuf.len = sep->se_ctrladdr.sa_len; 1357 if (sep->se_family == AF_INET) 1358 netid = sep->se_socktype==SOCK_DGRAM? udpconf:tcpconf; 1359 else { 1360 netid = sep->se_socktype==SOCK_DGRAM? udp6conf:tcp6conf; 1361 if (!sep->se_nomapped) { /* INET and INET6 */ 1362 netid2 = netid==udp6conf? udpconf:tcpconf; 1363 memset(&sock, 0, sizeof sock); /* ADDR_ANY */ 1364 nbuf2.buf = &sock; 1365 nbuf2.len = sock.sin_len = sizeof sock; 1366 sock.sin_family = AF_INET; 1367 sock.sin_port = sep->se_ctrladdr6.sin6_port; 1368 } 1369 } 1370 if (debug) 1371 print_service("REG ", sep); 1372 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1373 rpcb_unset(sep->se_rpc_prog, i, netid); 1374 rpcb_set(sep->se_rpc_prog, i, netid, &nbuf); 1375 if (netid2) { 1376 rpcb_unset(sep->se_rpc_prog, i, netid2); 1377 rpcb_set(sep->se_rpc_prog, i, netid2, &nbuf2); 1378 } 1379 } 1380 } 1381 if (sep->se_socktype == SOCK_STREAM) 1382 listen(sep->se_fd, 64); 1383 enable(sep); 1384 if (debug) { 1385 warnx("registered %s on %d", 1386 sep->se_server, sep->se_fd); 1387 } 1388} 1389 1390#ifdef IPSEC 1391void 1392ipsecsetup(sep) 1393 struct servtab *sep; 1394{ 1395 char *buf; 1396 char *policy_in = NULL; 1397 char *policy_out = NULL; 1398 int level; 1399 int opt; 1400 1401 switch (sep->se_family) { 1402 case AF_INET: 1403 level = IPPROTO_IP; 1404 opt = IP_IPSEC_POLICY; 1405 break; 1406#ifdef INET6 1407 case AF_INET6: 1408 level = IPPROTO_IPV6; 1409 opt = IPV6_IPSEC_POLICY; 1410 break; 1411#endif 1412 default: 1413 return; 1414 } 1415 1416 if (!sep->se_policy || sep->se_policy[0] == '\0') { 1417 static char def_in[] = "in entrust", def_out[] = "out entrust"; 1418 policy_in = def_in; 1419 policy_out = def_out; 1420 } else { 1421 if (!strncmp("in", sep->se_policy, 2)) 1422 policy_in = sep->se_policy; 1423 else if (!strncmp("out", sep->se_policy, 3)) 1424 policy_out = sep->se_policy; 1425 else { 1426 syslog(LOG_ERR, "invalid security policy \"%s\"", 1427 sep->se_policy); 1428 return; 1429 } 1430 } 1431 1432 if (policy_in != NULL) { 1433 buf = ipsec_set_policy(policy_in, strlen(policy_in)); 1434 if (buf != NULL) { 1435 if (setsockopt(sep->se_fd, level, opt, 1436 buf, ipsec_get_policylen(buf)) < 0 && 1437 debug != 0) 1438 warnx("%s/%s: ipsec initialization failed; %s", 1439 sep->se_service, sep->se_proto, 1440 policy_in); 1441 free(buf); 1442 } else 1443 syslog(LOG_ERR, "invalid security policy \"%s\"", 1444 policy_in); 1445 } 1446 if (policy_out != NULL) { 1447 buf = ipsec_set_policy(policy_out, strlen(policy_out)); 1448 if (buf != NULL) { 1449 if (setsockopt(sep->se_fd, level, opt, 1450 buf, ipsec_get_policylen(buf)) < 0 && 1451 debug != 0) 1452 warnx("%s/%s: ipsec initialization failed; %s", 1453 sep->se_service, sep->se_proto, 1454 policy_out); 1455 free(buf); 1456 } else 1457 syslog(LOG_ERR, "invalid security policy \"%s\"", 1458 policy_out); 1459 } 1460} 1461#endif 1462 1463/* 1464 * Finish with a service and its socket. 1465 */ 1466void 1467close_sep(struct servtab *sep) 1468{ 1469 if (sep->se_fd >= 0) { 1470 if (FD_ISSET(sep->se_fd, &allsock)) 1471 disable(sep); 1472 (void) close(sep->se_fd); 1473 sep->se_fd = -1; 1474 } 1475 sep->se_count = 0; 1476 sep->se_numchild = 0; /* forget about any existing children */ 1477} 1478 1479int 1480matchservent(const char *name1, const char *name2, const char *proto) 1481{ 1482 char **alias, *p; 1483 struct servent *se; 1484 1485 if (strcmp(proto, "unix") == 0) { 1486 if ((p = strrchr(name1, '/')) != NULL) 1487 name1 = p + 1; 1488 if ((p = strrchr(name2, '/')) != NULL) 1489 name2 = p + 1; 1490 } 1491 if (strcmp(name1, name2) == 0) 1492 return(1); 1493 if ((se = getservbyname(name1, proto)) != NULL) { 1494 if (strcmp(name2, se->s_name) == 0) 1495 return(1); 1496 for (alias = se->s_aliases; *alias; alias++) 1497 if (strcmp(name2, *alias) == 0) 1498 return(1); 1499 } 1500 return(0); 1501} 1502 1503struct servtab * 1504enter(struct servtab *cp) 1505{ 1506 struct servtab *sep; 1507 long omask; 1508 1509 sep = (struct servtab *)malloc(sizeof (*sep)); 1510 if (sep == (struct servtab *)0) { 1511 syslog(LOG_ERR, "malloc: %m"); 1512 exit(EX_OSERR); 1513 } 1514 *sep = *cp; 1515 sep->se_fd = -1; 1516 omask = sigblock(SIGBLOCK); 1517 sep->se_next = servtab; 1518 servtab = sep; 1519 sigsetmask(omask); 1520 return (sep); 1521} 1522 1523void 1524enable(struct servtab *sep) 1525{ 1526 if (debug) 1527 warnx( 1528 "enabling %s, fd %d", sep->se_service, sep->se_fd); 1529#ifdef SANITY_CHECK 1530 if (sep->se_fd < 0) { 1531 syslog(LOG_ERR, 1532 "%s: %s: bad fd", __func__, sep->se_service); 1533 exit(EX_SOFTWARE); 1534 } 1535 if (ISMUX(sep)) { 1536 syslog(LOG_ERR, 1537 "%s: %s: is mux", __func__, sep->se_service); 1538 exit(EX_SOFTWARE); 1539 } 1540 if (FD_ISSET(sep->se_fd, &allsock)) { 1541 syslog(LOG_ERR, 1542 "%s: %s: not off", __func__, sep->se_service); 1543 exit(EX_SOFTWARE); 1544 } 1545 nsock++; 1546#endif 1547 FD_SET(sep->se_fd, &allsock); 1548 if (sep->se_fd > maxsock) 1549 maxsock = sep->se_fd; 1550} 1551 1552void 1553disable(struct servtab *sep) 1554{ 1555 if (debug) 1556 warnx( 1557 "disabling %s, fd %d", sep->se_service, sep->se_fd); 1558#ifdef SANITY_CHECK 1559 if (sep->se_fd < 0) { 1560 syslog(LOG_ERR, 1561 "%s: %s: bad fd", __func__, sep->se_service); 1562 exit(EX_SOFTWARE); 1563 } 1564 if (ISMUX(sep)) { 1565 syslog(LOG_ERR, 1566 "%s: %s: is mux", __func__, sep->se_service); 1567 exit(EX_SOFTWARE); 1568 } 1569 if (!FD_ISSET(sep->se_fd, &allsock)) { 1570 syslog(LOG_ERR, 1571 "%s: %s: not on", __func__, sep->se_service); 1572 exit(EX_SOFTWARE); 1573 } 1574 if (nsock == 0) { 1575 syslog(LOG_ERR, "%s: nsock=0", __func__); 1576 exit(EX_SOFTWARE); 1577 } 1578 nsock--; 1579#endif 1580 FD_CLR(sep->se_fd, &allsock); 1581 if (sep->se_fd == maxsock) 1582 maxsock--; 1583} 1584 1585FILE *fconfig = NULL; 1586struct servtab serv; 1587char line[LINE_MAX]; 1588 1589int 1590setconfig(void) 1591{ 1592 1593 if (fconfig != NULL) { 1594 fseek(fconfig, 0L, SEEK_SET); 1595 return (1); 1596 } 1597 fconfig = fopen(CONFIG, "r"); 1598 return (fconfig != NULL); 1599} 1600 1601void 1602endconfig(void) 1603{ 1604 if (fconfig) { 1605 (void) fclose(fconfig); 1606 fconfig = NULL; 1607 } 1608} 1609 1610struct servtab * 1611getconfigent(void) 1612{ 1613 struct servtab *sep = &serv; 1614 int argc; 1615 char *cp, *arg, *s; 1616 char *versp; 1617 static char TCPMUX_TOKEN[] = "tcpmux/"; 1618#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) 1619#ifdef IPSEC 1620 char *policy; 1621#endif 1622 int v4bind; 1623#ifdef INET6 1624 int v6bind; 1625#endif 1626 int i; 1627 1628#ifdef IPSEC 1629 policy = NULL; 1630#endif 1631more: 1632 v4bind = 0; 1633#ifdef INET6 1634 v6bind = 0; 1635#endif 1636 while ((cp = nextline(fconfig)) != NULL) { 1637#ifdef IPSEC 1638 /* lines starting with #@ is not a comment, but the policy */ 1639 if (cp[0] == '#' && cp[1] == '@') { 1640 char *p; 1641 for (p = cp + 2; p && *p && isspace(*p); p++) 1642 ; 1643 if (*p == '\0') { 1644 if (policy) 1645 free(policy); 1646 policy = NULL; 1647 } else if (ipsec_get_policylen(p) >= 0) { 1648 if (policy) 1649 free(policy); 1650 policy = newstr(p); 1651 } else { 1652 syslog(LOG_ERR, 1653 "%s: invalid ipsec policy \"%s\"", 1654 CONFIG, p); 1655 exit(EX_CONFIG); 1656 } 1657 } 1658#endif 1659 if (*cp == '#' || *cp == '\0') 1660 continue; 1661 break; 1662 } 1663 if (cp == NULL) 1664 return ((struct servtab *)0); 1665 /* 1666 * clear the static buffer, since some fields (se_ctrladdr, 1667 * for example) don't get initialized here. 1668 */ 1669 memset(sep, 0, sizeof *sep); 1670 arg = skip(&cp); 1671 if (cp == NULL) { 1672 /* got an empty line containing just blanks/tabs. */ 1673 goto more; 1674 } 1675 if (arg[0] == ':') { /* :user:group:perm: */ 1676 char *user, *group, *perm; 1677 struct passwd *pw; 1678 struct group *gr; 1679 user = arg+1; 1680 if ((group = strchr(user, ':')) == NULL) { 1681 syslog(LOG_ERR, "no group after user '%s'", user); 1682 goto more; 1683 } 1684 *group++ = '\0'; 1685 if ((perm = strchr(group, ':')) == NULL) { 1686 syslog(LOG_ERR, "no mode after group '%s'", group); 1687 goto more; 1688 } 1689 *perm++ = '\0'; 1690 if ((pw = getpwnam(user)) == NULL) { 1691 syslog(LOG_ERR, "no such user '%s'", user); 1692 goto more; 1693 } 1694 sep->se_sockuid = pw->pw_uid; 1695 if ((gr = getgrnam(group)) == NULL) { 1696 syslog(LOG_ERR, "no such user '%s'", group); 1697 goto more; 1698 } 1699 sep->se_sockgid = gr->gr_gid; 1700 sep->se_sockmode = strtol(perm, &arg, 8); 1701 if (*arg != ':') { 1702 syslog(LOG_ERR, "bad mode '%s'", perm); 1703 goto more; 1704 } 1705 *arg++ = '\0'; 1706 } else { 1707 sep->se_sockuid = euid; 1708 sep->se_sockgid = egid; 1709 sep->se_sockmode = 0200; 1710 } 1711 if (strncmp(arg, TCPMUX_TOKEN, MUX_LEN) == 0) { 1712 char *c = arg + MUX_LEN; 1713 if (*c == '+') { 1714 sep->se_type = MUXPLUS_TYPE; 1715 c++; 1716 } else 1717 sep->se_type = MUX_TYPE; 1718 sep->se_service = newstr(c); 1719 } else { 1720 sep->se_service = newstr(arg); 1721 sep->se_type = NORM_TYPE; 1722 } 1723 arg = sskip(&cp); 1724 if (strcmp(arg, "stream") == 0) 1725 sep->se_socktype = SOCK_STREAM; 1726 else if (strcmp(arg, "dgram") == 0) 1727 sep->se_socktype = SOCK_DGRAM; 1728 else if (strcmp(arg, "rdm") == 0) 1729 sep->se_socktype = SOCK_RDM; 1730 else if (strcmp(arg, "seqpacket") == 0) 1731 sep->se_socktype = SOCK_SEQPACKET; 1732 else if (strcmp(arg, "raw") == 0) 1733 sep->se_socktype = SOCK_RAW; 1734 else 1735 sep->se_socktype = -1; 1736 1737 arg = sskip(&cp); 1738 if (strncmp(arg, "tcp", 3) == 0) { 1739 sep->se_proto = newstr(strsep(&arg, "/")); 1740 if (arg != NULL) { 1741 if (strcmp(arg, "ttcp") == 0) 1742 sep->se_type = TTCP_TYPE; 1743 else if (strcmp(arg, "faith") == 0) 1744 sep->se_type = FAITH_TYPE; 1745 } 1746 } else { 1747 if (sep->se_type == NORM_TYPE && 1748 strncmp(arg, "faith/", 6) == 0) { 1749 arg += 6; 1750 sep->se_type = FAITH_TYPE; 1751 } 1752 sep->se_proto = newstr(arg); 1753 } 1754 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { 1755 memmove(sep->se_proto, sep->se_proto + 4, 1756 strlen(sep->se_proto) + 1 - 4); 1757 sep->se_rpc = 1; 1758 sep->se_rpc_prog = sep->se_rpc_lowvers = 1759 sep->se_rpc_lowvers = 0; 1760 memcpy(&sep->se_ctrladdr4, bind_sa4, 1761 sizeof(sep->se_ctrladdr4)); 1762 if ((versp = rindex(sep->se_service, '/'))) { 1763 *versp++ = '\0'; 1764 switch (sscanf(versp, "%u-%u", 1765 &sep->se_rpc_lowvers, 1766 &sep->se_rpc_highvers)) { 1767 case 2: 1768 break; 1769 case 1: 1770 sep->se_rpc_highvers = 1771 sep->se_rpc_lowvers; 1772 break; 1773 default: 1774 syslog(LOG_ERR, 1775 "bad RPC version specifier; %s", 1776 sep->se_service); 1777 freeconfig(sep); 1778 goto more; 1779 } 1780 } 1781 else { 1782 sep->se_rpc_lowvers = 1783 sep->se_rpc_highvers = 1; 1784 } 1785 } 1786 sep->se_nomapped = 0; 1787 if (strcmp(sep->se_proto, "unix") == 0) { 1788 sep->se_family = AF_UNIX; 1789 } else { 1790 while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) { 1791#ifdef INET6 1792 if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') { 1793 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1794 v6bind = 1; 1795 continue; 1796 } 1797#endif 1798 if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') { 1799 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1800 v4bind = 1; 1801 continue; 1802 } 1803 /* illegal version num */ 1804 syslog(LOG_ERR, "bad IP version for %s", sep->se_proto); 1805 freeconfig(sep); 1806 goto more; 1807 } 1808#ifdef INET6 1809 if (v6bind && !v6bind_ok) { 1810 syslog(LOG_INFO, "IPv6 bind is ignored for %s", 1811 sep->se_service); 1812 if (v4bind && v4bind_ok) 1813 v6bind = 0; 1814 else { 1815 freeconfig(sep); 1816 goto more; 1817 } 1818 } 1819 if (v6bind) { 1820 sep->se_family = AF_INET6; 1821 if (!v4bind || !v4bind_ok) 1822 sep->se_nomapped = 1; 1823 } else 1824#endif 1825 { /* default to v4 bind if not v6 bind */ 1826 if (!v4bind_ok) { 1827 syslog(LOG_NOTICE, "IPv4 bind is ignored for %s", 1828 sep->se_service); 1829 freeconfig(sep); 1830 goto more; 1831 } 1832 sep->se_family = AF_INET; 1833 } 1834 } 1835 /* init ctladdr */ 1836 switch(sep->se_family) { 1837 case AF_INET: 1838 memcpy(&sep->se_ctrladdr4, bind_sa4, 1839 sizeof(sep->se_ctrladdr4)); 1840 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr4); 1841 break; 1842#ifdef INET6 1843 case AF_INET6: 1844 memcpy(&sep->se_ctrladdr6, bind_sa6, 1845 sizeof(sep->se_ctrladdr6)); 1846 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr6); 1847 break; 1848#endif 1849 case AF_UNIX: 1850 if (strlen(sep->se_service) >= sizeof(sep->se_ctrladdr_un.sun_path)) { 1851 syslog(LOG_ERR, 1852 "domain socket pathname too long for service %s", 1853 sep->se_service); 1854 goto more; 1855 } 1856 memset(&sep->se_ctrladdr, 0, sizeof(sep->se_ctrladdr)); 1857 sep->se_ctrladdr_un.sun_family = sep->se_family; 1858 sep->se_ctrladdr_un.sun_len = strlen(sep->se_service); 1859 strcpy(sep->se_ctrladdr_un.sun_path, sep->se_service); 1860 sep->se_ctrladdr_size = SUN_LEN(&sep->se_ctrladdr_un); 1861 } 1862 arg = sskip(&cp); 1863 if (!strncmp(arg, "wait", 4)) 1864 sep->se_accept = 0; 1865 else if (!strncmp(arg, "nowait", 6)) 1866 sep->se_accept = 1; 1867 else { 1868 syslog(LOG_ERR, 1869 "%s: bad wait/nowait for service %s", 1870 CONFIG, sep->se_service); 1871 goto more; 1872 } 1873 sep->se_maxchild = -1; 1874 sep->se_maxcpm = -1; 1875 sep->se_maxperip = -1; 1876 if ((s = strchr(arg, '/')) != NULL) { 1877 char *eptr; 1878 u_long val; 1879 1880 val = strtoul(s + 1, &eptr, 10); 1881 if (eptr == s + 1 || val > MAX_MAXCHLD) { 1882 syslog(LOG_ERR, 1883 "%s: bad max-child for service %s", 1884 CONFIG, sep->se_service); 1885 goto more; 1886 } 1887 if (debug) 1888 if (!sep->se_accept && val != 1) 1889 warnx("maxchild=%lu for wait service %s" 1890 " not recommended", val, sep->se_service); 1891 sep->se_maxchild = val; 1892 if (*eptr == '/') 1893 sep->se_maxcpm = strtol(eptr + 1, &eptr, 10); 1894 if (*eptr == '/') 1895 sep->se_maxperip = strtol(eptr + 1, &eptr, 10); 1896 /* 1897 * explicitly do not check for \0 for future expansion / 1898 * backwards compatibility 1899 */ 1900 } 1901 if (ISMUX(sep)) { 1902 /* 1903 * Silently enforce "nowait" mode for TCPMUX services 1904 * since they don't have an assigned port to listen on. 1905 */ 1906 sep->se_accept = 1; 1907 if (strcmp(sep->se_proto, "tcp")) { 1908 syslog(LOG_ERR, 1909 "%s: bad protocol for tcpmux service %s", 1910 CONFIG, sep->se_service); 1911 goto more; 1912 } 1913 if (sep->se_socktype != SOCK_STREAM) { 1914 syslog(LOG_ERR, 1915 "%s: bad socket type for tcpmux service %s", 1916 CONFIG, sep->se_service); 1917 goto more; 1918 } 1919 } 1920 sep->se_user = newstr(sskip(&cp)); 1921#ifdef LOGIN_CAP 1922 if ((s = strrchr(sep->se_user, '/')) != NULL) { 1923 *s = '\0'; 1924 sep->se_class = newstr(s + 1); 1925 } else 1926 sep->se_class = newstr(RESOURCE_RC); 1927#endif 1928 if ((s = strrchr(sep->se_user, ':')) != NULL) { 1929 *s = '\0'; 1930 sep->se_group = newstr(s + 1); 1931 } else 1932 sep->se_group = NULL; 1933 sep->se_server = newstr(sskip(&cp)); 1934 if ((sep->se_server_name = rindex(sep->se_server, '/'))) 1935 sep->se_server_name++; 1936 if (strcmp(sep->se_server, "internal") == 0) { 1937 struct biltin *bi; 1938 1939 for (bi = biltins; bi->bi_service; bi++) 1940 if (bi->bi_socktype == sep->se_socktype && 1941 matchservent(bi->bi_service, sep->se_service, 1942 sep->se_proto)) 1943 break; 1944 if (bi->bi_service == 0) { 1945 syslog(LOG_ERR, "internal service %s unknown", 1946 sep->se_service); 1947 goto more; 1948 } 1949 sep->se_accept = 1; /* force accept mode for built-ins */ 1950 sep->se_bi = bi; 1951 } else 1952 sep->se_bi = NULL; 1953 if (sep->se_maxperip < 0) 1954 sep->se_maxperip = maxperip; 1955 if (sep->se_maxcpm < 0) 1956 sep->se_maxcpm = maxcpm; 1957 if (sep->se_maxchild < 0) { /* apply default max-children */ 1958 if (sep->se_bi && sep->se_bi->bi_maxchild >= 0) 1959 sep->se_maxchild = sep->se_bi->bi_maxchild; 1960 else if (sep->se_accept) 1961 sep->se_maxchild = maxchild > 0 ? maxchild : 0; 1962 else 1963 sep->se_maxchild = 1; 1964 } 1965 if (sep->se_maxchild > 0) { 1966 sep->se_pids = malloc(sep->se_maxchild * sizeof(*sep->se_pids)); 1967 if (sep->se_pids == NULL) { 1968 syslog(LOG_ERR, "malloc: %m"); 1969 exit(EX_OSERR); 1970 } 1971 } 1972 argc = 0; 1973 for (arg = skip(&cp); cp; arg = skip(&cp)) 1974 if (argc < MAXARGV) { 1975 sep->se_argv[argc++] = newstr(arg); 1976 } else { 1977 syslog(LOG_ERR, 1978 "%s: too many arguments for service %s", 1979 CONFIG, sep->se_service); 1980 goto more; 1981 } 1982 while (argc <= MAXARGV) 1983 sep->se_argv[argc++] = NULL; 1984 for (i = 0; i < PERIPSIZE; ++i) 1985 LIST_INIT(&sep->se_conn[i]); 1986#ifdef IPSEC 1987 sep->se_policy = policy ? newstr(policy) : NULL; 1988#endif 1989 return (sep); 1990} 1991 1992void 1993freeconfig(struct servtab *cp) 1994{ 1995 int i; 1996 1997 if (cp->se_service) 1998 free(cp->se_service); 1999 if (cp->se_proto) 2000 free(cp->se_proto); 2001 if (cp->se_user) 2002 free(cp->se_user); 2003 if (cp->se_group) 2004 free(cp->se_group); 2005#ifdef LOGIN_CAP 2006 if (cp->se_class) 2007 free(cp->se_class); 2008#endif 2009 if (cp->se_server) 2010 free(cp->se_server); 2011 if (cp->se_pids) 2012 free(cp->se_pids); 2013 for (i = 0; i < MAXARGV; i++) 2014 if (cp->se_argv[i]) 2015 free(cp->se_argv[i]); 2016 free_connlist(cp); 2017#ifdef IPSEC 2018 if (cp->se_policy) 2019 free(cp->se_policy); 2020#endif 2021} 2022 2023 2024/* 2025 * Safe skip - if skip returns null, log a syntax error in the 2026 * configuration file and exit. 2027 */ 2028char * 2029sskip(char **cpp) 2030{ 2031 char *cp; 2032 2033 cp = skip(cpp); 2034 if (cp == NULL) { 2035 syslog(LOG_ERR, "%s: syntax error", CONFIG); 2036 exit(EX_DATAERR); 2037 } 2038 return (cp); 2039} 2040 2041char * 2042skip(char **cpp) 2043{ 2044 char *cp = *cpp; 2045 char *start; 2046 char quote = '\0'; 2047 2048again: 2049 while (*cp == ' ' || *cp == '\t') 2050 cp++; 2051 if (*cp == '\0') { 2052 int c; 2053 2054 c = getc(fconfig); 2055 (void) ungetc(c, fconfig); 2056 if (c == ' ' || c == '\t') 2057 if ((cp = nextline(fconfig))) 2058 goto again; 2059 *cpp = (char *)0; 2060 return ((char *)0); 2061 } 2062 if (*cp == '"' || *cp == '\'') 2063 quote = *cp++; 2064 start = cp; 2065 if (quote) 2066 while (*cp && *cp != quote) 2067 cp++; 2068 else 2069 while (*cp && *cp != ' ' && *cp != '\t') 2070 cp++; 2071 if (*cp != '\0') 2072 *cp++ = '\0'; 2073 *cpp = cp; 2074 return (start); 2075} 2076 2077char * 2078nextline(FILE *fd) 2079{ 2080 char *cp; 2081 2082 if (fgets(line, sizeof (line), fd) == NULL) 2083 return ((char *)0); 2084 cp = strchr(line, '\n'); 2085 if (cp) 2086 *cp = '\0'; 2087 return (line); 2088} 2089 2090char * 2091newstr(const char *cp) 2092{ 2093 char *cr; 2094 2095 if ((cr = strdup(cp != NULL ? cp : ""))) 2096 return (cr); 2097 syslog(LOG_ERR, "strdup: %m"); 2098 exit(EX_OSERR); 2099} 2100 2101void 2102inetd_setproctitle(const char *a, int s) 2103{ 2104 socklen_t size; 2105 struct sockaddr_storage ss; 2106 char buf[80], pbuf[INET6_ADDRSTRLEN]; 2107 2108 size = sizeof(ss); 2109 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) { 2110 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf),
|