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