1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation) 3 * 4 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. 5 * Copyright (C) 2003 CodeFactory AB 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #include <config.h> 26 27 #include "dbus-internals.h" 28 #include "dbus-sysdeps.h" 29 #include "dbus-sysdeps-unix.h" 30 #include "dbus-threads.h" 31 #include "dbus-protocol.h" 32 #include "dbus-transport.h" 33 #include "dbus-string.h" 34 #include "dbus-userdb.h" 35 #include "dbus-list.h" 36 #include "dbus-credentials.h" 37 #include "dbus-nonce.h" 38 39 #include <sys/types.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <signal.h> 43 #include <unistd.h> 44 #include <stdio.h> 45 #include <fcntl.h> 46 #include <sys/socket.h> 47 #include <dirent.h> 48 #include <sys/un.h> 49 #include <pwd.h> 50 #include <time.h> 51 #include <locale.h> 52 #include <sys/time.h> 53 #include <sys/stat.h> 54 #include <sys/wait.h> 55 #include <netinet/in.h> 56 #include <netdb.h> 57 #include <grp.h> 58 #include <cutils/sockets.h> 59 60 #ifdef HAVE_ERRNO_H 61 #include <errno.h> 62 #endif 63 #ifdef HAVE_WRITEV 64 #include <sys/uio.h> 65 #endif 66 #ifdef HAVE_POLL 67 #include <sys/poll.h> 68 #endif 69 #ifdef HAVE_BACKTRACE 70 #include <execinfo.h> 71 #endif 72 #ifdef HAVE_GETPEERUCRED 73 #include <ucred.h> 74 #endif 75 76 #ifdef HAVE_ADT 77 #include <bsm/adt.h> 78 #endif 79 80 // Android specific atomic operation header. 81 #ifdef ANDROID_ATOMIC 82 #include <cutils/atomic.h> 83 #endif 84 85 #include "sd-daemon.h" 86 87 #ifndef O_BINARY 88 #define O_BINARY 0 89 #endif 90 91 #ifndef AI_ADDRCONFIG 92 #define AI_ADDRCONFIG 0 93 #endif 94 95 #ifndef HAVE_SOCKLEN_T 96 #define socklen_t int 97 #endif 98 99 static dbus_bool_t 100 _dbus_open_socket (int *fd_p, 101 int domain, 102 int type, 103 int protocol, 104 DBusError *error) 105 { 106 #ifdef SOCK_CLOEXEC 107 dbus_bool_t cloexec_done; 108 109 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol); 110 cloexec_done = *fd_p >= 0; 111 112 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */ 113 if (*fd_p < 0 && errno == EINVAL) 114 #endif 115 { 116 *fd_p = socket (domain, type, protocol); 117 } 118 119 if (*fd_p >= 0) 120 { 121 #ifdef SOCK_CLOEXEC 122 if (!cloexec_done) 123 #endif 124 { 125 _dbus_fd_set_close_on_exec(*fd_p); 126 } 127 128 _dbus_verbose ("socket fd %d opened\n", *fd_p); 129 return TRUE; 130 } 131 else 132 { 133 dbus_set_error(error, 134 _dbus_error_from_errno (errno), 135 "Failed to open socket: %s", 136 _dbus_strerror (errno)); 137 return FALSE; 138 } 139 } 140 141 dbus_bool_t 142 _dbus_open_tcp_socket (int *fd, 143 DBusError *error) 144 { 145 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error); 146 } 147 148 /** 149 * Opens a UNIX domain socket (as in the socket() call). 150 * Does not bind the socket. 151 * 152 * This will set FD_CLOEXEC for the socket returned 153 * 154 * @param fd return location for socket descriptor 155 * @param error return location for an error 156 * @returns #FALSE if error is set 157 */ 158 dbus_bool_t 159 _dbus_open_unix_socket (int *fd, 160 DBusError *error) 161 { 162 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error); 163 } 164 165 /** 166 * Closes a socket. Should not be used on non-socket 167 * file descriptors or handles. 168 * 169 * @param fd the socket 170 * @param error return location for an error 171 * @returns #FALSE if error is set 172 */ 173 dbus_bool_t 174 _dbus_close_socket (int fd, 175 DBusError *error) 176 { 177 return _dbus_close (fd, error); 178 } 179 180 /** 181 * Like _dbus_read(), but only works on sockets so is 182 * available on Windows. 183 * 184 * @param fd the socket 185 * @param buffer string to append data to 186 * @param count max amount of data to read 187 * @returns number of bytes appended to the string 188 */ 189 int 190 _dbus_read_socket (int fd, 191 DBusString *buffer, 192 int count) 193 { 194 return _dbus_read (fd, buffer, count); 195 } 196 197 /** 198 * Like _dbus_write(), but only supports sockets 199 * and is thus available on Windows. 200 * 201 * @param fd the file descriptor to write 202 * @param buffer the buffer to write data from 203 * @param start the first byte in the buffer to write 204 * @param len the number of bytes to try to write 205 * @returns the number of bytes written or -1 on error 206 */ 207 int 208 _dbus_write_socket (int fd, 209 const DBusString *buffer, 210 int start, 211 int len) 212 { 213 #ifdef MSG_NOSIGNAL 214 const char *data; 215 int bytes_written; 216 217 data = _dbus_string_get_const_data_len (buffer, start, len); 218 219 again: 220 221 bytes_written = send (fd, data, len, MSG_NOSIGNAL); 222 223 if (bytes_written < 0 && errno == EINTR) 224 goto again; 225 226 return bytes_written; 227 228 #else 229 return _dbus_write (fd, buffer, start, len); 230 #endif 231 } 232 233 /** 234 * Like _dbus_read_socket() but also tries to read unix fds from the 235 * socket. When there are more fds to read than space in the array 236 * passed this function will fail with ENOSPC. 237 * 238 * @param fd the socket 239 * @param buffer string to append data to 240 * @param count max amount of data to read 241 * @param fds array to place read file descriptors in 242 * @param n_fds on input space in fds array, on output how many fds actually got read 243 * @returns number of bytes appended to string 244 */ 245 int 246 _dbus_read_socket_with_unix_fds (int fd, 247 DBusString *buffer, 248 int count, 249 int *fds, 250 int *n_fds) { 251 #ifndef HAVE_UNIX_FD_PASSING 252 int r; 253 254 if ((r = _dbus_read_socket(fd, buffer, count)) < 0) 255 return r; 256 257 *n_fds = 0; 258 return r; 259 260 #else 261 int bytes_read; 262 int start; 263 struct msghdr m; 264 struct iovec iov; 265 266 _dbus_assert (count >= 0); 267 _dbus_assert (*n_fds >= 0); 268 269 start = _dbus_string_get_length (buffer); 270 271 if (!_dbus_string_lengthen (buffer, count)) 272 { 273 errno = ENOMEM; 274 return -1; 275 } 276 277 _DBUS_ZERO(iov); 278 iov.iov_base = _dbus_string_get_data_len (buffer, start, count); 279 iov.iov_len = count; 280 281 _DBUS_ZERO(m); 282 m.msg_iov = &iov; 283 m.msg_iovlen = 1; 284 285 /* Hmm, we have no clue how long the control data will actually be 286 that is queued for us. The least we can do is assume that the 287 caller knows. Hence let's make space for the number of fds that 288 we shall read at max plus the cmsg header. */ 289 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int)); 290 291 /* It's probably safe to assume that systems with SCM_RIGHTS also 292 know alloca() */ 293 m.msg_control = alloca(m.msg_controllen); 294 memset(m.msg_control, 0, m.msg_controllen); 295 296 again: 297 298 bytes_read = recvmsg(fd, &m, 0 299 #ifdef MSG_CMSG_CLOEXEC 300 |MSG_CMSG_CLOEXEC 301 #endif 302 ); 303 304 if (bytes_read < 0) 305 { 306 if (errno == EINTR) 307 goto again; 308 else 309 { 310 /* put length back (note that this doesn't actually realloc anything) */ 311 _dbus_string_set_length (buffer, start); 312 return -1; 313 } 314 } 315 else 316 { 317 struct cmsghdr *cm; 318 dbus_bool_t found = FALSE; 319 320 if (m.msg_flags & MSG_CTRUNC) 321 { 322 /* Hmm, apparently the control data was truncated. The bad 323 thing is that we might have completely lost a couple of fds 324 without chance to recover them. Hence let's treat this as a 325 serious error. */ 326 327 errno = ENOSPC; 328 _dbus_string_set_length (buffer, start); 329 return -1; 330 } 331 332 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) 333 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) 334 { 335 unsigned i; 336 337 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int))); 338 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int); 339 340 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int)); 341 found = TRUE; 342 343 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually 344 worked, hence we need to go through this list and set 345 CLOEXEC everywhere in any case */ 346 for (i = 0; i < *n_fds; i++) 347 _dbus_fd_set_close_on_exec(fds[i]); 348 349 break; 350 } 351 352 if (!found) 353 *n_fds = 0; 354 355 /* put length back (doesn't actually realloc) */ 356 _dbus_string_set_length (buffer, start + bytes_read); 357 358 #if 0 359 if (bytes_read > 0) 360 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 361 #endif 362 363 return bytes_read; 364 } 365 #endif 366 } 367 368 int 369 _dbus_write_socket_with_unix_fds(int fd, 370 const DBusString *buffer, 371 int start, 372 int len, 373 const int *fds, 374 int n_fds) { 375 376 #ifndef HAVE_UNIX_FD_PASSING 377 378 if (n_fds > 0) { 379 errno = ENOTSUP; 380 return -1; 381 } 382 383 return _dbus_write_socket(fd, buffer, start, len); 384 #else 385 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds); 386 #endif 387 } 388 389 int 390 _dbus_write_socket_with_unix_fds_two(int fd, 391 const DBusString *buffer1, 392 int start1, 393 int len1, 394 const DBusString *buffer2, 395 int start2, 396 int len2, 397 const int *fds, 398 int n_fds) { 399 400 #ifndef HAVE_UNIX_FD_PASSING 401 402 if (n_fds > 0) { 403 errno = ENOTSUP; 404 return -1; 405 } 406 407 return _dbus_write_socket_two(fd, 408 buffer1, start1, len1, 409 buffer2, start2, len2); 410 #else 411 412 struct msghdr m; 413 struct cmsghdr *cm; 414 struct iovec iov[2]; 415 int bytes_written; 416 417 _dbus_assert (len1 >= 0); 418 _dbus_assert (len2 >= 0); 419 _dbus_assert (n_fds >= 0); 420 421 _DBUS_ZERO(iov); 422 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1); 423 iov[0].iov_len = len1; 424 425 if (buffer2) 426 { 427 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2); 428 iov[1].iov_len = len2; 429 } 430 431 _DBUS_ZERO(m); 432 m.msg_iov = iov; 433 m.msg_iovlen = buffer2 ? 2 : 1; 434 435 if (n_fds > 0) 436 { 437 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int)); 438 m.msg_control = alloca(m.msg_controllen); 439 memset(m.msg_control, 0, m.msg_controllen); 440 441 cm = CMSG_FIRSTHDR(&m); 442 cm->cmsg_level = SOL_SOCKET; 443 cm->cmsg_type = SCM_RIGHTS; 444 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int)); 445 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int)); 446 } 447 448 again: 449 450 bytes_written = sendmsg (fd, &m, 0 451 #ifdef MSG_NOSIGNAL 452 |MSG_NOSIGNAL 453 #endif 454 ); 455 456 if (bytes_written < 0 && errno == EINTR) 457 goto again; 458 459 #if 0 460 if (bytes_written > 0) 461 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 462 #endif 463 464 return bytes_written; 465 #endif 466 } 467 468 /** 469 * Like _dbus_write_two() but only works on sockets and is thus 470 * available on Windows. 471 * 472 * @param fd the file descriptor 473 * @param buffer1 first buffer 474 * @param start1 first byte to write in first buffer 475 * @param len1 number of bytes to write from first buffer 476 * @param buffer2 second buffer, or #NULL 477 * @param start2 first byte to write in second buffer 478 * @param len2 number of bytes to write in second buffer 479 * @returns total bytes written from both buffers, or -1 on error 480 */ 481 int 482 _dbus_write_socket_two (int fd, 483 const DBusString *buffer1, 484 int start1, 485 int len1, 486 const DBusString *buffer2, 487 int start2, 488 int len2) 489 { 490 #ifdef MSG_NOSIGNAL 491 struct iovec vectors[2]; 492 const char *data1; 493 const char *data2; 494 int bytes_written; 495 struct msghdr m; 496 497 _dbus_assert (buffer1 != NULL); 498 _dbus_assert (start1 >= 0); 499 _dbus_assert (start2 >= 0); 500 _dbus_assert (len1 >= 0); 501 _dbus_assert (len2 >= 0); 502 503 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 504 505 if (buffer2 != NULL) 506 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 507 else 508 { 509 data2 = NULL; 510 start2 = 0; 511 len2 = 0; 512 } 513 514 vectors[0].iov_base = (char*) data1; 515 vectors[0].iov_len = len1; 516 vectors[1].iov_base = (char*) data2; 517 vectors[1].iov_len = len2; 518 519 _DBUS_ZERO(m); 520 m.msg_iov = vectors; 521 m.msg_iovlen = data2 ? 2 : 1; 522 523 again: 524 525 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL); 526 527 if (bytes_written < 0 && errno == EINTR) 528 goto again; 529 530 return bytes_written; 531 532 #else 533 return _dbus_write_two (fd, buffer1, start1, len1, 534 buffer2, start2, len2); 535 #endif 536 } 537 538 dbus_bool_t 539 _dbus_socket_is_invalid (int fd) 540 { 541 return fd < 0 ? TRUE : FALSE; 542 } 543 544 /** 545 * Thin wrapper around the read() system call that appends 546 * the data it reads to the DBusString buffer. It appends 547 * up to the given count, and returns the same value 548 * and same errno as read(). The only exception is that 549 * _dbus_read() handles EINTR for you. Also, _dbus_read() can 550 * return ENOMEM, even though regular UNIX read doesn't. 551 * 552 * Unlike _dbus_read_socket(), _dbus_read() is not available 553 * on Windows. 554 * 555 * @param fd the file descriptor to read from 556 * @param buffer the buffer to append data to 557 * @param count the amount of data to read 558 * @returns the number of bytes read or -1 559 */ 560 int 561 _dbus_read (int fd, 562 DBusString *buffer, 563 int count) 564 { 565 int bytes_read; 566 int start; 567 char *data; 568 569 _dbus_assert (count >= 0); 570 571 start = _dbus_string_get_length (buffer); 572 573 if (!_dbus_string_lengthen (buffer, count)) 574 { 575 errno = ENOMEM; 576 return -1; 577 } 578 579 data = _dbus_string_get_data_len (buffer, start, count); 580 581 again: 582 583 bytes_read = read (fd, data, count); 584 585 if (bytes_read < 0) 586 { 587 if (errno == EINTR) 588 goto again; 589 else 590 { 591 /* put length back (note that this doesn't actually realloc anything) */ 592 _dbus_string_set_length (buffer, start); 593 return -1; 594 } 595 } 596 else 597 { 598 /* put length back (doesn't actually realloc) */ 599 _dbus_string_set_length (buffer, start + bytes_read); 600 601 #if 0 602 if (bytes_read > 0) 603 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 604 #endif 605 606 return bytes_read; 607 } 608 } 609 610 /** 611 * Thin wrapper around the write() system call that writes a part of a 612 * DBusString and handles EINTR for you. 613 * 614 * @param fd the file descriptor to write 615 * @param buffer the buffer to write data from 616 * @param start the first byte in the buffer to write 617 * @param len the number of bytes to try to write 618 * @returns the number of bytes written or -1 on error 619 */ 620 int 621 _dbus_write (int fd, 622 const DBusString *buffer, 623 int start, 624 int len) 625 { 626 const char *data; 627 int bytes_written; 628 629 data = _dbus_string_get_const_data_len (buffer, start, len); 630 631 again: 632 633 bytes_written = write (fd, data, len); 634 635 if (bytes_written < 0 && errno == EINTR) 636 goto again; 637 638 #if 0 639 if (bytes_written > 0) 640 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 641 #endif 642 643 return bytes_written; 644 } 645 646 /** 647 * Like _dbus_write() but will use writev() if possible 648 * to write both buffers in sequence. The return value 649 * is the number of bytes written in the first buffer, 650 * plus the number written in the second. If the first 651 * buffer is written successfully and an error occurs 652 * writing the second, the number of bytes in the first 653 * is returned (i.e. the error is ignored), on systems that 654 * don't have writev. Handles EINTR for you. 655 * The second buffer may be #NULL. 656 * 657 * @param fd the file descriptor 658 * @param buffer1 first buffer 659 * @param start1 first byte to write in first buffer 660 * @param len1 number of bytes to write from first buffer 661 * @param buffer2 second buffer, or #NULL 662 * @param start2 first byte to write in second buffer 663 * @param len2 number of bytes to write in second buffer 664 * @returns total bytes written from both buffers, or -1 on error 665 */ 666 int 667 _dbus_write_two (int fd, 668 const DBusString *buffer1, 669 int start1, 670 int len1, 671 const DBusString *buffer2, 672 int start2, 673 int len2) 674 { 675 _dbus_assert (buffer1 != NULL); 676 _dbus_assert (start1 >= 0); 677 _dbus_assert (start2 >= 0); 678 _dbus_assert (len1 >= 0); 679 _dbus_assert (len2 >= 0); 680 681 #ifdef HAVE_WRITEV 682 { 683 struct iovec vectors[2]; 684 const char *data1; 685 const char *data2; 686 int bytes_written; 687 688 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 689 690 if (buffer2 != NULL) 691 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 692 else 693 { 694 data2 = NULL; 695 start2 = 0; 696 len2 = 0; 697 } 698 699 vectors[0].iov_base = (char*) data1; 700 vectors[0].iov_len = len1; 701 vectors[1].iov_base = (char*) data2; 702 vectors[1].iov_len = len2; 703 704 again: 705 706 bytes_written = writev (fd, 707 vectors, 708 data2 ? 2 : 1); 709 710 if (bytes_written < 0 && errno == EINTR) 711 goto again; 712 713 return bytes_written; 714 } 715 #else /* HAVE_WRITEV */ 716 { 717 int ret1; 718 719 ret1 = _dbus_write (fd, buffer1, start1, len1); 720 if (ret1 == len1 && buffer2 != NULL) 721 { 722 ret2 = _dbus_write (fd, buffer2, start2, len2); 723 if (ret2 < 0) 724 ret2 = 0; /* we can't report an error as the first write was OK */ 725 726 return ret1 + ret2; 727 } 728 else 729 return ret1; 730 } 731 #endif /* !HAVE_WRITEV */ 732 } 733 734 #define _DBUS_MAX_SUN_PATH_LENGTH 99 735 736 /** 737 * @def _DBUS_MAX_SUN_PATH_LENGTH 738 * 739 * Maximum length of the path to a UNIX domain socket, 740 * sockaddr_un::sun_path member. POSIX requires that all systems 741 * support at least 100 bytes here, including the nul termination. 742 * We use 99 for the max value to allow for the nul. 743 * 744 * We could probably also do sizeof (addr.sun_path) 745 * but this way we are the same on all platforms 746 * which is probably a good idea. 747 */ 748 749 /** 750 * Creates a socket and connects it to the UNIX domain socket at the 751 * given path. The connection fd is returned, and is set up as 752 * nonblocking. 753 * 754 * Uses abstract sockets instead of filesystem-linked sockets if 755 * requested (it's possible only on Linux; see "man 7 unix" on Linux). 756 * On non-Linux abstract socket usage always fails. 757 * 758 * This will set FD_CLOEXEC for the socket returned. 759 * 760 * @param path the path to UNIX domain socket 761 * @param abstract #TRUE to use abstract namespace 762 * @param error return location for error code 763 * @returns connection file descriptor or -1 on error 764 */ 765 int 766 _dbus_connect_unix_socket (const char *path, 767 dbus_bool_t abstract, 768 DBusError *error) 769 { 770 int fd; 771 size_t path_len; 772 struct sockaddr_un addr; 773 774 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 775 776 _dbus_verbose ("connecting to unix socket %s abstract=%d\n", 777 path, abstract); 778 779 780 if (!_dbus_open_unix_socket (&fd, error)) 781 { 782 _DBUS_ASSERT_ERROR_IS_SET(error); 783 return -1; 784 } 785 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 786 787 _DBUS_ZERO (addr); 788 addr.sun_family = AF_UNIX; 789 path_len = strlen (path); 790 791 if (abstract) 792 { 793 #ifdef HAVE_ABSTRACT_SOCKETS 794 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 795 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 796 797 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 798 { 799 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 800 "Abstract socket name too long\n"); 801 _dbus_close (fd, NULL); 802 return -1; 803 } 804 805 strncpy (&addr.sun_path[1], path, path_len); 806 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 807 #else /* HAVE_ABSTRACT_SOCKETS */ 808 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 809 "Operating system does not support abstract socket namespace\n"); 810 _dbus_close (fd, NULL); 811 return -1; 812 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 813 } 814 else 815 { 816 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 817 { 818 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 819 "Socket name too long\n"); 820 _dbus_close (fd, NULL); 821 return -1; 822 } 823 824 strncpy (addr.sun_path, path, path_len); 825 } 826 827 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 828 { 829 dbus_set_error (error, 830 _dbus_error_from_errno (errno), 831 "Failed to connect to socket %s: %s", 832 path, _dbus_strerror (errno)); 833 834 _dbus_close (fd, NULL); 835 fd = -1; 836 837 return -1; 838 } 839 840 if (!_dbus_set_fd_nonblocking (fd, error)) 841 { 842 _DBUS_ASSERT_ERROR_IS_SET (error); 843 844 _dbus_close (fd, NULL); 845 fd = -1; 846 847 return -1; 848 } 849 850 return fd; 851 } 852 853 /** 854 * Enables or disables the reception of credentials on the given socket during 855 * the next message transmission. This is only effective if the #LOCAL_CREDS 856 * system feature exists, in which case the other side of the connection does 857 * not have to do anything special to send the credentials. 858 * 859 * @param fd socket on which to change the #LOCAL_CREDS flag. 860 * @param on whether to enable or disable the #LOCAL_CREDS flag. 861 */ 862 static dbus_bool_t 863 _dbus_set_local_creds (int fd, dbus_bool_t on) 864 { 865 dbus_bool_t retval = TRUE; 866 867 #if defined(HAVE_CMSGCRED) 868 /* NOOP just to make sure only one codepath is used 869 * and to prefer CMSGCRED 870 */ 871 #elif defined(LOCAL_CREDS) 872 int val = on ? 1 : 0; 873 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0) 874 { 875 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd); 876 retval = FALSE; 877 } 878 else 879 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n", 880 on ? "enabled" : "disabled", fd); 881 #endif 882 883 return retval; 884 } 885 886 /** 887 * Creates a socket and binds it to the given path, 888 * then listens on the socket. The socket is 889 * set to be nonblocking. 890 * 891 * Uses abstract sockets instead of filesystem-linked 892 * sockets if requested (it's possible only on Linux; 893 * see "man 7 unix" on Linux). 894 * On non-Linux abstract socket usage always fails. 895 * 896 * This will set FD_CLOEXEC for the socket returned 897 * 898 * @param path the socket name 899 * @param abstract #TRUE to use abstract namespace 900 * @param error return location for errors 901 * @returns the listening file descriptor or -1 on error 902 */ 903 int 904 _dbus_listen_unix_socket (const char *path, 905 dbus_bool_t abstract, 906 DBusError *error) 907 { 908 int listen_fd; 909 struct sockaddr_un addr; 910 size_t path_len; 911 unsigned int reuseaddr; 912 913 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 914 915 _dbus_verbose ("listening on unix socket %s abstract=%d\n", 916 path, abstract); 917 #ifdef ANDROID_MANAGED_SOCKET 918 if (strncmp (path, ANDROID_SOCKET_DIR"/", strlen(ANDROID_SOCKET_DIR"/")) == 0) 919 { 920 const char* suffix; 921 /* init has created a socket for us, pick it up from environ */ 922 suffix = &path[strlen (ANDROID_SOCKET_DIR"/")]; 923 listen_fd = android_get_control_socket (suffix); 924 if (listen_fd == -1) 925 { 926 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 927 "Could not obtain fd for android socket %s\n", suffix); 928 return -1; 929 } 930 931 _dbus_verbose ("Obtained fd for android socket %s\n", suffix); 932 } 933 else 934 { 935 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 936 "Not an android socket: %s\n", path); 937 return -1; 938 } 939 #else 940 941 if (!_dbus_open_unix_socket (&listen_fd, error)) 942 { 943 _DBUS_ASSERT_ERROR_IS_SET(error); 944 return -1; 945 } 946 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 947 948 _DBUS_ZERO (addr); 949 addr.sun_family = AF_UNIX; 950 path_len = strlen (path); 951 952 if (abstract) 953 { 954 #ifdef HAVE_ABSTRACT_SOCKETS 955 /* remember that abstract names aren't nul-terminated so we rely 956 * on sun_path being filled in with zeroes above. 957 */ 958 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 959 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 960 961 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 962 { 963 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 964 "Abstract socket name too long\n"); 965 _dbus_close (listen_fd, NULL); 966 return -1; 967 } 968 969 strncpy (&addr.sun_path[1], path, path_len); 970 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 971 #else /* HAVE_ABSTRACT_SOCKETS */ 972 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 973 "Operating system does not support abstract socket namespace\n"); 974 _dbus_close (listen_fd, NULL); 975 return -1; 976 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 977 } 978 else 979 { 980 /* Discussed security implications of this with Nalin, 981 * and we couldn't think of where it would kick our ass, but 982 * it still seems a bit sucky. It also has non-security suckage; 983 * really we'd prefer to exit if the socket is already in use. 984 * But there doesn't seem to be a good way to do this. 985 * 986 * Just to be extra careful, I threw in the stat() - clearly 987 * the stat() can't *fix* any security issue, but it at least 988 * avoids inadvertent/accidental data loss. 989 */ 990 { 991 struct stat sb; 992 993 if (stat (path, &sb) == 0 && 994 S_ISSOCK (sb.st_mode)) 995 unlink (path); 996 } 997 998 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 999 { 1000 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 1001 "Abstract socket name too long\n"); 1002 _dbus_close (listen_fd, NULL); 1003 return -1; 1004 } 1005 1006 strncpy (addr.sun_path, path, path_len); 1007 } 1008 1009 reuseaddr = 1; 1010 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 1011 { 1012 _dbus_warn ("Failed to set socket option\"%s\": %s", 1013 path, _dbus_strerror (errno)); 1014 } 1015 1016 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 1017 { 1018 dbus_set_error (error, _dbus_error_from_errno (errno), 1019 "Failed to bind socket \"%s\": %s", 1020 path, _dbus_strerror (errno)); 1021 _dbus_close (listen_fd, NULL); 1022 return -1; 1023 } 1024 1025 #endif /* android init managed sockets */ 1026 1027 if (listen (listen_fd, 30 /* backlog */) < 0) 1028 { 1029 dbus_set_error (error, _dbus_error_from_errno (errno), 1030 "Failed to listen on socket \"%s\": %s", 1031 path, _dbus_strerror (errno)); 1032 _dbus_close (listen_fd, NULL); 1033 return -1; 1034 } 1035 1036 if (!_dbus_set_local_creds (listen_fd, TRUE)) 1037 { 1038 dbus_set_error (error, _dbus_error_from_errno (errno), 1039 "Failed to enable LOCAL_CREDS on socket \"%s\": %s", 1040 path, _dbus_strerror (errno)); 1041 close (listen_fd); 1042 return -1; 1043 } 1044 1045 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 1046 { 1047 _DBUS_ASSERT_ERROR_IS_SET (error); 1048 _dbus_close (listen_fd, NULL); 1049 return -1; 1050 } 1051 1052 #ifndef ANDROID_MANAGED_SOCKET 1053 /* Try opening up the permissions, but if we can't, just go ahead 1054 * and continue, maybe it will be good enough. 1055 */ 1056 if (!abstract && chmod (path, 0777) < 0) 1057 _dbus_warn ("Could not set mode 0777 on socket %s\n", 1058 path); 1059 #endif 1060 1061 return listen_fd; 1062 } 1063 1064 /** 1065 * Acquires one or more sockets passed in from systemd. The sockets 1066 * are set to be nonblocking. 1067 * 1068 * This will set FD_CLOEXEC for the sockets returned. 1069 * 1070 * @oaram fds the file descriptors 1071 * @param error return location for errors 1072 * @returns the number of file descriptors 1073 */ 1074 int 1075 _dbus_listen_systemd_sockets (int **fds, 1076 DBusError *error) 1077 { 1078 int r, n; 1079 unsigned fd; 1080 int *new_fds; 1081 1082 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1083 1084 n = sd_listen_fds (TRUE); 1085 if (n < 0) 1086 { 1087 dbus_set_error (error, _dbus_error_from_errno (-n), 1088 "Failed to acquire systemd socket: %s", 1089 _dbus_strerror (-n)); 1090 return -1; 1091 } 1092 1093 if (n <= 0) 1094 { 1095 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 1096 "No socket received."); 1097 return -1; 1098 } 1099 1100 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 1101 { 1102 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1); 1103 if (r < 0) 1104 { 1105 dbus_set_error (error, _dbus_error_from_errno (-r), 1106 "Failed to verify systemd socket type: %s", 1107 _dbus_strerror (-r)); 1108 return -1; 1109 } 1110 1111 if (!r) 1112 { 1113 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 1114 "Passed socket has wrong type."); 1115 return -1; 1116 } 1117 } 1118 1119 /* OK, the file descriptors are all good, so let's take posession of 1120 them then. */ 1121 1122 new_fds = dbus_new (int, n); 1123 if (!new_fds) 1124 { 1125 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 1126 "Failed to allocate file handle array."); 1127 goto fail; 1128 } 1129 1130 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 1131 { 1132 if (!_dbus_set_local_creds (fd, TRUE)) 1133 { 1134 dbus_set_error (error, _dbus_error_from_errno (errno), 1135 "Failed to enable LOCAL_CREDS on systemd socket: %s", 1136 _dbus_strerror (errno)); 1137 goto fail; 1138 } 1139 1140 if (!_dbus_set_fd_nonblocking (fd, error)) 1141 { 1142 _DBUS_ASSERT_ERROR_IS_SET (error); 1143 goto fail; 1144 } 1145 1146 new_fds[fd - SD_LISTEN_FDS_START] = fd; 1147 } 1148 1149 *fds = new_fds; 1150 return n; 1151 1152 fail: 1153 1154 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 1155 { 1156 _dbus_close (fd, NULL); 1157 } 1158 1159 dbus_free (new_fds); 1160 return -1; 1161 } 1162 1163 /** 1164 * Creates a socket and connects to a socket at the given host 1165 * and port. The connection fd is returned, and is set up as 1166 * nonblocking. 1167 * 1168 * This will set FD_CLOEXEC for the socket returned 1169 * 1170 * @param host the host name to connect to 1171 * @param port the port to connect to 1172 * @param family the address family to listen on, NULL for all 1173 * @param error return location for error code 1174 * @returns connection file descriptor or -1 on error 1175 */ 1176 int 1177 _dbus_connect_tcp_socket (const char *host, 1178 const char *port, 1179 const char *family, 1180 DBusError *error) 1181 { 1182 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error); 1183 } 1184 1185 int 1186 _dbus_connect_tcp_socket_with_nonce (const char *host, 1187 const char *port, 1188 const char *family, 1189 const char *noncefile, 1190 DBusError *error) 1191 { 1192 int saved_errno = 0; 1193 int fd = -1, res; 1194 struct addrinfo hints; 1195 struct addrinfo *ai, *tmp; 1196 1197 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1198 1199 if (!_dbus_open_tcp_socket (&fd, error)) 1200 { 1201 _DBUS_ASSERT_ERROR_IS_SET(error); 1202 return -1; 1203 } 1204 1205 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 1206 1207 _DBUS_ZERO (hints); 1208 1209 if (!family) 1210 hints.ai_family = AF_UNSPEC; 1211 else if (!strcmp(family, "ipv4")) 1212 hints.ai_family = AF_INET; 1213 else if (!strcmp(family, "ipv6")) 1214 hints.ai_family = AF_INET6; 1215 else 1216 { 1217 dbus_set_error (error, 1218 DBUS_ERROR_BAD_ADDRESS, 1219 "Unknown address family %s", family); 1220 return -1; 1221 } 1222 hints.ai_protocol = IPPROTO_TCP; 1223 hints.ai_socktype = SOCK_STREAM; 1224 hints.ai_flags = AI_ADDRCONFIG; 1225 1226 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0) 1227 { 1228 dbus_set_error (error, 1229 _dbus_error_from_errno (errno), 1230 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 1231 host, port, gai_strerror(res), res); 1232 _dbus_close (fd, NULL); 1233 return -1; 1234 } 1235 1236 tmp = ai; 1237 while (tmp) 1238 { 1239 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 1240 { 1241 freeaddrinfo(ai); 1242 _DBUS_ASSERT_ERROR_IS_SET(error); 1243 return -1; 1244 } 1245 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 1246 1247 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 1248 { 1249 saved_errno = errno; 1250 _dbus_close(fd, NULL); 1251 fd = -1; 1252 tmp = tmp->ai_next; 1253 continue; 1254 } 1255 1256 break; 1257 } 1258 freeaddrinfo(ai); 1259 1260 if (fd == -1) 1261 { 1262 dbus_set_error (error, 1263 _dbus_error_from_errno (saved_errno), 1264 "Failed to connect to socket \"%s:%s\" %s", 1265 host, port, _dbus_strerror(saved_errno)); 1266 return -1; 1267 } 1268 1269 if (noncefile != NULL) 1270 { 1271 DBusString noncefileStr; 1272 dbus_bool_t ret; 1273 _dbus_string_init_const (&noncefileStr, noncefile); 1274 ret = _dbus_send_nonce (fd, &noncefileStr, error); 1275 _dbus_string_free (&noncefileStr); 1276 1277 if (!ret) 1278 { 1279 _dbus_close (fd, NULL); 1280 return -1; 1281 } 1282 } 1283 1284 if (!_dbus_set_fd_nonblocking (fd, error)) 1285 { 1286 _dbus_close (fd, NULL); 1287 return -1; 1288 } 1289 1290 return fd; 1291 } 1292 1293 /** 1294 * Creates a socket and binds it to the given path, then listens on 1295 * the socket. The socket is set to be nonblocking. In case of port=0 1296 * a random free port is used and returned in the port parameter. 1297 * If inaddr_any is specified, the hostname is ignored. 1298 * 1299 * This will set FD_CLOEXEC for the socket returned 1300 * 1301 * @param host the host name to listen on 1302 * @param port the port to listen on, if zero a free port will be used 1303 * @param family the address family to listen on, NULL for all 1304 * @param retport string to return the actual port listened on 1305 * @param fds_p location to store returned file descriptors 1306 * @param error return location for errors 1307 * @returns the number of listening file descriptors or -1 on error 1308 */ 1309 int 1310 _dbus_listen_tcp_socket (const char *host, 1311 const char *port, 1312 const char *family, 1313 DBusString *retport, 1314 int **fds_p, 1315 DBusError *error) 1316 { 1317 int saved_errno; 1318 int nlisten_fd = 0, *listen_fd = NULL, res, i; 1319 struct addrinfo hints; 1320 struct addrinfo *ai, *tmp; 1321 unsigned int reuseaddr; 1322 1323 *fds_p = NULL; 1324 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1325 1326 _DBUS_ZERO (hints); 1327 1328 if (!family) 1329 hints.ai_family = AF_UNSPEC; 1330 else if (!strcmp(family, "ipv4")) 1331 hints.ai_family = AF_INET; 1332 else if (!strcmp(family, "ipv6")) 1333 hints.ai_family = AF_INET6; 1334 else 1335 { 1336 dbus_set_error (error, 1337 DBUS_ERROR_BAD_ADDRESS, 1338 "Unknown address family %s", family); 1339 return -1; 1340 } 1341 1342 hints.ai_protocol = IPPROTO_TCP; 1343 hints.ai_socktype = SOCK_STREAM; 1344 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; 1345 1346 redo_lookup_with_port: 1347 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai) 1348 { 1349 dbus_set_error (error, 1350 _dbus_error_from_errno (errno), 1351 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 1352 host ? host : "*", port, gai_strerror(res), res); 1353 return -1; 1354 } 1355 1356 tmp = ai; 1357 while (tmp) 1358 { 1359 int fd = -1, *newlisten_fd; 1360 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 1361 { 1362 _DBUS_ASSERT_ERROR_IS_SET(error); 1363 goto failed; 1364 } 1365 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 1366 1367 reuseaddr = 1; 1368 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 1369 { 1370 _dbus_warn ("Failed to set socket option \"%s:%s\": %s", 1371 host ? host : "*", port, _dbus_strerror (errno)); 1372 } 1373 1374 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 1375 { 1376 saved_errno = errno; 1377 _dbus_close(fd, NULL); 1378 if (saved_errno == EADDRINUSE) 1379 { 1380 /* Depending on kernel policy, it may or may not 1381 be neccessary to bind to both IPv4 & 6 addresses 1382 so ignore EADDRINUSE here */ 1383 tmp = tmp->ai_next; 1384 continue; 1385 } 1386 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 1387 "Failed to bind socket \"%s:%s\": %s", 1388 host ? host : "*", port, _dbus_strerror (saved_errno)); 1389 goto failed; 1390 } 1391 1392 if (listen (fd, 30 /* backlog */) < 0) 1393 { 1394 saved_errno = errno; 1395 _dbus_close (fd, NULL); 1396 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 1397 "Failed to listen on socket \"%s:%s\": %s", 1398 host ? host : "*", port, _dbus_strerror (saved_errno)); 1399 goto failed; 1400 } 1401 1402 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); 1403 if (!newlisten_fd) 1404 { 1405 saved_errno = errno; 1406 _dbus_close (fd, NULL); 1407 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 1408 "Failed to allocate file handle array: %s", 1409 _dbus_strerror (saved_errno)); 1410 goto failed; 1411 } 1412 listen_fd = newlisten_fd; 1413 listen_fd[nlisten_fd] = fd; 1414 nlisten_fd++; 1415 1416 if (!_dbus_string_get_length(retport)) 1417 { 1418 /* If the user didn't specify a port, or used 0, then 1419 the kernel chooses a port. After the first address 1420 is bound to, we need to force all remaining addresses 1421 to use the same port */ 1422 if (!port || !strcmp(port, "0")) 1423 { 1424 struct sockaddr_storage addr; 1425 socklen_t addrlen; 1426 char portbuf[50]; 1427 1428 addrlen = sizeof(addr); 1429 getsockname(fd, (struct sockaddr*) &addr, &addrlen); 1430 1431 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0, 1432 portbuf, sizeof(portbuf), 1433 NI_NUMERICHOST)) != 0) 1434 { 1435 dbus_set_error (error, _dbus_error_from_errno (errno), 1436 "Failed to resolve port \"%s:%s\": %s (%s)", 1437 host ? host : "*", port, gai_strerror(res), res); 1438 goto failed; 1439 } 1440 if (!_dbus_string_append(retport, portbuf)) 1441 { 1442 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1443 goto failed; 1444 } 1445 1446 /* Release current address list & redo lookup */ 1447 port = _dbus_string_get_const_data(retport); 1448 freeaddrinfo(ai); 1449 goto redo_lookup_with_port; 1450 } 1451 else 1452 { 1453 if (!_dbus_string_append(retport, port)) 1454 { 1455 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1456 goto failed; 1457 } 1458 } 1459 } 1460 1461 tmp = tmp->ai_next; 1462 } 1463 freeaddrinfo(ai); 1464 ai = NULL; 1465 1466 if (!nlisten_fd) 1467 { 1468 errno = EADDRINUSE; 1469 dbus_set_error (error, _dbus_error_from_errno (errno), 1470 "Failed to bind socket \"%s:%s\": %s", 1471 host ? host : "*", port, _dbus_strerror (errno)); 1472 return -1; 1473 } 1474 1475 for (i = 0 ; i < nlisten_fd ; i++) 1476 { 1477 if (!_dbus_set_fd_nonblocking (listen_fd[i], error)) 1478 { 1479 goto failed; 1480 } 1481 } 1482 1483 *fds_p = listen_fd; 1484 1485 return nlisten_fd; 1486 1487 failed: 1488 if (ai) 1489 freeaddrinfo(ai); 1490 for (i = 0 ; i < nlisten_fd ; i++) 1491 _dbus_close(listen_fd[i], NULL); 1492 dbus_free(listen_fd); 1493 return -1; 1494 } 1495 1496 static dbus_bool_t 1497 write_credentials_byte (int server_fd, 1498 DBusError *error) 1499 { 1500 int bytes_written; 1501 char buf[1] = { '\0' }; 1502 #if defined(HAVE_CMSGCRED) 1503 union { 1504 struct cmsghdr hdr; 1505 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 1506 } cmsg; 1507 struct iovec iov; 1508 struct msghdr msg; 1509 iov.iov_base = buf; 1510 iov.iov_len = 1; 1511 1512 _DBUS_ZERO(msg); 1513 msg.msg_iov = &iov; 1514 msg.msg_iovlen = 1; 1515 1516 msg.msg_control = (caddr_t) &cmsg; 1517 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 1518 _DBUS_ZERO(cmsg); 1519 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); 1520 cmsg.hdr.cmsg_level = SOL_SOCKET; 1521 cmsg.hdr.cmsg_type = SCM_CREDS; 1522 #endif 1523 1524 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1525 1526 again: 1527 1528 #if defined(HAVE_CMSGCRED) 1529 bytes_written = sendmsg (server_fd, &msg, 0); 1530 #else 1531 bytes_written = write (server_fd, buf, 1); 1532 #endif 1533 1534 if (bytes_written < 0 && errno == EINTR) 1535 goto again; 1536 1537 if (bytes_written < 0) 1538 { 1539 dbus_set_error (error, _dbus_error_from_errno (errno), 1540 "Failed to write credentials byte: %s", 1541 _dbus_strerror (errno)); 1542 return FALSE; 1543 } 1544 else if (bytes_written == 0) 1545 { 1546 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 1547 "wrote zero bytes writing credentials byte"); 1548 return FALSE; 1549 } 1550 else 1551 { 1552 _dbus_assert (bytes_written == 1); 1553 _dbus_verbose ("wrote credentials byte\n"); 1554 return TRUE; 1555 } 1556 } 1557 1558 /** 1559 * Reads a single byte which must be nul (an error occurs otherwise), 1560 * and reads unix credentials if available. Clears the credentials 1561 * object, then adds pid/uid if available, so any previous credentials 1562 * stored in the object are lost. 1563 * 1564 * Return value indicates whether a byte was read, not whether 1565 * we got valid credentials. On some systems, such as Linux, 1566 * reading/writing the byte isn't actually required, but we do it 1567 * anyway just to avoid multiple codepaths. 1568 * 1569 * Fails if no byte is available, so you must select() first. 1570 * 1571 * The point of the byte is that on some systems we have to 1572 * use sendmsg()/recvmsg() to transmit credentials. 1573 * 1574 * @param client_fd the client file descriptor 1575 * @param credentials object to add client credentials to 1576 * @param error location to store error code 1577 * @returns #TRUE on success 1578 */ 1579 dbus_bool_t 1580 _dbus_read_credentials_socket (int client_fd, 1581 DBusCredentials *credentials, 1582 DBusError *error) 1583 { 1584 struct msghdr msg; 1585 struct iovec iov; 1586 char buf; 1587 dbus_uid_t uid_read; 1588 dbus_pid_t pid_read; 1589 int bytes_read; 1590 1591 #ifdef HAVE_CMSGCRED 1592 union { 1593 struct cmsghdr hdr; 1594 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 1595 } cmsg; 1596 1597 #elif defined(LOCAL_CREDS) 1598 struct { 1599 struct cmsghdr hdr; 1600 struct sockcred cred; 1601 } cmsg; 1602 #endif 1603 1604 uid_read = DBUS_UID_UNSET; 1605 pid_read = DBUS_PID_UNSET; 1606 1607 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1608 1609 /* The POSIX spec certainly doesn't promise this, but 1610 * we need these assertions to fail as soon as we're wrong about 1611 * it so we can do the porting fixups 1612 */ 1613 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 1614 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 1615 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 1616 1617 _dbus_credentials_clear (credentials); 1618 1619 /* Systems supporting LOCAL_CREDS are configured to have this feature 1620 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting 1621 * the connection. Therefore, the received message must carry the 1622 * credentials information without doing anything special. 1623 */ 1624 1625 iov.iov_base = &buf; 1626 iov.iov_len = 1; 1627 1628 _DBUS_ZERO(msg); 1629 msg.msg_iov = &iov; 1630 msg.msg_iovlen = 1; 1631 1632 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 1633 _DBUS_ZERO(cmsg); 1634 msg.msg_control = (caddr_t) &cmsg; 1635 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 1636 #endif 1637 1638 again: 1639 bytes_read = recvmsg (client_fd, &msg, 0); 1640 1641 if (bytes_read < 0) 1642 { 1643 if (errno == EINTR) 1644 goto again; 1645 1646 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would 1647 * normally only call read_credentials if the socket was ready 1648 * for reading 1649 */ 1650 1651 dbus_set_error (error, _dbus_error_from_errno (errno), 1652 "Failed to read credentials byte: %s", 1653 _dbus_strerror (errno)); 1654 return FALSE; 1655 } 1656 else if (bytes_read == 0) 1657 { 1658 /* this should not happen unless we are using recvmsg wrong, 1659 * so is essentially here for paranoia 1660 */ 1661 dbus_set_error (error, DBUS_ERROR_FAILED, 1662 "Failed to read credentials byte (zero-length read)"); 1663 return FALSE; 1664 } 1665 else if (buf != '\0') 1666 { 1667 dbus_set_error (error, DBUS_ERROR_FAILED, 1668 "Credentials byte was not nul"); 1669 return FALSE; 1670 } 1671 1672 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 1673 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) 1674 || cmsg.hdr.cmsg_type != SCM_CREDS) 1675 { 1676 dbus_set_error (error, DBUS_ERROR_FAILED, 1677 "Message from recvmsg() was not SCM_CREDS"); 1678 return FALSE; 1679 } 1680 #endif 1681 1682 _dbus_verbose ("read credentials byte\n"); 1683 1684 { 1685 #ifdef SO_PEERCRED 1686 struct ucred cr; 1687 int cr_len = sizeof (cr); 1688 1689 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && 1690 cr_len == sizeof (cr)) 1691 { 1692 pid_read = cr.pid; 1693 uid_read = cr.uid; 1694 } 1695 else 1696 { 1697 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", 1698 cr_len, (int) sizeof (cr), _dbus_strerror (errno)); 1699 } 1700 #elif defined(HAVE_CMSGCRED) 1701 struct cmsgcred *cred; 1702 1703 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr); 1704 pid_read = cred->cmcred_pid; 1705 uid_read = cred->cmcred_euid; 1706 #elif defined(LOCAL_CREDS) 1707 pid_read = DBUS_PID_UNSET; 1708 uid_read = cmsg.cred.sc_uid; 1709 /* Since we have already got the credentials from this socket, we can 1710 * disable its LOCAL_CREDS flag if it was ever set. */ 1711 _dbus_set_local_creds (client_fd, FALSE); 1712 #elif defined(HAVE_GETPEEREID) 1713 uid_t euid; 1714 gid_t egid; 1715 if (getpeereid (client_fd, &euid, &egid) == 0) 1716 { 1717 uid_read = euid; 1718 } 1719 else 1720 { 1721 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno)); 1722 } 1723 #elif defined(HAVE_GETPEERUCRED) 1724 ucred_t * ucred = NULL; 1725 if (getpeerucred (client_fd, &ucred) == 0) 1726 { 1727 pid_read = ucred_getpid (ucred); 1728 uid_read = ucred_geteuid (ucred); 1729 #ifdef HAVE_ADT 1730 /* generate audit session data based on socket ucred */ 1731 adt_session_data_t *adth = NULL; 1732 adt_export_data_t *data = NULL; 1733 size_t size = 0; 1734 if (adt_start_session (&adth, NULL, 0) || (adth == NULL)) 1735 { 1736 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno)); 1737 } 1738 else 1739 { 1740 if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 1741 { 1742 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno)); 1743 } 1744 else 1745 { 1746 size = adt_export_session_data (adth, &data); 1747 if (size <= 0) 1748 { 1749 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno)); 1750 } 1751 else 1752 { 1753 _dbus_credentials_add_adt_audit_data (credentials, data, size); 1754 free (data); 1755 } 1756 } 1757 (void) adt_end_session (adth); 1758 } 1759 #endif /* HAVE_ADT */ 1760 } 1761 else 1762 { 1763 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno)); 1764 } 1765 if (ucred != NULL) 1766 ucred_free (ucred); 1767 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ 1768 _dbus_verbose ("Socket credentials not supported on this OS\n"); 1769 #endif 1770 } 1771 1772 _dbus_verbose ("Credentials:" 1773 " pid "DBUS_PID_FORMAT 1774 " uid "DBUS_UID_FORMAT 1775 "\n", 1776 pid_read, 1777 uid_read); 1778 1779 if (pid_read != DBUS_PID_UNSET) 1780 { 1781 if (!_dbus_credentials_add_unix_pid (credentials, pid_read)) 1782 { 1783 _DBUS_SET_OOM (error); 1784 return FALSE; 1785 } 1786 } 1787 1788 if (uid_read != DBUS_UID_UNSET) 1789 { 1790 if (!_dbus_credentials_add_unix_uid (credentials, uid_read)) 1791 { 1792 _DBUS_SET_OOM (error); 1793 return FALSE; 1794 } 1795 } 1796 1797 return TRUE; 1798 } 1799 1800 /** 1801 * Sends a single nul byte with our UNIX credentials as ancillary 1802 * data. Returns #TRUE if the data was successfully written. On 1803 * systems that don't support sending credentials, just writes a byte, 1804 * doesn't send any credentials. On some systems, such as Linux, 1805 * reading/writing the byte isn't actually required, but we do it 1806 * anyway just to avoid multiple codepaths. 1807 * 1808 * Fails if no byte can be written, so you must select() first. 1809 * 1810 * The point of the byte is that on some systems we have to 1811 * use sendmsg()/recvmsg() to transmit credentials. 1812 * 1813 * @param server_fd file descriptor for connection to server 1814 * @param error return location for error code 1815 * @returns #TRUE if the byte was sent 1816 */ 1817 dbus_bool_t 1818 _dbus_send_credentials_socket (int server_fd, 1819 DBusError *error) 1820 { 1821 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1822 1823 if (write_credentials_byte (server_fd, error)) 1824 return TRUE; 1825 else 1826 return FALSE; 1827 } 1828 1829 /** 1830 * Accepts a connection on a listening socket. 1831 * Handles EINTR for you. 1832 * 1833 * This will enable FD_CLOEXEC for the returned socket. 1834 * 1835 * @param listen_fd the listen file descriptor 1836 * @returns the connection fd of the client, or -1 on error 1837 */ 1838 int 1839 _dbus_accept (int listen_fd) 1840 { 1841 int client_fd; 1842 struct sockaddr addr; 1843 socklen_t addrlen; 1844 #ifdef HAVE_ACCEPT4 1845 dbus_bool_t cloexec_done; 1846 #endif 1847 1848 addrlen = sizeof (addr); 1849 1850 retry: 1851 1852 #ifdef HAVE_ACCEPT4 1853 /* We assume that if accept4 is available SOCK_CLOEXEC is too */ 1854 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC); 1855 cloexec_done = client_fd >= 0; 1856 1857 if (client_fd < 0 && errno == ENOSYS) 1858 #endif 1859 { 1860 client_fd = accept (listen_fd, &addr, &addrlen); 1861 } 1862 1863 if (client_fd < 0) 1864 { 1865 if (errno == EINTR) 1866 goto retry; 1867 } 1868 1869 _dbus_verbose ("client fd %d accepted\n", client_fd); 1870 1871 #ifdef HAVE_ACCEPT4 1872 if (!cloexec_done) 1873 #endif 1874 { 1875 _dbus_fd_set_close_on_exec(client_fd); 1876 } 1877 1878 return client_fd; 1879 } 1880 1881 /** 1882 * Checks to make sure the given directory is 1883 * private to the user 1884 * 1885 * @param dir the name of the directory 1886 * @param error error return 1887 * @returns #FALSE on failure 1888 **/ 1889 dbus_bool_t 1890 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) 1891 { 1892 const char *directory; 1893 struct stat sb; 1894 1895 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1896 1897 directory = _dbus_string_get_const_data (dir); 1898 1899 if (stat (directory, &sb) < 0) 1900 { 1901 dbus_set_error (error, _dbus_error_from_errno (errno), 1902 "%s", _dbus_strerror (errno)); 1903 1904 return FALSE; 1905 } 1906 1907 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) || 1908 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode)) 1909 { 1910 dbus_set_error (error, DBUS_ERROR_FAILED, 1911 "%s directory is not private to the user", directory); 1912 return FALSE; 1913 } 1914 1915 return TRUE; 1916 } 1917 1918 static dbus_bool_t 1919 fill_user_info_from_passwd (struct passwd *p, 1920 DBusUserInfo *info, 1921 DBusError *error) 1922 { 1923 _dbus_assert (p->pw_name != NULL); 1924 _dbus_assert (p->pw_dir != NULL); 1925 1926 info->uid = p->pw_uid; 1927 info->primary_gid = p->pw_gid; 1928 info->username = _dbus_strdup (p->pw_name); 1929 info->homedir = _dbus_strdup (p->pw_dir); 1930 1931 if (info->username == NULL || 1932 info->homedir == NULL) 1933 { 1934 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1935 return FALSE; 1936 } 1937 1938 return TRUE; 1939 } 1940 1941 static dbus_bool_t 1942 fill_user_info (DBusUserInfo *info, 1943 dbus_uid_t uid, 1944 const DBusString *username, 1945 DBusError *error) 1946 { 1947 const char *username_c; 1948 1949 /* exactly one of username/uid provided */ 1950 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET); 1951 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET); 1952 1953 info->uid = DBUS_UID_UNSET; 1954 info->primary_gid = DBUS_GID_UNSET; 1955 info->group_ids = NULL; 1956 info->n_group_ids = 0; 1957 info->username = NULL; 1958 info->homedir = NULL; 1959 1960 if (username != NULL) 1961 username_c = _dbus_string_get_const_data (username); 1962 else 1963 username_c = NULL; 1964 1965 /* For now assuming that the getpwnam() and getpwuid() flavors 1966 * are always symmetrical, if not we have to add more configure 1967 * checks 1968 */ 1969 1970 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R) 1971 { 1972 struct passwd *p; 1973 int result; 1974 size_t buflen; 1975 char *buf; 1976 struct passwd p_str; 1977 1978 /* retrieve maximum needed size for buf */ 1979 buflen = sysconf (_SC_GETPW_R_SIZE_MAX); 1980 1981 /* sysconf actually returns a long, but everything else expects size_t, 1982 * so just recast here. 1983 * https://bugs.freedesktop.org/show_bug.cgi?id=17061 1984 */ 1985 if ((long) buflen <= 0) 1986 buflen = 1024; 1987 1988 result = -1; 1989 while (1) 1990 { 1991 buf = dbus_malloc (buflen); 1992 if (buf == NULL) 1993 { 1994 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1995 return FALSE; 1996 } 1997 1998 p = NULL; 1999 #ifdef HAVE_POSIX_GETPWNAM_R 2000 if (uid != DBUS_UID_UNSET) 2001 result = getpwuid_r (uid, &p_str, buf, buflen, 2002 &p); 2003 else 2004 result = getpwnam_r (username_c, &p_str, buf, buflen, 2005 &p); 2006 #else 2007 if (uid != DBUS_UID_UNSET) 2008 p = getpwuid_r (uid, &p_str, buf, buflen); 2009 else 2010 p = getpwnam_r (username_c, &p_str, buf, buflen); 2011 result = 0; 2012 #endif /* !HAVE_POSIX_GETPWNAM_R */ 2013 //Try a bigger buffer if ERANGE was returned 2014 if (result == ERANGE && buflen < 512 * 1024) 2015 { 2016 dbus_free (buf); 2017 buflen *= 2; 2018 } 2019 else 2020 { 2021 break; 2022 } 2023 } 2024 if (result == 0 && p == &p_str) 2025 { 2026 if (!fill_user_info_from_passwd (p, info, error)) 2027 { 2028 dbus_free (buf); 2029 return FALSE; 2030 } 2031 dbus_free (buf); 2032 } 2033 else 2034 { 2035 dbus_set_error (error, _dbus_error_from_errno (errno), 2036 "User \"%s\" unknown or no memory to allocate password entry\n", 2037 username_c ? username_c : "???"); 2038 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 2039 dbus_free (buf); 2040 return FALSE; 2041 } 2042 } 2043 #else /* ! HAVE_GETPWNAM_R */ 2044 { 2045 /* I guess we're screwed on thread safety here */ 2046 struct passwd *p; 2047 2048 if (uid != DBUS_UID_UNSET) 2049 p = getpwuid (uid); 2050 else 2051 p = getpwnam (username_c); 2052 2053 if (p != NULL) 2054 { 2055 if (!fill_user_info_from_passwd (p, info, error)) 2056 { 2057 return FALSE; 2058 } 2059 } 2060 else 2061 { 2062 dbus_set_error (error, _dbus_error_from_errno (errno), 2063 "User \"%s\" unknown or no memory to allocate password entry\n", 2064 username_c ? username_c : "???"); 2065 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 2066 return FALSE; 2067 } 2068 } 2069 #endif /* ! HAVE_GETPWNAM_R */ 2070 2071 /* Fill this in so we can use it to get groups */ 2072 username_c = info->username; 2073 2074 #ifdef HAVE_GETGROUPLIST 2075 { 2076 gid_t *buf; 2077 int buf_count; 2078 int i; 2079 int initial_buf_count; 2080 2081 initial_buf_count = 17; 2082 buf_count = initial_buf_count; 2083 buf = dbus_new (gid_t, buf_count); 2084 if (buf == NULL) 2085 { 2086 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 2087 goto failed; 2088 } 2089 2090 if (getgrouplist (username_c, 2091 info->primary_gid, 2092 buf, &buf_count) < 0) 2093 { 2094 gid_t *new; 2095 /* Presumed cause of negative return code: buf has insufficient 2096 entries to hold the entire group list. The Linux behavior in this 2097 case is to pass back the actual number of groups in buf_count, but 2098 on Mac OS X 10.5, buf_count is unhelpfully left alone. 2099 So as a hack, try to help out a bit by guessing a larger 2100 number of groups, within reason.. might still fail, of course, 2101 but we can at least print a more informative message. I looked up 2102 the "right way" to do this by downloading Apple's own source code 2103 for the "id" command, and it turns out that they use an 2104 undocumented library function getgrouplist_2 (!) which is not 2105 declared in any header in /usr/include (!!). That did not seem 2106 like the way to go here. 2107 */ 2108 if (buf_count == initial_buf_count) 2109 { 2110 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */ 2111 } 2112 new = dbus_realloc (buf, buf_count * sizeof (buf[0])); 2113 if (new == NULL) 2114 { 2115 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 2116 dbus_free (buf); 2117 goto failed; 2118 } 2119 2120 buf = new; 2121 2122 errno = 0; 2123 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0) 2124 { 2125 if (errno == 0) 2126 { 2127 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.", 2128 username_c, buf_count, buf_count); 2129 } 2130 else 2131 { 2132 dbus_set_error (error, 2133 _dbus_error_from_errno (errno), 2134 "Failed to get groups for username \"%s\" primary GID " 2135 DBUS_GID_FORMAT ": %s\n", 2136 username_c, info->primary_gid, 2137 _dbus_strerror (errno)); 2138 dbus_free (buf); 2139 goto failed; 2140 } 2141 } 2142 } 2143 2144 info->group_ids = dbus_new (dbus_gid_t, buf_count); 2145 if (info->group_ids == NULL) 2146 { 2147 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 2148 dbus_free (buf); 2149 goto failed; 2150 } 2151 2152 for (i = 0; i < buf_count; ++i) 2153 info->group_ids[i] = buf[i]; 2154 2155 info->n_group_ids = buf_count; 2156 2157 dbus_free (buf); 2158 } 2159 #else /* HAVE_GETGROUPLIST */ 2160 { 2161 /* We just get the one group ID */ 2162 info->group_ids = dbus_new (dbus_gid_t, 1); 2163 if (info->group_ids == NULL) 2164 { 2165 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 2166 goto failed; 2167 } 2168 2169 info->n_group_ids = 1; 2170 2171 (info->group_ids)[0] = info->primary_gid; 2172 } 2173 #endif /* HAVE_GETGROUPLIST */ 2174 2175 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2176 2177 return TRUE; 2178 2179 failed: 2180 _DBUS_ASSERT_ERROR_IS_SET (error); 2181 return FALSE; 2182 } 2183 2184 /** 2185 * Gets user info for the given username. 2186 * 2187 * @param info user info object to initialize 2188 * @param username the username 2189 * @param error error return 2190 * @returns #TRUE on success 2191 */ 2192 dbus_bool_t 2193 _dbus_user_info_fill (DBusUserInfo *info, 2194 const DBusString *username, 2195 DBusError *error) 2196 { 2197 return fill_user_info (info, DBUS_UID_UNSET, 2198 username, error); 2199 } 2200 2201 /** 2202 * Gets user info for the given user ID. 2203 * 2204 * @param info user info object to initialize 2205 * @param uid the user ID 2206 * @param error error return 2207 * @returns #TRUE on success 2208 */ 2209 dbus_bool_t 2210 _dbus_user_info_fill_uid (DBusUserInfo *info, 2211 dbus_uid_t uid, 2212 DBusError *error) 2213 { 2214 return fill_user_info (info, uid, 2215 NULL, error); 2216 } 2217 2218 /** 2219 * Adds the credentials of the current process to the 2220 * passed-in credentials object. 2221 * 2222 * @param credentials credentials to add to 2223 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added 2224 */ 2225 dbus_bool_t 2226 _dbus_credentials_add_from_current_process (DBusCredentials *credentials) 2227 { 2228 /* The POSIX spec certainly doesn't promise this, but 2229 * we need these assertions to fail as soon as we're wrong about 2230 * it so we can do the porting fixups 2231 */ 2232 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 2233 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 2234 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 2235 2236 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) 2237 return FALSE; 2238 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid())) 2239 return FALSE; 2240 2241 return TRUE; 2242 } 2243 2244 /** 2245 * Append to the string the identity we would like to have when we 2246 * authenticate, on UNIX this is the current process UID and on 2247 * Windows something else, probably a Windows SID string. No escaping 2248 * is required, that is done in dbus-auth.c. The username here 2249 * need not be anything human-readable, it can be the machine-readable 2250 * form i.e. a user id. 2251 * 2252 * @param str the string to append to 2253 * @returns #FALSE on no memory 2254 */ 2255 dbus_bool_t 2256 _dbus_append_user_from_current_process (DBusString *str) 2257 { 2258 return _dbus_string_append_uint (str, 2259 _dbus_geteuid ()); 2260 } 2261 2262 /** 2263 * Gets our process ID 2264 * @returns process ID 2265 */ 2266 dbus_pid_t 2267 _dbus_getpid (void) 2268 { 2269 return getpid (); 2270 } 2271 2272 /** Gets our UID 2273 * @returns process UID 2274 */ 2275 dbus_uid_t 2276 _dbus_getuid (void) 2277 { 2278 return getuid (); 2279 } 2280 2281 /** Gets our effective UID 2282 * @returns process effective UID 2283 */ 2284 dbus_uid_t 2285 _dbus_geteuid (void) 2286 { 2287 return geteuid (); 2288 } 2289 2290 /** 2291 * The only reason this is separate from _dbus_getpid() is to allow it 2292 * on Windows for logging but not for other purposes. 2293 * 2294 * @returns process ID to put in log messages 2295 */ 2296 unsigned long 2297 _dbus_pid_for_log (void) 2298 { 2299 return getpid (); 2300 } 2301 2302 /** 2303 * Gets a UID from a UID string. 2304 * 2305 * @param uid_str the UID in string form 2306 * @param uid UID to fill in 2307 * @returns #TRUE if successfully filled in UID 2308 */ 2309 dbus_bool_t 2310 _dbus_parse_uid (const DBusString *uid_str, 2311 dbus_uid_t *uid) 2312 { 2313 int end; 2314 long val; 2315 2316 if (_dbus_string_get_length (uid_str) == 0) 2317 { 2318 _dbus_verbose ("UID string was zero length\n"); 2319 return FALSE; 2320 } 2321 2322 val = -1; 2323 end = 0; 2324 if (!_dbus_string_parse_int (uid_str, 0, &val, 2325 &end)) 2326 { 2327 _dbus_verbose ("could not parse string as a UID\n"); 2328 return FALSE; 2329 } 2330 2331 if (end != _dbus_string_get_length (uid_str)) 2332 { 2333 _dbus_verbose ("string contained trailing stuff after UID\n"); 2334 return FALSE; 2335 } 2336 2337 *uid = val; 2338 2339 return TRUE; 2340 } 2341 2342 #if !DBUS_USE_SYNC 2343 _DBUS_DEFINE_GLOBAL_LOCK (atomic); 2344 #endif 2345 2346 /** 2347 * Atomically increments an integer 2348 * 2349 * @param atomic pointer to the integer to increment 2350 * @returns the value before incrementing 2351 */ 2352 dbus_int32_t 2353 _dbus_atomic_inc (DBusAtomic *atomic) 2354 { 2355 #if DBUS_USE_SYNC 2356 return __sync_add_and_fetch(&atomic->value, 1)-1; 2357 #elif defined(ANDROID_ATOMIC) 2358 return android_atomic_inc (&(atomic->value)); 2359 #else 2360 dbus_int32_t res; 2361 _DBUS_LOCK (atomic); 2362 res = atomic->value; 2363 atomic->value += 1; 2364 _DBUS_UNLOCK (atomic); 2365 return res; 2366 #endif 2367 } 2368 2369 /** 2370 * Atomically decrement an integer 2371 * 2372 * @param atomic pointer to the integer to decrement 2373 * @returns the value before decrementing 2374 */ 2375 dbus_int32_t 2376 _dbus_atomic_dec (DBusAtomic *atomic) 2377 { 2378 #if DBUS_USE_SYNC 2379 return __sync_sub_and_fetch(&atomic->value, 1)+1; 2380 #elif defined(ANDROID_ATOMIC) 2381 return android_atomic_dec (&(atomic->value)); 2382 #else 2383 dbus_int32_t res; 2384 2385 _DBUS_LOCK (atomic); 2386 res = atomic->value; 2387 atomic->value -= 1; 2388 _DBUS_UNLOCK (atomic); 2389 return res; 2390 #endif 2391 } 2392 2393 #ifdef DBUS_BUILD_TESTS 2394 /** Gets our GID 2395 * @returns process GID 2396 */ 2397 dbus_gid_t 2398 _dbus_getgid (void) 2399 { 2400 return getgid (); 2401 } 2402 #endif 2403 2404 /** 2405 * Wrapper for poll(). 2406 * 2407 * @param fds the file descriptors to poll 2408 * @param n_fds number of descriptors in the array 2409 * @param timeout_milliseconds timeout or -1 for infinite 2410 * @returns numbers of fds with revents, or <0 on error 2411 */ 2412 int 2413 _dbus_poll (DBusPollFD *fds, 2414 int n_fds, 2415 int timeout_milliseconds) 2416 { 2417 #if defined(HAVE_POLL) && !defined(BROKEN_POLL) 2418 /* This big thing is a constant expression and should get optimized 2419 * out of existence. So it's more robust than a configure check at 2420 * no cost. 2421 */ 2422 if (_DBUS_POLLIN == POLLIN && 2423 _DBUS_POLLPRI == POLLPRI && 2424 _DBUS_POLLOUT == POLLOUT && 2425 _DBUS_POLLERR == POLLERR && 2426 _DBUS_POLLHUP == POLLHUP && 2427 _DBUS_POLLNVAL == POLLNVAL && 2428 sizeof (DBusPollFD) == sizeof (struct pollfd) && 2429 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) == 2430 _DBUS_STRUCT_OFFSET (struct pollfd, fd) && 2431 _DBUS_STRUCT_OFFSET (DBusPollFD, events) == 2432 _DBUS_STRUCT_OFFSET (struct pollfd, events) && 2433 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == 2434 _DBUS_STRUCT_OFFSET (struct pollfd, revents)) 2435 { 2436 return poll ((struct pollfd*) fds, 2437 n_fds, 2438 timeout_milliseconds); 2439 } 2440 else 2441 { 2442 /* We have to convert the DBusPollFD to an array of 2443 * struct pollfd, poll, and convert back. 2444 */ 2445 _dbus_warn ("didn't implement poll() properly for this system yet\n"); 2446 return -1; 2447 } 2448 #else /* ! HAVE_POLL */ 2449 2450 fd_set read_set, write_set, err_set; 2451 int max_fd = 0; 2452 int i; 2453 struct timeval tv; 2454 int ready; 2455 2456 FD_ZERO (&read_set); 2457 FD_ZERO (&write_set); 2458 FD_ZERO (&err_set); 2459 2460 for (i = 0; i < n_fds; i++) 2461 { 2462 DBusPollFD *fdp = &fds[i]; 2463 2464 if (fdp->events & _DBUS_POLLIN) 2465 FD_SET (fdp->fd, &read_set); 2466 2467 if (fdp->events & _DBUS_POLLOUT) 2468 FD_SET (fdp->fd, &write_set); 2469 2470 FD_SET (fdp->fd, &err_set); 2471 2472 max_fd = MAX (max_fd, fdp->fd); 2473 } 2474 2475 tv.tv_sec = timeout_milliseconds / 1000; 2476 tv.tv_usec = (timeout_milliseconds % 1000) * 1000; 2477 2478 ready = select (max_fd + 1, &read_set, &write_set, &err_set, 2479 timeout_milliseconds < 0 ? NULL : &tv); 2480 2481 if (ready > 0) 2482 { 2483 for (i = 0; i < n_fds; i++) 2484 { 2485 DBusPollFD *fdp = &fds[i]; 2486 2487 fdp->revents = 0; 2488 2489 if (FD_ISSET (fdp->fd, &read_set)) 2490 fdp->revents |= _DBUS_POLLIN; 2491 2492 if (FD_ISSET (fdp->fd, &write_set)) 2493 fdp->revents |= _DBUS_POLLOUT; 2494 2495 if (FD_ISSET (fdp->fd, &err_set)) 2496 fdp->revents |= _DBUS_POLLERR; 2497 } 2498 } 2499 2500 return ready; 2501 #endif 2502 } 2503 2504 /** 2505 * Get current time, as in gettimeofday(). Use the monotonic clock if 2506 * available, to avoid problems when the system time changes. 2507 * 2508 * @param tv_sec return location for number of seconds 2509 * @param tv_usec return location for number of microseconds (thousandths) 2510 */ 2511 void 2512 _dbus_get_current_time (long *tv_sec, 2513 long *tv_usec) 2514 { 2515 struct timeval t; 2516 2517 #ifdef HAVE_MONOTONIC_CLOCK 2518 struct timespec ts; 2519 clock_gettime (CLOCK_MONOTONIC, &ts); 2520 2521 if (tv_sec) 2522 *tv_sec = ts.tv_sec; 2523 if (tv_usec) 2524 *tv_usec = ts.tv_nsec / 1000; 2525 #else 2526 gettimeofday (&t, NULL); 2527 2528 if (tv_sec) 2529 *tv_sec = t.tv_sec; 2530 if (tv_usec) 2531 *tv_usec = t.tv_usec; 2532 #endif 2533 } 2534 2535 /** 2536 * Creates a directory; succeeds if the directory 2537 * is created or already existed. 2538 * 2539 * @param filename directory filename 2540 * @param error initialized error object 2541 * @returns #TRUE on success 2542 */ 2543 dbus_bool_t 2544 _dbus_create_directory (const DBusString *filename, 2545 DBusError *error) 2546 { 2547 const char *filename_c; 2548 2549 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2550 2551 filename_c = _dbus_string_get_const_data (filename); 2552 2553 if (mkdir (filename_c, 0700) < 0) 2554 { 2555 if (errno == EEXIST) 2556 return TRUE; 2557 2558 dbus_set_error (error, DBUS_ERROR_FAILED, 2559 "Failed to create directory %s: %s\n", 2560 filename_c, _dbus_strerror (errno)); 2561 return FALSE; 2562 } 2563 else 2564 return TRUE; 2565 } 2566 2567 /** 2568 * Appends the given filename to the given directory. 2569 * 2570 * @todo it might be cute to collapse multiple '/' such as "foo//" 2571 * concat "//bar" 2572 * 2573 * @param dir the directory name 2574 * @param next_component the filename 2575 * @returns #TRUE on success 2576 */ 2577 dbus_bool_t 2578 _dbus_concat_dir_and_file (DBusString *dir, 2579 const DBusString *next_component) 2580 { 2581 dbus_bool_t dir_ends_in_slash; 2582 dbus_bool_t file_starts_with_slash; 2583 2584 if (_dbus_string_get_length (dir) == 0 || 2585 _dbus_string_get_length (next_component) == 0) 2586 return TRUE; 2587 2588 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, 2589 _dbus_string_get_length (dir) - 1); 2590 2591 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); 2592 2593 if (dir_ends_in_slash && file_starts_with_slash) 2594 { 2595 _dbus_string_shorten (dir, 1); 2596 } 2597 else if (!(dir_ends_in_slash || file_starts_with_slash)) 2598 { 2599 if (!_dbus_string_append_byte (dir, '/')) 2600 return FALSE; 2601 } 2602 2603 return _dbus_string_copy (next_component, 0, dir, 2604 _dbus_string_get_length (dir)); 2605 } 2606 2607 /** nanoseconds in a second */ 2608 #define NANOSECONDS_PER_SECOND 1000000000 2609 /** microseconds in a second */ 2610 #define MICROSECONDS_PER_SECOND 1000000 2611 /** milliseconds in a second */ 2612 #define MILLISECONDS_PER_SECOND 1000 2613 /** nanoseconds in a millisecond */ 2614 #define NANOSECONDS_PER_MILLISECOND 1000000 2615 /** microseconds in a millisecond */ 2616 #define MICROSECONDS_PER_MILLISECOND 1000 2617 2618 /** 2619 * Sleeps the given number of milliseconds. 2620 * @param milliseconds number of milliseconds 2621 */ 2622 void 2623 _dbus_sleep_milliseconds (int milliseconds) 2624 { 2625 #ifdef HAVE_NANOSLEEP 2626 struct timespec req; 2627 struct timespec rem; 2628 2629 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND; 2630 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; 2631 rem.tv_sec = 0; 2632 rem.tv_nsec = 0; 2633 2634 while (nanosleep (&req, &rem) < 0 && errno == EINTR) 2635 req = rem; 2636 #elif defined (HAVE_USLEEP) 2637 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND); 2638 #else /* ! HAVE_USLEEP */ 2639 sleep (MAX (milliseconds / 1000, 1)); 2640 #endif 2641 } 2642 2643 static dbus_bool_t 2644 _dbus_generate_pseudorandom_bytes (DBusString *str, 2645 int n_bytes) 2646 { 2647 int old_len; 2648 char *p; 2649 2650 old_len = _dbus_string_get_length (str); 2651 2652 if (!_dbus_string_lengthen (str, n_bytes)) 2653 return FALSE; 2654 2655 p = _dbus_string_get_data_len (str, old_len, n_bytes); 2656 2657 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes); 2658 2659 return TRUE; 2660 } 2661 2662 /** 2663 * Generates the given number of random bytes, 2664 * using the best mechanism we can come up with. 2665 * 2666 * @param str the string 2667 * @param n_bytes the number of random bytes to append to string 2668 * @returns #TRUE on success, #FALSE if no memory 2669 */ 2670 dbus_bool_t 2671 _dbus_generate_random_bytes (DBusString *str, 2672 int n_bytes) 2673 { 2674 int old_len; 2675 int fd; 2676 2677 /* FALSE return means "no memory", if it could 2678 * mean something else then we'd need to return 2679 * a DBusError. So we always fall back to pseudorandom 2680 * if the I/O fails. 2681 */ 2682 2683 old_len = _dbus_string_get_length (str); 2684 fd = -1; 2685 2686 /* note, urandom on linux will fall back to pseudorandom */ 2687 fd = open ("/dev/urandom", O_RDONLY); 2688 if (fd < 0) 2689 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 2690 2691 _dbus_verbose ("/dev/urandom fd %d opened\n", fd); 2692 2693 if (_dbus_read (fd, str, n_bytes) != n_bytes) 2694 { 2695 _dbus_close (fd, NULL); 2696 _dbus_string_set_length (str, old_len); 2697 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 2698 } 2699 2700 _dbus_verbose ("Read %d bytes from /dev/urandom\n", 2701 n_bytes); 2702 2703 _dbus_close (fd, NULL); 2704 2705 return TRUE; 2706 } 2707 2708 /** 2709 * Exit the process, returning the given value. 2710 * 2711 * @param code the exit code 2712 */ 2713 void 2714 _dbus_exit (int code) 2715 { 2716 _exit (code); 2717 } 2718 2719 /** 2720 * A wrapper around strerror() because some platforms 2721 * may be lame and not have strerror(). Also, never 2722 * returns NULL. 2723 * 2724 * @param error_number errno. 2725 * @returns error description. 2726 */ 2727 const char* 2728 _dbus_strerror (int error_number) 2729 { 2730 const char *msg; 2731 2732 msg = strerror (error_number); 2733 if (msg == NULL) 2734 msg = "unknown"; 2735 2736 return msg; 2737 } 2738 2739 /** 2740 * signal (SIGPIPE, SIG_IGN); 2741 */ 2742 void 2743 _dbus_disable_sigpipe (void) 2744 { 2745 signal (SIGPIPE, SIG_IGN); 2746 } 2747 2748 /** 2749 * Sets the file descriptor to be close 2750 * on exec. Should be called for all file 2751 * descriptors in D-Bus code. 2752 * 2753 * @param fd the file descriptor 2754 */ 2755 void 2756 _dbus_fd_set_close_on_exec (intptr_t fd) 2757 { 2758 int val; 2759 2760 val = fcntl (fd, F_GETFD, 0); 2761 2762 if (val < 0) 2763 return; 2764 2765 val |= FD_CLOEXEC; 2766 2767 fcntl (fd, F_SETFD, val); 2768 } 2769 2770 /** 2771 * Closes a file descriptor. 2772 * 2773 * @param fd the file descriptor 2774 * @param error error object 2775 * @returns #FALSE if error set 2776 */ 2777 dbus_bool_t 2778 _dbus_close (int fd, 2779 DBusError *error) 2780 { 2781 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2782 2783 again: 2784 if (close (fd) < 0) 2785 { 2786 if (errno == EINTR) 2787 goto again; 2788 2789 dbus_set_error (error, _dbus_error_from_errno (errno), 2790 "Could not close fd %d", fd); 2791 return FALSE; 2792 } 2793 2794 return TRUE; 2795 } 2796 2797 /** 2798 * Duplicates a file descriptor. Makes sure the fd returned is >= 3 2799 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC. 2800 * 2801 * @param fd the file descriptor to duplicate 2802 * @returns duplicated file descriptor 2803 * */ 2804 int 2805 _dbus_dup(int fd, 2806 DBusError *error) 2807 { 2808 int new_fd; 2809 2810 #ifdef F_DUPFD_CLOEXEC 2811 dbus_bool_t cloexec_done; 2812 2813 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); 2814 cloexec_done = new_fd >= 0; 2815 2816 if (new_fd < 0 && errno == EINVAL) 2817 #endif 2818 { 2819 new_fd = fcntl(fd, F_DUPFD, 3); 2820 } 2821 2822 if (new_fd < 0) { 2823 2824 dbus_set_error (error, _dbus_error_from_errno (errno), 2825 "Could not duplicate fd %d", fd); 2826 return -1; 2827 } 2828 2829 #ifdef F_DUPFD_CLOEXEC 2830 if (!cloexec_done) 2831 #endif 2832 { 2833 _dbus_fd_set_close_on_exec(new_fd); 2834 } 2835 2836 return new_fd; 2837 } 2838 2839 /** 2840 * Sets a file descriptor to be nonblocking. 2841 * 2842 * @param fd the file descriptor. 2843 * @param error address of error location. 2844 * @returns #TRUE on success. 2845 */ 2846 dbus_bool_t 2847 _dbus_set_fd_nonblocking (int fd, 2848 DBusError *error) 2849 { 2850 int val; 2851 2852 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2853 2854 val = fcntl (fd, F_GETFL, 0); 2855 if (val < 0) 2856 { 2857 dbus_set_error (error, _dbus_error_from_errno (errno), 2858 "Failed to get flags from file descriptor %d: %s", 2859 fd, _dbus_strerror (errno)); 2860 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 2861 _dbus_strerror (errno)); 2862 return FALSE; 2863 } 2864 2865 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 2866 { 2867 dbus_set_error (error, _dbus_error_from_errno (errno), 2868 "Failed to set nonblocking flag of file descriptor %d: %s", 2869 fd, _dbus_strerror (errno)); 2870 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 2871 fd, _dbus_strerror (errno)); 2872 2873 return FALSE; 2874 } 2875 2876 return TRUE; 2877 } 2878 2879 /** 2880 * On GNU libc systems, print a crude backtrace to stderr. On other 2881 * systems, print "no backtrace support" and block for possible gdb 2882 * attachment if an appropriate environment variable is set. 2883 */ 2884 void 2885 _dbus_print_backtrace (void) 2886 { 2887 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC) 2888 void *bt[500]; 2889 int bt_size; 2890 int i; 2891 char **syms; 2892 2893 bt_size = backtrace (bt, 500); 2894 2895 syms = backtrace_symbols (bt, bt_size); 2896 2897 i = 0; 2898 while (i < bt_size) 2899 { 2900 /* don't use dbus_warn since it can _dbus_abort() */ 2901 fprintf (stderr, " %s\n", syms[i]); 2902 ++i; 2903 } 2904 fflush (stderr); 2905 2906 free (syms); 2907 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC) 2908 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n"); 2909 #else 2910 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n"); 2911 #endif 2912 } 2913 2914 /** 2915 * Creates a full-duplex pipe (as in socketpair()). 2916 * Sets both ends of the pipe nonblocking. 2917 * 2918 * Marks both file descriptors as close-on-exec 2919 * 2920 * @todo libdbus only uses this for the debug-pipe server, so in 2921 * principle it could be in dbus-sysdeps-util.c, except that 2922 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the 2923 * debug-pipe server is used. 2924 * 2925 * @param fd1 return location for one end 2926 * @param fd2 return location for the other end 2927 * @param blocking #TRUE if pipe should be blocking 2928 * @param error error return 2929 * @returns #FALSE on failure (if error is set) 2930 */ 2931 dbus_bool_t 2932 _dbus_full_duplex_pipe (int *fd1, 2933 int *fd2, 2934 dbus_bool_t blocking, 2935 DBusError *error) 2936 { 2937 #ifdef HAVE_SOCKETPAIR 2938 int fds[2]; 2939 int retval; 2940 2941 #ifdef SOCK_CLOEXEC 2942 dbus_bool_t cloexec_done; 2943 2944 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); 2945 cloexec_done = retval >= 0; 2946 2947 if (retval < 0 && errno == EINVAL) 2948 #endif 2949 { 2950 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 2951 } 2952 2953 if (retval < 0) 2954 { 2955 dbus_set_error (error, _dbus_error_from_errno (errno), 2956 "Could not create full-duplex pipe"); 2957 return FALSE; 2958 } 2959 2960 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2961 2962 #ifdef SOCK_CLOEXEC 2963 if (!cloexec_done) 2964 #endif 2965 { 2966 _dbus_fd_set_close_on_exec (fds[0]); 2967 _dbus_fd_set_close_on_exec (fds[1]); 2968 } 2969 2970 if (!blocking && 2971 (!_dbus_set_fd_nonblocking (fds[0], NULL) || 2972 !_dbus_set_fd_nonblocking (fds[1], NULL))) 2973 { 2974 dbus_set_error (error, _dbus_error_from_errno (errno), 2975 "Could not set full-duplex pipe nonblocking"); 2976 2977 _dbus_close (fds[0], NULL); 2978 _dbus_close (fds[1], NULL); 2979 2980 return FALSE; 2981 } 2982 2983 *fd1 = fds[0]; 2984 *fd2 = fds[1]; 2985 2986 _dbus_verbose ("full-duplex pipe %d <-> %d\n", 2987 *fd1, *fd2); 2988 2989 return TRUE; 2990 #else 2991 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n"); 2992 dbus_set_error (error, DBUS_ERROR_FAILED, 2993 "_dbus_full_duplex_pipe() not implemented on this OS"); 2994 return FALSE; 2995 #endif 2996 } 2997 2998 /** 2999 * Measure the length of the given format string and arguments, 3000 * not including the terminating nul. 3001 * 3002 * @param format a printf-style format string 3003 * @param args arguments for the format string 3004 * @returns length of the given format string and args 3005 */ 3006 int 3007 _dbus_printf_string_upper_bound (const char *format, 3008 va_list args) 3009 { 3010 char c; 3011 return vsnprintf (&c, 1, format, args); 3012 } 3013 3014 /** 3015 * Gets the temporary files directory by inspecting the environment variables 3016 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned 3017 * 3018 * @returns location of temp directory 3019 */ 3020 const char* 3021 _dbus_get_tmpdir(void) 3022 { 3023 static const char* tmpdir = NULL; 3024 3025 if (tmpdir == NULL) 3026 { 3027 /* TMPDIR is what glibc uses, then 3028 * glibc falls back to the P_tmpdir macro which 3029 * just expands to "/tmp" 3030 */ 3031 if (tmpdir == NULL) 3032 tmpdir = getenv("TMPDIR"); 3033 3034 /* These two env variables are probably 3035 * broken, but maybe some OS uses them? 3036 */ 3037 if (tmpdir == NULL) 3038 tmpdir = getenv("TMP"); 3039 if (tmpdir == NULL) 3040 tmpdir = getenv("TEMP"); 3041 3042 /* And this is the sane fallback. */ 3043 if (tmpdir == NULL) 3044 tmpdir = "/tmp"; 3045 } 3046 3047 _dbus_assert(tmpdir != NULL); 3048 3049 return tmpdir; 3050 } 3051 3052 /** 3053 * Execute a subprocess, returning up to 1024 bytes of output 3054 * into @p result. 3055 * 3056 * If successful, returns #TRUE and appends the output to @p 3057 * result. If a failure happens, returns #FALSE and 3058 * sets an error in @p error. 3059 * 3060 * @note It's not an error if the subprocess terminates normally 3061 * without writing any data to stdout. Verify the @p result length 3062 * before and after this function call to cover this case. 3063 * 3064 * @param progname initial path to exec (may or may not be absolute) 3065 * @param path_fallback if %TRUE, search PATH for executable 3066 * @param argv NULL-terminated list of arguments 3067 * @param result a DBusString where the output can be append 3068 * @param error a DBusError to store the error in case of failure 3069 * @returns #TRUE on success, #FALSE if an error happened 3070 */ 3071 static dbus_bool_t 3072 _read_subprocess_line_argv (const char *progpath, 3073 dbus_bool_t path_fallback, 3074 char * const *argv, 3075 DBusString *result, 3076 DBusError *error) 3077 { 3078 int result_pipe[2] = { -1, -1 }; 3079 int errors_pipe[2] = { -1, -1 }; 3080 pid_t pid; 3081 int ret; 3082 int status; 3083 int orig_len; 3084 int i; 3085 3086 dbus_bool_t retval; 3087 sigset_t new_set, old_set; 3088 3089 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 3090 retval = FALSE; 3091 3092 /* We need to block any existing handlers for SIGCHLD temporarily; they 3093 * will cause waitpid() below to fail. 3094 * https://bugs.freedesktop.org/show_bug.cgi?id=21347 3095 */ 3096 sigemptyset (&new_set); 3097 sigaddset (&new_set, SIGCHLD); 3098 sigprocmask (SIG_BLOCK, &new_set, &old_set); 3099 3100 orig_len = _dbus_string_get_length (result); 3101 3102 #define READ_END 0 3103 #define WRITE_END 1 3104 if (pipe (result_pipe) < 0) 3105 { 3106 dbus_set_error (error, _dbus_error_from_errno (errno), 3107 "Failed to create a pipe to call %s: %s", 3108 progpath, _dbus_strerror (errno)); 3109 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 3110 progpath, _dbus_strerror (errno)); 3111 goto out; 3112 } 3113 if (pipe (errors_pipe) < 0) 3114 { 3115 dbus_set_error (error, _dbus_error_from_errno (errno), 3116 "Failed to create a pipe to call %s: %s", 3117 progpath, _dbus_strerror (errno)); 3118 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 3119 progpath, _dbus_strerror (errno)); 3120 goto out; 3121 } 3122 3123 pid = fork (); 3124 if (pid < 0) 3125 { 3126 dbus_set_error (error, _dbus_error_from_errno (errno), 3127 "Failed to fork() to call %s: %s", 3128 progpath, _dbus_strerror (errno)); 3129 _dbus_verbose ("Failed to fork() to call %s: %s\n", 3130 progpath, _dbus_strerror (errno)); 3131 goto out; 3132 } 3133 3134 if (pid == 0) 3135 { 3136 /* child process */ 3137 int maxfds; 3138 int fd; 3139 3140 fd = open ("/dev/null", O_RDWR); 3141 if (fd == -1) 3142 /* huh?! can't open /dev/null? */ 3143 _exit (1); 3144 3145 _dbus_verbose ("/dev/null fd %d opened\n", fd); 3146 3147 /* set-up stdXXX */ 3148 close (result_pipe[READ_END]); 3149 close (errors_pipe[READ_END]); 3150 close (0); /* close stdin */ 3151 close (1); /* close stdout */ 3152 close (2); /* close stderr */ 3153 3154 if (dup2 (fd, 0) == -1) 3155 _exit (1); 3156 if (dup2 (result_pipe[WRITE_END], 1) == -1) 3157 _exit (1); 3158 if (dup2 (errors_pipe[WRITE_END], 2) == -1) 3159 _exit (1); 3160 3161 maxfds = sysconf (_SC_OPEN_MAX); 3162 /* Pick something reasonable if for some reason sysconf 3163 * says unlimited. 3164 */ 3165 if (maxfds < 0) 3166 maxfds = 1024; 3167 /* close all inherited fds */ 3168 for (i = 3; i < maxfds; i++) 3169 close (i); 3170 3171 sigprocmask (SIG_SETMASK, &old_set, NULL); 3172 3173 /* If it looks fully-qualified, try execv first */ 3174 if (progpath[0] == '/') 3175 { 3176 execv (progpath, argv); 3177 /* Ok, that failed. Now if path_fallback is given, let's 3178 * try unqualified. This is mostly a hack to work 3179 * around systems which ship dbus-launch in /usr/bin 3180 * but everything else in /bin (because dbus-launch 3181 * depends on X11). 3182 */ 3183 if (path_fallback) 3184 /* We must have a slash, because we checked above */ 3185 execvp (strrchr (progpath, '/')+1, argv); 3186 } 3187 else 3188 execvp (progpath, argv); 3189 3190 /* still nothing, we failed */ 3191 _exit (1); 3192 } 3193 3194 /* parent process */ 3195 close (result_pipe[WRITE_END]); 3196 close (errors_pipe[WRITE_END]); 3197 result_pipe[WRITE_END] = -1; 3198 errors_pipe[WRITE_END] = -1; 3199 3200 ret = 0; 3201 do 3202 { 3203 ret = _dbus_read (result_pipe[READ_END], result, 1024); 3204 } 3205 while (ret > 0); 3206 3207 /* reap the child process to avoid it lingering as zombie */ 3208 do 3209 { 3210 ret = waitpid (pid, &status, 0); 3211 } 3212 while (ret == -1 && errno == EINTR); 3213 3214 /* We succeeded if the process exited with status 0 and 3215 anything was read */ 3216 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ) 3217 { 3218 /* The process ended with error */ 3219 DBusString error_message; 3220 _dbus_string_init (&error_message); 3221 ret = 0; 3222 do 3223 { 3224 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024); 3225 } 3226 while (ret > 0); 3227 3228 _dbus_string_set_length (result, orig_len); 3229 if (_dbus_string_get_length (&error_message) > 0) 3230 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 3231 "%s terminated abnormally with the following error: %s", 3232 progpath, _dbus_string_get_data (&error_message)); 3233 else 3234 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 3235 "%s terminated abnormally without any error message", 3236 progpath); 3237 goto out; 3238 } 3239 3240 retval = TRUE; 3241 3242 out: 3243 sigprocmask (SIG_SETMASK, &old_set, NULL); 3244 3245 if (retval) 3246 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 3247 else 3248 _DBUS_ASSERT_ERROR_IS_SET (error); 3249 3250 if (result_pipe[0] != -1) 3251 close (result_pipe[0]); 3252 if (result_pipe[1] != -1) 3253 close (result_pipe[1]); 3254 if (errors_pipe[0] != -1) 3255 close (errors_pipe[0]); 3256 if (errors_pipe[1] != -1) 3257 close (errors_pipe[1]); 3258 3259 return retval; 3260 } 3261 3262 /** 3263 * Returns the address of a new session bus. 3264 * 3265 * If successful, returns #TRUE and appends the address to @p 3266 * address. If a failure happens, returns #FALSE and 3267 * sets an error in @p error. 3268 * 3269 * @param address a DBusString where the address can be stored 3270 * @param error a DBusError to store the error in case of failure 3271 * @returns #TRUE on success, #FALSE if an error happened 3272 */ 3273 dbus_bool_t 3274 _dbus_get_autolaunch_address (DBusString *address, 3275 DBusError *error) 3276 { 3277 static char *argv[6]; 3278 int i; 3279 DBusString uuid; 3280 dbus_bool_t retval; 3281 3282 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 3283 retval = FALSE; 3284 3285 if (!_dbus_string_init (&uuid)) 3286 { 3287 _DBUS_SET_OOM (error); 3288 return FALSE; 3289 } 3290 3291 if (!_dbus_get_local_machine_uuid_encoded (&uuid)) 3292 { 3293 _DBUS_SET_OOM (error); 3294 goto out; 3295 } 3296 3297 i = 0; 3298 argv[i] = "dbus-launch"; 3299 ++i; 3300 argv[i] = "--autolaunch"; 3301 ++i; 3302 argv[i] = _dbus_string_get_data (&uuid); 3303 ++i; 3304 argv[i] = "--binary-syntax"; 3305 ++i; 3306 argv[i] = "--close-stderr"; 3307 ++i; 3308 argv[i] = NULL; 3309 ++i; 3310 3311 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 3312 3313 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch", 3314 TRUE, 3315 argv, address, error); 3316 3317 out: 3318 _dbus_string_free (&uuid); 3319 return retval; 3320 } 3321 3322 /** 3323 * Reads the uuid of the machine we're running on from 3324 * the dbus configuration. Optionally try to create it 3325 * (only root can do this usually). 3326 * 3327 * On UNIX, reads a file that gets created by dbus-uuidgen 3328 * in a post-install script. On Windows, if there's a standard 3329 * machine uuid we could just use that, but I can't find one 3330 * with the right properties (the hardware profile guid can change 3331 * without rebooting I believe). If there's no standard one 3332 * we might want to use the registry instead of a file for 3333 * this, and I'm not sure how we'd ensure the uuid gets created. 3334 * 3335 * @param machine_id guid to init with the machine's uuid 3336 * @param create_if_not_found try to create the uuid if it doesn't exist 3337 * @param error the error return 3338 * @returns #FALSE if the error is set 3339 */ 3340 dbus_bool_t 3341 _dbus_read_local_machine_uuid (DBusGUID *machine_id, 3342 dbus_bool_t create_if_not_found, 3343 DBusError *error) 3344 { 3345 DBusString filename; 3346 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE); 3347 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error); 3348 } 3349 3350 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" 3351 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" 3352 3353 /** 3354 * Determines the address of the session bus by querying a 3355 * platform-specific method. 3356 * 3357 * The first parameter will be a boolean specifying whether 3358 * or not a dynamic session lookup is supported on this platform. 3359 * 3360 * If supported is TRUE and the return value is #TRUE, the 3361 * address will be appended to @p address. 3362 * If a failure happens, returns #FALSE and sets an error in 3363 * @p error. 3364 * 3365 * If supported is FALSE, ignore the return value. 3366 * 3367 * @param supported returns whether this method is supported 3368 * @param address a DBusString where the address can be stored 3369 * @param error a DBusError to store the error in case of failure 3370 * @returns #TRUE on success, #FALSE if an error happened 3371 */ 3372 dbus_bool_t 3373 _dbus_lookup_session_address (dbus_bool_t *supported, 3374 DBusString *address, 3375 DBusError *error) 3376 { 3377 /* On non-Mac Unix platforms, if the session address isn't already 3378 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and 3379 * fall back to the autolaunch: global default; see 3380 * init_session_address in dbus/dbus-bus.c. */ 3381 *supported = FALSE; 3382 return TRUE; 3383 } 3384 3385 /** 3386 * Returns the standard directories for a session bus to look for service 3387 * activation files 3388 * 3389 * On UNIX this should be the standard xdg freedesktop.org data directories: 3390 * 3391 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share} 3392 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share} 3393 * 3394 * and 3395 * 3396 * DBUS_DATADIR 3397 * 3398 * @param dirs the directory list we are returning 3399 * @returns #FALSE on OOM 3400 */ 3401 3402 dbus_bool_t 3403 _dbus_get_standard_session_servicedirs (DBusList **dirs) 3404 { 3405 const char *xdg_data_home; 3406 const char *xdg_data_dirs; 3407 DBusString servicedir_path; 3408 3409 if (!_dbus_string_init (&servicedir_path)) 3410 return FALSE; 3411 3412 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); 3413 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 3414 3415 if (xdg_data_dirs != NULL) 3416 { 3417 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 3418 goto oom; 3419 3420 if (!_dbus_string_append (&servicedir_path, ":")) 3421 goto oom; 3422 } 3423 else 3424 { 3425 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 3426 goto oom; 3427 } 3428 3429 /* 3430 * add configured datadir to defaults 3431 * this may be the same as an xdg dir 3432 * however the config parser should take 3433 * care of duplicates 3434 */ 3435 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":")) 3436 goto oom; 3437 3438 if (xdg_data_home != NULL) 3439 { 3440 if (!_dbus_string_append (&servicedir_path, xdg_data_home)) 3441 goto oom; 3442 } 3443 else 3444 { 3445 const DBusString *homedir; 3446 DBusString local_share; 3447 3448 if (!_dbus_homedir_from_current_process (&homedir)) 3449 goto oom; 3450 3451 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) 3452 goto oom; 3453 3454 _dbus_string_init_const (&local_share, "/.local/share"); 3455 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) 3456 goto oom; 3457 } 3458 3459 if (!_dbus_split_paths_and_append (&servicedir_path, 3460 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 3461 dirs)) 3462 goto oom; 3463 3464 _dbus_string_free (&servicedir_path); 3465 return TRUE; 3466 3467 oom: 3468 _dbus_string_free (&servicedir_path); 3469 return FALSE; 3470 } 3471 3472 3473 /** 3474 * Returns the standard directories for a system bus to look for service 3475 * activation files 3476 * 3477 * On UNIX this should be the standard xdg freedesktop.org data directories: 3478 * 3479 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share} 3480 * 3481 * and 3482 * 3483 * DBUS_DATADIR 3484 * 3485 * On Windows there is no system bus and this function can return nothing. 3486 * 3487 * @param dirs the directory list we are returning 3488 * @returns #FALSE on OOM 3489 */ 3490 3491 dbus_bool_t 3492 _dbus_get_standard_system_servicedirs (DBusList **dirs) 3493 { 3494 const char *xdg_data_dirs; 3495 DBusString servicedir_path; 3496 3497 if (!_dbus_string_init (&servicedir_path)) 3498 return FALSE; 3499 3500 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 3501 3502 if (xdg_data_dirs != NULL) 3503 { 3504 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 3505 goto oom; 3506 3507 if (!_dbus_string_append (&servicedir_path, ":")) 3508 goto oom; 3509 } 3510 else 3511 { 3512 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 3513 goto oom; 3514 } 3515 3516 /* 3517 * add configured datadir to defaults 3518 * this may be the same as an xdg dir 3519 * however the config parser should take 3520 * care of duplicates 3521 */ 3522 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":")) 3523 goto oom; 3524 3525 if (!_dbus_split_paths_and_append (&servicedir_path, 3526 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 3527 dirs)) 3528 goto oom; 3529 3530 _dbus_string_free (&servicedir_path); 3531 return TRUE; 3532 3533 oom: 3534 _dbus_string_free (&servicedir_path); 3535 return FALSE; 3536 } 3537 3538 /** 3539 * Append the absolute path of the system.conf file 3540 * (there is no system bus on Windows so this can just 3541 * return FALSE and print a warning or something) 3542 * 3543 * @param str the string to append to 3544 * @returns #FALSE if no memory 3545 */ 3546 dbus_bool_t 3547 _dbus_append_system_config_file (DBusString *str) 3548 { 3549 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE); 3550 } 3551 3552 /** 3553 * Append the absolute path of the session.conf file. 3554 * 3555 * @param str the string to append to 3556 * @returns #FALSE if no memory 3557 */ 3558 dbus_bool_t 3559 _dbus_append_session_config_file (DBusString *str) 3560 { 3561 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); 3562 } 3563 3564 /** 3565 * Called when the bus daemon is signaled to reload its configuration; any 3566 * caches should be nuked. Of course any caches that need explicit reload 3567 * are probably broken, but c'est la vie. 3568 * 3569 * 3570 */ 3571 void 3572 _dbus_flush_caches (void) 3573 { 3574 _dbus_user_database_flush_system (); 3575 } 3576 3577 /** 3578 * Appends the directory in which a keyring for the given credentials 3579 * should be stored. The credentials should have either a Windows or 3580 * UNIX user in them. The directory should be an absolute path. 3581 * 3582 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably 3583 * be something else, since the dotfile convention is not normal on Windows. 3584 * 3585 * @param directory string to append directory to 3586 * @param credentials credentials the directory should be for 3587 * 3588 * @returns #FALSE on no memory 3589 */ 3590 dbus_bool_t 3591 _dbus_append_keyring_directory_for_credentials (DBusString *directory, 3592 DBusCredentials *credentials) 3593 { 3594 DBusString homedir; 3595 DBusString dotdir; 3596 dbus_uid_t uid; 3597 3598 _dbus_assert (credentials != NULL); 3599 _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); 3600 3601 if (!_dbus_string_init (&homedir)) 3602 return FALSE; 3603 3604 uid = _dbus_credentials_get_unix_uid (credentials); 3605 _dbus_assert (uid != DBUS_UID_UNSET); 3606 3607 if (!_dbus_homedir_from_uid (uid, &homedir)) 3608 goto failed; 3609 3610 #ifdef DBUS_BUILD_TESTS 3611 { 3612 const char *override; 3613 3614 override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); 3615 if (override != NULL && *override != '\0') 3616 { 3617 _dbus_string_set_length (&homedir, 0); 3618 if (!_dbus_string_append (&homedir, override)) 3619 goto failed; 3620 3621 _dbus_verbose ("Using fake homedir for testing: %s\n", 3622 _dbus_string_get_const_data (&homedir)); 3623 } 3624 else 3625 { 3626 static dbus_bool_t already_warned = FALSE; 3627 if (!already_warned) 3628 { 3629 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); 3630 already_warned = TRUE; 3631 } 3632 } 3633 } 3634 #endif 3635 3636 _dbus_string_init_const (&dotdir, ".dbus-keyrings"); 3637 if (!_dbus_concat_dir_and_file (&homedir, 3638 &dotdir)) 3639 goto failed; 3640 3641 if (!_dbus_string_copy (&homedir, 0, 3642 directory, _dbus_string_get_length (directory))) { 3643 goto failed; 3644 } 3645 3646 _dbus_string_free (&homedir); 3647 return TRUE; 3648 3649 failed: 3650 _dbus_string_free (&homedir); 3651 return FALSE; 3652 } 3653 3654 //PENDING(kdab) docs 3655 void 3656 _dbus_daemon_publish_session_bus_address (const char* addr) 3657 { 3658 3659 } 3660 3661 //PENDING(kdab) docs 3662 void 3663 _dbus_daemon_unpublish_session_bus_address (void) 3664 { 3665 3666 } 3667 3668 /** 3669 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently 3670 * for Winsock so is abstracted) 3671 * 3672 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK 3673 */ 3674 dbus_bool_t 3675 _dbus_get_is_errno_eagain_or_ewouldblock (void) 3676 { 3677 return errno == EAGAIN || errno == EWOULDBLOCK; 3678 } 3679 3680 /** 3681 * Removes a directory; Directory must be empty 3682 * 3683 * @param filename directory filename 3684 * @param error initialized error object 3685 * @returns #TRUE on success 3686 */ 3687 dbus_bool_t 3688 _dbus_delete_directory (const DBusString *filename, 3689 DBusError *error) 3690 { 3691 const char *filename_c; 3692 3693 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 3694 3695 filename_c = _dbus_string_get_const_data (filename); 3696 3697 if (rmdir (filename_c) != 0) 3698 { 3699 dbus_set_error (error, DBUS_ERROR_FAILED, 3700 "Failed to remove directory %s: %s\n", 3701 filename_c, _dbus_strerror (errno)); 3702 return FALSE; 3703 } 3704 3705 return TRUE; 3706 } 3707 3708 /** 3709 * Checks whether file descriptors may be passed via the socket 3710 * 3711 * @param fd the socket 3712 * @return TRUE when fd passing over this socket is supported 3713 * 3714 */ 3715 dbus_bool_t 3716 _dbus_socket_can_pass_unix_fd(int fd) { 3717 3718 #ifdef SCM_RIGHTS 3719 union { 3720 struct sockaddr sa; 3721 struct sockaddr_storage storage; 3722 struct sockaddr_un un; 3723 } sa_buf; 3724 3725 socklen_t sa_len = sizeof(sa_buf); 3726 3727 _DBUS_ZERO(sa_buf); 3728 3729 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0) 3730 return FALSE; 3731 3732 return sa_buf.sa.sa_family == AF_UNIX; 3733 3734 #else 3735 return FALSE; 3736 3737 #endif 3738 } 3739 3740 3741 /* 3742 * replaces the term DBUS_PREFIX in configure_time_path by the 3743 * current dbus installation directory. On unix this function is a noop 3744 * 3745 * @param configure_time_path 3746 * @return real path 3747 */ 3748 const char * 3749 _dbus_replace_install_prefix (const char *configure_time_path) 3750 { 3751 return configure_time_path; 3752 } 3753 3754 /* tests in dbus-sysdeps-util.c */ 3755