D-Bus
1.4.18
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation) 00003 * 00004 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. 00005 * Copyright (C) 2003 CodeFactory AB 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 */ 00024 00025 #include <config.h> 00026 00027 #include "dbus-internals.h" 00028 #include "dbus-sysdeps.h" 00029 #include "dbus-sysdeps-unix.h" 00030 #include "dbus-threads.h" 00031 #include "dbus-protocol.h" 00032 #include "dbus-transport.h" 00033 #include "dbus-string.h" 00034 #include "dbus-userdb.h" 00035 #include "dbus-list.h" 00036 #include "dbus-credentials.h" 00037 #include "dbus-nonce.h" 00038 00039 #include <sys/types.h> 00040 #include <stdlib.h> 00041 #include <string.h> 00042 #include <signal.h> 00043 #include <unistd.h> 00044 #include <stdio.h> 00045 #include <fcntl.h> 00046 #include <sys/socket.h> 00047 #include <dirent.h> 00048 #include <sys/un.h> 00049 #include <pwd.h> 00050 #include <time.h> 00051 #include <locale.h> 00052 #include <sys/time.h> 00053 #include <sys/stat.h> 00054 #include <sys/wait.h> 00055 #include <netinet/in.h> 00056 #include <netdb.h> 00057 #include <grp.h> 00058 00059 #ifdef HAVE_ERRNO_H 00060 #include <errno.h> 00061 #endif 00062 #ifdef HAVE_WRITEV 00063 #include <sys/uio.h> 00064 #endif 00065 #ifdef HAVE_POLL 00066 #include <sys/poll.h> 00067 #endif 00068 #ifdef HAVE_BACKTRACE 00069 #include <execinfo.h> 00070 #endif 00071 #ifdef HAVE_GETPEERUCRED 00072 #include <ucred.h> 00073 #endif 00074 00075 #ifdef HAVE_ADT 00076 #include <bsm/adt.h> 00077 #endif 00078 00079 #include "sd-daemon.h" 00080 00081 #ifndef O_BINARY 00082 #define O_BINARY 0 00083 #endif 00084 00085 #ifndef AI_ADDRCONFIG 00086 #define AI_ADDRCONFIG 0 00087 #endif 00088 00089 #ifndef HAVE_SOCKLEN_T 00090 #define socklen_t int 00091 #endif 00092 00093 #if defined (__sun) || defined (__sun__) 00094 /* 00095 * CMS_SPACE etc. definitions for Solaris < 10, based on 00096 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html 00097 * via 00098 * http://wiki.opencsw.org/porting-faq#toc10 00099 * 00100 * These are only redefined for Solaris, for now: if your OS needs these too, 00101 * please file a bug. (Or preferably, improve your OS so they're not needed.) 00102 */ 00103 00104 # ifndef CMSG_ALIGN 00105 # ifdef __sun__ 00106 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len) 00107 # else 00108 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */ 00109 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \ 00110 ~(sizeof (long) - 1)) 00111 # endif 00112 # endif 00113 00114 # ifndef CMSG_SPACE 00115 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \ 00116 CMSG_ALIGN (len)) 00117 # endif 00118 00119 # ifndef CMSG_LEN 00120 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) 00121 # endif 00122 00123 #endif /* Solaris */ 00124 00125 static dbus_bool_t 00126 _dbus_open_socket (int *fd_p, 00127 int domain, 00128 int type, 00129 int protocol, 00130 DBusError *error) 00131 { 00132 #ifdef SOCK_CLOEXEC 00133 dbus_bool_t cloexec_done; 00134 00135 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol); 00136 cloexec_done = *fd_p >= 0; 00137 00138 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */ 00139 if (*fd_p < 0 && errno == EINVAL) 00140 #endif 00141 { 00142 *fd_p = socket (domain, type, protocol); 00143 } 00144 00145 if (*fd_p >= 0) 00146 { 00147 #ifdef SOCK_CLOEXEC 00148 if (!cloexec_done) 00149 #endif 00150 { 00151 _dbus_fd_set_close_on_exec(*fd_p); 00152 } 00153 00154 _dbus_verbose ("socket fd %d opened\n", *fd_p); 00155 return TRUE; 00156 } 00157 else 00158 { 00159 dbus_set_error(error, 00160 _dbus_error_from_errno (errno), 00161 "Failed to open socket: %s", 00162 _dbus_strerror (errno)); 00163 return FALSE; 00164 } 00165 } 00166 00167 dbus_bool_t 00168 _dbus_open_tcp_socket (int *fd, 00169 DBusError *error) 00170 { 00171 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error); 00172 } 00173 00184 dbus_bool_t 00185 _dbus_open_unix_socket (int *fd, 00186 DBusError *error) 00187 { 00188 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error); 00189 } 00190 00199 dbus_bool_t 00200 _dbus_close_socket (int fd, 00201 DBusError *error) 00202 { 00203 return _dbus_close (fd, error); 00204 } 00205 00215 int 00216 _dbus_read_socket (int fd, 00217 DBusString *buffer, 00218 int count) 00219 { 00220 return _dbus_read (fd, buffer, count); 00221 } 00222 00233 int 00234 _dbus_write_socket (int fd, 00235 const DBusString *buffer, 00236 int start, 00237 int len) 00238 { 00239 #if HAVE_DECL_MSG_NOSIGNAL 00240 const char *data; 00241 int bytes_written; 00242 00243 data = _dbus_string_get_const_data_len (buffer, start, len); 00244 00245 again: 00246 00247 bytes_written = send (fd, data, len, MSG_NOSIGNAL); 00248 00249 if (bytes_written < 0 && errno == EINTR) 00250 goto again; 00251 00252 return bytes_written; 00253 00254 #else 00255 return _dbus_write (fd, buffer, start, len); 00256 #endif 00257 } 00258 00271 int 00272 _dbus_read_socket_with_unix_fds (int fd, 00273 DBusString *buffer, 00274 int count, 00275 int *fds, 00276 int *n_fds) { 00277 #ifndef HAVE_UNIX_FD_PASSING 00278 int r; 00279 00280 if ((r = _dbus_read_socket(fd, buffer, count)) < 0) 00281 return r; 00282 00283 *n_fds = 0; 00284 return r; 00285 00286 #else 00287 int bytes_read; 00288 int start; 00289 struct msghdr m; 00290 struct iovec iov; 00291 00292 _dbus_assert (count >= 0); 00293 _dbus_assert (*n_fds >= 0); 00294 00295 start = _dbus_string_get_length (buffer); 00296 00297 if (!_dbus_string_lengthen (buffer, count)) 00298 { 00299 errno = ENOMEM; 00300 return -1; 00301 } 00302 00303 _DBUS_ZERO(iov); 00304 iov.iov_base = _dbus_string_get_data_len (buffer, start, count); 00305 iov.iov_len = count; 00306 00307 _DBUS_ZERO(m); 00308 m.msg_iov = &iov; 00309 m.msg_iovlen = 1; 00310 00311 /* Hmm, we have no clue how long the control data will actually be 00312 that is queued for us. The least we can do is assume that the 00313 caller knows. Hence let's make space for the number of fds that 00314 we shall read at max plus the cmsg header. */ 00315 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int)); 00316 00317 /* It's probably safe to assume that systems with SCM_RIGHTS also 00318 know alloca() */ 00319 m.msg_control = alloca(m.msg_controllen); 00320 memset(m.msg_control, 0, m.msg_controllen); 00321 00322 /* Do not include the padding at the end when we tell the kernel 00323 * how much we're willing to receive. This avoids getting 00324 * the padding filled with additional fds that we weren't expecting, 00325 * if a (potentially malicious) sender included them. (fd.o #83622) */ 00326 m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int)); 00327 00328 again: 00329 00330 bytes_read = recvmsg(fd, &m, 0 00331 #ifdef MSG_CMSG_CLOEXEC 00332 |MSG_CMSG_CLOEXEC 00333 #endif 00334 ); 00335 00336 if (bytes_read < 0) 00337 { 00338 if (errno == EINTR) 00339 goto again; 00340 else 00341 { 00342 /* put length back (note that this doesn't actually realloc anything) */ 00343 _dbus_string_set_length (buffer, start); 00344 return -1; 00345 } 00346 } 00347 else 00348 { 00349 struct cmsghdr *cm; 00350 dbus_bool_t found = FALSE; 00351 00352 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) 00353 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) 00354 { 00355 size_t i; 00356 int *payload = (int *) CMSG_DATA (cm); 00357 size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0)); 00358 size_t payload_len_fds = payload_len_bytes / sizeof (int); 00359 size_t fds_to_use; 00360 00361 /* Every non-negative int fits in a size_t without truncation, 00362 * and we already know that *n_fds is non-negative, so 00363 * casting (size_t) *n_fds is OK */ 00364 _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int)); 00365 00366 if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds)) 00367 { 00368 /* The fds in the payload will fit in our buffer */ 00369 fds_to_use = payload_len_fds; 00370 } 00371 else 00372 { 00373 /* Too many fds in the payload. This shouldn't happen 00374 * any more because we're setting m.msg_controllen to 00375 * the exact number we can accept, but be safe and 00376 * truncate. */ 00377 fds_to_use = (size_t) *n_fds; 00378 00379 /* Close the excess fds to avoid DoS: if they stayed open, 00380 * someone could send us an extra fd per message 00381 * and we'd eventually run out. */ 00382 for (i = fds_to_use; i < payload_len_fds; i++) 00383 { 00384 close (payload[i]); 00385 } 00386 } 00387 00388 memcpy (fds, payload, fds_to_use * sizeof (int)); 00389 found = TRUE; 00390 /* This cannot overflow because we have chosen fds_to_use 00391 * to be <= *n_fds */ 00392 *n_fds = (int) fds_to_use; 00393 00394 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually 00395 worked, hence we need to go through this list and set 00396 CLOEXEC everywhere in any case */ 00397 for (i = 0; i < fds_to_use; i++) 00398 _dbus_fd_set_close_on_exec(fds[i]); 00399 00400 break; 00401 } 00402 00403 if (!found) 00404 *n_fds = 0; 00405 00406 if (m.msg_flags & MSG_CTRUNC) 00407 { 00408 int i; 00409 00410 /* Hmm, apparently the control data was truncated. The bad 00411 thing is that we might have completely lost a couple of fds 00412 without chance to recover them. Hence let's treat this as a 00413 serious error. */ 00414 00415 /* We still need to close whatever fds we *did* receive, 00416 * otherwise they'll never get closed. (CVE-2020-12049) */ 00417 for (i = 0; i < *n_fds; i++) 00418 close (fds[i]); 00419 00420 *n_fds = 0; 00421 errno = ENOSPC; 00422 _dbus_string_set_length (buffer, start); 00423 return -1; 00424 } 00425 00426 /* put length back (doesn't actually realloc) */ 00427 _dbus_string_set_length (buffer, start + bytes_read); 00428 00429 #if 0 00430 if (bytes_read > 0) 00431 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00432 #endif 00433 00434 return bytes_read; 00435 } 00436 #endif 00437 } 00438 00439 int 00440 _dbus_write_socket_with_unix_fds(int fd, 00441 const DBusString *buffer, 00442 int start, 00443 int len, 00444 const int *fds, 00445 int n_fds) { 00446 00447 #ifndef HAVE_UNIX_FD_PASSING 00448 00449 if (n_fds > 0) { 00450 errno = ENOTSUP; 00451 return -1; 00452 } 00453 00454 return _dbus_write_socket(fd, buffer, start, len); 00455 #else 00456 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds); 00457 #endif 00458 } 00459 00460 int 00461 _dbus_write_socket_with_unix_fds_two(int fd, 00462 const DBusString *buffer1, 00463 int start1, 00464 int len1, 00465 const DBusString *buffer2, 00466 int start2, 00467 int len2, 00468 const int *fds, 00469 int n_fds) { 00470 00471 #ifndef HAVE_UNIX_FD_PASSING 00472 00473 if (n_fds > 0) { 00474 errno = ENOTSUP; 00475 return -1; 00476 } 00477 00478 return _dbus_write_socket_two(fd, 00479 buffer1, start1, len1, 00480 buffer2, start2, len2); 00481 #else 00482 00483 struct msghdr m; 00484 struct cmsghdr *cm; 00485 struct iovec iov[2]; 00486 int bytes_written; 00487 00488 _dbus_assert (len1 >= 0); 00489 _dbus_assert (len2 >= 0); 00490 _dbus_assert (n_fds >= 0); 00491 00492 _DBUS_ZERO(iov); 00493 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1); 00494 iov[0].iov_len = len1; 00495 00496 if (buffer2) 00497 { 00498 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2); 00499 iov[1].iov_len = len2; 00500 } 00501 00502 _DBUS_ZERO(m); 00503 m.msg_iov = iov; 00504 m.msg_iovlen = buffer2 ? 2 : 1; 00505 00506 if (n_fds > 0) 00507 { 00508 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int)); 00509 m.msg_control = alloca(m.msg_controllen); 00510 memset(m.msg_control, 0, m.msg_controllen); 00511 00512 cm = CMSG_FIRSTHDR(&m); 00513 cm->cmsg_level = SOL_SOCKET; 00514 cm->cmsg_type = SCM_RIGHTS; 00515 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int)); 00516 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int)); 00517 } 00518 00519 again: 00520 00521 bytes_written = sendmsg (fd, &m, 0 00522 #if HAVE_DECL_MSG_NOSIGNAL 00523 |MSG_NOSIGNAL 00524 #endif 00525 ); 00526 00527 if (bytes_written < 0 && errno == EINTR) 00528 goto again; 00529 00530 #if 0 00531 if (bytes_written > 0) 00532 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00533 #endif 00534 00535 return bytes_written; 00536 #endif 00537 } 00538 00552 int 00553 _dbus_write_socket_two (int fd, 00554 const DBusString *buffer1, 00555 int start1, 00556 int len1, 00557 const DBusString *buffer2, 00558 int start2, 00559 int len2) 00560 { 00561 #if HAVE_DECL_MSG_NOSIGNAL 00562 struct iovec vectors[2]; 00563 const char *data1; 00564 const char *data2; 00565 int bytes_written; 00566 struct msghdr m; 00567 00568 _dbus_assert (buffer1 != NULL); 00569 _dbus_assert (start1 >= 0); 00570 _dbus_assert (start2 >= 0); 00571 _dbus_assert (len1 >= 0); 00572 _dbus_assert (len2 >= 0); 00573 00574 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00575 00576 if (buffer2 != NULL) 00577 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00578 else 00579 { 00580 data2 = NULL; 00581 start2 = 0; 00582 len2 = 0; 00583 } 00584 00585 vectors[0].iov_base = (char*) data1; 00586 vectors[0].iov_len = len1; 00587 vectors[1].iov_base = (char*) data2; 00588 vectors[1].iov_len = len2; 00589 00590 _DBUS_ZERO(m); 00591 m.msg_iov = vectors; 00592 m.msg_iovlen = data2 ? 2 : 1; 00593 00594 again: 00595 00596 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL); 00597 00598 if (bytes_written < 0 && errno == EINTR) 00599 goto again; 00600 00601 return bytes_written; 00602 00603 #else 00604 return _dbus_write_two (fd, buffer1, start1, len1, 00605 buffer2, start2, len2); 00606 #endif 00607 } 00608 00609 dbus_bool_t 00610 _dbus_socket_is_invalid (int fd) 00611 { 00612 return fd < 0 ? TRUE : FALSE; 00613 } 00614 00631 int 00632 _dbus_read (int fd, 00633 DBusString *buffer, 00634 int count) 00635 { 00636 int bytes_read; 00637 int start; 00638 char *data; 00639 00640 _dbus_assert (count >= 0); 00641 00642 start = _dbus_string_get_length (buffer); 00643 00644 if (!_dbus_string_lengthen (buffer, count)) 00645 { 00646 errno = ENOMEM; 00647 return -1; 00648 } 00649 00650 data = _dbus_string_get_data_len (buffer, start, count); 00651 00652 again: 00653 00654 bytes_read = read (fd, data, count); 00655 00656 if (bytes_read < 0) 00657 { 00658 if (errno == EINTR) 00659 goto again; 00660 else 00661 { 00662 /* put length back (note that this doesn't actually realloc anything) */ 00663 _dbus_string_set_length (buffer, start); 00664 return -1; 00665 } 00666 } 00667 else 00668 { 00669 /* put length back (doesn't actually realloc) */ 00670 _dbus_string_set_length (buffer, start + bytes_read); 00671 00672 #if 0 00673 if (bytes_read > 0) 00674 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00675 #endif 00676 00677 return bytes_read; 00678 } 00679 } 00680 00691 int 00692 _dbus_write (int fd, 00693 const DBusString *buffer, 00694 int start, 00695 int len) 00696 { 00697 const char *data; 00698 int bytes_written; 00699 00700 data = _dbus_string_get_const_data_len (buffer, start, len); 00701 00702 again: 00703 00704 bytes_written = write (fd, data, len); 00705 00706 if (bytes_written < 0 && errno == EINTR) 00707 goto again; 00708 00709 #if 0 00710 if (bytes_written > 0) 00711 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00712 #endif 00713 00714 return bytes_written; 00715 } 00716 00737 int 00738 _dbus_write_two (int fd, 00739 const DBusString *buffer1, 00740 int start1, 00741 int len1, 00742 const DBusString *buffer2, 00743 int start2, 00744 int len2) 00745 { 00746 _dbus_assert (buffer1 != NULL); 00747 _dbus_assert (start1 >= 0); 00748 _dbus_assert (start2 >= 0); 00749 _dbus_assert (len1 >= 0); 00750 _dbus_assert (len2 >= 0); 00751 00752 #ifdef HAVE_WRITEV 00753 { 00754 struct iovec vectors[2]; 00755 const char *data1; 00756 const char *data2; 00757 int bytes_written; 00758 00759 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00760 00761 if (buffer2 != NULL) 00762 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00763 else 00764 { 00765 data2 = NULL; 00766 start2 = 0; 00767 len2 = 0; 00768 } 00769 00770 vectors[0].iov_base = (char*) data1; 00771 vectors[0].iov_len = len1; 00772 vectors[1].iov_base = (char*) data2; 00773 vectors[1].iov_len = len2; 00774 00775 again: 00776 00777 bytes_written = writev (fd, 00778 vectors, 00779 data2 ? 2 : 1); 00780 00781 if (bytes_written < 0 && errno == EINTR) 00782 goto again; 00783 00784 return bytes_written; 00785 } 00786 #else /* HAVE_WRITEV */ 00787 { 00788 int ret1; 00789 00790 ret1 = _dbus_write (fd, buffer1, start1, len1); 00791 if (ret1 == len1 && buffer2 != NULL) 00792 { 00793 ret2 = _dbus_write (fd, buffer2, start2, len2); 00794 if (ret2 < 0) 00795 ret2 = 0; /* we can't report an error as the first write was OK */ 00796 00797 return ret1 + ret2; 00798 } 00799 else 00800 return ret1; 00801 } 00802 #endif /* !HAVE_WRITEV */ 00803 } 00804 00805 #define _DBUS_MAX_SUN_PATH_LENGTH 99 00806 00836 int 00837 _dbus_connect_unix_socket (const char *path, 00838 dbus_bool_t abstract, 00839 DBusError *error) 00840 { 00841 int fd; 00842 size_t path_len; 00843 struct sockaddr_un addr; 00844 00845 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00846 00847 _dbus_verbose ("connecting to unix socket %s abstract=%d\n", 00848 path, abstract); 00849 00850 00851 if (!_dbus_open_unix_socket (&fd, error)) 00852 { 00853 _DBUS_ASSERT_ERROR_IS_SET(error); 00854 return -1; 00855 } 00856 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00857 00858 _DBUS_ZERO (addr); 00859 addr.sun_family = AF_UNIX; 00860 path_len = strlen (path); 00861 00862 if (abstract) 00863 { 00864 #ifdef HAVE_ABSTRACT_SOCKETS 00865 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 00866 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 00867 00868 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00869 { 00870 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00871 "Abstract socket name too long\n"); 00872 _dbus_close (fd, NULL); 00873 return -1; 00874 } 00875 00876 strncpy (&addr.sun_path[1], path, path_len); 00877 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 00878 #else /* HAVE_ABSTRACT_SOCKETS */ 00879 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 00880 "Operating system does not support abstract socket namespace\n"); 00881 _dbus_close (fd, NULL); 00882 return -1; 00883 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 00884 } 00885 else 00886 { 00887 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00888 { 00889 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00890 "Socket name too long\n"); 00891 _dbus_close (fd, NULL); 00892 return -1; 00893 } 00894 00895 strncpy (addr.sun_path, path, path_len); 00896 } 00897 00898 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 00899 { 00900 dbus_set_error (error, 00901 _dbus_error_from_errno (errno), 00902 "Failed to connect to socket %s: %s", 00903 path, _dbus_strerror (errno)); 00904 00905 _dbus_close (fd, NULL); 00906 return -1; 00907 } 00908 00909 if (!_dbus_set_fd_nonblocking (fd, error)) 00910 { 00911 _DBUS_ASSERT_ERROR_IS_SET (error); 00912 00913 _dbus_close (fd, NULL); 00914 return -1; 00915 } 00916 00917 return fd; 00918 } 00919 00929 static dbus_bool_t 00930 _dbus_set_local_creds (int fd, dbus_bool_t on) 00931 { 00932 dbus_bool_t retval = TRUE; 00933 00934 #if defined(HAVE_CMSGCRED) 00935 /* NOOP just to make sure only one codepath is used 00936 * and to prefer CMSGCRED 00937 */ 00938 #elif defined(LOCAL_CREDS) 00939 int val = on ? 1 : 0; 00940 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0) 00941 { 00942 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd); 00943 retval = FALSE; 00944 } 00945 else 00946 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n", 00947 on ? "enabled" : "disabled", fd); 00948 #endif 00949 00950 return retval; 00951 } 00952 00970 int 00971 _dbus_listen_unix_socket (const char *path, 00972 dbus_bool_t abstract, 00973 DBusError *error) 00974 { 00975 int listen_fd; 00976 struct sockaddr_un addr; 00977 size_t path_len; 00978 unsigned int reuseaddr; 00979 00980 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00981 00982 _dbus_verbose ("listening on unix socket %s abstract=%d\n", 00983 path, abstract); 00984 00985 if (!_dbus_open_unix_socket (&listen_fd, error)) 00986 { 00987 _DBUS_ASSERT_ERROR_IS_SET(error); 00988 return -1; 00989 } 00990 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00991 00992 _DBUS_ZERO (addr); 00993 addr.sun_family = AF_UNIX; 00994 path_len = strlen (path); 00995 00996 if (abstract) 00997 { 00998 #ifdef HAVE_ABSTRACT_SOCKETS 00999 /* remember that abstract names aren't nul-terminated so we rely 01000 * on sun_path being filled in with zeroes above. 01001 */ 01002 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 01003 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 01004 01005 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 01006 { 01007 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01008 "Abstract socket name too long\n"); 01009 _dbus_close (listen_fd, NULL); 01010 return -1; 01011 } 01012 01013 strncpy (&addr.sun_path[1], path, path_len); 01014 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 01015 #else /* HAVE_ABSTRACT_SOCKETS */ 01016 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 01017 "Operating system does not support abstract socket namespace\n"); 01018 _dbus_close (listen_fd, NULL); 01019 return -1; 01020 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 01021 } 01022 else 01023 { 01024 /* Discussed security implications of this with Nalin, 01025 * and we couldn't think of where it would kick our ass, but 01026 * it still seems a bit sucky. It also has non-security suckage; 01027 * really we'd prefer to exit if the socket is already in use. 01028 * But there doesn't seem to be a good way to do this. 01029 * 01030 * Just to be extra careful, I threw in the stat() - clearly 01031 * the stat() can't *fix* any security issue, but it at least 01032 * avoids inadvertent/accidental data loss. 01033 */ 01034 { 01035 struct stat sb; 01036 01037 if (stat (path, &sb) == 0 && 01038 S_ISSOCK (sb.st_mode)) 01039 unlink (path); 01040 } 01041 01042 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 01043 { 01044 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01045 "Abstract socket name too long\n"); 01046 _dbus_close (listen_fd, NULL); 01047 return -1; 01048 } 01049 01050 strncpy (addr.sun_path, path, path_len); 01051 } 01052 01053 reuseaddr = 1; 01054 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01055 { 01056 _dbus_warn ("Failed to set socket option\"%s\": %s", 01057 path, _dbus_strerror (errno)); 01058 } 01059 01060 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 01061 { 01062 dbus_set_error (error, _dbus_error_from_errno (errno), 01063 "Failed to bind socket \"%s\": %s", 01064 path, _dbus_strerror (errno)); 01065 _dbus_close (listen_fd, NULL); 01066 return -1; 01067 } 01068 01069 if (listen (listen_fd, 30 /* backlog */) < 0) 01070 { 01071 dbus_set_error (error, _dbus_error_from_errno (errno), 01072 "Failed to listen on socket \"%s\": %s", 01073 path, _dbus_strerror (errno)); 01074 _dbus_close (listen_fd, NULL); 01075 return -1; 01076 } 01077 01078 if (!_dbus_set_local_creds (listen_fd, TRUE)) 01079 { 01080 dbus_set_error (error, _dbus_error_from_errno (errno), 01081 "Failed to enable LOCAL_CREDS on socket \"%s\": %s", 01082 path, _dbus_strerror (errno)); 01083 close (listen_fd); 01084 return -1; 01085 } 01086 01087 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 01088 { 01089 _DBUS_ASSERT_ERROR_IS_SET (error); 01090 _dbus_close (listen_fd, NULL); 01091 return -1; 01092 } 01093 01094 /* Try opening up the permissions, but if we can't, just go ahead 01095 * and continue, maybe it will be good enough. 01096 */ 01097 if (!abstract && chmod (path, 0777) < 0) 01098 _dbus_warn ("Could not set mode 0777 on socket %s\n", 01099 path); 01100 01101 return listen_fd; 01102 } 01103 01114 int 01115 _dbus_listen_systemd_sockets (int **fds, 01116 DBusError *error) 01117 { 01118 int r, n; 01119 unsigned fd; 01120 int *new_fds; 01121 01122 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01123 01124 n = sd_listen_fds (TRUE); 01125 if (n < 0) 01126 { 01127 dbus_set_error (error, _dbus_error_from_errno (-n), 01128 "Failed to acquire systemd socket: %s", 01129 _dbus_strerror (-n)); 01130 return -1; 01131 } 01132 01133 if (n <= 0) 01134 { 01135 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01136 "No socket received."); 01137 return -1; 01138 } 01139 01140 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01141 { 01142 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1); 01143 if (r < 0) 01144 { 01145 dbus_set_error (error, _dbus_error_from_errno (-r), 01146 "Failed to verify systemd socket type: %s", 01147 _dbus_strerror (-r)); 01148 return -1; 01149 } 01150 01151 if (!r) 01152 { 01153 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01154 "Passed socket has wrong type."); 01155 return -1; 01156 } 01157 } 01158 01159 /* OK, the file descriptors are all good, so let's take posession of 01160 them then. */ 01161 01162 new_fds = dbus_new (int, n); 01163 if (!new_fds) 01164 { 01165 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 01166 "Failed to allocate file handle array."); 01167 goto fail; 01168 } 01169 01170 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01171 { 01172 if (!_dbus_set_local_creds (fd, TRUE)) 01173 { 01174 dbus_set_error (error, _dbus_error_from_errno (errno), 01175 "Failed to enable LOCAL_CREDS on systemd socket: %s", 01176 _dbus_strerror (errno)); 01177 goto fail; 01178 } 01179 01180 if (!_dbus_set_fd_nonblocking (fd, error)) 01181 { 01182 _DBUS_ASSERT_ERROR_IS_SET (error); 01183 goto fail; 01184 } 01185 01186 new_fds[fd - SD_LISTEN_FDS_START] = fd; 01187 } 01188 01189 *fds = new_fds; 01190 return n; 01191 01192 fail: 01193 01194 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01195 { 01196 _dbus_close (fd, NULL); 01197 } 01198 01199 dbus_free (new_fds); 01200 return -1; 01201 } 01202 01216 int 01217 _dbus_connect_tcp_socket (const char *host, 01218 const char *port, 01219 const char *family, 01220 DBusError *error) 01221 { 01222 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error); 01223 } 01224 01225 int 01226 _dbus_connect_tcp_socket_with_nonce (const char *host, 01227 const char *port, 01228 const char *family, 01229 const char *noncefile, 01230 DBusError *error) 01231 { 01232 int saved_errno = 0; 01233 int fd = -1, res; 01234 struct addrinfo hints; 01235 struct addrinfo *ai, *tmp; 01236 01237 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01238 01239 _DBUS_ZERO (hints); 01240 01241 if (!family) 01242 hints.ai_family = AF_UNSPEC; 01243 else if (!strcmp(family, "ipv4")) 01244 hints.ai_family = AF_INET; 01245 else if (!strcmp(family, "ipv6")) 01246 hints.ai_family = AF_INET6; 01247 else 01248 { 01249 dbus_set_error (error, 01250 DBUS_ERROR_BAD_ADDRESS, 01251 "Unknown address family %s", family); 01252 return -1; 01253 } 01254 hints.ai_protocol = IPPROTO_TCP; 01255 hints.ai_socktype = SOCK_STREAM; 01256 hints.ai_flags = AI_ADDRCONFIG; 01257 01258 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0) 01259 { 01260 dbus_set_error (error, 01261 _dbus_error_from_errno (errno), 01262 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01263 host, port, gai_strerror(res), res); 01264 return -1; 01265 } 01266 01267 tmp = ai; 01268 while (tmp) 01269 { 01270 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01271 { 01272 freeaddrinfo(ai); 01273 _DBUS_ASSERT_ERROR_IS_SET(error); 01274 return -1; 01275 } 01276 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01277 01278 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01279 { 01280 saved_errno = errno; 01281 _dbus_close(fd, NULL); 01282 fd = -1; 01283 tmp = tmp->ai_next; 01284 continue; 01285 } 01286 01287 break; 01288 } 01289 freeaddrinfo(ai); 01290 01291 if (fd == -1) 01292 { 01293 dbus_set_error (error, 01294 _dbus_error_from_errno (saved_errno), 01295 "Failed to connect to socket \"%s:%s\" %s", 01296 host, port, _dbus_strerror(saved_errno)); 01297 return -1; 01298 } 01299 01300 if (noncefile != NULL) 01301 { 01302 DBusString noncefileStr; 01303 dbus_bool_t ret; 01304 _dbus_string_init_const (&noncefileStr, noncefile); 01305 ret = _dbus_send_nonce (fd, &noncefileStr, error); 01306 _dbus_string_free (&noncefileStr); 01307 01308 if (!ret) 01309 { 01310 _dbus_close (fd, NULL); 01311 return -1; 01312 } 01313 } 01314 01315 if (!_dbus_set_fd_nonblocking (fd, error)) 01316 { 01317 _dbus_close (fd, NULL); 01318 return -1; 01319 } 01320 01321 return fd; 01322 } 01323 01340 int 01341 _dbus_listen_tcp_socket (const char *host, 01342 const char *port, 01343 const char *family, 01344 DBusString *retport, 01345 int **fds_p, 01346 DBusError *error) 01347 { 01348 int saved_errno; 01349 int nlisten_fd = 0, *listen_fd = NULL, res, i; 01350 struct addrinfo hints; 01351 struct addrinfo *ai, *tmp; 01352 unsigned int reuseaddr; 01353 01354 *fds_p = NULL; 01355 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01356 01357 _DBUS_ZERO (hints); 01358 01359 if (!family) 01360 hints.ai_family = AF_UNSPEC; 01361 else if (!strcmp(family, "ipv4")) 01362 hints.ai_family = AF_INET; 01363 else if (!strcmp(family, "ipv6")) 01364 hints.ai_family = AF_INET6; 01365 else 01366 { 01367 dbus_set_error (error, 01368 DBUS_ERROR_BAD_ADDRESS, 01369 "Unknown address family %s", family); 01370 return -1; 01371 } 01372 01373 hints.ai_protocol = IPPROTO_TCP; 01374 hints.ai_socktype = SOCK_STREAM; 01375 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; 01376 01377 redo_lookup_with_port: 01378 ai = NULL; 01379 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai) 01380 { 01381 dbus_set_error (error, 01382 _dbus_error_from_errno (errno), 01383 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01384 host ? host : "*", port, gai_strerror(res), res); 01385 goto failed; 01386 } 01387 01388 tmp = ai; 01389 while (tmp) 01390 { 01391 int fd = -1, *newlisten_fd; 01392 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01393 { 01394 _DBUS_ASSERT_ERROR_IS_SET(error); 01395 goto failed; 01396 } 01397 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01398 01399 reuseaddr = 1; 01400 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01401 { 01402 _dbus_warn ("Failed to set socket option \"%s:%s\": %s", 01403 host ? host : "*", port, _dbus_strerror (errno)); 01404 } 01405 01406 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01407 { 01408 saved_errno = errno; 01409 _dbus_close(fd, NULL); 01410 if (saved_errno == EADDRINUSE) 01411 { 01412 /* Depending on kernel policy, it may or may not 01413 be neccessary to bind to both IPv4 & 6 addresses 01414 so ignore EADDRINUSE here */ 01415 tmp = tmp->ai_next; 01416 continue; 01417 } 01418 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01419 "Failed to bind socket \"%s:%s\": %s", 01420 host ? host : "*", port, _dbus_strerror (saved_errno)); 01421 goto failed; 01422 } 01423 01424 if (listen (fd, 30 /* backlog */) < 0) 01425 { 01426 saved_errno = errno; 01427 _dbus_close (fd, NULL); 01428 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01429 "Failed to listen on socket \"%s:%s\": %s", 01430 host ? host : "*", port, _dbus_strerror (saved_errno)); 01431 goto failed; 01432 } 01433 01434 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); 01435 if (!newlisten_fd) 01436 { 01437 saved_errno = errno; 01438 _dbus_close (fd, NULL); 01439 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01440 "Failed to allocate file handle array: %s", 01441 _dbus_strerror (saved_errno)); 01442 goto failed; 01443 } 01444 listen_fd = newlisten_fd; 01445 listen_fd[nlisten_fd] = fd; 01446 nlisten_fd++; 01447 01448 if (!_dbus_string_get_length(retport)) 01449 { 01450 /* If the user didn't specify a port, or used 0, then 01451 the kernel chooses a port. After the first address 01452 is bound to, we need to force all remaining addresses 01453 to use the same port */ 01454 if (!port || !strcmp(port, "0")) 01455 { 01456 int result; 01457 struct sockaddr_storage addr; 01458 socklen_t addrlen; 01459 char portbuf[50]; 01460 01461 addrlen = sizeof(addr); 01462 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen); 01463 01464 if (result == -1 || 01465 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0, 01466 portbuf, sizeof(portbuf), 01467 NI_NUMERICHOST)) != 0) 01468 { 01469 dbus_set_error (error, _dbus_error_from_errno (errno), 01470 "Failed to resolve port \"%s:%s\": %s (%s)", 01471 host ? host : "*", port, gai_strerror(res), res); 01472 goto failed; 01473 } 01474 if (!_dbus_string_append(retport, portbuf)) 01475 { 01476 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01477 goto failed; 01478 } 01479 01480 /* Release current address list & redo lookup */ 01481 port = _dbus_string_get_const_data(retport); 01482 freeaddrinfo(ai); 01483 goto redo_lookup_with_port; 01484 } 01485 else 01486 { 01487 if (!_dbus_string_append(retport, port)) 01488 { 01489 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01490 goto failed; 01491 } 01492 } 01493 } 01494 01495 tmp = tmp->ai_next; 01496 } 01497 freeaddrinfo(ai); 01498 ai = NULL; 01499 01500 if (!nlisten_fd) 01501 { 01502 errno = EADDRINUSE; 01503 dbus_set_error (error, _dbus_error_from_errno (errno), 01504 "Failed to bind socket \"%s:%s\": %s", 01505 host ? host : "*", port, _dbus_strerror (errno)); 01506 goto failed; 01507 } 01508 01509 for (i = 0 ; i < nlisten_fd ; i++) 01510 { 01511 if (!_dbus_set_fd_nonblocking (listen_fd[i], error)) 01512 { 01513 goto failed; 01514 } 01515 } 01516 01517 *fds_p = listen_fd; 01518 01519 return nlisten_fd; 01520 01521 failed: 01522 if (ai) 01523 freeaddrinfo(ai); 01524 for (i = 0 ; i < nlisten_fd ; i++) 01525 _dbus_close(listen_fd[i], NULL); 01526 dbus_free(listen_fd); 01527 return -1; 01528 } 01529 01530 static dbus_bool_t 01531 write_credentials_byte (int server_fd, 01532 DBusError *error) 01533 { 01534 int bytes_written; 01535 char buf[1] = { '\0' }; 01536 #if defined(HAVE_CMSGCRED) 01537 union { 01538 struct cmsghdr hdr; 01539 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01540 } cmsg; 01541 struct iovec iov; 01542 struct msghdr msg; 01543 iov.iov_base = buf; 01544 iov.iov_len = 1; 01545 01546 _DBUS_ZERO(msg); 01547 msg.msg_iov = &iov; 01548 msg.msg_iovlen = 1; 01549 01550 msg.msg_control = (caddr_t) &cmsg; 01551 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01552 _DBUS_ZERO(cmsg); 01553 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); 01554 cmsg.hdr.cmsg_level = SOL_SOCKET; 01555 cmsg.hdr.cmsg_type = SCM_CREDS; 01556 #endif 01557 01558 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01559 01560 again: 01561 01562 #if defined(HAVE_CMSGCRED) 01563 bytes_written = sendmsg (server_fd, &msg, 0 01564 #if HAVE_DECL_MSG_NOSIGNAL 01565 |MSG_NOSIGNAL 01566 #endif 01567 ); 01568 #else 01569 bytes_written = send (server_fd, buf, 1, 0 01570 #if HAVE_DECL_MSG_NOSIGNAL 01571 |MSG_NOSIGNAL 01572 #endif 01573 ); 01574 #endif 01575 01576 if (bytes_written < 0 && errno == EINTR) 01577 goto again; 01578 01579 if (bytes_written < 0) 01580 { 01581 dbus_set_error (error, _dbus_error_from_errno (errno), 01582 "Failed to write credentials byte: %s", 01583 _dbus_strerror (errno)); 01584 return FALSE; 01585 } 01586 else if (bytes_written == 0) 01587 { 01588 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 01589 "wrote zero bytes writing credentials byte"); 01590 return FALSE; 01591 } 01592 else 01593 { 01594 _dbus_assert (bytes_written == 1); 01595 _dbus_verbose ("wrote credentials byte\n"); 01596 return TRUE; 01597 } 01598 } 01599 01621 dbus_bool_t 01622 _dbus_read_credentials_socket (int client_fd, 01623 DBusCredentials *credentials, 01624 DBusError *error) 01625 { 01626 struct msghdr msg; 01627 struct iovec iov; 01628 char buf; 01629 dbus_uid_t uid_read; 01630 dbus_pid_t pid_read; 01631 int bytes_read; 01632 01633 #ifdef HAVE_CMSGCRED 01634 union { 01635 struct cmsghdr hdr; 01636 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01637 } cmsg; 01638 01639 #elif defined(LOCAL_CREDS) 01640 struct { 01641 struct cmsghdr hdr; 01642 struct sockcred cred; 01643 } cmsg; 01644 #endif 01645 01646 uid_read = DBUS_UID_UNSET; 01647 pid_read = DBUS_PID_UNSET; 01648 01649 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01650 01651 /* The POSIX spec certainly doesn't promise this, but 01652 * we need these assertions to fail as soon as we're wrong about 01653 * it so we can do the porting fixups 01654 */ 01655 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 01656 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 01657 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 01658 01659 _dbus_credentials_clear (credentials); 01660 01661 /* Systems supporting LOCAL_CREDS are configured to have this feature 01662 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting 01663 * the connection. Therefore, the received message must carry the 01664 * credentials information without doing anything special. 01665 */ 01666 01667 iov.iov_base = &buf; 01668 iov.iov_len = 1; 01669 01670 _DBUS_ZERO(msg); 01671 msg.msg_iov = &iov; 01672 msg.msg_iovlen = 1; 01673 01674 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01675 _DBUS_ZERO(cmsg); 01676 msg.msg_control = (caddr_t) &cmsg; 01677 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01678 #endif 01679 01680 again: 01681 bytes_read = recvmsg (client_fd, &msg, 0); 01682 01683 if (bytes_read < 0) 01684 { 01685 if (errno == EINTR) 01686 goto again; 01687 01688 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would 01689 * normally only call read_credentials if the socket was ready 01690 * for reading 01691 */ 01692 01693 dbus_set_error (error, _dbus_error_from_errno (errno), 01694 "Failed to read credentials byte: %s", 01695 _dbus_strerror (errno)); 01696 return FALSE; 01697 } 01698 else if (bytes_read == 0) 01699 { 01700 /* this should not happen unless we are using recvmsg wrong, 01701 * so is essentially here for paranoia 01702 */ 01703 dbus_set_error (error, DBUS_ERROR_FAILED, 01704 "Failed to read credentials byte (zero-length read)"); 01705 return FALSE; 01706 } 01707 else if (buf != '\0') 01708 { 01709 dbus_set_error (error, DBUS_ERROR_FAILED, 01710 "Credentials byte was not nul"); 01711 return FALSE; 01712 } 01713 01714 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01715 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) 01716 || cmsg.hdr.cmsg_type != SCM_CREDS) 01717 { 01718 dbus_set_error (error, DBUS_ERROR_FAILED, 01719 "Message from recvmsg() was not SCM_CREDS"); 01720 return FALSE; 01721 } 01722 #endif 01723 01724 _dbus_verbose ("read credentials byte\n"); 01725 01726 { 01727 #ifdef SO_PEERCRED 01728 #ifdef __OpenBSD__ 01729 struct sockpeercred cr; 01730 #else 01731 struct ucred cr; 01732 #endif 01733 int cr_len = sizeof (cr); 01734 01735 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && 01736 cr_len == sizeof (cr)) 01737 { 01738 pid_read = cr.pid; 01739 uid_read = cr.uid; 01740 } 01741 else 01742 { 01743 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", 01744 cr_len, (int) sizeof (cr), _dbus_strerror (errno)); 01745 } 01746 #elif defined(HAVE_CMSGCRED) 01747 struct cmsgcred *cred; 01748 01749 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr); 01750 pid_read = cred->cmcred_pid; 01751 uid_read = cred->cmcred_euid; 01752 #elif defined(LOCAL_CREDS) 01753 pid_read = DBUS_PID_UNSET; 01754 uid_read = cmsg.cred.sc_uid; 01755 /* Since we have already got the credentials from this socket, we can 01756 * disable its LOCAL_CREDS flag if it was ever set. */ 01757 _dbus_set_local_creds (client_fd, FALSE); 01758 #elif defined(HAVE_GETPEEREID) 01759 uid_t euid; 01760 gid_t egid; 01761 if (getpeereid (client_fd, &euid, &egid) == 0) 01762 { 01763 uid_read = euid; 01764 } 01765 else 01766 { 01767 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno)); 01768 } 01769 #elif defined(HAVE_GETPEERUCRED) 01770 ucred_t * ucred = NULL; 01771 if (getpeerucred (client_fd, &ucred) == 0) 01772 { 01773 pid_read = ucred_getpid (ucred); 01774 uid_read = ucred_geteuid (ucred); 01775 #ifdef HAVE_ADT 01776 /* generate audit session data based on socket ucred */ 01777 adt_session_data_t *adth = NULL; 01778 adt_export_data_t *data = NULL; 01779 size_t size = 0; 01780 if (adt_start_session (&adth, NULL, 0) || (adth == NULL)) 01781 { 01782 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno)); 01783 } 01784 else 01785 { 01786 if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 01787 { 01788 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno)); 01789 } 01790 else 01791 { 01792 size = adt_export_session_data (adth, &data); 01793 if (size <= 0) 01794 { 01795 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno)); 01796 } 01797 else 01798 { 01799 _dbus_credentials_add_adt_audit_data (credentials, data, size); 01800 free (data); 01801 } 01802 } 01803 (void) adt_end_session (adth); 01804 } 01805 #endif /* HAVE_ADT */ 01806 } 01807 else 01808 { 01809 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno)); 01810 } 01811 if (ucred != NULL) 01812 ucred_free (ucred); 01813 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ 01814 _dbus_verbose ("Socket credentials not supported on this OS\n"); 01815 #endif 01816 } 01817 01818 _dbus_verbose ("Credentials:" 01819 " pid "DBUS_PID_FORMAT 01820 " uid "DBUS_UID_FORMAT 01821 "\n", 01822 pid_read, 01823 uid_read); 01824 01825 if (pid_read != DBUS_PID_UNSET) 01826 { 01827 if (!_dbus_credentials_add_unix_pid (credentials, pid_read)) 01828 { 01829 _DBUS_SET_OOM (error); 01830 return FALSE; 01831 } 01832 } 01833 01834 if (uid_read != DBUS_UID_UNSET) 01835 { 01836 if (!_dbus_credentials_add_unix_uid (credentials, uid_read)) 01837 { 01838 _DBUS_SET_OOM (error); 01839 return FALSE; 01840 } 01841 } 01842 01843 return TRUE; 01844 } 01845 01863 dbus_bool_t 01864 _dbus_send_credentials_socket (int server_fd, 01865 DBusError *error) 01866 { 01867 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01868 01869 if (write_credentials_byte (server_fd, error)) 01870 return TRUE; 01871 else 01872 return FALSE; 01873 } 01874 01884 int 01885 _dbus_accept (int listen_fd) 01886 { 01887 int client_fd; 01888 struct sockaddr addr; 01889 socklen_t addrlen; 01890 #ifdef HAVE_ACCEPT4 01891 dbus_bool_t cloexec_done; 01892 #endif 01893 01894 addrlen = sizeof (addr); 01895 01896 retry: 01897 01898 #ifdef HAVE_ACCEPT4 01899 /* We assume that if accept4 is available SOCK_CLOEXEC is too */ 01900 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC); 01901 cloexec_done = client_fd >= 0; 01902 01903 if (client_fd < 0 && errno == ENOSYS) 01904 #endif 01905 { 01906 client_fd = accept (listen_fd, &addr, &addrlen); 01907 } 01908 01909 if (client_fd < 0) 01910 { 01911 if (errno == EINTR) 01912 goto retry; 01913 } 01914 01915 _dbus_verbose ("client fd %d accepted\n", client_fd); 01916 01917 #ifdef HAVE_ACCEPT4 01918 if (!cloexec_done) 01919 #endif 01920 { 01921 _dbus_fd_set_close_on_exec(client_fd); 01922 } 01923 01924 return client_fd; 01925 } 01926 01935 dbus_bool_t 01936 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) 01937 { 01938 const char *directory; 01939 struct stat sb; 01940 01941 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01942 01943 directory = _dbus_string_get_const_data (dir); 01944 01945 if (stat (directory, &sb) < 0) 01946 { 01947 dbus_set_error (error, _dbus_error_from_errno (errno), 01948 "%s", _dbus_strerror (errno)); 01949 01950 return FALSE; 01951 } 01952 01953 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) || 01954 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode)) 01955 { 01956 dbus_set_error (error, DBUS_ERROR_FAILED, 01957 "%s directory is not private to the user", directory); 01958 return FALSE; 01959 } 01960 01961 return TRUE; 01962 } 01963 01964 static dbus_bool_t 01965 fill_user_info_from_passwd (struct passwd *p, 01966 DBusUserInfo *info, 01967 DBusError *error) 01968 { 01969 _dbus_assert (p->pw_name != NULL); 01970 _dbus_assert (p->pw_dir != NULL); 01971 01972 info->uid = p->pw_uid; 01973 info->primary_gid = p->pw_gid; 01974 info->username = _dbus_strdup (p->pw_name); 01975 info->homedir = _dbus_strdup (p->pw_dir); 01976 01977 if (info->username == NULL || 01978 info->homedir == NULL) 01979 { 01980 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01981 return FALSE; 01982 } 01983 01984 return TRUE; 01985 } 01986 01987 static dbus_bool_t 01988 fill_user_info (DBusUserInfo *info, 01989 dbus_uid_t uid, 01990 const DBusString *username, 01991 DBusError *error) 01992 { 01993 const char *username_c; 01994 01995 /* exactly one of username/uid provided */ 01996 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET); 01997 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET); 01998 01999 info->uid = DBUS_UID_UNSET; 02000 info->primary_gid = DBUS_GID_UNSET; 02001 info->group_ids = NULL; 02002 info->n_group_ids = 0; 02003 info->username = NULL; 02004 info->homedir = NULL; 02005 02006 if (username != NULL) 02007 username_c = _dbus_string_get_const_data (username); 02008 else 02009 username_c = NULL; 02010 02011 /* For now assuming that the getpwnam() and getpwuid() flavors 02012 * are always symmetrical, if not we have to add more configure 02013 * checks 02014 */ 02015 02016 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R) 02017 { 02018 struct passwd *p; 02019 int result; 02020 size_t buflen; 02021 char *buf; 02022 struct passwd p_str; 02023 02024 /* retrieve maximum needed size for buf */ 02025 buflen = sysconf (_SC_GETPW_R_SIZE_MAX); 02026 02027 /* sysconf actually returns a long, but everything else expects size_t, 02028 * so just recast here. 02029 * https://bugs.freedesktop.org/show_bug.cgi?id=17061 02030 */ 02031 if ((long) buflen <= 0) 02032 buflen = 1024; 02033 02034 result = -1; 02035 while (1) 02036 { 02037 buf = dbus_malloc (buflen); 02038 if (buf == NULL) 02039 { 02040 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02041 return FALSE; 02042 } 02043 02044 p = NULL; 02045 #ifdef HAVE_POSIX_GETPWNAM_R 02046 if (uid != DBUS_UID_UNSET) 02047 result = getpwuid_r (uid, &p_str, buf, buflen, 02048 &p); 02049 else 02050 result = getpwnam_r (username_c, &p_str, buf, buflen, 02051 &p); 02052 #else 02053 if (uid != DBUS_UID_UNSET) 02054 p = getpwuid_r (uid, &p_str, buf, buflen); 02055 else 02056 p = getpwnam_r (username_c, &p_str, buf, buflen); 02057 result = 0; 02058 #endif /* !HAVE_POSIX_GETPWNAM_R */ 02059 //Try a bigger buffer if ERANGE was returned 02060 if (result == ERANGE && buflen < 512 * 1024) 02061 { 02062 dbus_free (buf); 02063 buflen *= 2; 02064 } 02065 else 02066 { 02067 break; 02068 } 02069 } 02070 if (result == 0 && p == &p_str) 02071 { 02072 if (!fill_user_info_from_passwd (p, info, error)) 02073 { 02074 dbus_free (buf); 02075 return FALSE; 02076 } 02077 dbus_free (buf); 02078 } 02079 else 02080 { 02081 dbus_set_error (error, _dbus_error_from_errno (errno), 02082 "User \"%s\" unknown or no memory to allocate password entry\n", 02083 username_c ? username_c : "???"); 02084 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02085 dbus_free (buf); 02086 return FALSE; 02087 } 02088 } 02089 #else /* ! HAVE_GETPWNAM_R */ 02090 { 02091 /* I guess we're screwed on thread safety here */ 02092 struct passwd *p; 02093 02094 if (uid != DBUS_UID_UNSET) 02095 p = getpwuid (uid); 02096 else 02097 p = getpwnam (username_c); 02098 02099 if (p != NULL) 02100 { 02101 if (!fill_user_info_from_passwd (p, info, error)) 02102 { 02103 return FALSE; 02104 } 02105 } 02106 else 02107 { 02108 dbus_set_error (error, _dbus_error_from_errno (errno), 02109 "User \"%s\" unknown or no memory to allocate password entry\n", 02110 username_c ? username_c : "???"); 02111 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02112 return FALSE; 02113 } 02114 } 02115 #endif /* ! HAVE_GETPWNAM_R */ 02116 02117 /* Fill this in so we can use it to get groups */ 02118 username_c = info->username; 02119 02120 #ifdef HAVE_GETGROUPLIST 02121 { 02122 gid_t *buf; 02123 int buf_count; 02124 int i; 02125 int initial_buf_count; 02126 02127 initial_buf_count = 17; 02128 buf_count = initial_buf_count; 02129 buf = dbus_new (gid_t, buf_count); 02130 if (buf == NULL) 02131 { 02132 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02133 goto failed; 02134 } 02135 02136 if (getgrouplist (username_c, 02137 info->primary_gid, 02138 buf, &buf_count) < 0) 02139 { 02140 gid_t *new; 02141 /* Presumed cause of negative return code: buf has insufficient 02142 entries to hold the entire group list. The Linux behavior in this 02143 case is to pass back the actual number of groups in buf_count, but 02144 on Mac OS X 10.5, buf_count is unhelpfully left alone. 02145 So as a hack, try to help out a bit by guessing a larger 02146 number of groups, within reason.. might still fail, of course, 02147 but we can at least print a more informative message. I looked up 02148 the "right way" to do this by downloading Apple's own source code 02149 for the "id" command, and it turns out that they use an 02150 undocumented library function getgrouplist_2 (!) which is not 02151 declared in any header in /usr/include (!!). That did not seem 02152 like the way to go here. 02153 */ 02154 if (buf_count == initial_buf_count) 02155 { 02156 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */ 02157 } 02158 new = dbus_realloc (buf, buf_count * sizeof (buf[0])); 02159 if (new == NULL) 02160 { 02161 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02162 dbus_free (buf); 02163 goto failed; 02164 } 02165 02166 buf = new; 02167 02168 errno = 0; 02169 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0) 02170 { 02171 if (errno == 0) 02172 { 02173 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.", 02174 username_c, buf_count, buf_count); 02175 } 02176 else 02177 { 02178 dbus_set_error (error, 02179 _dbus_error_from_errno (errno), 02180 "Failed to get groups for username \"%s\" primary GID " 02181 DBUS_GID_FORMAT ": %s\n", 02182 username_c, info->primary_gid, 02183 _dbus_strerror (errno)); 02184 dbus_free (buf); 02185 goto failed; 02186 } 02187 } 02188 } 02189 02190 info->group_ids = dbus_new (dbus_gid_t, buf_count); 02191 if (info->group_ids == NULL) 02192 { 02193 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02194 dbus_free (buf); 02195 goto failed; 02196 } 02197 02198 for (i = 0; i < buf_count; ++i) 02199 info->group_ids[i] = buf[i]; 02200 02201 info->n_group_ids = buf_count; 02202 02203 dbus_free (buf); 02204 } 02205 #else /* HAVE_GETGROUPLIST */ 02206 { 02207 /* We just get the one group ID */ 02208 info->group_ids = dbus_new (dbus_gid_t, 1); 02209 if (info->group_ids == NULL) 02210 { 02211 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02212 goto failed; 02213 } 02214 02215 info->n_group_ids = 1; 02216 02217 (info->group_ids)[0] = info->primary_gid; 02218 } 02219 #endif /* HAVE_GETGROUPLIST */ 02220 02221 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02222 02223 return TRUE; 02224 02225 failed: 02226 _DBUS_ASSERT_ERROR_IS_SET (error); 02227 return FALSE; 02228 } 02229 02238 dbus_bool_t 02239 _dbus_user_info_fill (DBusUserInfo *info, 02240 const DBusString *username, 02241 DBusError *error) 02242 { 02243 return fill_user_info (info, DBUS_UID_UNSET, 02244 username, error); 02245 } 02246 02255 dbus_bool_t 02256 _dbus_user_info_fill_uid (DBusUserInfo *info, 02257 dbus_uid_t uid, 02258 DBusError *error) 02259 { 02260 return fill_user_info (info, uid, 02261 NULL, error); 02262 } 02263 02271 dbus_bool_t 02272 _dbus_credentials_add_from_current_process (DBusCredentials *credentials) 02273 { 02274 /* The POSIX spec certainly doesn't promise this, but 02275 * we need these assertions to fail as soon as we're wrong about 02276 * it so we can do the porting fixups 02277 */ 02278 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 02279 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 02280 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 02281 02282 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) 02283 return FALSE; 02284 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid())) 02285 return FALSE; 02286 02287 return TRUE; 02288 } 02289 02301 dbus_bool_t 02302 _dbus_append_user_from_current_process (DBusString *str) 02303 { 02304 return _dbus_string_append_uint (str, 02305 _dbus_geteuid ()); 02306 } 02307 02312 dbus_pid_t 02313 _dbus_getpid (void) 02314 { 02315 return getpid (); 02316 } 02317 02321 dbus_uid_t 02322 _dbus_getuid (void) 02323 { 02324 return getuid (); 02325 } 02326 02330 dbus_uid_t 02331 _dbus_geteuid (void) 02332 { 02333 return geteuid (); 02334 } 02335 02342 unsigned long 02343 _dbus_pid_for_log (void) 02344 { 02345 return getpid (); 02346 } 02347 02355 dbus_bool_t 02356 _dbus_parse_uid (const DBusString *uid_str, 02357 dbus_uid_t *uid) 02358 { 02359 int end; 02360 long val; 02361 02362 if (_dbus_string_get_length (uid_str) == 0) 02363 { 02364 _dbus_verbose ("UID string was zero length\n"); 02365 return FALSE; 02366 } 02367 02368 val = -1; 02369 end = 0; 02370 if (!_dbus_string_parse_int (uid_str, 0, &val, 02371 &end)) 02372 { 02373 _dbus_verbose ("could not parse string as a UID\n"); 02374 return FALSE; 02375 } 02376 02377 if (end != _dbus_string_get_length (uid_str)) 02378 { 02379 _dbus_verbose ("string contained trailing stuff after UID\n"); 02380 return FALSE; 02381 } 02382 02383 *uid = val; 02384 02385 return TRUE; 02386 } 02387 02388 #if !DBUS_USE_SYNC 02389 _DBUS_DEFINE_GLOBAL_LOCK (atomic); 02390 #endif 02391 02398 dbus_int32_t 02399 _dbus_atomic_inc (DBusAtomic *atomic) 02400 { 02401 #if DBUS_USE_SYNC 02402 return __sync_add_and_fetch(&atomic->value, 1)-1; 02403 #else 02404 dbus_int32_t res; 02405 _DBUS_LOCK (atomic); 02406 res = atomic->value; 02407 atomic->value += 1; 02408 _DBUS_UNLOCK (atomic); 02409 return res; 02410 #endif 02411 } 02412 02419 dbus_int32_t 02420 _dbus_atomic_dec (DBusAtomic *atomic) 02421 { 02422 #if DBUS_USE_SYNC 02423 return __sync_sub_and_fetch(&atomic->value, 1)+1; 02424 #else 02425 dbus_int32_t res; 02426 02427 _DBUS_LOCK (atomic); 02428 res = atomic->value; 02429 atomic->value -= 1; 02430 _DBUS_UNLOCK (atomic); 02431 return res; 02432 #endif 02433 } 02434 02442 dbus_int32_t 02443 _dbus_atomic_get (DBusAtomic *atomic) 02444 { 02445 #if DBUS_USE_SYNC 02446 __sync_synchronize (); 02447 return atomic->value; 02448 #else 02449 dbus_int32_t res; 02450 02451 _DBUS_LOCK (atomic); 02452 res = atomic->value; 02453 _DBUS_UNLOCK (atomic); 02454 return res; 02455 #endif 02456 } 02457 02458 #ifdef DBUS_BUILD_TESTS 02459 02462 dbus_gid_t 02463 _dbus_getgid (void) 02464 { 02465 return getgid (); 02466 } 02467 #endif 02468 02477 int 02478 _dbus_poll (DBusPollFD *fds, 02479 int n_fds, 02480 int timeout_milliseconds) 02481 { 02482 #if defined(HAVE_POLL) && !defined(BROKEN_POLL) 02483 /* This big thing is a constant expression and should get optimized 02484 * out of existence. So it's more robust than a configure check at 02485 * no cost. 02486 */ 02487 if (_DBUS_POLLIN == POLLIN && 02488 _DBUS_POLLPRI == POLLPRI && 02489 _DBUS_POLLOUT == POLLOUT && 02490 _DBUS_POLLERR == POLLERR && 02491 _DBUS_POLLHUP == POLLHUP && 02492 _DBUS_POLLNVAL == POLLNVAL && 02493 sizeof (DBusPollFD) == sizeof (struct pollfd) && 02494 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) == 02495 _DBUS_STRUCT_OFFSET (struct pollfd, fd) && 02496 _DBUS_STRUCT_OFFSET (DBusPollFD, events) == 02497 _DBUS_STRUCT_OFFSET (struct pollfd, events) && 02498 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == 02499 _DBUS_STRUCT_OFFSET (struct pollfd, revents)) 02500 { 02501 return poll ((struct pollfd*) fds, 02502 n_fds, 02503 timeout_milliseconds); 02504 } 02505 else 02506 { 02507 /* We have to convert the DBusPollFD to an array of 02508 * struct pollfd, poll, and convert back. 02509 */ 02510 _dbus_warn ("didn't implement poll() properly for this system yet\n"); 02511 return -1; 02512 } 02513 #else /* ! HAVE_POLL */ 02514 02515 fd_set read_set, write_set, err_set; 02516 int max_fd = 0; 02517 int i; 02518 struct timeval tv; 02519 int ready; 02520 02521 FD_ZERO (&read_set); 02522 FD_ZERO (&write_set); 02523 FD_ZERO (&err_set); 02524 02525 for (i = 0; i < n_fds; i++) 02526 { 02527 DBusPollFD *fdp = &fds[i]; 02528 02529 if (fdp->events & _DBUS_POLLIN) 02530 FD_SET (fdp->fd, &read_set); 02531 02532 if (fdp->events & _DBUS_POLLOUT) 02533 FD_SET (fdp->fd, &write_set); 02534 02535 FD_SET (fdp->fd, &err_set); 02536 02537 max_fd = MAX (max_fd, fdp->fd); 02538 } 02539 02540 tv.tv_sec = timeout_milliseconds / 1000; 02541 tv.tv_usec = (timeout_milliseconds % 1000) * 1000; 02542 02543 ready = select (max_fd + 1, &read_set, &write_set, &err_set, 02544 timeout_milliseconds < 0 ? NULL : &tv); 02545 02546 if (ready > 0) 02547 { 02548 for (i = 0; i < n_fds; i++) 02549 { 02550 DBusPollFD *fdp = &fds[i]; 02551 02552 fdp->revents = 0; 02553 02554 if (FD_ISSET (fdp->fd, &read_set)) 02555 fdp->revents |= _DBUS_POLLIN; 02556 02557 if (FD_ISSET (fdp->fd, &write_set)) 02558 fdp->revents |= _DBUS_POLLOUT; 02559 02560 if (FD_ISSET (fdp->fd, &err_set)) 02561 fdp->revents |= _DBUS_POLLERR; 02562 } 02563 } 02564 02565 return ready; 02566 #endif 02567 } 02568 02576 void 02577 _dbus_get_current_time (long *tv_sec, 02578 long *tv_usec) 02579 { 02580 struct timeval t; 02581 02582 #ifdef HAVE_MONOTONIC_CLOCK 02583 struct timespec ts; 02584 clock_gettime (CLOCK_MONOTONIC, &ts); 02585 02586 if (tv_sec) 02587 *tv_sec = ts.tv_sec; 02588 if (tv_usec) 02589 *tv_usec = ts.tv_nsec / 1000; 02590 #else 02591 gettimeofday (&t, NULL); 02592 02593 if (tv_sec) 02594 *tv_sec = t.tv_sec; 02595 if (tv_usec) 02596 *tv_usec = t.tv_usec; 02597 #endif 02598 } 02599 02608 dbus_bool_t 02609 _dbus_create_directory (const DBusString *filename, 02610 DBusError *error) 02611 { 02612 const char *filename_c; 02613 02614 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02615 02616 filename_c = _dbus_string_get_const_data (filename); 02617 02618 if (mkdir (filename_c, 0700) < 0) 02619 { 02620 if (errno == EEXIST) 02621 return TRUE; 02622 02623 dbus_set_error (error, DBUS_ERROR_FAILED, 02624 "Failed to create directory %s: %s\n", 02625 filename_c, _dbus_strerror (errno)); 02626 return FALSE; 02627 } 02628 else 02629 return TRUE; 02630 } 02631 02642 dbus_bool_t 02643 _dbus_concat_dir_and_file (DBusString *dir, 02644 const DBusString *next_component) 02645 { 02646 dbus_bool_t dir_ends_in_slash; 02647 dbus_bool_t file_starts_with_slash; 02648 02649 if (_dbus_string_get_length (dir) == 0 || 02650 _dbus_string_get_length (next_component) == 0) 02651 return TRUE; 02652 02653 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, 02654 _dbus_string_get_length (dir) - 1); 02655 02656 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); 02657 02658 if (dir_ends_in_slash && file_starts_with_slash) 02659 { 02660 _dbus_string_shorten (dir, 1); 02661 } 02662 else if (!(dir_ends_in_slash || file_starts_with_slash)) 02663 { 02664 if (!_dbus_string_append_byte (dir, '/')) 02665 return FALSE; 02666 } 02667 02668 return _dbus_string_copy (next_component, 0, dir, 02669 _dbus_string_get_length (dir)); 02670 } 02671 02673 #define NANOSECONDS_PER_SECOND 1000000000 02674 02675 #define MICROSECONDS_PER_SECOND 1000000 02676 02677 #define MILLISECONDS_PER_SECOND 1000 02678 02679 #define NANOSECONDS_PER_MILLISECOND 1000000 02680 02681 #define MICROSECONDS_PER_MILLISECOND 1000 02682 02687 void 02688 _dbus_sleep_milliseconds (int milliseconds) 02689 { 02690 #ifdef HAVE_NANOSLEEP 02691 struct timespec req; 02692 struct timespec rem; 02693 02694 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND; 02695 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; 02696 rem.tv_sec = 0; 02697 rem.tv_nsec = 0; 02698 02699 while (nanosleep (&req, &rem) < 0 && errno == EINTR) 02700 req = rem; 02701 #elif defined (HAVE_USLEEP) 02702 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND); 02703 #else /* ! HAVE_USLEEP */ 02704 sleep (MAX (milliseconds / 1000, 1)); 02705 #endif 02706 } 02707 02708 static dbus_bool_t 02709 _dbus_generate_pseudorandom_bytes (DBusString *str, 02710 int n_bytes) 02711 { 02712 int old_len; 02713 char *p; 02714 02715 old_len = _dbus_string_get_length (str); 02716 02717 if (!_dbus_string_lengthen (str, n_bytes)) 02718 return FALSE; 02719 02720 p = _dbus_string_get_data_len (str, old_len, n_bytes); 02721 02722 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes); 02723 02724 return TRUE; 02725 } 02726 02735 dbus_bool_t 02736 _dbus_generate_random_bytes (DBusString *str, 02737 int n_bytes) 02738 { 02739 int old_len; 02740 int fd; 02741 02742 /* FALSE return means "no memory", if it could 02743 * mean something else then we'd need to return 02744 * a DBusError. So we always fall back to pseudorandom 02745 * if the I/O fails. 02746 */ 02747 02748 old_len = _dbus_string_get_length (str); 02749 fd = -1; 02750 02751 /* note, urandom on linux will fall back to pseudorandom */ 02752 fd = open ("/dev/urandom", O_RDONLY); 02753 if (fd < 0) 02754 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02755 02756 _dbus_verbose ("/dev/urandom fd %d opened\n", fd); 02757 02758 if (_dbus_read (fd, str, n_bytes) != n_bytes) 02759 { 02760 _dbus_close (fd, NULL); 02761 _dbus_string_set_length (str, old_len); 02762 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02763 } 02764 02765 _dbus_verbose ("Read %d bytes from /dev/urandom\n", 02766 n_bytes); 02767 02768 _dbus_close (fd, NULL); 02769 02770 return TRUE; 02771 } 02772 02778 void 02779 _dbus_exit (int code) 02780 { 02781 _exit (code); 02782 } 02783 02792 const char* 02793 _dbus_strerror (int error_number) 02794 { 02795 const char *msg; 02796 02797 msg = strerror (error_number); 02798 if (msg == NULL) 02799 msg = "unknown"; 02800 02801 return msg; 02802 } 02803 02807 void 02808 _dbus_disable_sigpipe (void) 02809 { 02810 signal (SIGPIPE, SIG_IGN); 02811 } 02812 02820 void 02821 _dbus_fd_set_close_on_exec (intptr_t fd) 02822 { 02823 int val; 02824 02825 val = fcntl (fd, F_GETFD, 0); 02826 02827 if (val < 0) 02828 return; 02829 02830 val |= FD_CLOEXEC; 02831 02832 fcntl (fd, F_SETFD, val); 02833 } 02834 02842 dbus_bool_t 02843 _dbus_close (int fd, 02844 DBusError *error) 02845 { 02846 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02847 02848 again: 02849 if (close (fd) < 0) 02850 { 02851 if (errno == EINTR) 02852 goto again; 02853 02854 dbus_set_error (error, _dbus_error_from_errno (errno), 02855 "Could not close fd %d", fd); 02856 return FALSE; 02857 } 02858 02859 return TRUE; 02860 } 02861 02869 int 02870 _dbus_dup(int fd, 02871 DBusError *error) 02872 { 02873 int new_fd; 02874 02875 #ifdef F_DUPFD_CLOEXEC 02876 dbus_bool_t cloexec_done; 02877 02878 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); 02879 cloexec_done = new_fd >= 0; 02880 02881 if (new_fd < 0 && errno == EINVAL) 02882 #endif 02883 { 02884 new_fd = fcntl(fd, F_DUPFD, 3); 02885 } 02886 02887 if (new_fd < 0) { 02888 02889 dbus_set_error (error, _dbus_error_from_errno (errno), 02890 "Could not duplicate fd %d", fd); 02891 return -1; 02892 } 02893 02894 #ifdef F_DUPFD_CLOEXEC 02895 if (!cloexec_done) 02896 #endif 02897 { 02898 _dbus_fd_set_close_on_exec(new_fd); 02899 } 02900 02901 return new_fd; 02902 } 02903 02911 dbus_bool_t 02912 _dbus_set_fd_nonblocking (int fd, 02913 DBusError *error) 02914 { 02915 int val; 02916 02917 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02918 02919 val = fcntl (fd, F_GETFL, 0); 02920 if (val < 0) 02921 { 02922 dbus_set_error (error, _dbus_error_from_errno (errno), 02923 "Failed to get flags from file descriptor %d: %s", 02924 fd, _dbus_strerror (errno)); 02925 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 02926 _dbus_strerror (errno)); 02927 return FALSE; 02928 } 02929 02930 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 02931 { 02932 dbus_set_error (error, _dbus_error_from_errno (errno), 02933 "Failed to set nonblocking flag of file descriptor %d: %s", 02934 fd, _dbus_strerror (errno)); 02935 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 02936 fd, _dbus_strerror (errno)); 02937 02938 return FALSE; 02939 } 02940 02941 return TRUE; 02942 } 02943 02949 void 02950 _dbus_print_backtrace (void) 02951 { 02952 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC) 02953 void *bt[500]; 02954 int bt_size; 02955 int i; 02956 char **syms; 02957 02958 bt_size = backtrace (bt, 500); 02959 02960 syms = backtrace_symbols (bt, bt_size); 02961 02962 i = 0; 02963 while (i < bt_size) 02964 { 02965 /* don't use dbus_warn since it can _dbus_abort() */ 02966 fprintf (stderr, " %s\n", syms[i]); 02967 ++i; 02968 } 02969 fflush (stderr); 02970 02971 free (syms); 02972 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC) 02973 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n"); 02974 #else 02975 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n"); 02976 #endif 02977 } 02978 02996 dbus_bool_t 02997 _dbus_full_duplex_pipe (int *fd1, 02998 int *fd2, 02999 dbus_bool_t blocking, 03000 DBusError *error) 03001 { 03002 #ifdef HAVE_SOCKETPAIR 03003 int fds[2]; 03004 int retval; 03005 03006 #ifdef SOCK_CLOEXEC 03007 dbus_bool_t cloexec_done; 03008 03009 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); 03010 cloexec_done = retval >= 0; 03011 03012 if (retval < 0 && errno == EINVAL) 03013 #endif 03014 { 03015 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 03016 } 03017 03018 if (retval < 0) 03019 { 03020 dbus_set_error (error, _dbus_error_from_errno (errno), 03021 "Could not create full-duplex pipe"); 03022 return FALSE; 03023 } 03024 03025 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03026 03027 #ifdef SOCK_CLOEXEC 03028 if (!cloexec_done) 03029 #endif 03030 { 03031 _dbus_fd_set_close_on_exec (fds[0]); 03032 _dbus_fd_set_close_on_exec (fds[1]); 03033 } 03034 03035 if (!blocking && 03036 (!_dbus_set_fd_nonblocking (fds[0], NULL) || 03037 !_dbus_set_fd_nonblocking (fds[1], NULL))) 03038 { 03039 dbus_set_error (error, _dbus_error_from_errno (errno), 03040 "Could not set full-duplex pipe nonblocking"); 03041 03042 _dbus_close (fds[0], NULL); 03043 _dbus_close (fds[1], NULL); 03044 03045 return FALSE; 03046 } 03047 03048 *fd1 = fds[0]; 03049 *fd2 = fds[1]; 03050 03051 _dbus_verbose ("full-duplex pipe %d <-> %d\n", 03052 *fd1, *fd2); 03053 03054 return TRUE; 03055 #else 03056 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n"); 03057 dbus_set_error (error, DBUS_ERROR_FAILED, 03058 "_dbus_full_duplex_pipe() not implemented on this OS"); 03059 return FALSE; 03060 #endif 03061 } 03062 03071 int 03072 _dbus_printf_string_upper_bound (const char *format, 03073 va_list args) 03074 { 03075 char static_buf[1024]; 03076 int bufsize = sizeof (static_buf); 03077 int len; 03078 va_list args_copy; 03079 03080 DBUS_VA_COPY (args_copy, args); 03081 len = vsnprintf (static_buf, bufsize, format, args_copy); 03082 va_end (args_copy); 03083 03084 /* If vsnprintf() returned non-negative, then either the string fits in 03085 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf 03086 * returns the number of characters that were needed, or this OS returns the 03087 * truncated length. 03088 * 03089 * We ignore the possibility that snprintf might just ignore the length and 03090 * overrun the buffer (64-bit Solaris 7), because that's pathological. 03091 * If your libc is really that bad, come back when you have a better one. */ 03092 if (len == bufsize) 03093 { 03094 /* This could be the truncated length (Tru64 and IRIX have this bug), 03095 * or the real length could be coincidentally the same. Which is it? 03096 * If vsnprintf returns the truncated length, we'll go to the slow 03097 * path. */ 03098 DBUS_VA_COPY (args_copy, args); 03099 03100 if (vsnprintf (static_buf, 1, format, args_copy) == 1) 03101 len = -1; 03102 03103 va_end (args_copy); 03104 } 03105 03106 /* If vsnprintf() returned negative, we have to do more work. 03107 * HP-UX returns negative. */ 03108 while (len < 0) 03109 { 03110 char *buf; 03111 03112 bufsize *= 2; 03113 03114 buf = dbus_malloc (bufsize); 03115 03116 if (buf == NULL) 03117 return -1; 03118 03119 DBUS_VA_COPY (args_copy, args); 03120 len = vsnprintf (buf, bufsize, format, args_copy); 03121 va_end (args_copy); 03122 03123 dbus_free (buf); 03124 03125 /* If the reported length is exactly the buffer size, round up to the 03126 * next size, in case vsnprintf has been returning the truncated 03127 * length */ 03128 if (len == bufsize) 03129 len = -1; 03130 } 03131 03132 return len; 03133 } 03134 03141 const char* 03142 _dbus_get_tmpdir(void) 03143 { 03144 static const char* tmpdir = NULL; 03145 03146 if (tmpdir == NULL) 03147 { 03148 /* TMPDIR is what glibc uses, then 03149 * glibc falls back to the P_tmpdir macro which 03150 * just expands to "/tmp" 03151 */ 03152 if (tmpdir == NULL) 03153 tmpdir = getenv("TMPDIR"); 03154 03155 /* These two env variables are probably 03156 * broken, but maybe some OS uses them? 03157 */ 03158 if (tmpdir == NULL) 03159 tmpdir = getenv("TMP"); 03160 if (tmpdir == NULL) 03161 tmpdir = getenv("TEMP"); 03162 03163 /* And this is the sane fallback. */ 03164 if (tmpdir == NULL) 03165 tmpdir = "/tmp"; 03166 } 03167 03168 _dbus_assert(tmpdir != NULL); 03169 03170 return tmpdir; 03171 } 03172 03192 static dbus_bool_t 03193 _read_subprocess_line_argv (const char *progpath, 03194 dbus_bool_t path_fallback, 03195 char * const *argv, 03196 DBusString *result, 03197 DBusError *error) 03198 { 03199 int result_pipe[2] = { -1, -1 }; 03200 int errors_pipe[2] = { -1, -1 }; 03201 pid_t pid; 03202 int ret; 03203 int status; 03204 int orig_len; 03205 int i; 03206 03207 dbus_bool_t retval; 03208 sigset_t new_set, old_set; 03209 03210 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03211 retval = FALSE; 03212 03213 /* We need to block any existing handlers for SIGCHLD temporarily; they 03214 * will cause waitpid() below to fail. 03215 * https://bugs.freedesktop.org/show_bug.cgi?id=21347 03216 */ 03217 sigemptyset (&new_set); 03218 sigaddset (&new_set, SIGCHLD); 03219 sigprocmask (SIG_BLOCK, &new_set, &old_set); 03220 03221 orig_len = _dbus_string_get_length (result); 03222 03223 #define READ_END 0 03224 #define WRITE_END 1 03225 if (pipe (result_pipe) < 0) 03226 { 03227 dbus_set_error (error, _dbus_error_from_errno (errno), 03228 "Failed to create a pipe to call %s: %s", 03229 progpath, _dbus_strerror (errno)); 03230 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03231 progpath, _dbus_strerror (errno)); 03232 goto out; 03233 } 03234 if (pipe (errors_pipe) < 0) 03235 { 03236 dbus_set_error (error, _dbus_error_from_errno (errno), 03237 "Failed to create a pipe to call %s: %s", 03238 progpath, _dbus_strerror (errno)); 03239 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03240 progpath, _dbus_strerror (errno)); 03241 goto out; 03242 } 03243 03244 pid = fork (); 03245 if (pid < 0) 03246 { 03247 dbus_set_error (error, _dbus_error_from_errno (errno), 03248 "Failed to fork() to call %s: %s", 03249 progpath, _dbus_strerror (errno)); 03250 _dbus_verbose ("Failed to fork() to call %s: %s\n", 03251 progpath, _dbus_strerror (errno)); 03252 goto out; 03253 } 03254 03255 if (pid == 0) 03256 { 03257 /* child process */ 03258 int maxfds; 03259 int fd; 03260 03261 fd = open ("/dev/null", O_RDWR); 03262 if (fd == -1) 03263 /* huh?! can't open /dev/null? */ 03264 _exit (1); 03265 03266 _dbus_verbose ("/dev/null fd %d opened\n", fd); 03267 03268 /* set-up stdXXX */ 03269 close (result_pipe[READ_END]); 03270 close (errors_pipe[READ_END]); 03271 close (0); /* close stdin */ 03272 close (1); /* close stdout */ 03273 close (2); /* close stderr */ 03274 03275 if (dup2 (fd, 0) == -1) 03276 _exit (1); 03277 if (dup2 (result_pipe[WRITE_END], 1) == -1) 03278 _exit (1); 03279 if (dup2 (errors_pipe[WRITE_END], 2) == -1) 03280 _exit (1); 03281 03282 maxfds = sysconf (_SC_OPEN_MAX); 03283 /* Pick something reasonable if for some reason sysconf 03284 * says unlimited. 03285 */ 03286 if (maxfds < 0) 03287 maxfds = 1024; 03288 /* close all inherited fds */ 03289 for (i = 3; i < maxfds; i++) 03290 close (i); 03291 03292 sigprocmask (SIG_SETMASK, &old_set, NULL); 03293 03294 /* If it looks fully-qualified, try execv first */ 03295 if (progpath[0] == '/') 03296 { 03297 execv (progpath, argv); 03298 /* Ok, that failed. Now if path_fallback is given, let's 03299 * try unqualified. This is mostly a hack to work 03300 * around systems which ship dbus-launch in /usr/bin 03301 * but everything else in /bin (because dbus-launch 03302 * depends on X11). 03303 */ 03304 if (path_fallback) 03305 /* We must have a slash, because we checked above */ 03306 execvp (strrchr (progpath, '/')+1, argv); 03307 } 03308 else 03309 execvp (progpath, argv); 03310 03311 /* still nothing, we failed */ 03312 _exit (1); 03313 } 03314 03315 /* parent process */ 03316 close (result_pipe[WRITE_END]); 03317 close (errors_pipe[WRITE_END]); 03318 result_pipe[WRITE_END] = -1; 03319 errors_pipe[WRITE_END] = -1; 03320 03321 ret = 0; 03322 do 03323 { 03324 ret = _dbus_read (result_pipe[READ_END], result, 1024); 03325 } 03326 while (ret > 0); 03327 03328 /* reap the child process to avoid it lingering as zombie */ 03329 do 03330 { 03331 ret = waitpid (pid, &status, 0); 03332 } 03333 while (ret == -1 && errno == EINTR); 03334 03335 /* We succeeded if the process exited with status 0 and 03336 anything was read */ 03337 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ) 03338 { 03339 /* The process ended with error */ 03340 DBusString error_message; 03341 if (!_dbus_string_init (&error_message)) 03342 { 03343 _DBUS_SET_OOM (error); 03344 goto out; 03345 } 03346 03347 ret = 0; 03348 do 03349 { 03350 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024); 03351 } 03352 while (ret > 0); 03353 03354 _dbus_string_set_length (result, orig_len); 03355 if (_dbus_string_get_length (&error_message) > 0) 03356 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03357 "%s terminated abnormally with the following error: %s", 03358 progpath, _dbus_string_get_data (&error_message)); 03359 else 03360 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03361 "%s terminated abnormally without any error message", 03362 progpath); 03363 goto out; 03364 } 03365 03366 retval = TRUE; 03367 03368 out: 03369 sigprocmask (SIG_SETMASK, &old_set, NULL); 03370 03371 if (retval) 03372 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03373 else 03374 _DBUS_ASSERT_ERROR_IS_SET (error); 03375 03376 if (result_pipe[0] != -1) 03377 close (result_pipe[0]); 03378 if (result_pipe[1] != -1) 03379 close (result_pipe[1]); 03380 if (errors_pipe[0] != -1) 03381 close (errors_pipe[0]); 03382 if (errors_pipe[1] != -1) 03383 close (errors_pipe[1]); 03384 03385 return retval; 03386 } 03387 03399 dbus_bool_t 03400 _dbus_get_autolaunch_address (const char *scope, 03401 DBusString *address, 03402 DBusError *error) 03403 { 03404 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH 03405 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch, 03406 * but that's done elsewhere, and if it worked, this function wouldn't 03407 * be called.) */ 03408 const char *display; 03409 static char *argv[6]; 03410 int i; 03411 DBusString uuid; 03412 dbus_bool_t retval; 03413 03414 if (_dbus_check_setuid ()) 03415 { 03416 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03417 "Unable to autolaunch when setuid"); 03418 return FALSE; 03419 } 03420 03421 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03422 retval = FALSE; 03423 03424 /* fd.o #19997: if $DISPLAY isn't set to something useful, then 03425 * dbus-launch-x11 is just going to fail. Rather than trying to 03426 * run it, we might as well bail out early with a nice error. */ 03427 display = _dbus_getenv ("DISPLAY"); 03428 03429 if (display == NULL || display[0] == '\0') 03430 { 03431 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03432 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11"); 03433 return FALSE; 03434 } 03435 03436 if (!_dbus_string_init (&uuid)) 03437 { 03438 _DBUS_SET_OOM (error); 03439 return FALSE; 03440 } 03441 03442 if (!_dbus_get_local_machine_uuid_encoded (&uuid)) 03443 { 03444 _DBUS_SET_OOM (error); 03445 goto out; 03446 } 03447 03448 i = 0; 03449 argv[i] = "dbus-launch"; 03450 ++i; 03451 argv[i] = "--autolaunch"; 03452 ++i; 03453 argv[i] = _dbus_string_get_data (&uuid); 03454 ++i; 03455 argv[i] = "--binary-syntax"; 03456 ++i; 03457 argv[i] = "--close-stderr"; 03458 ++i; 03459 argv[i] = NULL; 03460 ++i; 03461 03462 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03463 03464 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch", 03465 TRUE, 03466 argv, address, error); 03467 03468 out: 03469 _dbus_string_free (&uuid); 03470 return retval; 03471 #else 03472 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03473 "Using X11 for dbus-daemon autolaunch was disabled at compile time, " 03474 "set your DBUS_SESSION_BUS_ADDRESS instead"); 03475 return FALSE; 03476 #endif 03477 } 03478 03497 dbus_bool_t 03498 _dbus_read_local_machine_uuid (DBusGUID *machine_id, 03499 dbus_bool_t create_if_not_found, 03500 DBusError *error) 03501 { 03502 DBusString filename; 03503 dbus_bool_t b; 03504 03505 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE); 03506 03507 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error); 03508 if (b) 03509 return TRUE; 03510 03511 dbus_error_free (error); 03512 03513 /* Fallback to the system machine ID */ 03514 _dbus_string_init_const (&filename, "/etc/machine-id"); 03515 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error); 03516 } 03517 03518 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" 03519 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" 03520 03527 dbus_bool_t 03528 _dbus_lookup_launchd_socket (DBusString *socket_path, 03529 const char *launchd_env_var, 03530 DBusError *error) 03531 { 03532 #ifdef DBUS_ENABLE_LAUNCHD 03533 char *argv[4]; 03534 int i; 03535 03536 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03537 03538 if (_dbus_check_setuid ()) 03539 { 03540 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03541 "Unable to find launchd socket when setuid"); 03542 return FALSE; 03543 } 03544 03545 i = 0; 03546 argv[i] = "launchctl"; 03547 ++i; 03548 argv[i] = "getenv"; 03549 ++i; 03550 argv[i] = (char*)launchd_env_var; 03551 ++i; 03552 argv[i] = NULL; 03553 ++i; 03554 03555 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03556 03557 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error)) 03558 { 03559 return FALSE; 03560 } 03561 03562 /* no error, but no result either */ 03563 if (_dbus_string_get_length(socket_path) == 0) 03564 { 03565 return FALSE; 03566 } 03567 03568 /* strip the carriage-return */ 03569 _dbus_string_shorten(socket_path, 1); 03570 return TRUE; 03571 #else /* DBUS_ENABLE_LAUNCHD */ 03572 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, 03573 "can't lookup socket from launchd; launchd support not compiled in"); 03574 return FALSE; 03575 #endif 03576 } 03577 03578 static dbus_bool_t 03579 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error) 03580 { 03581 #ifdef DBUS_ENABLE_LAUNCHD 03582 dbus_bool_t valid_socket; 03583 DBusString socket_path; 03584 03585 if (_dbus_check_setuid ()) 03586 { 03587 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03588 "Unable to find launchd socket when setuid"); 03589 return FALSE; 03590 } 03591 03592 if (!_dbus_string_init (&socket_path)) 03593 { 03594 _DBUS_SET_OOM (error); 03595 return FALSE; 03596 } 03597 03598 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error); 03599 03600 if (dbus_error_is_set(error)) 03601 { 03602 _dbus_string_free(&socket_path); 03603 return FALSE; 03604 } 03605 03606 if (!valid_socket) 03607 { 03608 dbus_set_error(error, "no socket path", 03609 "launchd did not provide a socket path, " 03610 "verify that org.freedesktop.dbus-session.plist is loaded!"); 03611 _dbus_string_free(&socket_path); 03612 return FALSE; 03613 } 03614 if (!_dbus_string_append (address, "unix:path=")) 03615 { 03616 _DBUS_SET_OOM (error); 03617 _dbus_string_free(&socket_path); 03618 return FALSE; 03619 } 03620 if (!_dbus_string_copy (&socket_path, 0, address, 03621 _dbus_string_get_length (address))) 03622 { 03623 _DBUS_SET_OOM (error); 03624 _dbus_string_free(&socket_path); 03625 return FALSE; 03626 } 03627 03628 _dbus_string_free(&socket_path); 03629 return TRUE; 03630 #else 03631 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, 03632 "can't lookup session address from launchd; launchd support not compiled in"); 03633 return FALSE; 03634 #endif 03635 } 03636 03656 dbus_bool_t 03657 _dbus_lookup_session_address (dbus_bool_t *supported, 03658 DBusString *address, 03659 DBusError *error) 03660 { 03661 #ifdef DBUS_ENABLE_LAUNCHD 03662 *supported = TRUE; 03663 return _dbus_lookup_session_address_launchd (address, error); 03664 #else 03665 /* On non-Mac Unix platforms, if the session address isn't already 03666 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and 03667 * fall back to the autolaunch: global default; see 03668 * init_session_address in dbus/dbus-bus.c. */ 03669 *supported = FALSE; 03670 return TRUE; 03671 #endif 03672 } 03673 03691 dbus_bool_t 03692 _dbus_get_standard_session_servicedirs (DBusList **dirs) 03693 { 03694 const char *xdg_data_home; 03695 const char *xdg_data_dirs; 03696 DBusString servicedir_path; 03697 03698 if (!_dbus_string_init (&servicedir_path)) 03699 return FALSE; 03700 03701 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); 03702 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 03703 03704 if (xdg_data_home != NULL) 03705 { 03706 if (!_dbus_string_append (&servicedir_path, xdg_data_home)) 03707 goto oom; 03708 } 03709 else 03710 { 03711 const DBusString *homedir; 03712 DBusString local_share; 03713 03714 if (!_dbus_homedir_from_current_process (&homedir)) 03715 goto oom; 03716 03717 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) 03718 goto oom; 03719 03720 _dbus_string_init_const (&local_share, "/.local/share"); 03721 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) 03722 goto oom; 03723 } 03724 03725 if (!_dbus_string_append (&servicedir_path, ":")) 03726 goto oom; 03727 03728 if (xdg_data_dirs != NULL) 03729 { 03730 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 03731 goto oom; 03732 03733 if (!_dbus_string_append (&servicedir_path, ":")) 03734 goto oom; 03735 } 03736 else 03737 { 03738 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 03739 goto oom; 03740 } 03741 03742 /* 03743 * add configured datadir to defaults 03744 * this may be the same as an xdg dir 03745 * however the config parser should take 03746 * care of duplicates 03747 */ 03748 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR)) 03749 goto oom; 03750 03751 if (!_dbus_split_paths_and_append (&servicedir_path, 03752 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 03753 dirs)) 03754 goto oom; 03755 03756 _dbus_string_free (&servicedir_path); 03757 return TRUE; 03758 03759 oom: 03760 _dbus_string_free (&servicedir_path); 03761 return FALSE; 03762 } 03763 03764 03783 dbus_bool_t 03784 _dbus_get_standard_system_servicedirs (DBusList **dirs) 03785 { 03786 const char *xdg_data_dirs; 03787 DBusString servicedir_path; 03788 03789 if (!_dbus_string_init (&servicedir_path)) 03790 return FALSE; 03791 03792 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 03793 03794 if (xdg_data_dirs != NULL) 03795 { 03796 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 03797 goto oom; 03798 03799 if (!_dbus_string_append (&servicedir_path, ":")) 03800 goto oom; 03801 } 03802 else 03803 { 03804 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 03805 goto oom; 03806 } 03807 03808 /* 03809 * Add configured datadir to defaults. This may be the same as one 03810 * of the XDG directories. However, the config parser should take 03811 * care of the duplicates. 03812 * 03813 * Also, append /lib as counterpart of /usr/share on the root 03814 * directory (the root directory does not know /share), in order to 03815 * facilitate early boot system bus activation where /usr might not 03816 * be available. 03817 */ 03818 if (!_dbus_string_append (&servicedir_path, 03819 DBUS_DATADIR":" 03820 "/lib:")) 03821 goto oom; 03822 03823 if (!_dbus_split_paths_and_append (&servicedir_path, 03824 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 03825 dirs)) 03826 goto oom; 03827 03828 _dbus_string_free (&servicedir_path); 03829 return TRUE; 03830 03831 oom: 03832 _dbus_string_free (&servicedir_path); 03833 return FALSE; 03834 } 03835 03844 dbus_bool_t 03845 _dbus_append_system_config_file (DBusString *str) 03846 { 03847 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE); 03848 } 03849 03856 dbus_bool_t 03857 _dbus_append_session_config_file (DBusString *str) 03858 { 03859 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); 03860 } 03861 03869 void 03870 _dbus_flush_caches (void) 03871 { 03872 _dbus_user_database_flush_system (); 03873 } 03874 03888 dbus_bool_t 03889 _dbus_append_keyring_directory_for_credentials (DBusString *directory, 03890 DBusCredentials *credentials) 03891 { 03892 DBusString homedir; 03893 DBusString dotdir; 03894 dbus_uid_t uid; 03895 03896 _dbus_assert (credentials != NULL); 03897 _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); 03898 03899 if (!_dbus_string_init (&homedir)) 03900 return FALSE; 03901 03902 uid = _dbus_credentials_get_unix_uid (credentials); 03903 _dbus_assert (uid != DBUS_UID_UNSET); 03904 03905 if (!_dbus_homedir_from_uid (uid, &homedir)) 03906 goto failed; 03907 03908 #ifdef DBUS_BUILD_TESTS 03909 { 03910 const char *override; 03911 03912 override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); 03913 if (override != NULL && *override != '\0') 03914 { 03915 _dbus_string_set_length (&homedir, 0); 03916 if (!_dbus_string_append (&homedir, override)) 03917 goto failed; 03918 03919 _dbus_verbose ("Using fake homedir for testing: %s\n", 03920 _dbus_string_get_const_data (&homedir)); 03921 } 03922 else 03923 { 03924 static dbus_bool_t already_warned = FALSE; 03925 if (!already_warned) 03926 { 03927 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); 03928 already_warned = TRUE; 03929 } 03930 } 03931 } 03932 #endif 03933 03934 _dbus_string_init_const (&dotdir, ".dbus-keyrings"); 03935 if (!_dbus_concat_dir_and_file (&homedir, 03936 &dotdir)) 03937 goto failed; 03938 03939 if (!_dbus_string_copy (&homedir, 0, 03940 directory, _dbus_string_get_length (directory))) { 03941 goto failed; 03942 } 03943 03944 _dbus_string_free (&homedir); 03945 return TRUE; 03946 03947 failed: 03948 _dbus_string_free (&homedir); 03949 return FALSE; 03950 } 03951 03952 //PENDING(kdab) docs 03953 dbus_bool_t 03954 _dbus_daemon_publish_session_bus_address (const char* addr, 03955 const char *scope) 03956 { 03957 return TRUE; 03958 } 03959 03960 //PENDING(kdab) docs 03961 void 03962 _dbus_daemon_unpublish_session_bus_address (void) 03963 { 03964 03965 } 03966 03973 dbus_bool_t 03974 _dbus_get_is_errno_eagain_or_ewouldblock (void) 03975 { 03976 return errno == EAGAIN || errno == EWOULDBLOCK; 03977 } 03978 03986 dbus_bool_t 03987 _dbus_delete_directory (const DBusString *filename, 03988 DBusError *error) 03989 { 03990 const char *filename_c; 03991 03992 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03993 03994 filename_c = _dbus_string_get_const_data (filename); 03995 03996 if (rmdir (filename_c) != 0) 03997 { 03998 dbus_set_error (error, DBUS_ERROR_FAILED, 03999 "Failed to remove directory %s: %s\n", 04000 filename_c, _dbus_strerror (errno)); 04001 return FALSE; 04002 } 04003 04004 return TRUE; 04005 } 04006 04014 dbus_bool_t 04015 _dbus_socket_can_pass_unix_fd(int fd) { 04016 04017 #ifdef SCM_RIGHTS 04018 union { 04019 struct sockaddr sa; 04020 struct sockaddr_storage storage; 04021 struct sockaddr_un un; 04022 } sa_buf; 04023 04024 socklen_t sa_len = sizeof(sa_buf); 04025 04026 _DBUS_ZERO(sa_buf); 04027 04028 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0) 04029 return FALSE; 04030 04031 return sa_buf.sa.sa_family == AF_UNIX; 04032 04033 #else 04034 return FALSE; 04035 04036 #endif 04037 } 04038 04039 04040 /* 04041 * replaces the term DBUS_PREFIX in configure_time_path by the 04042 * current dbus installation directory. On unix this function is a noop 04043 * 04044 * @param configure_time_path 04045 * @return real path 04046 */ 04047 const char * 04048 _dbus_replace_install_prefix (const char *configure_time_path) 04049 { 04050 return configure_time_path; 04051 } 04052 04062 dbus_bool_t 04063 _dbus_check_setuid (void) 04064 { 04065 /* TODO: get __libc_enable_secure exported from glibc. 04066 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1 04067 */ 04068 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE) 04069 { 04070 /* See glibc/include/unistd.h */ 04071 extern int __libc_enable_secure; 04072 return __libc_enable_secure; 04073 } 04074 #elif defined(HAVE_ISSETUGID) 04075 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */ 04076 return issetugid (); 04077 #else 04078 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */ 04079 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */ 04080 04081 static dbus_bool_t check_setuid_initialised; 04082 static dbus_bool_t is_setuid; 04083 04084 if (_DBUS_UNLIKELY (!check_setuid_initialised)) 04085 { 04086 #ifdef HAVE_GETRESUID 04087 if (getresuid (&ruid, &euid, &suid) != 0 || 04088 getresgid (&rgid, &egid, &sgid) != 0) 04089 #endif /* HAVE_GETRESUID */ 04090 { 04091 suid = ruid = getuid (); 04092 sgid = rgid = getgid (); 04093 euid = geteuid (); 04094 egid = getegid (); 04095 } 04096 04097 check_setuid_initialised = TRUE; 04098 is_setuid = (ruid != euid || ruid != suid || 04099 rgid != egid || rgid != sgid); 04100 04101 } 04102 return is_setuid; 04103 #endif 04104 } 04105 04106 /* tests in dbus-sysdeps-util.c */