1 /* -*- mode: C; c-file-style: "gnu" -*- */ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 */ 24 25 #include "dbus-internals.h" 26 #include "dbus-sysdeps.h" 27 #include "dbus-sysdeps-unix.h" 28 #include "dbus-threads.h" 29 #include "dbus-protocol.h" 30 #include "dbus-transport.h" 31 #include "dbus-string.h" 32 #include "dbus-userdb.h" 33 #include "dbus-list.h" 34 #include <sys/types.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <signal.h> 38 #include <unistd.h> 39 #include <stdio.h> 40 #include <fcntl.h> 41 #include <sys/socket.h> 42 #include <dirent.h> 43 #include <sys/un.h> 44 #include <pwd.h> 45 #include <time.h> 46 #include <locale.h> 47 #include <sys/time.h> 48 #include <sys/stat.h> 49 #include <sys/wait.h> 50 #include <netinet/in.h> 51 #include <netdb.h> 52 #include <grp.h> 53 #include <cutils/sockets.h> 54 55 #ifdef HAVE_ERRNO_H 56 #include <errno.h> 57 #endif 58 #ifdef HAVE_WRITEV 59 #include <sys/uio.h> 60 #endif 61 #ifdef HAVE_POLL 62 #include <sys/poll.h> 63 #endif 64 #ifdef HAVE_BACKTRACE 65 #include <execinfo.h> 66 #endif 67 #ifdef HAVE_GETPEERUCRED 68 #include <ucred.h> 69 #endif 70 71 #ifndef O_BINARY 72 #define O_BINARY 0 73 #endif 74 75 #ifndef HAVE_SOCKLEN_T 76 #define socklen_t int 77 #endif 78 79 static dbus_bool_t 80 _dbus_open_socket (int *fd, 81 int domain, 82 int type, 83 int protocol, 84 DBusError *error) 85 { 86 *fd = socket (domain, type, protocol); 87 if (*fd >= 0) 88 { 89 return TRUE; 90 } 91 else 92 { 93 dbus_set_error(error, 94 _dbus_error_from_errno (errno), 95 "Failed to open socket: %s", 96 _dbus_strerror (errno)); 97 return FALSE; 98 } 99 } 100 101 dbus_bool_t 102 _dbus_open_tcp_socket (int *fd, 103 DBusError *error) 104 { 105 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error); 106 } 107 108 /** 109 * Opens a UNIX domain socket (as in the socket() call). 110 * Does not bind the socket. 111 * @param fd return location for socket descriptor 112 * @param error return location for an error 113 * @returns #FALSE if error is set 114 */ 115 dbus_bool_t 116 _dbus_open_unix_socket (int *fd, 117 DBusError *error) 118 { 119 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error); 120 } 121 122 /** 123 * Closes a socket. Should not be used on non-socket 124 * file descriptors or handles. 125 * 126 * @param fd the socket 127 * @param error return location for an error 128 * @returns #FALSE if error is set 129 */ 130 dbus_bool_t 131 _dbus_close_socket (int fd, 132 DBusError *error) 133 { 134 return _dbus_close (fd, error); 135 } 136 137 /** 138 * Like _dbus_read(), but only works on sockets so is 139 * available on Windows. 140 * 141 * @param fd the socket 142 * @param buffer string to append data to 143 * @param count max amount of data to read 144 * @returns number of bytes appended to the string 145 */ 146 int 147 _dbus_read_socket (int fd, 148 DBusString *buffer, 149 int count) 150 { 151 return _dbus_read (fd, buffer, count); 152 } 153 154 /** 155 * Like _dbus_write(), but only supports sockets 156 * and is thus available on Windows. 157 * 158 * @param fd the file descriptor to write 159 * @param buffer the buffer to write data from 160 * @param start the first byte in the buffer to write 161 * @param len the number of bytes to try to write 162 * @returns the number of bytes written or -1 on error 163 */ 164 int 165 _dbus_write_socket (int fd, 166 const DBusString *buffer, 167 int start, 168 int len) 169 { 170 return _dbus_write (fd, buffer, start, len); 171 } 172 173 /** 174 * Like _dbus_write_two() but only works on sockets and is thus 175 * available on Windows. 176 * 177 * @param fd the file descriptor 178 * @param buffer1 first buffer 179 * @param start1 first byte to write in first buffer 180 * @param len1 number of bytes to write from first buffer 181 * @param buffer2 second buffer, or #NULL 182 * @param start2 first byte to write in second buffer 183 * @param len2 number of bytes to write in second buffer 184 * @returns total bytes written from both buffers, or -1 on error 185 */ 186 int 187 _dbus_write_socket_two (int fd, 188 const DBusString *buffer1, 189 int start1, 190 int len1, 191 const DBusString *buffer2, 192 int start2, 193 int len2) 194 { 195 return _dbus_write_two (fd, buffer1, start1, len1, 196 buffer2, start2, len2); 197 } 198 199 200 /** 201 * Thin wrapper around the read() system call that appends 202 * the data it reads to the DBusString buffer. It appends 203 * up to the given count, and returns the same value 204 * and same errno as read(). The only exception is that 205 * _dbus_read() handles EINTR for you. Also, _dbus_read() can 206 * return ENOMEM, even though regular UNIX read doesn't. 207 * 208 * Unlike _dbus_read_socket(), _dbus_read() is not available 209 * on Windows. 210 * 211 * @param fd the file descriptor to read from 212 * @param buffer the buffer to append data to 213 * @param count the amount of data to read 214 * @returns the number of bytes read or -1 215 */ 216 int 217 _dbus_read (int fd, 218 DBusString *buffer, 219 int count) 220 { 221 int bytes_read; 222 int start; 223 char *data; 224 225 _dbus_assert (count >= 0); 226 227 start = _dbus_string_get_length (buffer); 228 229 if (!_dbus_string_lengthen (buffer, count)) 230 { 231 errno = ENOMEM; 232 return -1; 233 } 234 235 data = _dbus_string_get_data_len (buffer, start, count); 236 237 again: 238 239 bytes_read = read (fd, data, count); 240 241 if (bytes_read < 0) 242 { 243 if (errno == EINTR) 244 goto again; 245 else 246 { 247 /* put length back (note that this doesn't actually realloc anything) */ 248 _dbus_string_set_length (buffer, start); 249 return -1; 250 } 251 } 252 else 253 { 254 /* put length back (doesn't actually realloc) */ 255 _dbus_string_set_length (buffer, start + bytes_read); 256 257 #if 0 258 if (bytes_read > 0) 259 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 260 #endif 261 262 return bytes_read; 263 } 264 } 265 266 /** 267 * Thin wrapper around the write() system call that writes a part of a 268 * DBusString and handles EINTR for you. 269 * 270 * @param fd the file descriptor to write 271 * @param buffer the buffer to write data from 272 * @param start the first byte in the buffer to write 273 * @param len the number of bytes to try to write 274 * @returns the number of bytes written or -1 on error 275 */ 276 int 277 _dbus_write (int fd, 278 const DBusString *buffer, 279 int start, 280 int len) 281 { 282 const char *data; 283 int bytes_written; 284 285 data = _dbus_string_get_const_data_len (buffer, start, len); 286 287 again: 288 289 bytes_written = write (fd, data, len); 290 291 if (bytes_written < 0 && errno == EINTR) 292 goto again; 293 294 #if 0 295 if (bytes_written > 0) 296 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 297 #endif 298 299 return bytes_written; 300 } 301 302 /** 303 * Like _dbus_write() but will use writev() if possible 304 * to write both buffers in sequence. The return value 305 * is the number of bytes written in the first buffer, 306 * plus the number written in the second. If the first 307 * buffer is written successfully and an error occurs 308 * writing the second, the number of bytes in the first 309 * is returned (i.e. the error is ignored), on systems that 310 * don't have writev. Handles EINTR for you. 311 * The second buffer may be #NULL. 312 * 313 * @param fd the file descriptor 314 * @param buffer1 first buffer 315 * @param start1 first byte to write in first buffer 316 * @param len1 number of bytes to write from first buffer 317 * @param buffer2 second buffer, or #NULL 318 * @param start2 first byte to write in second buffer 319 * @param len2 number of bytes to write in second buffer 320 * @returns total bytes written from both buffers, or -1 on error 321 */ 322 int 323 _dbus_write_two (int fd, 324 const DBusString *buffer1, 325 int start1, 326 int len1, 327 const DBusString *buffer2, 328 int start2, 329 int len2) 330 { 331 _dbus_assert (buffer1 != NULL); 332 _dbus_assert (start1 >= 0); 333 _dbus_assert (start2 >= 0); 334 _dbus_assert (len1 >= 0); 335 _dbus_assert (len2 >= 0); 336 337 #ifdef HAVE_WRITEV 338 { 339 struct iovec vectors[2]; 340 const char *data1; 341 const char *data2; 342 int bytes_written; 343 344 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 345 346 if (buffer2 != NULL) 347 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 348 else 349 { 350 data2 = NULL; 351 start2 = 0; 352 len2 = 0; 353 } 354 355 vectors[0].iov_base = (char*) data1; 356 vectors[0].iov_len = len1; 357 vectors[1].iov_base = (char*) data2; 358 vectors[1].iov_len = len2; 359 360 again: 361 362 bytes_written = writev (fd, 363 vectors, 364 data2 ? 2 : 1); 365 366 if (bytes_written < 0 && errno == EINTR) 367 goto again; 368 369 return bytes_written; 370 } 371 #else /* HAVE_WRITEV */ 372 { 373 int ret1; 374 375 ret1 = _dbus_write (fd, buffer1, start1, len1); 376 if (ret1 == len1 && buffer2 != NULL) 377 { 378 ret2 = _dbus_write (fd, buffer2, start2, len2); 379 if (ret2 < 0) 380 ret2 = 0; /* we can't report an error as the first write was OK */ 381 382 return ret1 + ret2; 383 } 384 else 385 return ret1; 386 } 387 #endif /* !HAVE_WRITEV */ 388 } 389 390 #define _DBUS_MAX_SUN_PATH_LENGTH 99 391 392 /** 393 * @def _DBUS_MAX_SUN_PATH_LENGTH 394 * 395 * Maximum length of the path to a UNIX domain socket, 396 * sockaddr_un::sun_path member. POSIX requires that all systems 397 * support at least 100 bytes here, including the nul termination. 398 * We use 99 for the max value to allow for the nul. 399 * 400 * We could probably also do sizeof (addr.sun_path) 401 * but this way we are the same on all platforms 402 * which is probably a good idea. 403 */ 404 405 /** 406 * Creates a socket and connects it to the UNIX domain socket at the 407 * given path. The connection fd is returned, and is set up as 408 * nonblocking. 409 * 410 * Uses abstract sockets instead of filesystem-linked sockets if 411 * requested (it's possible only on Linux; see "man 7 unix" on Linux). 412 * On non-Linux abstract socket usage always fails. 413 * 414 * @param path the path to UNIX domain socket 415 * @param abstract #TRUE to use abstract namespace 416 * @param error return location for error code 417 * @returns connection file descriptor or -1 on error 418 */ 419 int 420 _dbus_connect_unix_socket (const char *path, 421 dbus_bool_t abstract, 422 DBusError *error) 423 { 424 int fd; 425 size_t path_len; 426 struct sockaddr_un addr; 427 428 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 429 430 _dbus_verbose ("connecting to unix socket %s abstract=%d\n", 431 path, abstract); 432 433 434 if (!_dbus_open_unix_socket (&fd, error)) 435 { 436 _DBUS_ASSERT_ERROR_IS_SET(error); 437 return -1; 438 } 439 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 440 441 _DBUS_ZERO (addr); 442 addr.sun_family = AF_UNIX; 443 path_len = strlen (path); 444 445 if (abstract) 446 { 447 #ifdef HAVE_ABSTRACT_SOCKETS 448 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 449 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 450 451 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 452 { 453 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 454 "Abstract socket name too long\n"); 455 _dbus_close (fd, NULL); 456 return -1; 457 } 458 459 strncpy (&addr.sun_path[1], path, path_len); 460 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 461 #else /* HAVE_ABSTRACT_SOCKETS */ 462 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 463 "Operating system does not support abstract socket namespace\n"); 464 _dbus_close (fd, NULL); 465 return -1; 466 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 467 } 468 else 469 { 470 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 471 { 472 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 473 "Socket name too long\n"); 474 _dbus_close (fd, NULL); 475 return -1; 476 } 477 478 strncpy (addr.sun_path, path, path_len); 479 } 480 481 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 482 { 483 dbus_set_error (error, 484 _dbus_error_from_errno (errno), 485 "Failed to connect to socket %s: %s", 486 path, _dbus_strerror (errno)); 487 488 _dbus_close (fd, NULL); 489 fd = -1; 490 491 return -1; 492 } 493 494 if (!_dbus_set_fd_nonblocking (fd, error)) 495 { 496 _DBUS_ASSERT_ERROR_IS_SET (error); 497 498 _dbus_close (fd, NULL); 499 fd = -1; 500 501 return -1; 502 } 503 504 return fd; 505 } 506 507 /** 508 * Enables or disables the reception of credentials on the given socket during 509 * the next message transmission. This is only effective if the #LOCAL_CREDS 510 * system feature exists, in which case the other side of the connection does 511 * not have to do anything special to send the credentials. 512 * 513 * @param fd socket on which to change the #LOCAL_CREDS flag. 514 * @param on whether to enable or disable the #LOCAL_CREDS flag. 515 */ 516 static dbus_bool_t 517 _dbus_set_local_creds (int fd, dbus_bool_t on) 518 { 519 dbus_bool_t retval = TRUE; 520 521 #if defined(HAVE_CMSGCRED) 522 /* NOOP just to make sure only one codepath is used 523 * and to prefer CMSGCRED 524 */ 525 #elif defined(LOCAL_CREDS) 526 int val = on ? 1 : 0; 527 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0) 528 { 529 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd); 530 retval = FALSE; 531 } 532 else 533 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n", 534 on ? "enabled" : "disabled", fd); 535 #endif 536 537 return retval; 538 } 539 540 /** 541 * Creates a socket and binds it to the given path, 542 * then listens on the socket. The socket is 543 * set to be nonblocking. 544 * 545 * Uses abstract sockets instead of filesystem-linked 546 * sockets if requested (it's possible only on Linux; 547 * see "man 7 unix" on Linux). 548 * On non-Linux abstract socket usage always fails. 549 * 550 * @param path the socket name 551 * @param abstract #TRUE to use abstract namespace 552 * @param error return location for errors 553 * @returns the listening file descriptor or -1 on error 554 */ 555 int 556 _dbus_listen_unix_socket (const char *path, 557 dbus_bool_t abstract, 558 DBusError *error) 559 { 560 int listen_fd; 561 struct sockaddr_un addr; 562 size_t path_len; 563 564 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 565 566 _dbus_verbose ("listening on unix socket %s abstract=%d\n", 567 path, abstract); 568 #ifdef ANDROID_MANAGED_SOCKET 569 if (strncmp (path, ANDROID_SOCKET_DIR"/", strlen(ANDROID_SOCKET_DIR"/")) == 0) 570 { 571 const char* suffix; 572 /* init has created a socket for us, pick it up from environ */ 573 suffix = &path[strlen (ANDROID_SOCKET_DIR"/")]; 574 listen_fd = android_get_control_socket (suffix); 575 if (listen_fd == -1) 576 { 577 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 578 "Could not obtain fd for android socket %s\n", suffix); 579 return -1; 580 } 581 582 _dbus_verbose ("Obtained fd for android socket %s\n", suffix); 583 } 584 else 585 { 586 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 587 "Not an android socket: %s\n", path); 588 return -1; 589 } 590 #else 591 592 if (!_dbus_open_unix_socket (&listen_fd, error)) 593 { 594 _DBUS_ASSERT_ERROR_IS_SET(error); 595 return -1; 596 } 597 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 598 599 _DBUS_ZERO (addr); 600 addr.sun_family = AF_UNIX; 601 path_len = strlen (path); 602 603 if (abstract) 604 { 605 #ifdef HAVE_ABSTRACT_SOCKETS 606 /* remember that abstract names aren't nul-terminated so we rely 607 * on sun_path being filled in with zeroes above. 608 */ 609 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 610 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 611 612 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 613 { 614 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 615 "Abstract socket name too long\n"); 616 _dbus_close (listen_fd, NULL); 617 return -1; 618 } 619 620 strncpy (&addr.sun_path[1], path, path_len); 621 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 622 #else /* HAVE_ABSTRACT_SOCKETS */ 623 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 624 "Operating system does not support abstract socket namespace\n"); 625 _dbus_close (listen_fd, NULL); 626 return -1; 627 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 628 } 629 else 630 { 631 /* Discussed security implications of this with Nalin, 632 * and we couldn't think of where it would kick our ass, but 633 * it still seems a bit sucky. It also has non-security suckage; 634 * really we'd prefer to exit if the socket is already in use. 635 * But there doesn't seem to be a good way to do this. 636 * 637 * Just to be extra careful, I threw in the stat() - clearly 638 * the stat() can't *fix* any security issue, but it at least 639 * avoids inadvertent/accidental data loss. 640 */ 641 { 642 struct stat sb; 643 644 if (stat (path, &sb) == 0 && 645 S_ISSOCK (sb.st_mode)) 646 unlink (path); 647 } 648 649 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 650 { 651 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 652 "Abstract socket name too long\n"); 653 _dbus_close (listen_fd, NULL); 654 return -1; 655 } 656 657 strncpy (addr.sun_path, path, path_len); 658 } 659 660 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 661 { 662 dbus_set_error (error, _dbus_error_from_errno (errno), 663 "Failed to bind socket \"%s\": %s", 664 path, _dbus_strerror (errno)); 665 _dbus_close (listen_fd, NULL); 666 return -1; 667 } 668 669 #endif /* android init managed sockets */ 670 671 if (listen (listen_fd, 30 /* backlog */) < 0) 672 { 673 dbus_set_error (error, _dbus_error_from_errno (errno), 674 "Failed to listen on socket \"%s\": %s", 675 path, _dbus_strerror (errno)); 676 _dbus_close (listen_fd, NULL); 677 return -1; 678 } 679 680 if (!_dbus_set_local_creds (listen_fd, TRUE)) 681 { 682 dbus_set_error (error, _dbus_error_from_errno (errno), 683 "Failed to enable LOCAL_CREDS on socket \"%s\": %s", 684 path, _dbus_strerror (errno)); 685 close (listen_fd); 686 return -1; 687 } 688 689 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 690 { 691 _DBUS_ASSERT_ERROR_IS_SET (error); 692 _dbus_close (listen_fd, NULL); 693 return -1; 694 } 695 696 #ifndef ANDROID_MANAGED_SOCKET 697 /* Try opening up the permissions, but if we can't, just go ahead 698 * and continue, maybe it will be good enough. 699 */ 700 if (!abstract && chmod (path, 0777) < 0) 701 _dbus_warn ("Could not set mode 0777 on socket %s\n", 702 path); 703 #endif 704 705 return listen_fd; 706 } 707 708 /** 709 * Creates a socket and connects to a socket at the given host 710 * and port. The connection fd is returned, and is set up as 711 * nonblocking. 712 * 713 * @param host the host name to connect to 714 * @param port the prot to connect to 715 * @param error return location for error code 716 * @returns connection file descriptor or -1 on error 717 */ 718 int 719 _dbus_connect_tcp_socket (const char *host, 720 dbus_uint32_t port, 721 DBusError *error) 722 { 723 int fd; 724 struct sockaddr_in addr; 725 struct hostent *he; 726 struct in_addr *haddr; 727 728 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 729 730 731 if (!_dbus_open_tcp_socket (&fd, error)) 732 { 733 _DBUS_ASSERT_ERROR_IS_SET(error); 734 735 return -1; 736 } 737 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 738 739 if (host == NULL) 740 host = "localhost"; 741 742 he = gethostbyname (host); 743 if (he == NULL) 744 { 745 dbus_set_error (error, 746 _dbus_error_from_errno (errno), 747 "Failed to lookup hostname: %s", 748 host); 749 _dbus_close (fd, NULL); 750 return -1; 751 } 752 753 haddr = ((struct in_addr *) (he->h_addr_list)[0]); 754 755 _DBUS_ZERO (addr); 756 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr)); 757 addr.sin_family = AF_INET; 758 addr.sin_port = htons (port); 759 760 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0) 761 { 762 dbus_set_error (error, 763 _dbus_error_from_errno (errno), 764 "Failed to connect to socket %s:%d %s", 765 host, port, _dbus_strerror (errno)); 766 767 _dbus_close (fd, NULL); 768 fd = -1; 769 770 return -1; 771 } 772 773 if (!_dbus_set_fd_nonblocking (fd, error)) 774 { 775 _dbus_close (fd, NULL); 776 fd = -1; 777 778 return -1; 779 } 780 781 return fd; 782 } 783 784 /** 785 * Creates a socket and binds it to the given path, 786 * then listens on the socket. The socket is 787 * set to be nonblocking. 788 * 789 * @param host the host name to listen on 790 * @param port the prot to listen on 791 * @param error return location for errors 792 * @returns the listening file descriptor or -1 on error 793 */ 794 int 795 _dbus_listen_tcp_socket (const char *host, 796 dbus_uint32_t port, 797 DBusError *error) 798 { 799 int listen_fd; 800 struct sockaddr_in addr; 801 struct hostent *he; 802 struct in_addr *haddr; 803 804 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 805 806 807 if (!_dbus_open_tcp_socket (&listen_fd, error)) 808 { 809 _DBUS_ASSERT_ERROR_IS_SET(error); 810 return -1; 811 } 812 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 813 814 he = gethostbyname (host); 815 if (he == NULL) 816 { 817 dbus_set_error (error, 818 _dbus_error_from_errno (errno), 819 "Failed to lookup hostname: %s", 820 host); 821 _dbus_close (listen_fd, NULL); 822 return -1; 823 } 824 825 haddr = ((struct in_addr *) (he->h_addr_list)[0]); 826 827 _DBUS_ZERO (addr); 828 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr)); 829 addr.sin_family = AF_INET; 830 addr.sin_port = htons (port); 831 832 if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr))) 833 { 834 dbus_set_error (error, _dbus_error_from_errno (errno), 835 "Failed to bind socket \"%s:%d\": %s", 836 host, port, _dbus_strerror (errno)); 837 _dbus_close (listen_fd, NULL); 838 return -1; 839 } 840 841 if (listen (listen_fd, 30 /* backlog */) < 0) 842 { 843 dbus_set_error (error, _dbus_error_from_errno (errno), 844 "Failed to listen on socket \"%s:%d\": %s", 845 host, port, _dbus_strerror (errno)); 846 _dbus_close (listen_fd, NULL); 847 return -1; 848 } 849 850 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 851 { 852 _dbus_close (listen_fd, NULL); 853 return -1; 854 } 855 856 return listen_fd; 857 } 858 859 static dbus_bool_t 860 write_credentials_byte (int server_fd, 861 DBusError *error) 862 { 863 int bytes_written; 864 char buf[1] = { '\0' }; 865 #if defined(HAVE_CMSGCRED) 866 struct { 867 struct cmsghdr hdr; 868 struct cmsgcred cred; 869 } cmsg; 870 struct iovec iov; 871 struct msghdr msg; 872 iov.iov_base = buf; 873 iov.iov_len = 1; 874 875 memset (&msg, 0, sizeof (msg)); 876 msg.msg_iov = &iov; 877 msg.msg_iovlen = 1; 878 879 msg.msg_control = &cmsg; 880 msg.msg_controllen = sizeof (cmsg); 881 memset (&cmsg, 0, sizeof (cmsg)); 882 cmsg.hdr.cmsg_len = sizeof (cmsg); 883 cmsg.hdr.cmsg_level = SOL_SOCKET; 884 cmsg.hdr.cmsg_type = SCM_CREDS; 885 #endif 886 887 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 888 889 again: 890 891 #if defined(HAVE_CMSGCRED) 892 bytes_written = sendmsg (server_fd, &msg, 0); 893 #else 894 bytes_written = write (server_fd, buf, 1); 895 #endif 896 897 if (bytes_written < 0 && errno == EINTR) 898 goto again; 899 900 if (bytes_written < 0) 901 { 902 dbus_set_error (error, _dbus_error_from_errno (errno), 903 "Failed to write credentials byte: %s", 904 _dbus_strerror (errno)); 905 return FALSE; 906 } 907 else if (bytes_written == 0) 908 { 909 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 910 "wrote zero bytes writing credentials byte"); 911 return FALSE; 912 } 913 else 914 { 915 _dbus_assert (bytes_written == 1); 916 _dbus_verbose ("wrote credentials byte\n"); 917 return TRUE; 918 } 919 } 920 921 /** 922 * Reads a single byte which must be nul (an error occurs otherwise), 923 * and reads unix credentials if available. Fills in pid/uid/gid with 924 * -1 if no credentials are available. Return value indicates whether 925 * a byte was read, not whether we got valid credentials. On some 926 * systems, such as Linux, reading/writing the byte isn't actually 927 * required, but we do it anyway just to avoid multiple codepaths. 928 * 929 * Fails if no byte is available, so you must select() first. 930 * 931 * The point of the byte is that on some systems we have to 932 * use sendmsg()/recvmsg() to transmit credentials. 933 * 934 * @param client_fd the client file descriptor 935 * @param credentials struct to fill with credentials of client 936 * @param error location to store error code 937 * @returns #TRUE on success 938 */ 939 dbus_bool_t 940 _dbus_read_credentials_unix_socket (int client_fd, 941 DBusCredentials *credentials, 942 DBusError *error) 943 { 944 struct msghdr msg; 945 struct iovec iov; 946 char buf; 947 948 #ifdef HAVE_CMSGCRED 949 struct { 950 struct cmsghdr hdr; 951 struct cmsgcred cred; 952 } cmsg; 953 954 #elif defined(LOCAL_CREDS) 955 struct { 956 struct cmsghdr hdr; 957 struct sockcred cred; 958 } cmsg; 959 #endif 960 961 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 962 963 /* The POSIX spec certainly doesn't promise this, but 964 * we need these assertions to fail as soon as we're wrong about 965 * it so we can do the porting fixups 966 */ 967 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid)); 968 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid)); 969 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid)); 970 971 _dbus_credentials_clear (credentials); 972 973 /* Systems supporting LOCAL_CREDS are configured to have this feature 974 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting 975 * the connection. Therefore, the received message must carry the 976 * credentials information without doing anything special. 977 */ 978 979 iov.iov_base = &buf; 980 iov.iov_len = 1; 981 982 memset (&msg, 0, sizeof (msg)); 983 msg.msg_iov = &iov; 984 msg.msg_iovlen = 1; 985 986 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 987 memset (&cmsg, 0, sizeof (cmsg)); 988 msg.msg_control = &cmsg; 989 msg.msg_controllen = sizeof (cmsg); 990 #endif 991 992 again: 993 if (recvmsg (client_fd, &msg, 0) < 0) 994 { 995 if (errno == EINTR) 996 goto again; 997 998 dbus_set_error (error, _dbus_error_from_errno (errno), 999 "Failed to read credentials byte: %s", 1000 _dbus_strerror (errno)); 1001 return FALSE; 1002 } 1003 1004 if (buf != '\0') 1005 { 1006 dbus_set_error (error, DBUS_ERROR_FAILED, 1007 "Credentials byte was not nul"); 1008 return FALSE; 1009 } 1010 1011 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 1012 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) 1013 { 1014 dbus_set_error (error, DBUS_ERROR_FAILED, 1015 "Message from recvmsg() was not SCM_CREDS"); 1016 return FALSE; 1017 } 1018 #endif 1019 1020 _dbus_verbose ("read credentials byte\n"); 1021 1022 { 1023 #ifdef SO_PEERCRED 1024 struct ucred cr; 1025 int cr_len = sizeof (cr); 1026 1027 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && 1028 cr_len == sizeof (cr)) 1029 { 1030 credentials->pid = cr.pid; 1031 credentials->uid = cr.uid; 1032 credentials->gid = cr.gid; 1033 } 1034 else 1035 { 1036 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", 1037 cr_len, (int) sizeof (cr), _dbus_strerror (errno)); 1038 } 1039 #elif defined(HAVE_CMSGCRED) 1040 credentials->pid = cmsg.cred.cmcred_pid; 1041 credentials->uid = cmsg.cred.cmcred_euid; 1042 credentials->gid = cmsg.cred.cmcred_groups[0]; 1043 #elif defined(LOCAL_CREDS) 1044 credentials->pid = DBUS_PID_UNSET; 1045 credentials->uid = cmsg.cred.sc_uid; 1046 credentials->gid = cmsg.cred.sc_gid; 1047 /* Since we have already got the credentials from this socket, we can 1048 * disable its LOCAL_CREDS flag if it was ever set. */ 1049 _dbus_set_local_creds (client_fd, FALSE); 1050 #elif defined(HAVE_GETPEEREID) 1051 uid_t euid; 1052 gid_t egid; 1053 if (getpeereid (client_fd, &euid, &egid) == 0) 1054 { 1055 credentials->uid = euid; 1056 credentials->gid = egid; 1057 } 1058 else 1059 { 1060 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno)); 1061 } 1062 #elif defined(HAVE_GETPEERUCRED) 1063 ucred_t * ucred = NULL; 1064 if (getpeerucred (client_fd, &ucred) == 0) 1065 { 1066 credentials->pid = ucred_getpid (ucred); 1067 credentials->uid = ucred_geteuid (ucred); 1068 credentials->gid = ucred_getegid (ucred); 1069 } 1070 else 1071 { 1072 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno)); 1073 } 1074 if (ucred != NULL) 1075 ucred_free (ucred); 1076 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ 1077 _dbus_verbose ("Socket credentials not supported on this OS\n"); 1078 #endif 1079 } 1080 1081 _dbus_verbose ("Credentials:" 1082 " pid "DBUS_PID_FORMAT 1083 " uid "DBUS_UID_FORMAT 1084 " gid "DBUS_GID_FORMAT"\n", 1085 credentials->pid, 1086 credentials->uid, 1087 credentials->gid); 1088 1089 return TRUE; 1090 } 1091 1092 /** 1093 * Sends a single nul byte with our UNIX credentials as ancillary 1094 * data. Returns #TRUE if the data was successfully written. On 1095 * systems that don't support sending credentials, just writes a byte, 1096 * doesn't send any credentials. On some systems, such as Linux, 1097 * reading/writing the byte isn't actually required, but we do it 1098 * anyway just to avoid multiple codepaths. 1099 * 1100 * Fails if no byte can be written, so you must select() first. 1101 * 1102 * The point of the byte is that on some systems we have to 1103 * use sendmsg()/recvmsg() to transmit credentials. 1104 * 1105 * @param server_fd file descriptor for connection to server 1106 * @param error return location for error code 1107 * @returns #TRUE if the byte was sent 1108 */ 1109 dbus_bool_t 1110 _dbus_send_credentials_unix_socket (int server_fd, 1111 DBusError *error) 1112 { 1113 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1114 1115 if (write_credentials_byte (server_fd, error)) 1116 return TRUE; 1117 else 1118 return FALSE; 1119 } 1120 1121 /** 1122 * Accepts a connection on a listening socket. 1123 * Handles EINTR for you. 1124 * 1125 * @param listen_fd the listen file descriptor 1126 * @returns the connection fd of the client, or -1 on error 1127 */ 1128 int 1129 _dbus_accept (int listen_fd) 1130 { 1131 int client_fd; 1132 struct sockaddr addr; 1133 socklen_t addrlen; 1134 1135 addrlen = sizeof (addr); 1136 1137 retry: 1138 client_fd = accept (listen_fd, &addr, &addrlen); 1139 1140 if (client_fd < 0) 1141 { 1142 if (errno == EINTR) 1143 goto retry; 1144 } 1145 1146 return client_fd; 1147 } 1148 1149 /** 1150 * Checks to make sure the given directory is 1151 * private to the user 1152 * 1153 * @param dir the name of the directory 1154 * @param error error return 1155 * @returns #FALSE on failure 1156 **/ 1157 dbus_bool_t 1158 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) 1159 { 1160 const char *directory; 1161 struct stat sb; 1162 1163 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1164 1165 directory = _dbus_string_get_const_data (dir); 1166 1167 if (stat (directory, &sb) < 0) 1168 { 1169 dbus_set_error (error, _dbus_error_from_errno (errno), 1170 "%s", _dbus_strerror (errno)); 1171 1172 return FALSE; 1173 } 1174 1175 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) || 1176 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode)) 1177 { 1178 dbus_set_error (error, DBUS_ERROR_FAILED, 1179 "%s directory is not private to the user", directory); 1180 return FALSE; 1181 } 1182 1183 return TRUE; 1184 } 1185 1186 static dbus_bool_t 1187 fill_user_info_from_passwd (struct passwd *p, 1188 DBusUserInfo *info, 1189 DBusError *error) 1190 { 1191 _dbus_assert (p->pw_name != NULL); 1192 _dbus_assert (p->pw_dir != NULL); 1193 1194 info->uid = p->pw_uid; 1195 info->primary_gid = p->pw_gid; 1196 info->username = _dbus_strdup (p->pw_name); 1197 info->homedir = _dbus_strdup (p->pw_dir); 1198 1199 if (info->username == NULL || 1200 info->homedir == NULL) 1201 { 1202 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1203 return FALSE; 1204 } 1205 1206 return TRUE; 1207 } 1208 1209 static dbus_bool_t 1210 fill_user_info (DBusUserInfo *info, 1211 dbus_uid_t uid, 1212 const DBusString *username, 1213 DBusError *error) 1214 { 1215 const char *username_c; 1216 1217 /* exactly one of username/uid provided */ 1218 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET); 1219 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET); 1220 1221 info->uid = DBUS_UID_UNSET; 1222 info->primary_gid = DBUS_GID_UNSET; 1223 info->group_ids = NULL; 1224 info->n_group_ids = 0; 1225 info->username = NULL; 1226 info->homedir = NULL; 1227 1228 if (username != NULL) 1229 username_c = _dbus_string_get_const_data (username); 1230 else 1231 username_c = NULL; 1232 1233 /* For now assuming that the getpwnam() and getpwuid() flavors 1234 * are always symmetrical, if not we have to add more configure 1235 * checks 1236 */ 1237 1238 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R) 1239 { 1240 struct passwd *p; 1241 int result; 1242 char buf[1024]; 1243 struct passwd p_str; 1244 1245 p = NULL; 1246 #ifdef HAVE_POSIX_GETPWNAM_R 1247 if (uid != DBUS_UID_UNSET) 1248 result = getpwuid_r (uid, &p_str, buf, sizeof (buf), 1249 &p); 1250 else 1251 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf), 1252 &p); 1253 #else 1254 if (uid != DBUS_UID_UNSET) 1255 p = getpwuid_r (uid, &p_str, buf, sizeof (buf)); 1256 else 1257 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf)); 1258 result = 0; 1259 #endif /* !HAVE_POSIX_GETPWNAM_R */ 1260 if (result == 0 && p == &p_str) 1261 { 1262 if (!fill_user_info_from_passwd (p, info, error)) 1263 return FALSE; 1264 } 1265 else 1266 { 1267 dbus_set_error (error, _dbus_error_from_errno (errno), 1268 "User \"%s\" unknown or no memory to allocate password entry\n", 1269 username_c ? username_c : "???"); 1270 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 1271 return FALSE; 1272 } 1273 } 1274 #else /* ! HAVE_GETPWNAM_R */ 1275 { 1276 /* I guess we're screwed on thread safety here */ 1277 struct passwd *p; 1278 1279 if (uid != DBUS_UID_UNSET) 1280 p = getpwuid (uid); 1281 else 1282 p = getpwnam (username_c); 1283 1284 if (p != NULL) 1285 { 1286 if (!fill_user_info_from_passwd (p, info, error)) 1287 return FALSE; 1288 } 1289 else 1290 { 1291 dbus_set_error (error, _dbus_error_from_errno (errno), 1292 "User \"%s\" unknown or no memory to allocate password entry\n", 1293 username_c ? username_c : "???"); 1294 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 1295 return FALSE; 1296 } 1297 } 1298 #endif /* ! HAVE_GETPWNAM_R */ 1299 1300 /* Fill this in so we can use it to get groups */ 1301 username_c = info->username; 1302 1303 #ifdef HAVE_GETGROUPLIST 1304 { 1305 gid_t *buf; 1306 int buf_count; 1307 int i; 1308 1309 buf_count = 17; 1310 buf = dbus_new (gid_t, buf_count); 1311 if (buf == NULL) 1312 { 1313 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1314 goto failed; 1315 } 1316 1317 if (getgrouplist (username_c, 1318 info->primary_gid, 1319 buf, &buf_count) < 0) 1320 { 1321 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0])); 1322 if (new == NULL) 1323 { 1324 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1325 dbus_free (buf); 1326 goto failed; 1327 } 1328 1329 buf = new; 1330 1331 errno = 0; 1332 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0) 1333 { 1334 dbus_set_error (error, 1335 _dbus_error_from_errno (errno), 1336 "Failed to get groups for username \"%s\" primary GID " 1337 DBUS_GID_FORMAT ": %s\n", 1338 username_c, info->primary_gid, 1339 _dbus_strerror (errno)); 1340 dbus_free (buf); 1341 goto failed; 1342 } 1343 } 1344 1345 info->group_ids = dbus_new (dbus_gid_t, buf_count); 1346 if (info->group_ids == NULL) 1347 { 1348 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1349 dbus_free (buf); 1350 goto failed; 1351 } 1352 1353 for (i = 0; i < buf_count; ++i) 1354 info->group_ids[i] = buf[i]; 1355 1356 info->n_group_ids = buf_count; 1357 1358 dbus_free (buf); 1359 } 1360 #else /* HAVE_GETGROUPLIST */ 1361 { 1362 /* We just get the one group ID */ 1363 info->group_ids = dbus_new (dbus_gid_t, 1); 1364 if (info->group_ids == NULL) 1365 { 1366 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1367 goto failed; 1368 } 1369 1370 info->n_group_ids = 1; 1371 1372 (info->group_ids)[0] = info->primary_gid; 1373 } 1374 #endif /* HAVE_GETGROUPLIST */ 1375 1376 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1377 1378 return TRUE; 1379 1380 failed: 1381 _DBUS_ASSERT_ERROR_IS_SET (error); 1382 return FALSE; 1383 } 1384 1385 /** 1386 * Gets user info for the given username. 1387 * 1388 * @param info user info object to initialize 1389 * @param username the username 1390 * @param error error return 1391 * @returns #TRUE on success 1392 */ 1393 dbus_bool_t 1394 _dbus_user_info_fill (DBusUserInfo *info, 1395 const DBusString *username, 1396 DBusError *error) 1397 { 1398 return fill_user_info (info, DBUS_UID_UNSET, 1399 username, error); 1400 } 1401 1402 /** 1403 * Gets user info for the given user ID. 1404 * 1405 * @param info user info object to initialize 1406 * @param uid the user ID 1407 * @param error error return 1408 * @returns #TRUE on success 1409 */ 1410 dbus_bool_t 1411 _dbus_user_info_fill_uid (DBusUserInfo *info, 1412 dbus_uid_t uid, 1413 DBusError *error) 1414 { 1415 return fill_user_info (info, uid, 1416 NULL, error); 1417 } 1418 1419 /** 1420 * Gets the credentials of the current process. 1421 * 1422 * @param credentials credentials to fill in. 1423 */ 1424 void 1425 _dbus_credentials_from_current_process (DBusCredentials *credentials) 1426 { 1427 /* The POSIX spec certainly doesn't promise this, but 1428 * we need these assertions to fail as soon as we're wrong about 1429 * it so we can do the porting fixups 1430 */ 1431 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid)); 1432 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid)); 1433 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid)); 1434 1435 credentials->pid = getpid (); 1436 credentials->uid = getuid (); 1437 credentials->gid = getgid (); 1438 } 1439 1440 /** 1441 * Gets our process ID 1442 * @returns process ID 1443 */ 1444 unsigned long 1445 _dbus_getpid (void) 1446 { 1447 return getpid (); 1448 } 1449 1450 /** Gets our UID 1451 * @returns process UID 1452 */ 1453 dbus_uid_t 1454 _dbus_getuid (void) 1455 { 1456 return getuid (); 1457 } 1458 1459 #ifdef DBUS_BUILD_TESTS 1460 /** Gets our GID 1461 * @returns process GID 1462 */ 1463 dbus_gid_t 1464 _dbus_getgid (void) 1465 { 1466 return getgid (); 1467 } 1468 #endif 1469 1470 /** 1471 * Wrapper for poll(). 1472 * 1473 * @param fds the file descriptors to poll 1474 * @param n_fds number of descriptors in the array 1475 * @param timeout_milliseconds timeout or -1 for infinite 1476 * @returns numbers of fds with revents, or <0 on error 1477 */ 1478 int 1479 _dbus_poll (DBusPollFD *fds, 1480 int n_fds, 1481 int timeout_milliseconds) 1482 { 1483 #ifdef HAVE_POLL 1484 /* This big thing is a constant expression and should get optimized 1485 * out of existence. So it's more robust than a configure check at 1486 * no cost. 1487 */ 1488 if (_DBUS_POLLIN == POLLIN && 1489 _DBUS_POLLPRI == POLLPRI && 1490 _DBUS_POLLOUT == POLLOUT && 1491 _DBUS_POLLERR == POLLERR && 1492 _DBUS_POLLHUP == POLLHUP && 1493 _DBUS_POLLNVAL == POLLNVAL && 1494 sizeof (DBusPollFD) == sizeof (struct pollfd) && 1495 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) == 1496 _DBUS_STRUCT_OFFSET (struct pollfd, fd) && 1497 _DBUS_STRUCT_OFFSET (DBusPollFD, events) == 1498 _DBUS_STRUCT_OFFSET (struct pollfd, events) && 1499 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == 1500 _DBUS_STRUCT_OFFSET (struct pollfd, revents)) 1501 { 1502 return poll ((struct pollfd*) fds, 1503 n_fds, 1504 timeout_milliseconds); 1505 } 1506 else 1507 { 1508 /* We have to convert the DBusPollFD to an array of 1509 * struct pollfd, poll, and convert back. 1510 */ 1511 _dbus_warn ("didn't implement poll() properly for this system yet\n"); 1512 return -1; 1513 } 1514 #else /* ! HAVE_POLL */ 1515 1516 fd_set read_set, write_set, err_set; 1517 int max_fd = 0; 1518 int i; 1519 struct timeval tv; 1520 int ready; 1521 1522 FD_ZERO (&read_set); 1523 FD_ZERO (&write_set); 1524 FD_ZERO (&err_set); 1525 1526 for (i = 0; i < n_fds; i++) 1527 { 1528 DBusPollFD *fdp = &fds[i]; 1529 1530 if (fdp->events & _DBUS_POLLIN) 1531 FD_SET (fdp->fd, &read_set); 1532 1533 if (fdp->events & _DBUS_POLLOUT) 1534 FD_SET (fdp->fd, &write_set); 1535 1536 FD_SET (fdp->fd, &err_set); 1537 1538 max_fd = MAX (max_fd, fdp->fd); 1539 } 1540 1541 tv.tv_sec = timeout_milliseconds / 1000; 1542 tv.tv_usec = (timeout_milliseconds % 1000) * 1000; 1543 1544 ready = select (max_fd + 1, &read_set, &write_set, &err_set, 1545 timeout_milliseconds < 0 ? NULL : &tv); 1546 1547 if (ready > 0) 1548 { 1549 for (i = 0; i < n_fds; i++) 1550 { 1551 DBusPollFD *fdp = &fds[i]; 1552 1553 fdp->revents = 0; 1554 1555 if (FD_ISSET (fdp->fd, &read_set)) 1556 fdp->revents |= _DBUS_POLLIN; 1557 1558 if (FD_ISSET (fdp->fd, &write_set)) 1559 fdp->revents |= _DBUS_POLLOUT; 1560 1561 if (FD_ISSET (fdp->fd, &err_set)) 1562 fdp->revents |= _DBUS_POLLERR; 1563 } 1564 } 1565 1566 return ready; 1567 #endif 1568 } 1569 1570 /** 1571 * Get current time, as in gettimeofday(). 1572 * 1573 * @param tv_sec return location for number of seconds 1574 * @param tv_usec return location for number of microseconds (thousandths) 1575 */ 1576 void 1577 _dbus_get_current_time (long *tv_sec, 1578 long *tv_usec) 1579 { 1580 struct timeval t; 1581 1582 gettimeofday (&t, NULL); 1583 1584 if (tv_sec) 1585 *tv_sec = t.tv_sec; 1586 if (tv_usec) 1587 *tv_usec = t.tv_usec; 1588 } 1589 1590 /** 1591 * Appends the contents of the given file to the string, 1592 * returning error code. At the moment, won't open a file 1593 * more than a megabyte in size. 1594 * 1595 * @param str the string to append to 1596 * @param filename filename to load 1597 * @param error place to set an error 1598 * @returns #FALSE if error was set 1599 */ 1600 dbus_bool_t 1601 _dbus_file_get_contents (DBusString *str, 1602 const DBusString *filename, 1603 DBusError *error) 1604 { 1605 int fd; 1606 struct stat sb; 1607 int orig_len; 1608 int total; 1609 const char *filename_c; 1610 1611 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1612 1613 filename_c = _dbus_string_get_const_data (filename); 1614 1615 /* O_BINARY useful on Cygwin */ 1616 fd = open (filename_c, O_RDONLY | O_BINARY); 1617 if (fd < 0) 1618 { 1619 dbus_set_error (error, _dbus_error_from_errno (errno), 1620 "Failed to open \"%s\": %s", 1621 filename_c, 1622 _dbus_strerror (errno)); 1623 return FALSE; 1624 } 1625 1626 if (fstat (fd, &sb) < 0) 1627 { 1628 dbus_set_error (error, _dbus_error_from_errno (errno), 1629 "Failed to stat \"%s\": %s", 1630 filename_c, 1631 _dbus_strerror (errno)); 1632 1633 _dbus_verbose ("fstat() failed: %s", 1634 _dbus_strerror (errno)); 1635 1636 _dbus_close (fd, NULL); 1637 1638 return FALSE; 1639 } 1640 1641 if (sb.st_size > _DBUS_ONE_MEGABYTE) 1642 { 1643 dbus_set_error (error, DBUS_ERROR_FAILED, 1644 "File size %lu of \"%s\" is too large.", 1645 (unsigned long) sb.st_size, filename_c); 1646 _dbus_close (fd, NULL); 1647 return FALSE; 1648 } 1649 1650 total = 0; 1651 orig_len = _dbus_string_get_length (str); 1652 if (sb.st_size > 0 && S_ISREG (sb.st_mode)) 1653 { 1654 int bytes_read; 1655 1656 while (total < (int) sb.st_size) 1657 { 1658 bytes_read = _dbus_read (fd, str, 1659 sb.st_size - total); 1660 if (bytes_read <= 0) 1661 { 1662 dbus_set_error (error, _dbus_error_from_errno (errno), 1663 "Error reading \"%s\": %s", 1664 filename_c, 1665 _dbus_strerror (errno)); 1666 1667 _dbus_verbose ("read() failed: %s", 1668 _dbus_strerror (errno)); 1669 1670 _dbus_close (fd, NULL); 1671 _dbus_string_set_length (str, orig_len); 1672 return FALSE; 1673 } 1674 else 1675 total += bytes_read; 1676 } 1677 1678 _dbus_close (fd, NULL); 1679 return TRUE; 1680 } 1681 else if (sb.st_size != 0) 1682 { 1683 _dbus_verbose ("Can only open regular files at the moment.\n"); 1684 dbus_set_error (error, DBUS_ERROR_FAILED, 1685 "\"%s\" is not a regular file", 1686 filename_c); 1687 _dbus_close (fd, NULL); 1688 return FALSE; 1689 } 1690 else 1691 { 1692 _dbus_close (fd, NULL); 1693 return TRUE; 1694 } 1695 } 1696 1697 /** 1698 * Writes a string out to a file. If the file exists, 1699 * it will be atomically overwritten by the new data. 1700 * 1701 * @param str the string to write out 1702 * @param filename the file to save string to 1703 * @param error error to be filled in on failure 1704 * @returns #FALSE on failure 1705 */ 1706 dbus_bool_t 1707 _dbus_string_save_to_file (const DBusString *str, 1708 const DBusString *filename, 1709 DBusError *error) 1710 { 1711 int fd; 1712 int bytes_to_write; 1713 const char *filename_c; 1714 DBusString tmp_filename; 1715 const char *tmp_filename_c; 1716 int total; 1717 dbus_bool_t need_unlink; 1718 dbus_bool_t retval; 1719 1720 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1721 1722 fd = -1; 1723 retval = FALSE; 1724 need_unlink = FALSE; 1725 1726 if (!_dbus_string_init (&tmp_filename)) 1727 { 1728 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1729 return FALSE; 1730 } 1731 1732 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0)) 1733 { 1734 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1735 _dbus_string_free (&tmp_filename); 1736 return FALSE; 1737 } 1738 1739 if (!_dbus_string_append (&tmp_filename, ".")) 1740 { 1741 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1742 _dbus_string_free (&tmp_filename); 1743 return FALSE; 1744 } 1745 1746 #define N_TMP_FILENAME_RANDOM_BYTES 8 1747 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES)) 1748 { 1749 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1750 _dbus_string_free (&tmp_filename); 1751 return FALSE; 1752 } 1753 1754 filename_c = _dbus_string_get_const_data (filename); 1755 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename); 1756 1757 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, 1758 0600); 1759 if (fd < 0) 1760 { 1761 dbus_set_error (error, _dbus_error_from_errno (errno), 1762 "Could not create %s: %s", tmp_filename_c, 1763 _dbus_strerror (errno)); 1764 goto out; 1765 } 1766 1767 need_unlink = TRUE; 1768 1769 total = 0; 1770 bytes_to_write = _dbus_string_get_length (str); 1771 1772 while (total < bytes_to_write) 1773 { 1774 int bytes_written; 1775 1776 bytes_written = _dbus_write (fd, str, total, 1777 bytes_to_write - total); 1778 1779 if (bytes_written <= 0) 1780 { 1781 dbus_set_error (error, _dbus_error_from_errno (errno), 1782 "Could not write to %s: %s", tmp_filename_c, 1783 _dbus_strerror (errno)); 1784 1785 goto out; 1786 } 1787 1788 total += bytes_written; 1789 } 1790 1791 if (!_dbus_close (fd, NULL)) 1792 { 1793 dbus_set_error (error, _dbus_error_from_errno (errno), 1794 "Could not close file %s: %s", 1795 tmp_filename_c, _dbus_strerror (errno)); 1796 1797 goto out; 1798 } 1799 1800 fd = -1; 1801 1802 if (rename (tmp_filename_c, filename_c) < 0) 1803 { 1804 dbus_set_error (error, _dbus_error_from_errno (errno), 1805 "Could not rename %s to %s: %s", 1806 tmp_filename_c, filename_c, 1807 _dbus_strerror (errno)); 1808 1809 goto out; 1810 } 1811 1812 need_unlink = FALSE; 1813 1814 retval = TRUE; 1815 1816 out: 1817 /* close first, then unlink, to prevent ".nfs34234235" garbage 1818 * files 1819 */ 1820 1821 if (fd >= 0) 1822 _dbus_close (fd, NULL); 1823 1824 if (need_unlink && unlink (tmp_filename_c) < 0) 1825 _dbus_verbose ("Failed to unlink temp file %s: %s\n", 1826 tmp_filename_c, _dbus_strerror (errno)); 1827 1828 _dbus_string_free (&tmp_filename); 1829 1830 if (!retval) 1831 _DBUS_ASSERT_ERROR_IS_SET (error); 1832 1833 return retval; 1834 } 1835 1836 /** Makes the file readable by every user in the system. 1837 * 1838 * @param filename the filename 1839 * @param error error location 1840 * @returns #TRUE if the file's permissions could be changed. 1841 */ 1842 dbus_bool_t 1843 _dbus_make_file_world_readable(const DBusString *filename, 1844 DBusError *error) 1845 { 1846 const char *filename_c; 1847 1848 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1849 1850 filename_c = _dbus_string_get_const_data (filename); 1851 if (chmod (filename_c, 0644) == -1) 1852 { 1853 dbus_set_error (error, 1854 DBUS_ERROR_FAILED, 1855 "Could not change permissions of file %s: %s\n", 1856 filename_c, 1857 _dbus_strerror (errno)); 1858 return FALSE; 1859 } 1860 return TRUE; 1861 } 1862 1863 /** Creates the given file, failing if the file already exists. 1864 * 1865 * @param filename the filename 1866 * @param error error location 1867 * @returns #TRUE if we created the file and it didn't exist 1868 */ 1869 dbus_bool_t 1870 _dbus_create_file_exclusively (const DBusString *filename, 1871 DBusError *error) 1872 { 1873 int fd; 1874 const char *filename_c; 1875 1876 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1877 1878 filename_c = _dbus_string_get_const_data (filename); 1879 1880 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT, 1881 0600); 1882 if (fd < 0) 1883 { 1884 dbus_set_error (error, 1885 DBUS_ERROR_FAILED, 1886 "Could not create file %s: %s\n", 1887 filename_c, 1888 _dbus_strerror (errno)); 1889 return FALSE; 1890 } 1891 1892 if (!_dbus_close (fd, NULL)) 1893 { 1894 dbus_set_error (error, 1895 DBUS_ERROR_FAILED, 1896 "Could not close file %s: %s\n", 1897 filename_c, 1898 _dbus_strerror (errno)); 1899 return FALSE; 1900 } 1901 1902 return TRUE; 1903 } 1904 1905 /** 1906 * Deletes the given file. 1907 * 1908 * @param filename the filename 1909 * @param error error location 1910 * 1911 * @returns #TRUE if unlink() succeeded 1912 */ 1913 dbus_bool_t 1914 _dbus_delete_file (const DBusString *filename, 1915 DBusError *error) 1916 { 1917 const char *filename_c; 1918 1919 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1920 1921 filename_c = _dbus_string_get_const_data (filename); 1922 1923 if (unlink (filename_c) < 0) 1924 { 1925 dbus_set_error (error, DBUS_ERROR_FAILED, 1926 "Failed to delete file %s: %s\n", 1927 filename_c, _dbus_strerror (errno)); 1928 return FALSE; 1929 } 1930 else 1931 return TRUE; 1932 } 1933 1934 /** 1935 * Creates a directory; succeeds if the directory 1936 * is created or already existed. 1937 * 1938 * @param filename directory filename 1939 * @param error initialized error object 1940 * @returns #TRUE on success 1941 */ 1942 dbus_bool_t 1943 _dbus_create_directory (const DBusString *filename, 1944 DBusError *error) 1945 { 1946 const char *filename_c; 1947 1948 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1949 1950 filename_c = _dbus_string_get_const_data (filename); 1951 1952 if (mkdir (filename_c, 0700) < 0) 1953 { 1954 if (errno == EEXIST) 1955 return TRUE; 1956 1957 dbus_set_error (error, DBUS_ERROR_FAILED, 1958 "Failed to create directory %s: %s\n", 1959 filename_c, _dbus_strerror (errno)); 1960 return FALSE; 1961 } 1962 else 1963 return TRUE; 1964 } 1965 1966 /** 1967 * Appends the given filename to the given directory. 1968 * 1969 * @todo it might be cute to collapse multiple '/' such as "foo//" 1970 * concat "//bar" 1971 * 1972 * @param dir the directory name 1973 * @param next_component the filename 1974 * @returns #TRUE on success 1975 */ 1976 dbus_bool_t 1977 _dbus_concat_dir_and_file (DBusString *dir, 1978 const DBusString *next_component) 1979 { 1980 dbus_bool_t dir_ends_in_slash; 1981 dbus_bool_t file_starts_with_slash; 1982 1983 if (_dbus_string_get_length (dir) == 0 || 1984 _dbus_string_get_length (next_component) == 0) 1985 return TRUE; 1986 1987 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, 1988 _dbus_string_get_length (dir) - 1); 1989 1990 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); 1991 1992 if (dir_ends_in_slash && file_starts_with_slash) 1993 { 1994 _dbus_string_shorten (dir, 1); 1995 } 1996 else if (!(dir_ends_in_slash || file_starts_with_slash)) 1997 { 1998 if (!_dbus_string_append_byte (dir, '/')) 1999 return FALSE; 2000 } 2001 2002 return _dbus_string_copy (next_component, 0, dir, 2003 _dbus_string_get_length (dir)); 2004 } 2005 2006 /** nanoseconds in a second */ 2007 #define NANOSECONDS_PER_SECOND 1000000000 2008 /** microseconds in a second */ 2009 #define MICROSECONDS_PER_SECOND 1000000 2010 /** milliseconds in a second */ 2011 #define MILLISECONDS_PER_SECOND 1000 2012 /** nanoseconds in a millisecond */ 2013 #define NANOSECONDS_PER_MILLISECOND 1000000 2014 /** microseconds in a millisecond */ 2015 #define MICROSECONDS_PER_MILLISECOND 1000 2016 2017 /** 2018 * Sleeps the given number of milliseconds. 2019 * @param milliseconds number of milliseconds 2020 */ 2021 void 2022 _dbus_sleep_milliseconds (int milliseconds) 2023 { 2024 #ifdef HAVE_NANOSLEEP 2025 struct timespec req; 2026 struct timespec rem; 2027 2028 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND; 2029 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; 2030 rem.tv_sec = 0; 2031 rem.tv_nsec = 0; 2032 2033 while (nanosleep (&req, &rem) < 0 && errno == EINTR) 2034 req = rem; 2035 #elif defined (HAVE_USLEEP) 2036 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND); 2037 #else /* ! HAVE_USLEEP */ 2038 sleep (MAX (milliseconds / 1000, 1)); 2039 #endif 2040 } 2041 2042 static dbus_bool_t 2043 _dbus_generate_pseudorandom_bytes (DBusString *str, 2044 int n_bytes) 2045 { 2046 int old_len; 2047 char *p; 2048 2049 old_len = _dbus_string_get_length (str); 2050 2051 if (!_dbus_string_lengthen (str, n_bytes)) 2052 return FALSE; 2053 2054 p = _dbus_string_get_data_len (str, old_len, n_bytes); 2055 2056 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes); 2057 2058 return TRUE; 2059 } 2060 2061 /** 2062 * Generates the given number of random bytes, 2063 * using the best mechanism we can come up with. 2064 * 2065 * @param str the string 2066 * @param n_bytes the number of random bytes to append to string 2067 * @returns #TRUE on success, #FALSE if no memory 2068 */ 2069 dbus_bool_t 2070 _dbus_generate_random_bytes (DBusString *str, 2071 int n_bytes) 2072 { 2073 int old_len; 2074 int fd; 2075 2076 /* FALSE return means "no memory", if it could 2077 * mean something else then we'd need to return 2078 * a DBusError. So we always fall back to pseudorandom 2079 * if the I/O fails. 2080 */ 2081 2082 old_len = _dbus_string_get_length (str); 2083 fd = -1; 2084 2085 /* note, urandom on linux will fall back to pseudorandom */ 2086 fd = open ("/dev/urandom", O_RDONLY); 2087 if (fd < 0) 2088 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 2089 2090 if (_dbus_read (fd, str, n_bytes) != n_bytes) 2091 { 2092 _dbus_close (fd, NULL); 2093 _dbus_string_set_length (str, old_len); 2094 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 2095 } 2096 2097 _dbus_verbose ("Read %d bytes from /dev/urandom\n", 2098 n_bytes); 2099 2100 _dbus_close (fd, NULL); 2101 2102 return TRUE; 2103 } 2104 2105 /** 2106 * Exit the process, returning the given value. 2107 * 2108 * @param code the exit code 2109 */ 2110 void 2111 _dbus_exit (int code) 2112 { 2113 _exit (code); 2114 } 2115 2116 /** 2117 * A wrapper around strerror() because some platforms 2118 * may be lame and not have strerror(). 2119 * 2120 * @param error_number errno. 2121 * @returns error description. 2122 */ 2123 const char* 2124 _dbus_strerror (int error_number) 2125 { 2126 const char *msg; 2127 2128 msg = strerror (error_number); 2129 if (msg == NULL) 2130 msg = "unknown"; 2131 2132 return msg; 2133 } 2134 2135 /** 2136 * signal (SIGPIPE, SIG_IGN); 2137 */ 2138 void 2139 _dbus_disable_sigpipe (void) 2140 { 2141 signal (SIGPIPE, SIG_IGN); 2142 } 2143 2144 /** 2145 * Sets the file descriptor to be close 2146 * on exec. Should be called for all file 2147 * descriptors in D-Bus code. 2148 * 2149 * @param fd the file descriptor 2150 */ 2151 void 2152 _dbus_fd_set_close_on_exec (int fd) 2153 { 2154 int val; 2155 2156 val = fcntl (fd, F_GETFD, 0); 2157 2158 if (val < 0) 2159 return; 2160 2161 val |= FD_CLOEXEC; 2162 2163 fcntl (fd, F_SETFD, val); 2164 } 2165 2166 /** 2167 * Closes a file descriptor. 2168 * 2169 * @param fd the file descriptor 2170 * @param error error object 2171 * @returns #FALSE if error set 2172 */ 2173 dbus_bool_t 2174 _dbus_close (int fd, 2175 DBusError *error) 2176 { 2177 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2178 2179 again: 2180 if (close (fd) < 0) 2181 { 2182 if (errno == EINTR) 2183 goto again; 2184 2185 dbus_set_error (error, _dbus_error_from_errno (errno), 2186 "Could not close fd %d", fd); 2187 return FALSE; 2188 } 2189 2190 return TRUE; 2191 } 2192 2193 /** 2194 * Sets a file descriptor to be nonblocking. 2195 * 2196 * @param fd the file descriptor. 2197 * @param error address of error location. 2198 * @returns #TRUE on success. 2199 */ 2200 dbus_bool_t 2201 _dbus_set_fd_nonblocking (int fd, 2202 DBusError *error) 2203 { 2204 int val; 2205 2206 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2207 2208 val = fcntl (fd, F_GETFL, 0); 2209 if (val < 0) 2210 { 2211 dbus_set_error (error, _dbus_error_from_errno (errno), 2212 "Failed to get flags from file descriptor %d: %s", 2213 fd, _dbus_strerror (errno)); 2214 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 2215 _dbus_strerror (errno)); 2216 return FALSE; 2217 } 2218 2219 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 2220 { 2221 dbus_set_error (error, _dbus_error_from_errno (errno), 2222 "Failed to set nonblocking flag of file descriptor %d: %s", 2223 fd, _dbus_strerror (errno)); 2224 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 2225 fd, _dbus_strerror (errno)); 2226 2227 return FALSE; 2228 } 2229 2230 return TRUE; 2231 } 2232 2233 /** 2234 * On GNU libc systems, print a crude backtrace to stderr. On other 2235 * systems, print "no backtrace support" and block for possible gdb 2236 * attachment if an appropriate environment variable is set. 2237 */ 2238 void 2239 _dbus_print_backtrace (void) 2240 { 2241 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC) 2242 void *bt[500]; 2243 int bt_size; 2244 int i; 2245 char **syms; 2246 2247 bt_size = backtrace (bt, 500); 2248 2249 syms = backtrace_symbols (bt, bt_size); 2250 2251 i = 0; 2252 while (i < bt_size) 2253 { 2254 /* don't use dbus_warn since it can _dbus_abort() */ 2255 fprintf (stderr, " %s\n", syms[i]); 2256 ++i; 2257 } 2258 fflush (stderr); 2259 2260 free (syms); 2261 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC) 2262 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n"); 2263 #else 2264 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n"); 2265 #endif 2266 } 2267 2268 /** 2269 * Creates a full-duplex pipe (as in socketpair()). 2270 * Sets both ends of the pipe nonblocking. 2271 * 2272 * @todo libdbus only uses this for the debug-pipe server, so in 2273 * principle it could be in dbus-sysdeps-util.c, except that 2274 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the 2275 * debug-pipe server is used. 2276 * 2277 * @param fd1 return location for one end 2278 * @param fd2 return location for the other end 2279 * @param blocking #TRUE if pipe should be blocking 2280 * @param error error return 2281 * @returns #FALSE on failure (if error is set) 2282 */ 2283 dbus_bool_t 2284 _dbus_full_duplex_pipe (int *fd1, 2285 int *fd2, 2286 dbus_bool_t blocking, 2287 DBusError *error) 2288 { 2289 #ifdef HAVE_SOCKETPAIR 2290 int fds[2]; 2291 2292 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2293 2294 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0) 2295 { 2296 dbus_set_error (error, _dbus_error_from_errno (errno), 2297 "Could not create full-duplex pipe"); 2298 return FALSE; 2299 } 2300 2301 if (!blocking && 2302 (!_dbus_set_fd_nonblocking (fds[0], NULL) || 2303 !_dbus_set_fd_nonblocking (fds[1], NULL))) 2304 { 2305 dbus_set_error (error, _dbus_error_from_errno (errno), 2306 "Could not set full-duplex pipe nonblocking"); 2307 2308 _dbus_close (fds[0], NULL); 2309 _dbus_close (fds[1], NULL); 2310 2311 return FALSE; 2312 } 2313 2314 *fd1 = fds[0]; 2315 *fd2 = fds[1]; 2316 2317 _dbus_verbose ("full-duplex pipe %d <-> %d\n", 2318 *fd1, *fd2); 2319 2320 return TRUE; 2321 #else 2322 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n"); 2323 dbus_set_error (error, DBUS_ERROR_FAILED, 2324 "_dbus_full_duplex_pipe() not implemented on this OS"); 2325 return FALSE; 2326 #endif 2327 } 2328 2329 2330 /** 2331 * Measure the length of the given format string and arguments, 2332 * not including the terminating nul. 2333 * 2334 * @param format a printf-style format string 2335 * @param args arguments for the format string 2336 * @returns length of the given format string and args 2337 */ 2338 int 2339 _dbus_printf_string_upper_bound (const char *format, 2340 va_list args) 2341 { 2342 char c; 2343 return vsnprintf (&c, 1, format, args); 2344 } 2345 2346 /** 2347 * Gets the temporary files directory by inspecting the environment variables 2348 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned 2349 * 2350 * @returns location of temp directory 2351 */ 2352 const char* 2353 _dbus_get_tmpdir(void) 2354 { 2355 static const char* tmpdir = NULL; 2356 2357 if (tmpdir == NULL) 2358 { 2359 /* TMPDIR is what glibc uses, then 2360 * glibc falls back to the P_tmpdir macro which 2361 * just expands to "/tmp" 2362 */ 2363 if (tmpdir == NULL) 2364 tmpdir = getenv("TMPDIR"); 2365 2366 /* These two env variables are probably 2367 * broken, but maybe some OS uses them? 2368 */ 2369 if (tmpdir == NULL) 2370 tmpdir = getenv("TMP"); 2371 if (tmpdir == NULL) 2372 tmpdir = getenv("TEMP"); 2373 2374 /* And this is the sane fallback. */ 2375 if (tmpdir == NULL) 2376 tmpdir = "/tmp"; 2377 } 2378 2379 _dbus_assert(tmpdir != NULL); 2380 2381 return tmpdir; 2382 } 2383 2384 /** 2385 * Determines the address of the session bus by querying a 2386 * platform-specific method. 2387 * 2388 * If successful, returns #TRUE and appends the address to @p 2389 * address. If a failure happens, returns #FALSE and 2390 * sets an error in @p error. 2391 * 2392 * @param address a DBusString where the address can be stored 2393 * @param error a DBusError to store the error in case of failure 2394 * @returns #TRUE on success, #FALSE if an error happened 2395 */ 2396 dbus_bool_t 2397 _dbus_get_autolaunch_address (DBusString *address, 2398 DBusError *error) 2399 { 2400 static char *argv[5]; 2401 int address_pipe[2]; 2402 pid_t pid; 2403 int ret; 2404 int status; 2405 int orig_len; 2406 int i; 2407 DBusString uuid; 2408 dbus_bool_t retval; 2409 2410 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2411 retval = FALSE; 2412 2413 _dbus_string_init (&uuid); 2414 2415 if (!_dbus_get_local_machine_uuid_encoded (&uuid)) 2416 { 2417 _DBUS_SET_OOM (error); 2418 goto out; 2419 } 2420 2421 i = 0; 2422 argv[i] = "dbus-launch"; 2423 ++i; 2424 argv[i] = "--autolaunch"; 2425 ++i; 2426 argv[i] = _dbus_string_get_data (&uuid); 2427 ++i; 2428 argv[i] = "--binary-syntax"; 2429 ++i; 2430 argv[i] = NULL; 2431 ++i; 2432 2433 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 2434 2435 orig_len = _dbus_string_get_length (address); 2436 2437 #define READ_END 0 2438 #define WRITE_END 1 2439 if (pipe (address_pipe) < 0) 2440 { 2441 dbus_set_error (error, _dbus_error_from_errno (errno), 2442 "Failed to create a pipe: %s", 2443 _dbus_strerror (errno)); 2444 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n", 2445 _dbus_strerror (errno)); 2446 goto out; 2447 } 2448 2449 pid = fork (); 2450 if (pid < 0) 2451 { 2452 dbus_set_error (error, _dbus_error_from_errno (errno), 2453 "Failed to fork(): %s", 2454 _dbus_strerror (errno)); 2455 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n", 2456 _dbus_strerror (errno)); 2457 goto out; 2458 } 2459 2460 if (pid == 0) 2461 { 2462 /* child process */ 2463 int fd = open ("/dev/null", O_RDWR); 2464 if (fd == -1) 2465 /* huh?! can't open /dev/null? */ 2466 _exit (1); 2467 2468 /* set-up stdXXX */ 2469 close (address_pipe[READ_END]); 2470 close (0); /* close stdin */ 2471 close (1); /* close stdout */ 2472 close (2); /* close stderr */ 2473 2474 if (dup2 (fd, 0) == -1) 2475 _exit (1); 2476 if (dup2 (address_pipe[WRITE_END], 1) == -1) 2477 _exit (1); 2478 if (dup2 (fd, 2) == -1) 2479 _exit (1); 2480 2481 close (fd); 2482 close (address_pipe[WRITE_END]); 2483 2484 execv (DBUS_BINDIR "/dbus-launch", argv); 2485 2486 /* failed, try searching PATH */ 2487 execvp ("dbus-launch", argv); 2488 2489 /* still nothing, we failed */ 2490 _exit (1); 2491 } 2492 2493 /* parent process */ 2494 close (address_pipe[WRITE_END]); 2495 ret = 0; 2496 do 2497 { 2498 ret = _dbus_read (address_pipe[READ_END], address, 1024); 2499 } 2500 while (ret > 0); 2501 2502 /* reap the child process to avoid it lingering as zombie */ 2503 do 2504 { 2505 ret = waitpid (pid, &status, 0); 2506 } 2507 while (ret == -1 && errno == EINTR); 2508 2509 /* We succeeded if the process exited with status 0 and 2510 anything was read */ 2511 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 || 2512 _dbus_string_get_length (address) == orig_len) 2513 { 2514 /* The process ended with error */ 2515 _dbus_string_set_length (address, orig_len); 2516 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 2517 "Failed to execute dbus-launch to autolaunch D-Bus session"); 2518 goto out; 2519 } 2520 2521 retval = TRUE; 2522 2523 out: 2524 if (retval) 2525 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2526 else 2527 _DBUS_ASSERT_ERROR_IS_SET (error); 2528 2529 _dbus_string_free (&uuid); 2530 return retval; 2531 } 2532 2533 /** 2534 * Reads the uuid of the machine we're running on from 2535 * the dbus configuration. Optionally try to create it 2536 * (only root can do this usually). 2537 * 2538 * On UNIX, reads a file that gets created by dbus-uuidgen 2539 * in a post-install script. On Windows, if there's a standard 2540 * machine uuid we could just use that, but I can't find one 2541 * with the right properties (the hardware profile guid can change 2542 * without rebooting I believe). If there's no standard one 2543 * we might want to use the registry instead of a file for 2544 * this, and I'm not sure how we'd ensure the uuid gets created. 2545 * 2546 * @param machine_id guid to init with the machine's uuid 2547 * @param create_if_not_found try to create the uuid if it doesn't exist 2548 * @param error the error return 2549 * @returns #FALSE if the error is set 2550 */ 2551 dbus_bool_t 2552 _dbus_read_local_machine_uuid (DBusGUID *machine_id, 2553 dbus_bool_t create_if_not_found, 2554 DBusError *error) 2555 { 2556 DBusString filename; 2557 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE); 2558 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error); 2559 } 2560 2561 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" 2562 2563 static dbus_bool_t 2564 split_paths_and_append (DBusString *dirs, 2565 const char *suffix, 2566 DBusList **dir_list) 2567 { 2568 /* split on colon (:) */ 2569 int start; 2570 int i; 2571 int len; 2572 char *cpath; 2573 const DBusString file_suffix; 2574 2575 start = 0; 2576 i = 0; 2577 2578 _dbus_string_init_const (&file_suffix, suffix); 2579 2580 len = _dbus_string_get_length (dirs); 2581 2582 while (_dbus_string_find (dirs, start, ":", &i)) 2583 { 2584 DBusString path; 2585 2586 if (!_dbus_string_init (&path)) 2587 goto oom; 2588 2589 if (!_dbus_string_copy_len (dirs, 2590 start, 2591 i - start, 2592 &path, 2593 0)) 2594 { 2595 _dbus_string_free (&path); 2596 goto oom; 2597 } 2598 2599 _dbus_string_chop_white (&path); 2600 2601 /* check for an empty path */ 2602 if (_dbus_string_get_length (&path) == 0) 2603 goto next; 2604 2605 if (!_dbus_concat_dir_and_file (&path, 2606 &file_suffix)) 2607 { 2608 _dbus_string_free (&path); 2609 goto oom; 2610 } 2611 2612 if (!_dbus_string_copy_data(&path, &cpath)) 2613 { 2614 _dbus_string_free (&path); 2615 goto oom; 2616 } 2617 2618 if (!_dbus_list_append (dir_list, cpath)) 2619 { 2620 _dbus_string_free (&path); 2621 dbus_free (cpath); 2622 goto oom; 2623 } 2624 2625 next: 2626 _dbus_string_free (&path); 2627 start = i + 1; 2628 } 2629 2630 if (start != len) 2631 { 2632 DBusString path; 2633 2634 if (!_dbus_string_init (&path)) 2635 goto oom; 2636 2637 if (!_dbus_string_copy_len (dirs, 2638 start, 2639 len - start, 2640 &path, 2641 0)) 2642 { 2643 _dbus_string_free (&path); 2644 goto oom; 2645 } 2646 2647 if (!_dbus_concat_dir_and_file (&path, 2648 &file_suffix)) 2649 { 2650 _dbus_string_free (&path); 2651 goto oom; 2652 } 2653 2654 if (!_dbus_string_copy_data(&path, &cpath)) 2655 { 2656 _dbus_string_free (&path); 2657 goto oom; 2658 } 2659 2660 if (!_dbus_list_append (dir_list, cpath)) 2661 { 2662 _dbus_string_free (&path); 2663 dbus_free (cpath); 2664 goto oom; 2665 } 2666 2667 _dbus_string_free (&path); 2668 } 2669 2670 return TRUE; 2671 2672 oom: 2673 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 2674 _dbus_list_clear (dir_list); 2675 return FALSE; 2676 } 2677 2678 /** 2679 * Returns the standard directories for a session bus to look for service 2680 * activation files 2681 * 2682 * On UNIX this should be the standard xdg freedesktop.org data directories: 2683 * 2684 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share} 2685 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share} 2686 * 2687 * and 2688 * 2689 * DBUS_DATADIR 2690 * 2691 * @param dirs the directory list we are returning 2692 * @returns #FALSE on OOM 2693 */ 2694 2695 dbus_bool_t 2696 _dbus_get_standard_session_servicedirs (DBusList **dirs) 2697 { 2698 const char *xdg_data_home; 2699 const char *xdg_data_dirs; 2700 DBusString servicedir_path; 2701 2702 if (!_dbus_string_init (&servicedir_path)) 2703 return FALSE; 2704 2705 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); 2706 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 2707 2708 if (xdg_data_dirs != NULL) 2709 { 2710 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 2711 goto oom; 2712 2713 if (!_dbus_string_append (&servicedir_path, ":")) 2714 goto oom; 2715 } 2716 else 2717 { 2718 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 2719 goto oom; 2720 } 2721 2722 /* 2723 * add configured datadir to defaults 2724 * this may be the same as an xdg dir 2725 * however the config parser should take 2726 * care of duplicates 2727 */ 2728 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":")) 2729 goto oom; 2730 2731 if (xdg_data_home != NULL) 2732 { 2733 if (!_dbus_string_append (&servicedir_path, xdg_data_home)) 2734 goto oom; 2735 } 2736 else 2737 { 2738 const DBusString *homedir; 2739 const DBusString local_share; 2740 2741 if (!_dbus_homedir_from_current_process (&homedir)) 2742 goto oom; 2743 2744 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) 2745 goto oom; 2746 2747 _dbus_string_init_const (&local_share, "/.local/share"); 2748 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) 2749 goto oom; 2750 } 2751 2752 if (!split_paths_and_append (&servicedir_path, 2753 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 2754 dirs)) 2755 goto oom; 2756 2757 _dbus_string_free (&servicedir_path); 2758 return TRUE; 2759 2760 oom: 2761 _dbus_string_free (&servicedir_path); 2762 return FALSE; 2763 } 2764 2765 /* tests in dbus-sysdeps-util.c */ 2766