1 /* $OpenBSD: monitor.c,v 1.72 2010/05/10 02:00:50 krw Exp $ */ 2 3 /* 4 * Copyright (c) 2003 H�kan Olsson. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include <sys/ioctl.h> 31 #include <sys/stat.h> 32 #include <sys/wait.h> 33 #include <netinet/in.h> 34 35 #include <dirent.h> 36 #include <errno.h> 37 #include <fcntl.h> 38 #include <pwd.h> 39 #include <signal.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 #include <regex.h> 45 #include <keynote.h> 46 47 #include "conf.h" 48 #include "log.h" 49 #include "monitor.h" 50 #include "policy.h" 51 #include "ui.h" 52 #include "util.h" 53 #include "pf_key_v2.h" 54 55 struct monitor_state { 56 pid_t pid; 57 int s; 58 char root[MAXPATHLEN]; 59 } m_state; 60 61 extern char *pid_file; 62 63 extern void set_slave_signals(void); 64 65 /* Private functions. */ 66 static void must_read(void *, size_t); 67 static void must_write(const void *, size_t); 68 69 static void m_priv_getfd(void); 70 static void m_priv_setsockopt(void); 71 static void m_priv_req_readdir(void); 72 static void m_priv_bind(void); 73 static void m_priv_pfkey_open(void); 74 static int m_priv_local_sanitize_path(char *, size_t, int); 75 static int m_priv_check_sockopt(int, int); 76 static int m_priv_check_bind(const struct sockaddr *, socklen_t); 77 78 static void set_monitor_signals(void); 79 static void sig_pass_to_chld(int); 80 81 /* 82 * Public functions, unprivileged. 83 */ 84 85 /* Setup monitor context, fork, drop child privs. */ 86 pid_t 87 monitor_init(int debug) 88 { 89 struct passwd *pw; 90 int p[2]; 91 92 bzero(&m_state, sizeof m_state); 93 94 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) != 0) 95 log_fatal("monitor_init: socketpair() failed"); 96 97 pw = getpwnam(ISAKMPD_PRIVSEP_USER); 98 if (pw == NULL) 99 log_fatalx("monitor_init: getpwnam(\"%s\") failed", 100 ISAKMPD_PRIVSEP_USER); 101 strlcpy(m_state.root, pw->pw_dir, sizeof m_state.root); 102 103 set_monitor_signals(); 104 m_state.pid = fork(); 105 106 if (m_state.pid == -1) 107 log_fatal("monitor_init: fork of unprivileged child failed"); 108 if (m_state.pid == 0) { 109 /* The child process drops privileges. */ 110 set_slave_signals(); 111 112 if (chroot(pw->pw_dir) != 0 || chdir("/") != 0) 113 log_fatal("monitor_init: chroot failed"); 114 115 if (setgroups(1, &pw->pw_gid) == -1 || 116 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 117 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 118 log_fatal("monitor_init: can't drop privileges"); 119 120 m_state.s = p[0]; 121 close(p[1]); 122 123 LOG_DBG((LOG_MISC, 10, 124 "monitor_init: privileges dropped for child process")); 125 } else { 126 /* Privileged monitor. */ 127 setproctitle("monitor [priv]"); 128 129 m_state.s = p[1]; 130 close(p[0]); 131 } 132 133 /* With "-dd", stop and wait here. For gdb "attach" etc. */ 134 if (debug > 1) { 135 log_print("monitor_init: stopped %s PID %d fd %d%s", 136 m_state.pid ? "priv" : "child", getpid(), m_state.s, 137 m_state.pid ? ", waiting for SIGCONT" : ""); 138 kill(getpid(), SIGSTOP); /* Wait here for SIGCONT. */ 139 if (m_state.pid) 140 kill(m_state.pid, SIGCONT); /* Continue child. */ 141 } 142 143 return m_state.pid; 144 } 145 146 void 147 monitor_exit(int code) 148 { 149 int status; 150 pid_t pid; 151 152 if (m_state.pid != 0) { 153 /* When called from the monitor, kill slave and wait for it */ 154 kill(m_state.pid, SIGTERM); 155 156 do { 157 pid = waitpid(m_state.pid, &status, 0); 158 } while (pid == -1 && errno == EINTR); 159 160 /* Remove FIFO and pid files. */ 161 unlink(ui_fifo); 162 unlink(pid_file); 163 } 164 165 close(m_state.s); 166 exit(code); 167 } 168 169 int 170 monitor_pf_key_v2_open(void) 171 { 172 int err, cmd; 173 174 cmd = MONITOR_PFKEY_OPEN; 175 must_write(&cmd, sizeof cmd); 176 177 must_read(&err, sizeof err); 178 if (err < 0) { 179 log_error("monitor_pf_key_v2_open: parent could not create " 180 "PF_KEY socket"); 181 return -1; 182 } 183 pf_key_v2_socket = mm_receive_fd(m_state.s); 184 if (pf_key_v2_socket < 0) { 185 log_error("monitor_pf_key_v2_open: mm_receive_fd() failed"); 186 return -1; 187 } 188 189 return pf_key_v2_socket; 190 } 191 192 int 193 monitor_open(const char *path, int flags, mode_t mode) 194 { 195 size_t len; 196 int fd, err, cmd; 197 char pathreal[MAXPATHLEN]; 198 199 if (path[0] == '/') 200 strlcpy(pathreal, path, sizeof pathreal); 201 else 202 snprintf(pathreal, sizeof pathreal, "%s/%s", m_state.root, 203 path); 204 205 cmd = MONITOR_GET_FD; 206 must_write(&cmd, sizeof cmd); 207 208 len = strlen(pathreal); 209 must_write(&len, sizeof len); 210 must_write(&pathreal, len); 211 212 must_write(&flags, sizeof flags); 213 must_write(&mode, sizeof mode); 214 215 must_read(&err, sizeof err); 216 if (err != 0) { 217 errno = err; 218 return -1; 219 } 220 221 fd = mm_receive_fd(m_state.s); 222 if (fd < 0) { 223 log_error("monitor_open: mm_receive_fd () failed"); 224 return -1; 225 } 226 227 return fd; 228 } 229 230 FILE * 231 monitor_fopen(const char *path, const char *mode) 232 { 233 FILE *fp; 234 int fd, flags = 0, saved_errno; 235 mode_t mask, cur_umask; 236 237 /* Only the child process is supposed to run this. */ 238 if (m_state.pid) 239 log_fatal("[priv] bad call to monitor_fopen"); 240 241 switch (mode[0]) { 242 case 'r': 243 flags = (mode[1] == '+' ? O_RDWR : O_RDONLY); 244 break; 245 case 'w': 246 flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT | 247 O_TRUNC; 248 break; 249 case 'a': 250 flags = (mode[1] == '+' ? O_RDWR : O_WRONLY) | O_CREAT | 251 O_APPEND; 252 break; 253 default: 254 log_fatal("monitor_fopen: bad call"); 255 } 256 257 cur_umask = umask(0); 258 (void)umask(cur_umask); 259 mask = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 260 mask &= ~cur_umask; 261 262 fd = monitor_open(path, flags, mask); 263 if (fd < 0) 264 return NULL; 265 266 /* Got the fd, attach a FILE * to it. */ 267 fp = fdopen(fd, mode); 268 if (!fp) { 269 log_error("monitor_fopen: fdopen() failed"); 270 saved_errno = errno; 271 close(fd); 272 errno = saved_errno; 273 return NULL; 274 } 275 return fp; 276 } 277 278 int 279 monitor_stat(const char *path, struct stat *sb) 280 { 281 int fd, r, saved_errno; 282 283 /* O_NONBLOCK is needed for stat'ing fifos. */ 284 fd = monitor_open(path, O_RDONLY | O_NONBLOCK, 0); 285 if (fd < 0) 286 return -1; 287 288 r = fstat(fd, sb); 289 saved_errno = errno; 290 close(fd); 291 errno = saved_errno; 292 return r; 293 } 294 295 int 296 monitor_setsockopt(int s, int level, int optname, const void *optval, 297 socklen_t optlen) 298 { 299 int ret, err, cmd; 300 301 cmd = MONITOR_SETSOCKOPT; 302 must_write(&cmd, sizeof cmd); 303 if (mm_send_fd(m_state.s, s)) { 304 log_print("monitor_setsockopt: read/write error"); 305 return -1; 306 } 307 308 must_write(&level, sizeof level); 309 must_write(&optname, sizeof optname); 310 must_write(&optlen, sizeof optlen); 311 must_write(optval, optlen); 312 313 must_read(&err, sizeof err); 314 must_read(&ret, sizeof ret); 315 if (err != 0) 316 errno = err; 317 return ret; 318 } 319 320 int 321 monitor_bind(int s, const struct sockaddr *name, socklen_t namelen) 322 { 323 int ret, err, cmd; 324 325 cmd = MONITOR_BIND; 326 must_write(&cmd, sizeof cmd); 327 if (mm_send_fd(m_state.s, s)) { 328 log_print("monitor_bind: read/write error"); 329 return -1; 330 } 331 332 must_write(&namelen, sizeof namelen); 333 must_write(name, namelen); 334 335 must_read(&err, sizeof err); 336 must_read(&ret, sizeof ret); 337 if (err != 0) 338 errno = err; 339 return ret; 340 } 341 342 int 343 monitor_req_readdir(const char *filename) 344 { 345 int cmd, err; 346 size_t len; 347 348 cmd = MONITOR_REQ_READDIR; 349 must_write(&cmd, sizeof cmd); 350 351 len = strlen(filename); 352 must_write(&len, sizeof len); 353 must_write(filename, len); 354 355 must_read(&err, sizeof err); 356 if (err == -1) 357 must_read(&errno, sizeof errno); 358 359 return err; 360 } 361 362 int 363 monitor_readdir(char *file, size_t size) 364 { 365 int fd; 366 size_t len; 367 368 must_read(&len, sizeof len); 369 if (len == 0) 370 return -1; 371 if (len >= size) 372 log_fatal("monitor_readdir: received bad length from monitor"); 373 must_read(file, len); 374 file[len] = '\0'; 375 fd = mm_receive_fd(m_state.s); 376 return fd; 377 } 378 379 void 380 monitor_init_done(void) 381 { 382 int cmd; 383 384 cmd = MONITOR_INIT_DONE; 385 must_write(&cmd, sizeof cmd); 386 } 387 388 /* 389 * Start of code running with privileges (the monitor process). 390 */ 391 392 static void 393 set_monitor_signals(void) 394 { 395 int n; 396 397 for (n = 1; n < _NSIG; n++) 398 signal(n, SIG_DFL); 399 400 /* Forward some signals to the child. */ 401 signal(SIGTERM, sig_pass_to_chld); 402 signal(SIGHUP, sig_pass_to_chld); 403 signal(SIGUSR1, sig_pass_to_chld); 404 } 405 406 static void 407 sig_pass_to_chld(int sig) 408 { 409 int oerrno = errno; 410 411 if (m_state.pid > 0) 412 kill(m_state.pid, sig); 413 errno = oerrno; 414 } 415 416 /* This function is where the privileged process waits(loops) indefinitely. */ 417 void 418 monitor_loop(int debug) 419 { 420 int msgcode; 421 422 if (!debug) 423 log_to(0); 424 425 for (;;) { 426 must_read(&msgcode, sizeof msgcode); 427 428 switch (msgcode) { 429 case MONITOR_GET_FD: 430 m_priv_getfd(); 431 break; 432 433 case MONITOR_PFKEY_OPEN: 434 LOG_DBG((LOG_MISC, 80, 435 "monitor_loop: MONITOR_PFKEY_OPEN")); 436 m_priv_pfkey_open(); 437 break; 438 439 case MONITOR_SETSOCKOPT: 440 LOG_DBG((LOG_MISC, 80, 441 "monitor_loop: MONITOR_SETSOCKOPT")); 442 m_priv_setsockopt(); 443 break; 444 445 case MONITOR_BIND: 446 LOG_DBG((LOG_MISC, 80, 447 "monitor_loop: MONITOR_BIND")); 448 m_priv_bind(); 449 break; 450 451 case MONITOR_REQ_READDIR: 452 LOG_DBG((LOG_MISC, 80, 453 "monitor_loop: MONITOR_REQ_READDIR")); 454 m_priv_req_readdir(); 455 break; 456 457 case MONITOR_INIT_DONE: 458 LOG_DBG((LOG_MISC, 80, 459 "monitor_loop: MONITOR_INIT_DONE")); 460 break; 461 462 case MONITOR_SHUTDOWN: 463 LOG_DBG((LOG_MISC, 80, 464 "monitor_loop: MONITOR_SHUTDOWN")); 465 break; 466 467 default: 468 log_print("monitor_loop: got unknown code %d", 469 msgcode); 470 } 471 } 472 473 exit(0); 474 } 475 476 477 /* Privileged: called by monitor_loop. */ 478 static void 479 m_priv_pfkey_open(void) 480 { 481 int fd, err = 0; 482 483 fd = pf_key_v2_open(); 484 if (fd < 0) 485 err = -1; 486 487 must_write(&err, sizeof err); 488 489 if (fd > 0 && mm_send_fd(m_state.s, fd)) { 490 log_error("m_priv_pfkey_open: read/write operation failed"); 491 close(fd); 492 return; 493 } 494 close(fd); 495 } 496 497 /* Privileged: called by monitor_loop. */ 498 static void 499 m_priv_getfd(void) 500 { 501 char path[MAXPATHLEN]; 502 size_t len; 503 int v, flags, ret; 504 int err = 0; 505 mode_t mode; 506 507 must_read(&len, sizeof len); 508 if (len == 0 || len >= sizeof path) 509 log_fatal("m_priv_getfd: invalid pathname length"); 510 511 must_read(path, len); 512 path[len] = '\0'; 513 if (strlen(path) != len) 514 log_fatal("m_priv_getfd: invalid pathname"); 515 516 must_read(&flags, sizeof flags); 517 must_read(&mode, sizeof mode); 518 519 if ((ret = m_priv_local_sanitize_path(path, sizeof path, flags)) 520 != 0) { 521 if (ret == 1) 522 log_print("m_priv_getfd: illegal path \"%s\"", path); 523 err = EACCES; 524 v = -1; 525 } else { 526 if ((v = open(path, flags, mode)) == -1) 527 err = errno; 528 } 529 530 must_write(&err, sizeof err); 531 532 if (v != -1) { 533 if (mm_send_fd(m_state.s, v) == -1) 534 log_error("m_priv_getfd: sending fd failed"); 535 close(v); 536 } 537 } 538 539 /* Privileged: called by monitor_loop. */ 540 static void 541 m_priv_setsockopt(void) 542 { 543 int sock, level, optname, v; 544 int err = 0; 545 char *optval = 0; 546 socklen_t optlen; 547 548 sock = mm_receive_fd(m_state.s); 549 if (sock < 0) { 550 log_print("m_priv_setsockopt: read/write error"); 551 return; 552 } 553 554 must_read(&level, sizeof level); 555 must_read(&optname, sizeof optname); 556 must_read(&optlen, sizeof optlen); 557 558 optval = (char *)malloc(optlen); 559 if (!optval) { 560 log_print("m_priv_setsockopt: malloc failed"); 561 close(sock); 562 return; 563 } 564 565 must_read(optval, optlen); 566 567 if (m_priv_check_sockopt(level, optname) != 0) { 568 err = EACCES; 569 v = -1; 570 } else { 571 v = setsockopt(sock, level, optname, optval, optlen); 572 if (v < 0) 573 err = errno; 574 } 575 576 close(sock); 577 sock = -1; 578 579 must_write(&err, sizeof err); 580 must_write(&v, sizeof v); 581 582 free(optval); 583 return; 584 } 585 586 /* Privileged: called by monitor_loop. */ 587 static void 588 m_priv_bind(void) 589 { 590 int sock, v, err = 0; 591 struct sockaddr *name = 0; 592 socklen_t namelen; 593 594 sock = mm_receive_fd(m_state.s); 595 if (sock < 0) { 596 log_print("m_priv_bind: read/write error"); 597 return; 598 } 599 600 must_read(&namelen, sizeof namelen); 601 name = (struct sockaddr *)malloc(namelen); 602 if (!name) { 603 log_print("m_priv_bind: malloc failed"); 604 close(sock); 605 return; 606 } 607 must_read((char *)name, namelen); 608 609 if (m_priv_check_bind(name, namelen) != 0) { 610 err = EACCES; 611 v = -1; 612 } else { 613 v = bind(sock, name, namelen); 614 if (v < 0) { 615 log_error("m_priv_bind: bind(%d,%p,%d) returned %d", 616 sock, name, namelen, v); 617 err = errno; 618 } 619 } 620 621 close(sock); 622 sock = -1; 623 624 must_write(&err, sizeof err); 625 must_write(&v, sizeof v); 626 627 free(name); 628 return; 629 } 630 631 /* 632 * Help functions, used by both privileged and unprivileged code 633 */ 634 635 /* 636 * Read data with the assertion that it all must come through, or else abort 637 * the process. Based on atomicio() from openssh. 638 */ 639 static void 640 must_read(void *buf, size_t n) 641 { 642 char *s = buf; 643 size_t pos = 0; 644 ssize_t res; 645 646 while (n > pos) { 647 res = read(m_state.s, s + pos, n - pos); 648 switch (res) { 649 case -1: 650 if (errno == EINTR || errno == EAGAIN) 651 continue; 652 case 0: 653 monitor_exit(0); 654 default: 655 pos += res; 656 } 657 } 658 } 659 660 /* 661 * Write data with the assertion that it all has to be written, or else abort 662 * the process. Based on atomicio() from openssh. 663 */ 664 static void 665 must_write(const void *buf, size_t n) 666 { 667 const char *s = buf; 668 size_t pos = 0; 669 ssize_t res; 670 671 while (n > pos) { 672 res = write(m_state.s, s + pos, n - pos); 673 switch (res) { 674 case -1: 675 if (errno == EINTR || errno == EAGAIN) 676 continue; 677 case 0: 678 monitor_exit(0); 679 default: 680 pos += res; 681 } 682 } 683 } 684 685 /* Check that path/mode is permitted. */ 686 static int 687 m_priv_local_sanitize_path(char *path, size_t pmax, int flags) 688 { 689 char new_path[PATH_MAX], var_run[PATH_MAX]; 690 691 /* 692 * We only permit paths starting with 693 * /etc/isakmpd/ (read only) 694 * /var/run/ (rw) 695 */ 696 697 if (realpath(path, new_path) == NULL || 698 realpath("/var/run", var_run) == NULL) { 699 /* 700 * We could not decide whether the path is ok or not. 701 * Indicate this be returning 2. 702 */ 703 if (errno == ENOENT) 704 return 2; 705 goto bad_path; 706 } 707 strlcat(var_run, "/", sizeof(var_run)); 708 709 if (strncmp(var_run, new_path, strlen(var_run)) == 0) 710 return 0; 711 712 if (strncmp(ISAKMPD_ROOT, new_path, strlen(ISAKMPD_ROOT)) == 0 && 713 (flags & O_ACCMODE) == O_RDONLY) 714 return 0; 715 716 bad_path: 717 return 1; 718 } 719 720 /* Check setsockopt */ 721 static int 722 m_priv_check_sockopt(int level, int name) 723 { 724 switch (level) { 725 /* These are allowed */ 726 case SOL_SOCKET: 727 case IPPROTO_IP: 728 case IPPROTO_IPV6: 729 break; 730 731 default: 732 log_print("m_priv_check_sockopt: Illegal level %d", level); 733 return 1; 734 } 735 736 switch (name) { 737 /* These are allowed */ 738 case SO_REUSEPORT: 739 case SO_REUSEADDR: 740 case IP_AUTH_LEVEL: 741 case IP_ESP_TRANS_LEVEL: 742 case IP_ESP_NETWORK_LEVEL: 743 case IP_IPCOMP_LEVEL: 744 case IPV6_AUTH_LEVEL: 745 case IPV6_ESP_TRANS_LEVEL: 746 case IPV6_ESP_NETWORK_LEVEL: 747 case IPV6_IPCOMP_LEVEL: 748 break; 749 750 default: 751 log_print("m_priv_check_sockopt: Illegal option name %d", 752 name); 753 return 1; 754 } 755 756 return 0; 757 } 758 759 /* Check bind */ 760 static int 761 m_priv_check_bind(const struct sockaddr *sa, socklen_t salen) 762 { 763 in_port_t port; 764 765 if (sa == NULL) { 766 log_print("NULL address"); 767 return 1; 768 } 769 if (SA_LEN(sa) != salen) { 770 log_print("Length mismatch: %lu %lu", (unsigned long)sa->sa_len, 771 (unsigned long)salen); 772 return 1; 773 } 774 switch (sa->sa_family) { 775 case AF_INET: 776 if (salen != sizeof(struct sockaddr_in)) { 777 log_print("Invalid inet address length"); 778 return 1; 779 } 780 port = ((const struct sockaddr_in *)sa)->sin_port; 781 break; 782 case AF_INET6: 783 if (salen != sizeof(struct sockaddr_in6)) { 784 log_print("Invalid inet6 address length"); 785 return 1; 786 } 787 port = ((const struct sockaddr_in6 *)sa)->sin6_port; 788 break; 789 default: 790 log_print("Unknown address family"); 791 return 1; 792 } 793 794 port = ntohs(port); 795 796 if (port != ISAKMP_PORT_DEFAULT && port < 1024) { 797 log_print("Disallowed port %u", port); 798 return 1; 799 } 800 return 0; 801 } 802 803 static void 804 m_priv_req_readdir() 805 { 806 size_t len; 807 char path[MAXPATHLEN]; 808 DIR *dp; 809 struct dirent *file; 810 struct stat sb; 811 int off, size, fd, ret, serrno; 812 813 must_read(&len, sizeof len); 814 if (len == 0 || len >= sizeof path) 815 log_fatal("m_priv_req_readdir: invalid pathname length"); 816 must_read(path, len); 817 path[len] = '\0'; 818 if (strlen(path) != len) 819 log_fatal("m_priv_req_readdir: invalid pathname"); 820 821 off = strlen(path); 822 size = sizeof path - off; 823 824 if ((dp = opendir(path)) == NULL) { 825 serrno = errno; 826 ret = -1; 827 must_write(&ret, sizeof ret); 828 must_write(&serrno, sizeof serrno); 829 return; 830 } 831 832 /* report opendir() success */ 833 ret = 0; 834 must_write(&ret, sizeof ret); 835 836 while ((file = readdir(dp)) != NULL) { 837 strlcpy(path + off, file->d_name, size); 838 839 if (m_priv_local_sanitize_path(path, sizeof path, O_RDONLY) 840 != 0) 841 continue; 842 fd = open(path, O_RDONLY, 0); 843 if (fd == -1) { 844 log_error("m_priv_req_readdir: open " 845 "(\"%s\", O_RDONLY, 0) failed", path); 846 continue; 847 } 848 if ((fstat(fd, &sb) == -1) || 849 !(S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode))) { 850 close(fd); 851 continue; 852 } 853 854 len = strlen(path); 855 must_write(&len, sizeof len); 856 must_write(path, len); 857 858 mm_send_fd(m_state.s, fd); 859 close(fd); 860 } 861 closedir(dp); 862 863 len = 0; 864 must_write(&len, sizeof len); 865 } 866