|
D-Bus
1.6.30
|
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 #ifdef HAVE_ALLOCA_H 00075 #include <alloca.h> 00076 #endif 00077 00078 #ifdef HAVE_ADT 00079 #include <bsm/adt.h> 00080 #endif 00081 00082 #include "sd-daemon.h" 00083 00084 #ifndef O_BINARY 00085 #define O_BINARY 0 00086 #endif 00087 00088 #ifndef AI_ADDRCONFIG 00089 #define AI_ADDRCONFIG 0 00090 #endif 00091 00092 #ifndef HAVE_SOCKLEN_T 00093 #define socklen_t int 00094 #endif 00095 00096 #if defined (__sun) || defined (__sun__) 00097 /* 00098 * CMS_SPACE etc. definitions for Solaris < 10, based on 00099 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html 00100 * via 00101 * http://wiki.opencsw.org/porting-faq#toc10 00102 * 00103 * These are only redefined for Solaris, for now: if your OS needs these too, 00104 * please file a bug. (Or preferably, improve your OS so they're not needed.) 00105 */ 00106 00107 # ifndef CMSG_ALIGN 00108 # ifdef __sun__ 00109 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len) 00110 # else 00111 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */ 00112 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \ 00113 ~(sizeof (long) - 1)) 00114 # endif 00115 # endif 00116 00117 # ifndef CMSG_SPACE 00118 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \ 00119 CMSG_ALIGN (len)) 00120 # endif 00121 00122 # ifndef CMSG_LEN 00123 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) 00124 # endif 00125 00126 #endif /* Solaris */ 00127 00128 static dbus_bool_t 00129 _dbus_open_socket (int *fd_p, 00130 int domain, 00131 int type, 00132 int protocol, 00133 DBusError *error) 00134 { 00135 #ifdef SOCK_CLOEXEC 00136 dbus_bool_t cloexec_done; 00137 00138 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol); 00139 cloexec_done = *fd_p >= 0; 00140 00141 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */ 00142 if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE)) 00143 #endif 00144 { 00145 *fd_p = socket (domain, type, protocol); 00146 } 00147 00148 if (*fd_p >= 0) 00149 { 00150 #ifdef SOCK_CLOEXEC 00151 if (!cloexec_done) 00152 #endif 00153 { 00154 _dbus_fd_set_close_on_exec(*fd_p); 00155 } 00156 00157 _dbus_verbose ("socket fd %d opened\n", *fd_p); 00158 return TRUE; 00159 } 00160 else 00161 { 00162 dbus_set_error(error, 00163 _dbus_error_from_errno (errno), 00164 "Failed to open socket: %s", 00165 _dbus_strerror (errno)); 00166 return FALSE; 00167 } 00168 } 00169 00180 static dbus_bool_t 00181 _dbus_open_unix_socket (int *fd, 00182 DBusError *error) 00183 { 00184 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error); 00185 } 00186 00195 dbus_bool_t 00196 _dbus_close_socket (int fd, 00197 DBusError *error) 00198 { 00199 return _dbus_close (fd, error); 00200 } 00201 00211 int 00212 _dbus_read_socket (int fd, 00213 DBusString *buffer, 00214 int count) 00215 { 00216 return _dbus_read (fd, buffer, count); 00217 } 00218 00229 int 00230 _dbus_write_socket (int fd, 00231 const DBusString *buffer, 00232 int start, 00233 int len) 00234 { 00235 #if HAVE_DECL_MSG_NOSIGNAL 00236 const char *data; 00237 int bytes_written; 00238 00239 data = _dbus_string_get_const_data_len (buffer, start, len); 00240 00241 again: 00242 00243 bytes_written = send (fd, data, len, MSG_NOSIGNAL); 00244 00245 if (bytes_written < 0 && errno == EINTR) 00246 goto again; 00247 00248 return bytes_written; 00249 00250 #else 00251 return _dbus_write (fd, buffer, start, len); 00252 #endif 00253 } 00254 00267 int 00268 _dbus_read_socket_with_unix_fds (int fd, 00269 DBusString *buffer, 00270 int count, 00271 int *fds, 00272 int *n_fds) { 00273 #ifndef HAVE_UNIX_FD_PASSING 00274 int r; 00275 00276 if ((r = _dbus_read_socket(fd, buffer, count)) < 0) 00277 return r; 00278 00279 *n_fds = 0; 00280 return r; 00281 00282 #else 00283 int bytes_read; 00284 int start; 00285 struct msghdr m; 00286 struct iovec iov; 00287 00288 _dbus_assert (count >= 0); 00289 _dbus_assert (*n_fds >= 0); 00290 00291 start = _dbus_string_get_length (buffer); 00292 00293 if (!_dbus_string_lengthen (buffer, count)) 00294 { 00295 errno = ENOMEM; 00296 return -1; 00297 } 00298 00299 _DBUS_ZERO(iov); 00300 iov.iov_base = _dbus_string_get_data_len (buffer, start, count); 00301 iov.iov_len = count; 00302 00303 _DBUS_ZERO(m); 00304 m.msg_iov = &iov; 00305 m.msg_iovlen = 1; 00306 00307 /* Hmm, we have no clue how long the control data will actually be 00308 that is queued for us. The least we can do is assume that the 00309 caller knows. Hence let's make space for the number of fds that 00310 we shall read at max plus the cmsg header. */ 00311 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int)); 00312 00313 /* It's probably safe to assume that systems with SCM_RIGHTS also 00314 know alloca() */ 00315 m.msg_control = alloca(m.msg_controllen); 00316 memset(m.msg_control, 0, m.msg_controllen); 00317 00318 /* Do not include the padding at the end when we tell the kernel 00319 * how much we're willing to receive. This avoids getting 00320 * the padding filled with additional fds that we weren't expecting, 00321 * if a (potentially malicious) sender included them. (fd.o #83622) */ 00322 m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int)); 00323 00324 again: 00325 00326 bytes_read = recvmsg(fd, &m, 0 00327 #ifdef MSG_CMSG_CLOEXEC 00328 |MSG_CMSG_CLOEXEC 00329 #endif 00330 ); 00331 00332 if (bytes_read < 0) 00333 { 00334 if (errno == EINTR) 00335 goto again; 00336 else 00337 { 00338 /* put length back (note that this doesn't actually realloc anything) */ 00339 _dbus_string_set_length (buffer, start); 00340 return -1; 00341 } 00342 } 00343 else 00344 { 00345 struct cmsghdr *cm; 00346 dbus_bool_t found = FALSE; 00347 00348 if (m.msg_flags & MSG_CTRUNC) 00349 { 00350 /* Hmm, apparently the control data was truncated. The bad 00351 thing is that we might have completely lost a couple of fds 00352 without chance to recover them. Hence let's treat this as a 00353 serious error. */ 00354 00355 errno = ENOSPC; 00356 _dbus_string_set_length (buffer, start); 00357 return -1; 00358 } 00359 00360 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) 00361 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) 00362 { 00363 size_t i; 00364 int *payload = (int *) CMSG_DATA (cm); 00365 size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0)); 00366 size_t payload_len_fds = payload_len_bytes / sizeof (int); 00367 size_t fds_to_use; 00368 00369 /* Every non-negative int fits in a size_t without truncation, 00370 * and we already know that *n_fds is non-negative, so 00371 * casting (size_t) *n_fds is OK */ 00372 _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int)); 00373 00374 if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds)) 00375 { 00376 /* The fds in the payload will fit in our buffer */ 00377 fds_to_use = payload_len_fds; 00378 } 00379 else 00380 { 00381 /* Too many fds in the payload. This shouldn't happen 00382 * any more because we're setting m.msg_controllen to 00383 * the exact number we can accept, but be safe and 00384 * truncate. */ 00385 fds_to_use = (size_t) *n_fds; 00386 00387 /* Close the excess fds to avoid DoS: if they stayed open, 00388 * someone could send us an extra fd per message 00389 * and we'd eventually run out. */ 00390 for (i = fds_to_use; i < payload_len_fds; i++) 00391 { 00392 close (payload[i]); 00393 } 00394 } 00395 00396 memcpy (fds, payload, fds_to_use * sizeof (int)); 00397 found = TRUE; 00398 /* This cannot overflow because we have chosen fds_to_use 00399 * to be <= *n_fds */ 00400 *n_fds = (int) fds_to_use; 00401 00402 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually 00403 worked, hence we need to go through this list and set 00404 CLOEXEC everywhere in any case */ 00405 for (i = 0; i < fds_to_use; i++) 00406 _dbus_fd_set_close_on_exec(fds[i]); 00407 00408 break; 00409 } 00410 00411 if (!found) 00412 *n_fds = 0; 00413 00414 /* put length back (doesn't actually realloc) */ 00415 _dbus_string_set_length (buffer, start + bytes_read); 00416 00417 #if 0 00418 if (bytes_read > 0) 00419 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00420 #endif 00421 00422 return bytes_read; 00423 } 00424 #endif 00425 } 00426 00427 int 00428 _dbus_write_socket_with_unix_fds(int fd, 00429 const DBusString *buffer, 00430 int start, 00431 int len, 00432 const int *fds, 00433 int n_fds) { 00434 00435 #ifndef HAVE_UNIX_FD_PASSING 00436 00437 if (n_fds > 0) { 00438 errno = ENOTSUP; 00439 return -1; 00440 } 00441 00442 return _dbus_write_socket(fd, buffer, start, len); 00443 #else 00444 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds); 00445 #endif 00446 } 00447 00448 int 00449 _dbus_write_socket_with_unix_fds_two(int fd, 00450 const DBusString *buffer1, 00451 int start1, 00452 int len1, 00453 const DBusString *buffer2, 00454 int start2, 00455 int len2, 00456 const int *fds, 00457 int n_fds) { 00458 00459 #ifndef HAVE_UNIX_FD_PASSING 00460 00461 if (n_fds > 0) { 00462 errno = ENOTSUP; 00463 return -1; 00464 } 00465 00466 return _dbus_write_socket_two(fd, 00467 buffer1, start1, len1, 00468 buffer2, start2, len2); 00469 #else 00470 00471 struct msghdr m; 00472 struct cmsghdr *cm; 00473 struct iovec iov[2]; 00474 int bytes_written; 00475 00476 _dbus_assert (len1 >= 0); 00477 _dbus_assert (len2 >= 0); 00478 _dbus_assert (n_fds >= 0); 00479 00480 _DBUS_ZERO(iov); 00481 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1); 00482 iov[0].iov_len = len1; 00483 00484 if (buffer2) 00485 { 00486 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2); 00487 iov[1].iov_len = len2; 00488 } 00489 00490 _DBUS_ZERO(m); 00491 m.msg_iov = iov; 00492 m.msg_iovlen = buffer2 ? 2 : 1; 00493 00494 if (n_fds > 0) 00495 { 00496 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int)); 00497 m.msg_control = alloca(m.msg_controllen); 00498 memset(m.msg_control, 0, m.msg_controllen); 00499 00500 cm = CMSG_FIRSTHDR(&m); 00501 cm->cmsg_level = SOL_SOCKET; 00502 cm->cmsg_type = SCM_RIGHTS; 00503 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int)); 00504 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int)); 00505 } 00506 00507 again: 00508 00509 bytes_written = sendmsg (fd, &m, 0 00510 #if HAVE_DECL_MSG_NOSIGNAL 00511 |MSG_NOSIGNAL 00512 #endif 00513 ); 00514 00515 if (bytes_written < 0 && errno == EINTR) 00516 goto again; 00517 00518 #if 0 00519 if (bytes_written > 0) 00520 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00521 #endif 00522 00523 return bytes_written; 00524 #endif 00525 } 00526 00540 int 00541 _dbus_write_socket_two (int fd, 00542 const DBusString *buffer1, 00543 int start1, 00544 int len1, 00545 const DBusString *buffer2, 00546 int start2, 00547 int len2) 00548 { 00549 #if HAVE_DECL_MSG_NOSIGNAL 00550 struct iovec vectors[2]; 00551 const char *data1; 00552 const char *data2; 00553 int bytes_written; 00554 struct msghdr m; 00555 00556 _dbus_assert (buffer1 != NULL); 00557 _dbus_assert (start1 >= 0); 00558 _dbus_assert (start2 >= 0); 00559 _dbus_assert (len1 >= 0); 00560 _dbus_assert (len2 >= 0); 00561 00562 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00563 00564 if (buffer2 != NULL) 00565 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00566 else 00567 { 00568 data2 = NULL; 00569 start2 = 0; 00570 len2 = 0; 00571 } 00572 00573 vectors[0].iov_base = (char*) data1; 00574 vectors[0].iov_len = len1; 00575 vectors[1].iov_base = (char*) data2; 00576 vectors[1].iov_len = len2; 00577 00578 _DBUS_ZERO(m); 00579 m.msg_iov = vectors; 00580 m.msg_iovlen = data2 ? 2 : 1; 00581 00582 again: 00583 00584 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL); 00585 00586 if (bytes_written < 0 && errno == EINTR) 00587 goto again; 00588 00589 return bytes_written; 00590 00591 #else 00592 return _dbus_write_two (fd, buffer1, start1, len1, 00593 buffer2, start2, len2); 00594 #endif 00595 } 00596 00597 dbus_bool_t 00598 _dbus_socket_is_invalid (int fd) 00599 { 00600 return fd < 0 ? TRUE : FALSE; 00601 } 00602 00619 int 00620 _dbus_read (int fd, 00621 DBusString *buffer, 00622 int count) 00623 { 00624 int bytes_read; 00625 int start; 00626 char *data; 00627 00628 _dbus_assert (count >= 0); 00629 00630 start = _dbus_string_get_length (buffer); 00631 00632 if (!_dbus_string_lengthen (buffer, count)) 00633 { 00634 errno = ENOMEM; 00635 return -1; 00636 } 00637 00638 data = _dbus_string_get_data_len (buffer, start, count); 00639 00640 again: 00641 00642 bytes_read = read (fd, data, count); 00643 00644 if (bytes_read < 0) 00645 { 00646 if (errno == EINTR) 00647 goto again; 00648 else 00649 { 00650 /* put length back (note that this doesn't actually realloc anything) */ 00651 _dbus_string_set_length (buffer, start); 00652 return -1; 00653 } 00654 } 00655 else 00656 { 00657 /* put length back (doesn't actually realloc) */ 00658 _dbus_string_set_length (buffer, start + bytes_read); 00659 00660 #if 0 00661 if (bytes_read > 0) 00662 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00663 #endif 00664 00665 return bytes_read; 00666 } 00667 } 00668 00679 int 00680 _dbus_write (int fd, 00681 const DBusString *buffer, 00682 int start, 00683 int len) 00684 { 00685 const char *data; 00686 int bytes_written; 00687 00688 data = _dbus_string_get_const_data_len (buffer, start, len); 00689 00690 again: 00691 00692 bytes_written = write (fd, data, len); 00693 00694 if (bytes_written < 0 && errno == EINTR) 00695 goto again; 00696 00697 #if 0 00698 if (bytes_written > 0) 00699 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00700 #endif 00701 00702 return bytes_written; 00703 } 00704 00725 int 00726 _dbus_write_two (int fd, 00727 const DBusString *buffer1, 00728 int start1, 00729 int len1, 00730 const DBusString *buffer2, 00731 int start2, 00732 int len2) 00733 { 00734 _dbus_assert (buffer1 != NULL); 00735 _dbus_assert (start1 >= 0); 00736 _dbus_assert (start2 >= 0); 00737 _dbus_assert (len1 >= 0); 00738 _dbus_assert (len2 >= 0); 00739 00740 #ifdef HAVE_WRITEV 00741 { 00742 struct iovec vectors[2]; 00743 const char *data1; 00744 const char *data2; 00745 int bytes_written; 00746 00747 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00748 00749 if (buffer2 != NULL) 00750 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00751 else 00752 { 00753 data2 = NULL; 00754 start2 = 0; 00755 len2 = 0; 00756 } 00757 00758 vectors[0].iov_base = (char*) data1; 00759 vectors[0].iov_len = len1; 00760 vectors[1].iov_base = (char*) data2; 00761 vectors[1].iov_len = len2; 00762 00763 again: 00764 00765 bytes_written = writev (fd, 00766 vectors, 00767 data2 ? 2 : 1); 00768 00769 if (bytes_written < 0 && errno == EINTR) 00770 goto again; 00771 00772 return bytes_written; 00773 } 00774 #else /* HAVE_WRITEV */ 00775 { 00776 int ret1, ret2; 00777 00778 ret1 = _dbus_write (fd, buffer1, start1, len1); 00779 if (ret1 == len1 && buffer2 != NULL) 00780 { 00781 ret2 = _dbus_write (fd, buffer2, start2, len2); 00782 if (ret2 < 0) 00783 ret2 = 0; /* we can't report an error as the first write was OK */ 00784 00785 return ret1 + ret2; 00786 } 00787 else 00788 return ret1; 00789 } 00790 #endif /* !HAVE_WRITEV */ 00791 } 00792 00793 #define _DBUS_MAX_SUN_PATH_LENGTH 99 00794 00824 int 00825 _dbus_connect_unix_socket (const char *path, 00826 dbus_bool_t abstract, 00827 DBusError *error) 00828 { 00829 int fd; 00830 size_t path_len; 00831 struct sockaddr_un addr; 00832 00833 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00834 00835 _dbus_verbose ("connecting to unix socket %s abstract=%d\n", 00836 path, abstract); 00837 00838 00839 if (!_dbus_open_unix_socket (&fd, error)) 00840 { 00841 _DBUS_ASSERT_ERROR_IS_SET(error); 00842 return -1; 00843 } 00844 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00845 00846 _DBUS_ZERO (addr); 00847 addr.sun_family = AF_UNIX; 00848 path_len = strlen (path); 00849 00850 if (abstract) 00851 { 00852 #ifdef HAVE_ABSTRACT_SOCKETS 00853 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 00854 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 00855 00856 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00857 { 00858 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00859 "Abstract socket name too long\n"); 00860 _dbus_close (fd, NULL); 00861 return -1; 00862 } 00863 00864 strncpy (&addr.sun_path[1], path, path_len); 00865 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 00866 #else /* HAVE_ABSTRACT_SOCKETS */ 00867 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 00868 "Operating system does not support abstract socket namespace\n"); 00869 _dbus_close (fd, NULL); 00870 return -1; 00871 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 00872 } 00873 else 00874 { 00875 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00876 { 00877 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00878 "Socket name too long\n"); 00879 _dbus_close (fd, NULL); 00880 return -1; 00881 } 00882 00883 strncpy (addr.sun_path, path, path_len); 00884 } 00885 00886 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 00887 { 00888 dbus_set_error (error, 00889 _dbus_error_from_errno (errno), 00890 "Failed to connect to socket %s: %s", 00891 path, _dbus_strerror (errno)); 00892 00893 _dbus_close (fd, NULL); 00894 return -1; 00895 } 00896 00897 if (!_dbus_set_fd_nonblocking (fd, error)) 00898 { 00899 _DBUS_ASSERT_ERROR_IS_SET (error); 00900 00901 _dbus_close (fd, NULL); 00902 return -1; 00903 } 00904 00905 return fd; 00906 } 00907 00920 int 00921 _dbus_connect_exec (const char *path, 00922 char *const argv[], 00923 DBusError *error) 00924 { 00925 int fds[2]; 00926 pid_t pid; 00927 int retval; 00928 dbus_bool_t cloexec_done = 0; 00929 00930 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00931 00932 _dbus_verbose ("connecting to process %s\n", path); 00933 00934 #ifdef SOCK_CLOEXEC 00935 retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); 00936 cloexec_done = (retval >= 0); 00937 00938 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE)) 00939 #endif 00940 { 00941 retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds); 00942 } 00943 00944 if (retval < 0) 00945 { 00946 dbus_set_error (error, 00947 _dbus_error_from_errno (errno), 00948 "Failed to create socket pair: %s", 00949 _dbus_strerror (errno)); 00950 return -1; 00951 } 00952 00953 if (!cloexec_done) 00954 { 00955 _dbus_fd_set_close_on_exec (fds[0]); 00956 _dbus_fd_set_close_on_exec (fds[1]); 00957 } 00958 00959 pid = fork (); 00960 if (pid < 0) 00961 { 00962 dbus_set_error (error, 00963 _dbus_error_from_errno (errno), 00964 "Failed to fork() to call %s: %s", 00965 path, _dbus_strerror (errno)); 00966 close (fds[0]); 00967 close (fds[1]); 00968 return -1; 00969 } 00970 00971 if (pid == 0) 00972 { 00973 /* child */ 00974 close (fds[0]); 00975 00976 dup2 (fds[1], STDIN_FILENO); 00977 dup2 (fds[1], STDOUT_FILENO); 00978 00979 if (fds[1] != STDIN_FILENO && 00980 fds[1] != STDOUT_FILENO) 00981 close (fds[1]); 00982 00983 /* Inherit STDERR and the controlling terminal from the 00984 parent */ 00985 00986 _dbus_close_all (); 00987 00988 execvp (path, argv); 00989 00990 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno)); 00991 00992 _exit(1); 00993 } 00994 00995 /* parent */ 00996 close (fds[1]); 00997 00998 if (!_dbus_set_fd_nonblocking (fds[0], error)) 00999 { 01000 _DBUS_ASSERT_ERROR_IS_SET (error); 01001 01002 close (fds[0]); 01003 return -1; 01004 } 01005 01006 return fds[0]; 01007 } 01008 01018 static dbus_bool_t 01019 _dbus_set_local_creds (int fd, dbus_bool_t on) 01020 { 01021 dbus_bool_t retval = TRUE; 01022 01023 #if defined(HAVE_CMSGCRED) 01024 /* NOOP just to make sure only one codepath is used 01025 * and to prefer CMSGCRED 01026 */ 01027 #elif defined(LOCAL_CREDS) 01028 int val = on ? 1 : 0; 01029 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0) 01030 { 01031 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd); 01032 retval = FALSE; 01033 } 01034 else 01035 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n", 01036 on ? "enabled" : "disabled", fd); 01037 #endif 01038 01039 return retval; 01040 } 01041 01059 int 01060 _dbus_listen_unix_socket (const char *path, 01061 dbus_bool_t abstract, 01062 DBusError *error) 01063 { 01064 int listen_fd; 01065 struct sockaddr_un addr; 01066 size_t path_len; 01067 unsigned int reuseaddr; 01068 01069 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01070 01071 _dbus_verbose ("listening on unix socket %s abstract=%d\n", 01072 path, abstract); 01073 01074 if (!_dbus_open_unix_socket (&listen_fd, error)) 01075 { 01076 _DBUS_ASSERT_ERROR_IS_SET(error); 01077 return -1; 01078 } 01079 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01080 01081 _DBUS_ZERO (addr); 01082 addr.sun_family = AF_UNIX; 01083 path_len = strlen (path); 01084 01085 if (abstract) 01086 { 01087 #ifdef HAVE_ABSTRACT_SOCKETS 01088 /* remember that abstract names aren't nul-terminated so we rely 01089 * on sun_path being filled in with zeroes above. 01090 */ 01091 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 01092 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 01093 01094 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 01095 { 01096 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01097 "Abstract socket name too long\n"); 01098 _dbus_close (listen_fd, NULL); 01099 return -1; 01100 } 01101 01102 strncpy (&addr.sun_path[1], path, path_len); 01103 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 01104 #else /* HAVE_ABSTRACT_SOCKETS */ 01105 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 01106 "Operating system does not support abstract socket namespace\n"); 01107 _dbus_close (listen_fd, NULL); 01108 return -1; 01109 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 01110 } 01111 else 01112 { 01113 /* Discussed security implications of this with Nalin, 01114 * and we couldn't think of where it would kick our ass, but 01115 * it still seems a bit sucky. It also has non-security suckage; 01116 * really we'd prefer to exit if the socket is already in use. 01117 * But there doesn't seem to be a good way to do this. 01118 * 01119 * Just to be extra careful, I threw in the stat() - clearly 01120 * the stat() can't *fix* any security issue, but it at least 01121 * avoids inadvertent/accidental data loss. 01122 */ 01123 { 01124 struct stat sb; 01125 01126 if (stat (path, &sb) == 0 && 01127 S_ISSOCK (sb.st_mode)) 01128 unlink (path); 01129 } 01130 01131 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 01132 { 01133 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01134 "Abstract socket name too long\n"); 01135 _dbus_close (listen_fd, NULL); 01136 return -1; 01137 } 01138 01139 strncpy (addr.sun_path, path, path_len); 01140 } 01141 01142 reuseaddr = 1; 01143 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01144 { 01145 _dbus_warn ("Failed to set socket option\"%s\": %s", 01146 path, _dbus_strerror (errno)); 01147 } 01148 01149 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 01150 { 01151 dbus_set_error (error, _dbus_error_from_errno (errno), 01152 "Failed to bind socket \"%s\": %s", 01153 path, _dbus_strerror (errno)); 01154 _dbus_close (listen_fd, NULL); 01155 return -1; 01156 } 01157 01158 if (listen (listen_fd, 30 /* backlog */) < 0) 01159 { 01160 dbus_set_error (error, _dbus_error_from_errno (errno), 01161 "Failed to listen on socket \"%s\": %s", 01162 path, _dbus_strerror (errno)); 01163 _dbus_close (listen_fd, NULL); 01164 return -1; 01165 } 01166 01167 if (!_dbus_set_local_creds (listen_fd, TRUE)) 01168 { 01169 dbus_set_error (error, _dbus_error_from_errno (errno), 01170 "Failed to enable LOCAL_CREDS on socket \"%s\": %s", 01171 path, _dbus_strerror (errno)); 01172 close (listen_fd); 01173 return -1; 01174 } 01175 01176 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 01177 { 01178 _DBUS_ASSERT_ERROR_IS_SET (error); 01179 _dbus_close (listen_fd, NULL); 01180 return -1; 01181 } 01182 01183 /* Try opening up the permissions, but if we can't, just go ahead 01184 * and continue, maybe it will be good enough. 01185 */ 01186 if (!abstract && chmod (path, 0777) < 0) 01187 _dbus_warn ("Could not set mode 0777 on socket %s\n", 01188 path); 01189 01190 return listen_fd; 01191 } 01192 01203 int 01204 _dbus_listen_systemd_sockets (int **fds, 01205 DBusError *error) 01206 { 01207 int r, n; 01208 unsigned fd; 01209 int *new_fds; 01210 01211 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01212 01213 n = sd_listen_fds (TRUE); 01214 if (n < 0) 01215 { 01216 dbus_set_error (error, _dbus_error_from_errno (-n), 01217 "Failed to acquire systemd socket: %s", 01218 _dbus_strerror (-n)); 01219 return -1; 01220 } 01221 01222 if (n <= 0) 01223 { 01224 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01225 "No socket received."); 01226 return -1; 01227 } 01228 01229 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01230 { 01231 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1); 01232 if (r < 0) 01233 { 01234 dbus_set_error (error, _dbus_error_from_errno (-r), 01235 "Failed to verify systemd socket type: %s", 01236 _dbus_strerror (-r)); 01237 return -1; 01238 } 01239 01240 if (!r) 01241 { 01242 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01243 "Passed socket has wrong type."); 01244 return -1; 01245 } 01246 } 01247 01248 /* OK, the file descriptors are all good, so let's take posession of 01249 them then. */ 01250 01251 new_fds = dbus_new (int, n); 01252 if (!new_fds) 01253 { 01254 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 01255 "Failed to allocate file handle array."); 01256 goto fail; 01257 } 01258 01259 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01260 { 01261 if (!_dbus_set_local_creds (fd, TRUE)) 01262 { 01263 dbus_set_error (error, _dbus_error_from_errno (errno), 01264 "Failed to enable LOCAL_CREDS on systemd socket: %s", 01265 _dbus_strerror (errno)); 01266 goto fail; 01267 } 01268 01269 if (!_dbus_set_fd_nonblocking (fd, error)) 01270 { 01271 _DBUS_ASSERT_ERROR_IS_SET (error); 01272 goto fail; 01273 } 01274 01275 new_fds[fd - SD_LISTEN_FDS_START] = fd; 01276 } 01277 01278 *fds = new_fds; 01279 return n; 01280 01281 fail: 01282 01283 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01284 { 01285 _dbus_close (fd, NULL); 01286 } 01287 01288 dbus_free (new_fds); 01289 return -1; 01290 } 01291 01305 int 01306 _dbus_connect_tcp_socket (const char *host, 01307 const char *port, 01308 const char *family, 01309 DBusError *error) 01310 { 01311 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error); 01312 } 01313 01314 int 01315 _dbus_connect_tcp_socket_with_nonce (const char *host, 01316 const char *port, 01317 const char *family, 01318 const char *noncefile, 01319 DBusError *error) 01320 { 01321 int saved_errno = 0; 01322 int fd = -1, res; 01323 struct addrinfo hints; 01324 struct addrinfo *ai, *tmp; 01325 01326 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01327 01328 _DBUS_ZERO (hints); 01329 01330 if (!family) 01331 hints.ai_family = AF_UNSPEC; 01332 else if (!strcmp(family, "ipv4")) 01333 hints.ai_family = AF_INET; 01334 else if (!strcmp(family, "ipv6")) 01335 hints.ai_family = AF_INET6; 01336 else 01337 { 01338 dbus_set_error (error, 01339 DBUS_ERROR_BAD_ADDRESS, 01340 "Unknown address family %s", family); 01341 return -1; 01342 } 01343 hints.ai_protocol = IPPROTO_TCP; 01344 hints.ai_socktype = SOCK_STREAM; 01345 hints.ai_flags = AI_ADDRCONFIG; 01346 01347 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0) 01348 { 01349 dbus_set_error (error, 01350 _dbus_error_from_errno (errno), 01351 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01352 host, port, gai_strerror(res), res); 01353 return -1; 01354 } 01355 01356 tmp = ai; 01357 while (tmp) 01358 { 01359 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01360 { 01361 freeaddrinfo(ai); 01362 _DBUS_ASSERT_ERROR_IS_SET(error); 01363 return -1; 01364 } 01365 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01366 01367 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01368 { 01369 saved_errno = errno; 01370 _dbus_close(fd, NULL); 01371 fd = -1; 01372 tmp = tmp->ai_next; 01373 continue; 01374 } 01375 01376 break; 01377 } 01378 freeaddrinfo(ai); 01379 01380 if (fd == -1) 01381 { 01382 dbus_set_error (error, 01383 _dbus_error_from_errno (saved_errno), 01384 "Failed to connect to socket \"%s:%s\" %s", 01385 host, port, _dbus_strerror(saved_errno)); 01386 return -1; 01387 } 01388 01389 if (noncefile != NULL) 01390 { 01391 DBusString noncefileStr; 01392 dbus_bool_t ret; 01393 _dbus_string_init_const (&noncefileStr, noncefile); 01394 ret = _dbus_send_nonce (fd, &noncefileStr, error); 01395 _dbus_string_free (&noncefileStr); 01396 01397 if (!ret) 01398 { 01399 _dbus_close (fd, NULL); 01400 return -1; 01401 } 01402 } 01403 01404 if (!_dbus_set_fd_nonblocking (fd, error)) 01405 { 01406 _dbus_close (fd, NULL); 01407 return -1; 01408 } 01409 01410 return fd; 01411 } 01412 01429 int 01430 _dbus_listen_tcp_socket (const char *host, 01431 const char *port, 01432 const char *family, 01433 DBusString *retport, 01434 int **fds_p, 01435 DBusError *error) 01436 { 01437 int saved_errno; 01438 int nlisten_fd = 0, *listen_fd = NULL, res, i; 01439 struct addrinfo hints; 01440 struct addrinfo *ai, *tmp; 01441 unsigned int reuseaddr; 01442 01443 *fds_p = NULL; 01444 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01445 01446 _DBUS_ZERO (hints); 01447 01448 if (!family) 01449 hints.ai_family = AF_UNSPEC; 01450 else if (!strcmp(family, "ipv4")) 01451 hints.ai_family = AF_INET; 01452 else if (!strcmp(family, "ipv6")) 01453 hints.ai_family = AF_INET6; 01454 else 01455 { 01456 dbus_set_error (error, 01457 DBUS_ERROR_BAD_ADDRESS, 01458 "Unknown address family %s", family); 01459 return -1; 01460 } 01461 01462 hints.ai_protocol = IPPROTO_TCP; 01463 hints.ai_socktype = SOCK_STREAM; 01464 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; 01465 01466 redo_lookup_with_port: 01467 ai = NULL; 01468 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai) 01469 { 01470 dbus_set_error (error, 01471 _dbus_error_from_errno (errno), 01472 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01473 host ? host : "*", port, gai_strerror(res), res); 01474 goto failed; 01475 } 01476 01477 tmp = ai; 01478 while (tmp) 01479 { 01480 int fd = -1, *newlisten_fd; 01481 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01482 { 01483 _DBUS_ASSERT_ERROR_IS_SET(error); 01484 goto failed; 01485 } 01486 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01487 01488 reuseaddr = 1; 01489 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01490 { 01491 _dbus_warn ("Failed to set socket option \"%s:%s\": %s", 01492 host ? host : "*", port, _dbus_strerror (errno)); 01493 } 01494 01495 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01496 { 01497 saved_errno = errno; 01498 _dbus_close(fd, NULL); 01499 if (saved_errno == EADDRINUSE) 01500 { 01501 /* Depending on kernel policy, it may or may not 01502 be neccessary to bind to both IPv4 & 6 addresses 01503 so ignore EADDRINUSE here */ 01504 tmp = tmp->ai_next; 01505 continue; 01506 } 01507 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01508 "Failed to bind socket \"%s:%s\": %s", 01509 host ? host : "*", port, _dbus_strerror (saved_errno)); 01510 goto failed; 01511 } 01512 01513 if (listen (fd, 30 /* backlog */) < 0) 01514 { 01515 saved_errno = errno; 01516 _dbus_close (fd, NULL); 01517 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01518 "Failed to listen on socket \"%s:%s\": %s", 01519 host ? host : "*", port, _dbus_strerror (saved_errno)); 01520 goto failed; 01521 } 01522 01523 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); 01524 if (!newlisten_fd) 01525 { 01526 saved_errno = errno; 01527 _dbus_close (fd, NULL); 01528 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01529 "Failed to allocate file handle array: %s", 01530 _dbus_strerror (saved_errno)); 01531 goto failed; 01532 } 01533 listen_fd = newlisten_fd; 01534 listen_fd[nlisten_fd] = fd; 01535 nlisten_fd++; 01536 01537 if (!_dbus_string_get_length(retport)) 01538 { 01539 /* If the user didn't specify a port, or used 0, then 01540 the kernel chooses a port. After the first address 01541 is bound to, we need to force all remaining addresses 01542 to use the same port */ 01543 if (!port || !strcmp(port, "0")) 01544 { 01545 int result; 01546 struct sockaddr_storage addr; 01547 socklen_t addrlen; 01548 char portbuf[50]; 01549 01550 addrlen = sizeof(addr); 01551 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen); 01552 01553 if (result == -1 || 01554 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0, 01555 portbuf, sizeof(portbuf), 01556 NI_NUMERICHOST)) != 0) 01557 { 01558 dbus_set_error (error, _dbus_error_from_errno (errno), 01559 "Failed to resolve port \"%s:%s\": %s (%s)", 01560 host ? host : "*", port, gai_strerror(res), res); 01561 goto failed; 01562 } 01563 if (!_dbus_string_append(retport, portbuf)) 01564 { 01565 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01566 goto failed; 01567 } 01568 01569 /* Release current address list & redo lookup */ 01570 port = _dbus_string_get_const_data(retport); 01571 freeaddrinfo(ai); 01572 goto redo_lookup_with_port; 01573 } 01574 else 01575 { 01576 if (!_dbus_string_append(retport, port)) 01577 { 01578 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01579 goto failed; 01580 } 01581 } 01582 } 01583 01584 tmp = tmp->ai_next; 01585 } 01586 freeaddrinfo(ai); 01587 ai = NULL; 01588 01589 if (!nlisten_fd) 01590 { 01591 errno = EADDRINUSE; 01592 dbus_set_error (error, _dbus_error_from_errno (errno), 01593 "Failed to bind socket \"%s:%s\": %s", 01594 host ? host : "*", port, _dbus_strerror (errno)); 01595 goto failed; 01596 } 01597 01598 for (i = 0 ; i < nlisten_fd ; i++) 01599 { 01600 if (!_dbus_set_fd_nonblocking (listen_fd[i], error)) 01601 { 01602 goto failed; 01603 } 01604 } 01605 01606 *fds_p = listen_fd; 01607 01608 return nlisten_fd; 01609 01610 failed: 01611 if (ai) 01612 freeaddrinfo(ai); 01613 for (i = 0 ; i < nlisten_fd ; i++) 01614 _dbus_close(listen_fd[i], NULL); 01615 dbus_free(listen_fd); 01616 return -1; 01617 } 01618 01619 static dbus_bool_t 01620 write_credentials_byte (int server_fd, 01621 DBusError *error) 01622 { 01623 int bytes_written; 01624 char buf[1] = { '\0' }; 01625 #if defined(HAVE_CMSGCRED) 01626 union { 01627 struct cmsghdr hdr; 01628 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01629 } cmsg; 01630 struct iovec iov; 01631 struct msghdr msg; 01632 iov.iov_base = buf; 01633 iov.iov_len = 1; 01634 01635 _DBUS_ZERO(msg); 01636 msg.msg_iov = &iov; 01637 msg.msg_iovlen = 1; 01638 01639 msg.msg_control = (caddr_t) &cmsg; 01640 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01641 _DBUS_ZERO(cmsg); 01642 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); 01643 cmsg.hdr.cmsg_level = SOL_SOCKET; 01644 cmsg.hdr.cmsg_type = SCM_CREDS; 01645 #endif 01646 01647 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01648 01649 again: 01650 01651 #if defined(HAVE_CMSGCRED) 01652 bytes_written = sendmsg (server_fd, &msg, 0 01653 #if HAVE_DECL_MSG_NOSIGNAL 01654 |MSG_NOSIGNAL 01655 #endif 01656 ); 01657 #else 01658 bytes_written = send (server_fd, buf, 1, 0 01659 #if HAVE_DECL_MSG_NOSIGNAL 01660 |MSG_NOSIGNAL 01661 #endif 01662 ); 01663 #endif 01664 01665 if (bytes_written < 0 && errno == EINTR) 01666 goto again; 01667 01668 if (bytes_written < 0) 01669 { 01670 dbus_set_error (error, _dbus_error_from_errno (errno), 01671 "Failed to write credentials byte: %s", 01672 _dbus_strerror (errno)); 01673 return FALSE; 01674 } 01675 else if (bytes_written == 0) 01676 { 01677 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 01678 "wrote zero bytes writing credentials byte"); 01679 return FALSE; 01680 } 01681 else 01682 { 01683 _dbus_assert (bytes_written == 1); 01684 _dbus_verbose ("wrote credentials byte\n"); 01685 return TRUE; 01686 } 01687 } 01688 01710 dbus_bool_t 01711 _dbus_read_credentials_socket (int client_fd, 01712 DBusCredentials *credentials, 01713 DBusError *error) 01714 { 01715 struct msghdr msg; 01716 struct iovec iov; 01717 char buf; 01718 dbus_uid_t uid_read; 01719 dbus_pid_t pid_read; 01720 int bytes_read; 01721 01722 #ifdef HAVE_CMSGCRED 01723 union { 01724 struct cmsghdr hdr; 01725 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01726 } cmsg; 01727 01728 #elif defined(LOCAL_CREDS) 01729 struct { 01730 struct cmsghdr hdr; 01731 struct sockcred cred; 01732 } cmsg; 01733 #endif 01734 01735 uid_read = DBUS_UID_UNSET; 01736 pid_read = DBUS_PID_UNSET; 01737 01738 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01739 01740 /* The POSIX spec certainly doesn't promise this, but 01741 * we need these assertions to fail as soon as we're wrong about 01742 * it so we can do the porting fixups 01743 */ 01744 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 01745 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 01746 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 01747 01748 _dbus_credentials_clear (credentials); 01749 01750 /* Systems supporting LOCAL_CREDS are configured to have this feature 01751 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting 01752 * the connection. Therefore, the received message must carry the 01753 * credentials information without doing anything special. 01754 */ 01755 01756 iov.iov_base = &buf; 01757 iov.iov_len = 1; 01758 01759 _DBUS_ZERO(msg); 01760 msg.msg_iov = &iov; 01761 msg.msg_iovlen = 1; 01762 01763 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01764 _DBUS_ZERO(cmsg); 01765 msg.msg_control = (caddr_t) &cmsg; 01766 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01767 #endif 01768 01769 again: 01770 bytes_read = recvmsg (client_fd, &msg, 0); 01771 01772 if (bytes_read < 0) 01773 { 01774 if (errno == EINTR) 01775 goto again; 01776 01777 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would 01778 * normally only call read_credentials if the socket was ready 01779 * for reading 01780 */ 01781 01782 dbus_set_error (error, _dbus_error_from_errno (errno), 01783 "Failed to read credentials byte: %s", 01784 _dbus_strerror (errno)); 01785 return FALSE; 01786 } 01787 else if (bytes_read == 0) 01788 { 01789 /* this should not happen unless we are using recvmsg wrong, 01790 * so is essentially here for paranoia 01791 */ 01792 dbus_set_error (error, DBUS_ERROR_FAILED, 01793 "Failed to read credentials byte (zero-length read)"); 01794 return FALSE; 01795 } 01796 else if (buf != '\0') 01797 { 01798 dbus_set_error (error, DBUS_ERROR_FAILED, 01799 "Credentials byte was not nul"); 01800 return FALSE; 01801 } 01802 01803 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01804 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) 01805 || cmsg.hdr.cmsg_type != SCM_CREDS) 01806 { 01807 dbus_set_error (error, DBUS_ERROR_FAILED, 01808 "Message from recvmsg() was not SCM_CREDS"); 01809 return FALSE; 01810 } 01811 #endif 01812 01813 _dbus_verbose ("read credentials byte\n"); 01814 01815 { 01816 #ifdef SO_PEERCRED 01817 #ifdef __OpenBSD__ 01818 struct sockpeercred cr; 01819 #else 01820 struct ucred cr; 01821 #endif 01822 int cr_len = sizeof (cr); 01823 01824 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && 01825 cr_len == sizeof (cr)) 01826 { 01827 pid_read = cr.pid; 01828 uid_read = cr.uid; 01829 } 01830 else 01831 { 01832 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", 01833 cr_len, (int) sizeof (cr), _dbus_strerror (errno)); 01834 } 01835 #elif defined(HAVE_CMSGCRED) 01836 struct cmsgcred *cred; 01837 01838 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr); 01839 pid_read = cred->cmcred_pid; 01840 uid_read = cred->cmcred_euid; 01841 #elif defined(LOCAL_CREDS) 01842 pid_read = DBUS_PID_UNSET; 01843 uid_read = cmsg.cred.sc_uid; 01844 /* Since we have already got the credentials from this socket, we can 01845 * disable its LOCAL_CREDS flag if it was ever set. */ 01846 _dbus_set_local_creds (client_fd, FALSE); 01847 #elif defined(HAVE_GETPEEREID) 01848 uid_t euid; 01849 gid_t egid; 01850 if (getpeereid (client_fd, &euid, &egid) == 0) 01851 { 01852 uid_read = euid; 01853 } 01854 else 01855 { 01856 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno)); 01857 } 01858 #elif defined(HAVE_GETPEERUCRED) 01859 ucred_t * ucred = NULL; 01860 if (getpeerucred (client_fd, &ucred) == 0) 01861 { 01862 pid_read = ucred_getpid (ucred); 01863 uid_read = ucred_geteuid (ucred); 01864 #ifdef HAVE_ADT 01865 /* generate audit session data based on socket ucred */ 01866 adt_session_data_t *adth = NULL; 01867 adt_export_data_t *data = NULL; 01868 size_t size = 0; 01869 if (adt_start_session (&adth, NULL, 0) || (adth == NULL)) 01870 { 01871 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno)); 01872 } 01873 else 01874 { 01875 if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 01876 { 01877 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno)); 01878 } 01879 else 01880 { 01881 size = adt_export_session_data (adth, &data); 01882 if (size <= 0) 01883 { 01884 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno)); 01885 } 01886 else 01887 { 01888 _dbus_credentials_add_adt_audit_data (credentials, data, size); 01889 free (data); 01890 } 01891 } 01892 (void) adt_end_session (adth); 01893 } 01894 #endif /* HAVE_ADT */ 01895 } 01896 else 01897 { 01898 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno)); 01899 } 01900 if (ucred != NULL) 01901 ucred_free (ucred); 01902 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ 01903 _dbus_verbose ("Socket credentials not supported on this OS\n"); 01904 #endif 01905 } 01906 01907 _dbus_verbose ("Credentials:" 01908 " pid "DBUS_PID_FORMAT 01909 " uid "DBUS_UID_FORMAT 01910 "\n", 01911 pid_read, 01912 uid_read); 01913 01914 if (pid_read != DBUS_PID_UNSET) 01915 { 01916 if (!_dbus_credentials_add_unix_pid (credentials, pid_read)) 01917 { 01918 _DBUS_SET_OOM (error); 01919 return FALSE; 01920 } 01921 } 01922 01923 if (uid_read != DBUS_UID_UNSET) 01924 { 01925 if (!_dbus_credentials_add_unix_uid (credentials, uid_read)) 01926 { 01927 _DBUS_SET_OOM (error); 01928 return FALSE; 01929 } 01930 } 01931 01932 return TRUE; 01933 } 01934 01952 dbus_bool_t 01953 _dbus_send_credentials_socket (int server_fd, 01954 DBusError *error) 01955 { 01956 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01957 01958 if (write_credentials_byte (server_fd, error)) 01959 return TRUE; 01960 else 01961 return FALSE; 01962 } 01963 01973 int 01974 _dbus_accept (int listen_fd) 01975 { 01976 int client_fd; 01977 struct sockaddr addr; 01978 socklen_t addrlen; 01979 #ifdef HAVE_ACCEPT4 01980 dbus_bool_t cloexec_done; 01981 #endif 01982 01983 addrlen = sizeof (addr); 01984 01985 retry: 01986 01987 #ifdef HAVE_ACCEPT4 01988 /* 01989 * At compile-time, we assume that if accept4() is available in 01990 * libc headers, SOCK_CLOEXEC is too. At runtime, it is still 01991 * not necessarily true that either is supported by the running kernel. 01992 */ 01993 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC); 01994 cloexec_done = client_fd >= 0; 01995 01996 if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL)) 01997 #endif 01998 { 01999 client_fd = accept (listen_fd, &addr, &addrlen); 02000 } 02001 02002 if (client_fd < 0) 02003 { 02004 if (errno == EINTR) 02005 goto retry; 02006 } 02007 02008 _dbus_verbose ("client fd %d accepted\n", client_fd); 02009 02010 #ifdef HAVE_ACCEPT4 02011 if (!cloexec_done) 02012 #endif 02013 { 02014 _dbus_fd_set_close_on_exec(client_fd); 02015 } 02016 02017 return client_fd; 02018 } 02019 02028 dbus_bool_t 02029 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) 02030 { 02031 const char *directory; 02032 struct stat sb; 02033 02034 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02035 02036 directory = _dbus_string_get_const_data (dir); 02037 02038 if (stat (directory, &sb) < 0) 02039 { 02040 dbus_set_error (error, _dbus_error_from_errno (errno), 02041 "%s", _dbus_strerror (errno)); 02042 02043 return FALSE; 02044 } 02045 02046 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) || 02047 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode)) 02048 { 02049 dbus_set_error (error, DBUS_ERROR_FAILED, 02050 "%s directory is not private to the user", directory); 02051 return FALSE; 02052 } 02053 02054 return TRUE; 02055 } 02056 02057 static dbus_bool_t 02058 fill_user_info_from_passwd (struct passwd *p, 02059 DBusUserInfo *info, 02060 DBusError *error) 02061 { 02062 _dbus_assert (p->pw_name != NULL); 02063 _dbus_assert (p->pw_dir != NULL); 02064 02065 info->uid = p->pw_uid; 02066 info->primary_gid = p->pw_gid; 02067 info->username = _dbus_strdup (p->pw_name); 02068 info->homedir = _dbus_strdup (p->pw_dir); 02069 02070 if (info->username == NULL || 02071 info->homedir == NULL) 02072 { 02073 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02074 return FALSE; 02075 } 02076 02077 return TRUE; 02078 } 02079 02080 static dbus_bool_t 02081 fill_user_info (DBusUserInfo *info, 02082 dbus_uid_t uid, 02083 const DBusString *username, 02084 DBusError *error) 02085 { 02086 const char *username_c; 02087 02088 /* exactly one of username/uid provided */ 02089 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET); 02090 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET); 02091 02092 info->uid = DBUS_UID_UNSET; 02093 info->primary_gid = DBUS_GID_UNSET; 02094 info->group_ids = NULL; 02095 info->n_group_ids = 0; 02096 info->username = NULL; 02097 info->homedir = NULL; 02098 02099 if (username != NULL) 02100 username_c = _dbus_string_get_const_data (username); 02101 else 02102 username_c = NULL; 02103 02104 /* For now assuming that the getpwnam() and getpwuid() flavors 02105 * are always symmetrical, if not we have to add more configure 02106 * checks 02107 */ 02108 02109 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R) 02110 { 02111 struct passwd *p; 02112 int result; 02113 size_t buflen; 02114 char *buf; 02115 struct passwd p_str; 02116 02117 /* retrieve maximum needed size for buf */ 02118 buflen = sysconf (_SC_GETPW_R_SIZE_MAX); 02119 02120 /* sysconf actually returns a long, but everything else expects size_t, 02121 * so just recast here. 02122 * https://bugs.freedesktop.org/show_bug.cgi?id=17061 02123 */ 02124 if ((long) buflen <= 0) 02125 buflen = 1024; 02126 02127 result = -1; 02128 while (1) 02129 { 02130 buf = dbus_malloc (buflen); 02131 if (buf == NULL) 02132 { 02133 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02134 return FALSE; 02135 } 02136 02137 p = NULL; 02138 #ifdef HAVE_POSIX_GETPWNAM_R 02139 if (uid != DBUS_UID_UNSET) 02140 result = getpwuid_r (uid, &p_str, buf, buflen, 02141 &p); 02142 else 02143 result = getpwnam_r (username_c, &p_str, buf, buflen, 02144 &p); 02145 #else 02146 if (uid != DBUS_UID_UNSET) 02147 p = getpwuid_r (uid, &p_str, buf, buflen); 02148 else 02149 p = getpwnam_r (username_c, &p_str, buf, buflen); 02150 result = 0; 02151 #endif /* !HAVE_POSIX_GETPWNAM_R */ 02152 //Try a bigger buffer if ERANGE was returned 02153 if (result == ERANGE && buflen < 512 * 1024) 02154 { 02155 dbus_free (buf); 02156 buflen *= 2; 02157 } 02158 else 02159 { 02160 break; 02161 } 02162 } 02163 if (result == 0 && p == &p_str) 02164 { 02165 if (!fill_user_info_from_passwd (p, info, error)) 02166 { 02167 dbus_free (buf); 02168 return FALSE; 02169 } 02170 dbus_free (buf); 02171 } 02172 else 02173 { 02174 dbus_set_error (error, _dbus_error_from_errno (errno), 02175 "User \"%s\" unknown or no memory to allocate password entry\n", 02176 username_c ? username_c : "???"); 02177 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02178 dbus_free (buf); 02179 return FALSE; 02180 } 02181 } 02182 #else /* ! HAVE_GETPWNAM_R */ 02183 { 02184 /* I guess we're screwed on thread safety here */ 02185 struct passwd *p; 02186 02187 if (uid != DBUS_UID_UNSET) 02188 p = getpwuid (uid); 02189 else 02190 p = getpwnam (username_c); 02191 02192 if (p != NULL) 02193 { 02194 if (!fill_user_info_from_passwd (p, info, error)) 02195 { 02196 return FALSE; 02197 } 02198 } 02199 else 02200 { 02201 dbus_set_error (error, _dbus_error_from_errno (errno), 02202 "User \"%s\" unknown or no memory to allocate password entry\n", 02203 username_c ? username_c : "???"); 02204 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02205 return FALSE; 02206 } 02207 } 02208 #endif /* ! HAVE_GETPWNAM_R */ 02209 02210 /* Fill this in so we can use it to get groups */ 02211 username_c = info->username; 02212 02213 #ifdef HAVE_GETGROUPLIST 02214 { 02215 gid_t *buf; 02216 int buf_count; 02217 int i; 02218 int initial_buf_count; 02219 02220 initial_buf_count = 17; 02221 buf_count = initial_buf_count; 02222 buf = dbus_new (gid_t, buf_count); 02223 if (buf == NULL) 02224 { 02225 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02226 goto failed; 02227 } 02228 02229 if (getgrouplist (username_c, 02230 info->primary_gid, 02231 buf, &buf_count) < 0) 02232 { 02233 gid_t *new; 02234 /* Presumed cause of negative return code: buf has insufficient 02235 entries to hold the entire group list. The Linux behavior in this 02236 case is to pass back the actual number of groups in buf_count, but 02237 on Mac OS X 10.5, buf_count is unhelpfully left alone. 02238 So as a hack, try to help out a bit by guessing a larger 02239 number of groups, within reason.. might still fail, of course, 02240 but we can at least print a more informative message. I looked up 02241 the "right way" to do this by downloading Apple's own source code 02242 for the "id" command, and it turns out that they use an 02243 undocumented library function getgrouplist_2 (!) which is not 02244 declared in any header in /usr/include (!!). That did not seem 02245 like the way to go here. 02246 */ 02247 if (buf_count == initial_buf_count) 02248 { 02249 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */ 02250 } 02251 new = dbus_realloc (buf, buf_count * sizeof (buf[0])); 02252 if (new == NULL) 02253 { 02254 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02255 dbus_free (buf); 02256 goto failed; 02257 } 02258 02259 buf = new; 02260 02261 errno = 0; 02262 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0) 02263 { 02264 if (errno == 0) 02265 { 02266 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.", 02267 username_c, buf_count, buf_count); 02268 } 02269 else 02270 { 02271 dbus_set_error (error, 02272 _dbus_error_from_errno (errno), 02273 "Failed to get groups for username \"%s\" primary GID " 02274 DBUS_GID_FORMAT ": %s\n", 02275 username_c, info->primary_gid, 02276 _dbus_strerror (errno)); 02277 dbus_free (buf); 02278 goto failed; 02279 } 02280 } 02281 } 02282 02283 info->group_ids = dbus_new (dbus_gid_t, buf_count); 02284 if (info->group_ids == NULL) 02285 { 02286 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02287 dbus_free (buf); 02288 goto failed; 02289 } 02290 02291 for (i = 0; i < buf_count; ++i) 02292 info->group_ids[i] = buf[i]; 02293 02294 info->n_group_ids = buf_count; 02295 02296 dbus_free (buf); 02297 } 02298 #else /* HAVE_GETGROUPLIST */ 02299 { 02300 /* We just get the one group ID */ 02301 info->group_ids = dbus_new (dbus_gid_t, 1); 02302 if (info->group_ids == NULL) 02303 { 02304 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02305 goto failed; 02306 } 02307 02308 info->n_group_ids = 1; 02309 02310 (info->group_ids)[0] = info->primary_gid; 02311 } 02312 #endif /* HAVE_GETGROUPLIST */ 02313 02314 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02315 02316 return TRUE; 02317 02318 failed: 02319 _DBUS_ASSERT_ERROR_IS_SET (error); 02320 return FALSE; 02321 } 02322 02331 dbus_bool_t 02332 _dbus_user_info_fill (DBusUserInfo *info, 02333 const DBusString *username, 02334 DBusError *error) 02335 { 02336 return fill_user_info (info, DBUS_UID_UNSET, 02337 username, error); 02338 } 02339 02348 dbus_bool_t 02349 _dbus_user_info_fill_uid (DBusUserInfo *info, 02350 dbus_uid_t uid, 02351 DBusError *error) 02352 { 02353 return fill_user_info (info, uid, 02354 NULL, error); 02355 } 02356 02364 dbus_bool_t 02365 _dbus_credentials_add_from_current_process (DBusCredentials *credentials) 02366 { 02367 /* The POSIX spec certainly doesn't promise this, but 02368 * we need these assertions to fail as soon as we're wrong about 02369 * it so we can do the porting fixups 02370 */ 02371 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 02372 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 02373 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 02374 02375 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) 02376 return FALSE; 02377 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid())) 02378 return FALSE; 02379 02380 return TRUE; 02381 } 02382 02394 dbus_bool_t 02395 _dbus_append_user_from_current_process (DBusString *str) 02396 { 02397 return _dbus_string_append_uint (str, 02398 _dbus_geteuid ()); 02399 } 02400 02405 dbus_pid_t 02406 _dbus_getpid (void) 02407 { 02408 return getpid (); 02409 } 02410 02414 dbus_uid_t 02415 _dbus_getuid (void) 02416 { 02417 return getuid (); 02418 } 02419 02423 dbus_uid_t 02424 _dbus_geteuid (void) 02425 { 02426 return geteuid (); 02427 } 02428 02435 unsigned long 02436 _dbus_pid_for_log (void) 02437 { 02438 return getpid (); 02439 } 02440 02448 dbus_bool_t 02449 _dbus_parse_uid (const DBusString *uid_str, 02450 dbus_uid_t *uid) 02451 { 02452 int end; 02453 long val; 02454 02455 if (_dbus_string_get_length (uid_str) == 0) 02456 { 02457 _dbus_verbose ("UID string was zero length\n"); 02458 return FALSE; 02459 } 02460 02461 val = -1; 02462 end = 0; 02463 if (!_dbus_string_parse_int (uid_str, 0, &val, 02464 &end)) 02465 { 02466 _dbus_verbose ("could not parse string as a UID\n"); 02467 return FALSE; 02468 } 02469 02470 if (end != _dbus_string_get_length (uid_str)) 02471 { 02472 _dbus_verbose ("string contained trailing stuff after UID\n"); 02473 return FALSE; 02474 } 02475 02476 *uid = val; 02477 02478 return TRUE; 02479 } 02480 02481 #if !DBUS_USE_SYNC 02482 _DBUS_DEFINE_GLOBAL_LOCK (atomic); 02483 #endif 02484 02491 dbus_int32_t 02492 _dbus_atomic_inc (DBusAtomic *atomic) 02493 { 02494 #if DBUS_USE_SYNC 02495 return __sync_add_and_fetch(&atomic->value, 1)-1; 02496 #else 02497 dbus_int32_t res; 02498 _DBUS_LOCK (atomic); 02499 res = atomic->value; 02500 atomic->value += 1; 02501 _DBUS_UNLOCK (atomic); 02502 return res; 02503 #endif 02504 } 02505 02512 dbus_int32_t 02513 _dbus_atomic_dec (DBusAtomic *atomic) 02514 { 02515 #if DBUS_USE_SYNC 02516 return __sync_sub_and_fetch(&atomic->value, 1)+1; 02517 #else 02518 dbus_int32_t res; 02519 02520 _DBUS_LOCK (atomic); 02521 res = atomic->value; 02522 atomic->value -= 1; 02523 _DBUS_UNLOCK (atomic); 02524 return res; 02525 #endif 02526 } 02527 02535 dbus_int32_t 02536 _dbus_atomic_get (DBusAtomic *atomic) 02537 { 02538 #if DBUS_USE_SYNC 02539 __sync_synchronize (); 02540 return atomic->value; 02541 #else 02542 dbus_int32_t res; 02543 02544 _DBUS_LOCK (atomic); 02545 res = atomic->value; 02546 _DBUS_UNLOCK (atomic); 02547 return res; 02548 #endif 02549 } 02550 02559 int 02560 _dbus_poll (DBusPollFD *fds, 02561 int n_fds, 02562 int timeout_milliseconds) 02563 { 02564 #if defined(HAVE_POLL) && !defined(BROKEN_POLL) 02565 /* This big thing is a constant expression and should get optimized 02566 * out of existence. So it's more robust than a configure check at 02567 * no cost. 02568 */ 02569 if (_DBUS_POLLIN == POLLIN && 02570 _DBUS_POLLPRI == POLLPRI && 02571 _DBUS_POLLOUT == POLLOUT && 02572 _DBUS_POLLERR == POLLERR && 02573 _DBUS_POLLHUP == POLLHUP && 02574 _DBUS_POLLNVAL == POLLNVAL && 02575 sizeof (DBusPollFD) == sizeof (struct pollfd) && 02576 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) == 02577 _DBUS_STRUCT_OFFSET (struct pollfd, fd) && 02578 _DBUS_STRUCT_OFFSET (DBusPollFD, events) == 02579 _DBUS_STRUCT_OFFSET (struct pollfd, events) && 02580 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == 02581 _DBUS_STRUCT_OFFSET (struct pollfd, revents)) 02582 { 02583 return poll ((struct pollfd*) fds, 02584 n_fds, 02585 timeout_milliseconds); 02586 } 02587 else 02588 { 02589 /* We have to convert the DBusPollFD to an array of 02590 * struct pollfd, poll, and convert back. 02591 */ 02592 _dbus_warn ("didn't implement poll() properly for this system yet\n"); 02593 return -1; 02594 } 02595 #else /* ! HAVE_POLL */ 02596 02597 fd_set read_set, write_set, err_set; 02598 int max_fd = 0; 02599 int i; 02600 struct timeval tv; 02601 int ready; 02602 02603 FD_ZERO (&read_set); 02604 FD_ZERO (&write_set); 02605 FD_ZERO (&err_set); 02606 02607 for (i = 0; i < n_fds; i++) 02608 { 02609 DBusPollFD *fdp = &fds[i]; 02610 02611 if (fdp->events & _DBUS_POLLIN) 02612 FD_SET (fdp->fd, &read_set); 02613 02614 if (fdp->events & _DBUS_POLLOUT) 02615 FD_SET (fdp->fd, &write_set); 02616 02617 FD_SET (fdp->fd, &err_set); 02618 02619 max_fd = MAX (max_fd, fdp->fd); 02620 } 02621 02622 tv.tv_sec = timeout_milliseconds / 1000; 02623 tv.tv_usec = (timeout_milliseconds % 1000) * 1000; 02624 02625 ready = select (max_fd + 1, &read_set, &write_set, &err_set, 02626 timeout_milliseconds < 0 ? NULL : &tv); 02627 02628 if (ready > 0) 02629 { 02630 for (i = 0; i < n_fds; i++) 02631 { 02632 DBusPollFD *fdp = &fds[i]; 02633 02634 fdp->revents = 0; 02635 02636 if (FD_ISSET (fdp->fd, &read_set)) 02637 fdp->revents |= _DBUS_POLLIN; 02638 02639 if (FD_ISSET (fdp->fd, &write_set)) 02640 fdp->revents |= _DBUS_POLLOUT; 02641 02642 if (FD_ISSET (fdp->fd, &err_set)) 02643 fdp->revents |= _DBUS_POLLERR; 02644 } 02645 } 02646 02647 return ready; 02648 #endif 02649 } 02650 02658 void 02659 _dbus_get_monotonic_time (long *tv_sec, 02660 long *tv_usec) 02661 { 02662 #ifdef HAVE_MONOTONIC_CLOCK 02663 struct timespec ts; 02664 clock_gettime (CLOCK_MONOTONIC, &ts); 02665 02666 if (tv_sec) 02667 *tv_sec = ts.tv_sec; 02668 if (tv_usec) 02669 *tv_usec = ts.tv_nsec / 1000; 02670 #else 02671 struct timeval t; 02672 02673 gettimeofday (&t, NULL); 02674 02675 if (tv_sec) 02676 *tv_sec = t.tv_sec; 02677 if (tv_usec) 02678 *tv_usec = t.tv_usec; 02679 #endif 02680 } 02681 02689 void 02690 _dbus_get_real_time (long *tv_sec, 02691 long *tv_usec) 02692 { 02693 struct timeval t; 02694 02695 gettimeofday (&t, NULL); 02696 02697 if (tv_sec) 02698 *tv_sec = t.tv_sec; 02699 if (tv_usec) 02700 *tv_usec = t.tv_usec; 02701 } 02702 02711 dbus_bool_t 02712 _dbus_create_directory (const DBusString *filename, 02713 DBusError *error) 02714 { 02715 const char *filename_c; 02716 02717 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02718 02719 filename_c = _dbus_string_get_const_data (filename); 02720 02721 if (mkdir (filename_c, 0700) < 0) 02722 { 02723 if (errno == EEXIST) 02724 return TRUE; 02725 02726 dbus_set_error (error, DBUS_ERROR_FAILED, 02727 "Failed to create directory %s: %s\n", 02728 filename_c, _dbus_strerror (errno)); 02729 return FALSE; 02730 } 02731 else 02732 return TRUE; 02733 } 02734 02745 dbus_bool_t 02746 _dbus_concat_dir_and_file (DBusString *dir, 02747 const DBusString *next_component) 02748 { 02749 dbus_bool_t dir_ends_in_slash; 02750 dbus_bool_t file_starts_with_slash; 02751 02752 if (_dbus_string_get_length (dir) == 0 || 02753 _dbus_string_get_length (next_component) == 0) 02754 return TRUE; 02755 02756 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, 02757 _dbus_string_get_length (dir) - 1); 02758 02759 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); 02760 02761 if (dir_ends_in_slash && file_starts_with_slash) 02762 { 02763 _dbus_string_shorten (dir, 1); 02764 } 02765 else if (!(dir_ends_in_slash || file_starts_with_slash)) 02766 { 02767 if (!_dbus_string_append_byte (dir, '/')) 02768 return FALSE; 02769 } 02770 02771 return _dbus_string_copy (next_component, 0, dir, 02772 _dbus_string_get_length (dir)); 02773 } 02774 02776 #define NANOSECONDS_PER_SECOND 1000000000 02777 02778 #define MICROSECONDS_PER_SECOND 1000000 02779 02780 #define MILLISECONDS_PER_SECOND 1000 02781 02782 #define NANOSECONDS_PER_MILLISECOND 1000000 02783 02784 #define MICROSECONDS_PER_MILLISECOND 1000 02785 02790 void 02791 _dbus_sleep_milliseconds (int milliseconds) 02792 { 02793 #ifdef HAVE_NANOSLEEP 02794 struct timespec req; 02795 struct timespec rem; 02796 02797 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND; 02798 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; 02799 rem.tv_sec = 0; 02800 rem.tv_nsec = 0; 02801 02802 while (nanosleep (&req, &rem) < 0 && errno == EINTR) 02803 req = rem; 02804 #elif defined (HAVE_USLEEP) 02805 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND); 02806 #else /* ! HAVE_USLEEP */ 02807 sleep (MAX (milliseconds / 1000, 1)); 02808 #endif 02809 } 02810 02811 static dbus_bool_t 02812 _dbus_generate_pseudorandom_bytes (DBusString *str, 02813 int n_bytes) 02814 { 02815 int old_len; 02816 char *p; 02817 02818 old_len = _dbus_string_get_length (str); 02819 02820 if (!_dbus_string_lengthen (str, n_bytes)) 02821 return FALSE; 02822 02823 p = _dbus_string_get_data_len (str, old_len, n_bytes); 02824 02825 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes); 02826 02827 return TRUE; 02828 } 02829 02838 dbus_bool_t 02839 _dbus_generate_random_bytes (DBusString *str, 02840 int n_bytes) 02841 { 02842 int old_len; 02843 int fd; 02844 02845 /* FALSE return means "no memory", if it could 02846 * mean something else then we'd need to return 02847 * a DBusError. So we always fall back to pseudorandom 02848 * if the I/O fails. 02849 */ 02850 02851 old_len = _dbus_string_get_length (str); 02852 fd = -1; 02853 02854 /* note, urandom on linux will fall back to pseudorandom */ 02855 fd = open ("/dev/urandom", O_RDONLY); 02856 if (fd < 0) 02857 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02858 02859 _dbus_verbose ("/dev/urandom fd %d opened\n", fd); 02860 02861 if (_dbus_read (fd, str, n_bytes) != n_bytes) 02862 { 02863 _dbus_close (fd, NULL); 02864 _dbus_string_set_length (str, old_len); 02865 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02866 } 02867 02868 _dbus_verbose ("Read %d bytes from /dev/urandom\n", 02869 n_bytes); 02870 02871 _dbus_close (fd, NULL); 02872 02873 return TRUE; 02874 } 02875 02881 void 02882 _dbus_exit (int code) 02883 { 02884 _exit (code); 02885 } 02886 02895 const char* 02896 _dbus_strerror (int error_number) 02897 { 02898 const char *msg; 02899 02900 msg = strerror (error_number); 02901 if (msg == NULL) 02902 msg = "unknown"; 02903 02904 return msg; 02905 } 02906 02910 void 02911 _dbus_disable_sigpipe (void) 02912 { 02913 signal (SIGPIPE, SIG_IGN); 02914 } 02915 02923 void 02924 _dbus_fd_set_close_on_exec (intptr_t fd) 02925 { 02926 int val; 02927 02928 val = fcntl (fd, F_GETFD, 0); 02929 02930 if (val < 0) 02931 return; 02932 02933 val |= FD_CLOEXEC; 02934 02935 fcntl (fd, F_SETFD, val); 02936 } 02937 02945 dbus_bool_t 02946 _dbus_close (int fd, 02947 DBusError *error) 02948 { 02949 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02950 02951 again: 02952 if (close (fd) < 0) 02953 { 02954 if (errno == EINTR) 02955 goto again; 02956 02957 dbus_set_error (error, _dbus_error_from_errno (errno), 02958 "Could not close fd %d", fd); 02959 return FALSE; 02960 } 02961 02962 return TRUE; 02963 } 02964 02972 int 02973 _dbus_dup(int fd, 02974 DBusError *error) 02975 { 02976 int new_fd; 02977 02978 #ifdef F_DUPFD_CLOEXEC 02979 dbus_bool_t cloexec_done; 02980 02981 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); 02982 cloexec_done = new_fd >= 0; 02983 02984 if (new_fd < 0 && errno == EINVAL) 02985 #endif 02986 { 02987 new_fd = fcntl(fd, F_DUPFD, 3); 02988 } 02989 02990 if (new_fd < 0) { 02991 02992 dbus_set_error (error, _dbus_error_from_errno (errno), 02993 "Could not duplicate fd %d", fd); 02994 return -1; 02995 } 02996 02997 #ifdef F_DUPFD_CLOEXEC 02998 if (!cloexec_done) 02999 #endif 03000 { 03001 _dbus_fd_set_close_on_exec(new_fd); 03002 } 03003 03004 return new_fd; 03005 } 03006 03014 dbus_bool_t 03015 _dbus_set_fd_nonblocking (int fd, 03016 DBusError *error) 03017 { 03018 int val; 03019 03020 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03021 03022 val = fcntl (fd, F_GETFL, 0); 03023 if (val < 0) 03024 { 03025 dbus_set_error (error, _dbus_error_from_errno (errno), 03026 "Failed to get flags from file descriptor %d: %s", 03027 fd, _dbus_strerror (errno)); 03028 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 03029 _dbus_strerror (errno)); 03030 return FALSE; 03031 } 03032 03033 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 03034 { 03035 dbus_set_error (error, _dbus_error_from_errno (errno), 03036 "Failed to set nonblocking flag of file descriptor %d: %s", 03037 fd, _dbus_strerror (errno)); 03038 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 03039 fd, _dbus_strerror (errno)); 03040 03041 return FALSE; 03042 } 03043 03044 return TRUE; 03045 } 03046 03052 void 03053 _dbus_print_backtrace (void) 03054 { 03055 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC) 03056 void *bt[500]; 03057 int bt_size; 03058 int i; 03059 char **syms; 03060 03061 bt_size = backtrace (bt, 500); 03062 03063 syms = backtrace_symbols (bt, bt_size); 03064 03065 i = 0; 03066 while (i < bt_size) 03067 { 03068 /* don't use dbus_warn since it can _dbus_abort() */ 03069 fprintf (stderr, " %s\n", syms[i]); 03070 ++i; 03071 } 03072 fflush (stderr); 03073 03074 free (syms); 03075 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC) 03076 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n"); 03077 #else 03078 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n"); 03079 #endif 03080 } 03081 03094 dbus_bool_t 03095 _dbus_full_duplex_pipe (int *fd1, 03096 int *fd2, 03097 dbus_bool_t blocking, 03098 DBusError *error) 03099 { 03100 #ifdef HAVE_SOCKETPAIR 03101 int fds[2]; 03102 int retval; 03103 03104 #ifdef SOCK_CLOEXEC 03105 dbus_bool_t cloexec_done; 03106 03107 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); 03108 cloexec_done = retval >= 0; 03109 03110 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE)) 03111 #endif 03112 { 03113 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 03114 } 03115 03116 if (retval < 0) 03117 { 03118 dbus_set_error (error, _dbus_error_from_errno (errno), 03119 "Could not create full-duplex pipe"); 03120 return FALSE; 03121 } 03122 03123 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03124 03125 #ifdef SOCK_CLOEXEC 03126 if (!cloexec_done) 03127 #endif 03128 { 03129 _dbus_fd_set_close_on_exec (fds[0]); 03130 _dbus_fd_set_close_on_exec (fds[1]); 03131 } 03132 03133 if (!blocking && 03134 (!_dbus_set_fd_nonblocking (fds[0], NULL) || 03135 !_dbus_set_fd_nonblocking (fds[1], NULL))) 03136 { 03137 dbus_set_error (error, _dbus_error_from_errno (errno), 03138 "Could not set full-duplex pipe nonblocking"); 03139 03140 _dbus_close (fds[0], NULL); 03141 _dbus_close (fds[1], NULL); 03142 03143 return FALSE; 03144 } 03145 03146 *fd1 = fds[0]; 03147 *fd2 = fds[1]; 03148 03149 _dbus_verbose ("full-duplex pipe %d <-> %d\n", 03150 *fd1, *fd2); 03151 03152 return TRUE; 03153 #else 03154 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n"); 03155 dbus_set_error (error, DBUS_ERROR_FAILED, 03156 "_dbus_full_duplex_pipe() not implemented on this OS"); 03157 return FALSE; 03158 #endif 03159 } 03160 03169 int 03170 _dbus_printf_string_upper_bound (const char *format, 03171 va_list args) 03172 { 03173 char static_buf[1024]; 03174 int bufsize = sizeof (static_buf); 03175 int len; 03176 va_list args_copy; 03177 03178 DBUS_VA_COPY (args_copy, args); 03179 len = vsnprintf (static_buf, bufsize, format, args_copy); 03180 va_end (args_copy); 03181 03182 /* If vsnprintf() returned non-negative, then either the string fits in 03183 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf 03184 * returns the number of characters that were needed, or this OS returns the 03185 * truncated length. 03186 * 03187 * We ignore the possibility that snprintf might just ignore the length and 03188 * overrun the buffer (64-bit Solaris 7), because that's pathological. 03189 * If your libc is really that bad, come back when you have a better one. */ 03190 if (len == bufsize) 03191 { 03192 /* This could be the truncated length (Tru64 and IRIX have this bug), 03193 * or the real length could be coincidentally the same. Which is it? 03194 * If vsnprintf returns the truncated length, we'll go to the slow 03195 * path. */ 03196 DBUS_VA_COPY (args_copy, args); 03197 03198 if (vsnprintf (static_buf, 1, format, args_copy) == 1) 03199 len = -1; 03200 03201 va_end (args_copy); 03202 } 03203 03204 /* If vsnprintf() returned negative, we have to do more work. 03205 * HP-UX returns negative. */ 03206 while (len < 0) 03207 { 03208 char *buf; 03209 03210 bufsize *= 2; 03211 03212 buf = dbus_malloc (bufsize); 03213 03214 if (buf == NULL) 03215 return -1; 03216 03217 DBUS_VA_COPY (args_copy, args); 03218 len = vsnprintf (buf, bufsize, format, args_copy); 03219 va_end (args_copy); 03220 03221 dbus_free (buf); 03222 03223 /* If the reported length is exactly the buffer size, round up to the 03224 * next size, in case vsnprintf has been returning the truncated 03225 * length */ 03226 if (len == bufsize) 03227 len = -1; 03228 } 03229 03230 return len; 03231 } 03232 03239 const char* 03240 _dbus_get_tmpdir(void) 03241 { 03242 static const char* tmpdir = NULL; 03243 03244 if (tmpdir == NULL) 03245 { 03246 /* TMPDIR is what glibc uses, then 03247 * glibc falls back to the P_tmpdir macro which 03248 * just expands to "/tmp" 03249 */ 03250 if (tmpdir == NULL) 03251 tmpdir = getenv("TMPDIR"); 03252 03253 /* These two env variables are probably 03254 * broken, but maybe some OS uses them? 03255 */ 03256 if (tmpdir == NULL) 03257 tmpdir = getenv("TMP"); 03258 if (tmpdir == NULL) 03259 tmpdir = getenv("TEMP"); 03260 03261 /* And this is the sane fallback. */ 03262 if (tmpdir == NULL) 03263 tmpdir = "/tmp"; 03264 } 03265 03266 _dbus_assert(tmpdir != NULL); 03267 03268 return tmpdir; 03269 } 03270 03290 static dbus_bool_t 03291 _read_subprocess_line_argv (const char *progpath, 03292 dbus_bool_t path_fallback, 03293 char * const *argv, 03294 DBusString *result, 03295 DBusError *error) 03296 { 03297 int result_pipe[2] = { -1, -1 }; 03298 int errors_pipe[2] = { -1, -1 }; 03299 pid_t pid; 03300 int ret; 03301 int status; 03302 int orig_len; 03303 03304 dbus_bool_t retval; 03305 sigset_t new_set, old_set; 03306 03307 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03308 retval = FALSE; 03309 03310 /* We need to block any existing handlers for SIGCHLD temporarily; they 03311 * will cause waitpid() below to fail. 03312 * https://bugs.freedesktop.org/show_bug.cgi?id=21347 03313 */ 03314 sigemptyset (&new_set); 03315 sigaddset (&new_set, SIGCHLD); 03316 sigprocmask (SIG_BLOCK, &new_set, &old_set); 03317 03318 orig_len = _dbus_string_get_length (result); 03319 03320 #define READ_END 0 03321 #define WRITE_END 1 03322 if (pipe (result_pipe) < 0) 03323 { 03324 dbus_set_error (error, _dbus_error_from_errno (errno), 03325 "Failed to create a pipe to call %s: %s", 03326 progpath, _dbus_strerror (errno)); 03327 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03328 progpath, _dbus_strerror (errno)); 03329 goto out; 03330 } 03331 if (pipe (errors_pipe) < 0) 03332 { 03333 dbus_set_error (error, _dbus_error_from_errno (errno), 03334 "Failed to create a pipe to call %s: %s", 03335 progpath, _dbus_strerror (errno)); 03336 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03337 progpath, _dbus_strerror (errno)); 03338 goto out; 03339 } 03340 03341 pid = fork (); 03342 if (pid < 0) 03343 { 03344 dbus_set_error (error, _dbus_error_from_errno (errno), 03345 "Failed to fork() to call %s: %s", 03346 progpath, _dbus_strerror (errno)); 03347 _dbus_verbose ("Failed to fork() to call %s: %s\n", 03348 progpath, _dbus_strerror (errno)); 03349 goto out; 03350 } 03351 03352 if (pid == 0) 03353 { 03354 /* child process */ 03355 int fd; 03356 03357 fd = open ("/dev/null", O_RDWR); 03358 if (fd == -1) 03359 /* huh?! can't open /dev/null? */ 03360 _exit (1); 03361 03362 _dbus_verbose ("/dev/null fd %d opened\n", fd); 03363 03364 /* set-up stdXXX */ 03365 close (result_pipe[READ_END]); 03366 close (errors_pipe[READ_END]); 03367 close (0); /* close stdin */ 03368 close (1); /* close stdout */ 03369 close (2); /* close stderr */ 03370 03371 if (dup2 (fd, 0) == -1) 03372 _exit (1); 03373 if (dup2 (result_pipe[WRITE_END], 1) == -1) 03374 _exit (1); 03375 if (dup2 (errors_pipe[WRITE_END], 2) == -1) 03376 _exit (1); 03377 03378 _dbus_close_all (); 03379 03380 sigprocmask (SIG_SETMASK, &old_set, NULL); 03381 03382 /* If it looks fully-qualified, try execv first */ 03383 if (progpath[0] == '/') 03384 { 03385 execv (progpath, argv); 03386 /* Ok, that failed. Now if path_fallback is given, let's 03387 * try unqualified. This is mostly a hack to work 03388 * around systems which ship dbus-launch in /usr/bin 03389 * but everything else in /bin (because dbus-launch 03390 * depends on X11). 03391 */ 03392 if (path_fallback) 03393 /* We must have a slash, because we checked above */ 03394 execvp (strrchr (progpath, '/')+1, argv); 03395 } 03396 else 03397 execvp (progpath, argv); 03398 03399 /* still nothing, we failed */ 03400 _exit (1); 03401 } 03402 03403 /* parent process */ 03404 close (result_pipe[WRITE_END]); 03405 close (errors_pipe[WRITE_END]); 03406 result_pipe[WRITE_END] = -1; 03407 errors_pipe[WRITE_END] = -1; 03408 03409 ret = 0; 03410 do 03411 { 03412 ret = _dbus_read (result_pipe[READ_END], result, 1024); 03413 } 03414 while (ret > 0); 03415 03416 /* reap the child process to avoid it lingering as zombie */ 03417 do 03418 { 03419 ret = waitpid (pid, &status, 0); 03420 } 03421 while (ret == -1 && errno == EINTR); 03422 03423 /* We succeeded if the process exited with status 0 and 03424 anything was read */ 03425 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ) 03426 { 03427 /* The process ended with error */ 03428 DBusString error_message; 03429 if (!_dbus_string_init (&error_message)) 03430 { 03431 _DBUS_SET_OOM (error); 03432 goto out; 03433 } 03434 03435 ret = 0; 03436 do 03437 { 03438 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024); 03439 } 03440 while (ret > 0); 03441 03442 _dbus_string_set_length (result, orig_len); 03443 if (_dbus_string_get_length (&error_message) > 0) 03444 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03445 "%s terminated abnormally with the following error: %s", 03446 progpath, _dbus_string_get_data (&error_message)); 03447 else 03448 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03449 "%s terminated abnormally without any error message", 03450 progpath); 03451 goto out; 03452 } 03453 03454 retval = TRUE; 03455 03456 out: 03457 sigprocmask (SIG_SETMASK, &old_set, NULL); 03458 03459 if (retval) 03460 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03461 else 03462 _DBUS_ASSERT_ERROR_IS_SET (error); 03463 03464 if (result_pipe[0] != -1) 03465 close (result_pipe[0]); 03466 if (result_pipe[1] != -1) 03467 close (result_pipe[1]); 03468 if (errors_pipe[0] != -1) 03469 close (errors_pipe[0]); 03470 if (errors_pipe[1] != -1) 03471 close (errors_pipe[1]); 03472 03473 return retval; 03474 } 03475 03487 dbus_bool_t 03488 _dbus_get_autolaunch_address (const char *scope, 03489 DBusString *address, 03490 DBusError *error) 03491 { 03492 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH 03493 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch, 03494 * but that's done elsewhere, and if it worked, this function wouldn't 03495 * be called.) */ 03496 const char *display; 03497 static char *argv[6]; 03498 int i; 03499 DBusString uuid; 03500 dbus_bool_t retval; 03501 03502 if (_dbus_check_setuid ()) 03503 { 03504 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03505 "Unable to autolaunch when setuid"); 03506 return FALSE; 03507 } 03508 03509 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03510 retval = FALSE; 03511 03512 /* fd.o #19997: if $DISPLAY isn't set to something useful, then 03513 * dbus-launch-x11 is just going to fail. Rather than trying to 03514 * run it, we might as well bail out early with a nice error. */ 03515 display = _dbus_getenv ("DISPLAY"); 03516 03517 if (display == NULL || display[0] == '\0') 03518 { 03519 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03520 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11"); 03521 return FALSE; 03522 } 03523 03524 if (!_dbus_string_init (&uuid)) 03525 { 03526 _DBUS_SET_OOM (error); 03527 return FALSE; 03528 } 03529 03530 if (!_dbus_get_local_machine_uuid_encoded (&uuid)) 03531 { 03532 _DBUS_SET_OOM (error); 03533 goto out; 03534 } 03535 03536 i = 0; 03537 argv[i] = "dbus-launch"; 03538 ++i; 03539 argv[i] = "--autolaunch"; 03540 ++i; 03541 argv[i] = _dbus_string_get_data (&uuid); 03542 ++i; 03543 argv[i] = "--binary-syntax"; 03544 ++i; 03545 argv[i] = "--close-stderr"; 03546 ++i; 03547 argv[i] = NULL; 03548 ++i; 03549 03550 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03551 03552 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch", 03553 TRUE, 03554 argv, address, error); 03555 03556 out: 03557 _dbus_string_free (&uuid); 03558 return retval; 03559 #else 03560 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03561 "Using X11 for dbus-daemon autolaunch was disabled at compile time, " 03562 "set your DBUS_SESSION_BUS_ADDRESS instead"); 03563 return FALSE; 03564 #endif 03565 } 03566 03585 dbus_bool_t 03586 _dbus_read_local_machine_uuid (DBusGUID *machine_id, 03587 dbus_bool_t create_if_not_found, 03588 DBusError *error) 03589 { 03590 DBusString filename; 03591 dbus_bool_t b; 03592 03593 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE); 03594 03595 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error); 03596 if (b) 03597 return TRUE; 03598 03599 dbus_error_free (error); 03600 03601 /* Fallback to the system machine ID */ 03602 _dbus_string_init_const (&filename, "/etc/machine-id"); 03603 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error); 03604 } 03605 03606 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" 03607 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" 03608 03615 dbus_bool_t 03616 _dbus_lookup_launchd_socket (DBusString *socket_path, 03617 const char *launchd_env_var, 03618 DBusError *error) 03619 { 03620 #ifdef DBUS_ENABLE_LAUNCHD 03621 char *argv[4]; 03622 int i; 03623 03624 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03625 03626 if (_dbus_check_setuid ()) 03627 { 03628 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03629 "Unable to find launchd socket when setuid"); 03630 return FALSE; 03631 } 03632 03633 i = 0; 03634 argv[i] = "launchctl"; 03635 ++i; 03636 argv[i] = "getenv"; 03637 ++i; 03638 argv[i] = (char*)launchd_env_var; 03639 ++i; 03640 argv[i] = NULL; 03641 ++i; 03642 03643 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03644 03645 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error)) 03646 { 03647 return FALSE; 03648 } 03649 03650 /* no error, but no result either */ 03651 if (_dbus_string_get_length(socket_path) == 0) 03652 { 03653 return FALSE; 03654 } 03655 03656 /* strip the carriage-return */ 03657 _dbus_string_shorten(socket_path, 1); 03658 return TRUE; 03659 #else /* DBUS_ENABLE_LAUNCHD */ 03660 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, 03661 "can't lookup socket from launchd; launchd support not compiled in"); 03662 return FALSE; 03663 #endif 03664 } 03665 03666 #ifdef DBUS_ENABLE_LAUNCHD 03667 static dbus_bool_t 03668 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error) 03669 { 03670 dbus_bool_t valid_socket; 03671 DBusString socket_path; 03672 03673 if (_dbus_check_setuid ()) 03674 { 03675 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03676 "Unable to find launchd socket when setuid"); 03677 return FALSE; 03678 } 03679 03680 if (!_dbus_string_init (&socket_path)) 03681 { 03682 _DBUS_SET_OOM (error); 03683 return FALSE; 03684 } 03685 03686 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error); 03687 03688 if (dbus_error_is_set(error)) 03689 { 03690 _dbus_string_free(&socket_path); 03691 return FALSE; 03692 } 03693 03694 if (!valid_socket) 03695 { 03696 dbus_set_error(error, "no socket path", 03697 "launchd did not provide a socket path, " 03698 "verify that org.freedesktop.dbus-session.plist is loaded!"); 03699 _dbus_string_free(&socket_path); 03700 return FALSE; 03701 } 03702 if (!_dbus_string_append (address, "unix:path=")) 03703 { 03704 _DBUS_SET_OOM (error); 03705 _dbus_string_free(&socket_path); 03706 return FALSE; 03707 } 03708 if (!_dbus_string_copy (&socket_path, 0, address, 03709 _dbus_string_get_length (address))) 03710 { 03711 _DBUS_SET_OOM (error); 03712 _dbus_string_free(&socket_path); 03713 return FALSE; 03714 } 03715 03716 _dbus_string_free(&socket_path); 03717 return TRUE; 03718 } 03719 #endif 03720 03740 dbus_bool_t 03741 _dbus_lookup_session_address (dbus_bool_t *supported, 03742 DBusString *address, 03743 DBusError *error) 03744 { 03745 #ifdef DBUS_ENABLE_LAUNCHD 03746 *supported = TRUE; 03747 return _dbus_lookup_session_address_launchd (address, error); 03748 #else 03749 /* On non-Mac Unix platforms, if the session address isn't already 03750 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and 03751 * fall back to the autolaunch: global default; see 03752 * init_session_address in dbus/dbus-bus.c. */ 03753 *supported = FALSE; 03754 return TRUE; 03755 #endif 03756 } 03757 03775 dbus_bool_t 03776 _dbus_get_standard_session_servicedirs (DBusList **dirs) 03777 { 03778 const char *xdg_data_home; 03779 const char *xdg_data_dirs; 03780 DBusString servicedir_path; 03781 03782 if (!_dbus_string_init (&servicedir_path)) 03783 return FALSE; 03784 03785 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); 03786 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 03787 03788 if (xdg_data_home != NULL) 03789 { 03790 if (!_dbus_string_append (&servicedir_path, xdg_data_home)) 03791 goto oom; 03792 } 03793 else 03794 { 03795 const DBusString *homedir; 03796 DBusString local_share; 03797 03798 if (!_dbus_homedir_from_current_process (&homedir)) 03799 goto oom; 03800 03801 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) 03802 goto oom; 03803 03804 _dbus_string_init_const (&local_share, "/.local/share"); 03805 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) 03806 goto oom; 03807 } 03808 03809 if (!_dbus_string_append (&servicedir_path, ":")) 03810 goto oom; 03811 03812 if (xdg_data_dirs != NULL) 03813 { 03814 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 03815 goto oom; 03816 03817 if (!_dbus_string_append (&servicedir_path, ":")) 03818 goto oom; 03819 } 03820 else 03821 { 03822 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 03823 goto oom; 03824 } 03825 03826 /* 03827 * add configured datadir to defaults 03828 * this may be the same as an xdg dir 03829 * however the config parser should take 03830 * care of duplicates 03831 */ 03832 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR)) 03833 goto oom; 03834 03835 if (!_dbus_split_paths_and_append (&servicedir_path, 03836 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 03837 dirs)) 03838 goto oom; 03839 03840 _dbus_string_free (&servicedir_path); 03841 return TRUE; 03842 03843 oom: 03844 _dbus_string_free (&servicedir_path); 03845 return FALSE; 03846 } 03847 03848 03867 dbus_bool_t 03868 _dbus_get_standard_system_servicedirs (DBusList **dirs) 03869 { 03870 /* 03871 * DBUS_DATADIR may be the same as one of the standard directories. However, 03872 * the config parser should take care of the duplicates. 03873 * 03874 * Also, append /lib as counterpart of /usr/share on the root 03875 * directory (the root directory does not know /share), in order to 03876 * facilitate early boot system bus activation where /usr might not 03877 * be available. 03878 */ 03879 static const char standard_search_path[] = 03880 "/usr/local/share:" 03881 "/usr/share:" 03882 DBUS_DATADIR ":" 03883 "/lib"; 03884 DBusString servicedir_path; 03885 03886 _dbus_string_init_const (&servicedir_path, standard_search_path); 03887 03888 return _dbus_split_paths_and_append (&servicedir_path, 03889 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 03890 dirs); 03891 } 03892 03901 dbus_bool_t 03902 _dbus_append_system_config_file (DBusString *str) 03903 { 03904 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE); 03905 } 03906 03913 dbus_bool_t 03914 _dbus_append_session_config_file (DBusString *str) 03915 { 03916 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); 03917 } 03918 03926 void 03927 _dbus_flush_caches (void) 03928 { 03929 _dbus_user_database_flush_system (); 03930 } 03931 03945 dbus_bool_t 03946 _dbus_append_keyring_directory_for_credentials (DBusString *directory, 03947 DBusCredentials *credentials) 03948 { 03949 DBusString homedir; 03950 DBusString dotdir; 03951 dbus_uid_t uid; 03952 03953 _dbus_assert (credentials != NULL); 03954 _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); 03955 03956 if (!_dbus_string_init (&homedir)) 03957 return FALSE; 03958 03959 uid = _dbus_credentials_get_unix_uid (credentials); 03960 _dbus_assert (uid != DBUS_UID_UNSET); 03961 03962 if (!_dbus_homedir_from_uid (uid, &homedir)) 03963 goto failed; 03964 03965 #ifdef DBUS_BUILD_TESTS 03966 { 03967 const char *override; 03968 03969 override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); 03970 if (override != NULL && *override != '\0') 03971 { 03972 _dbus_string_set_length (&homedir, 0); 03973 if (!_dbus_string_append (&homedir, override)) 03974 goto failed; 03975 03976 _dbus_verbose ("Using fake homedir for testing: %s\n", 03977 _dbus_string_get_const_data (&homedir)); 03978 } 03979 else 03980 { 03981 static dbus_bool_t already_warned = FALSE; 03982 if (!already_warned) 03983 { 03984 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); 03985 already_warned = TRUE; 03986 } 03987 } 03988 } 03989 #endif 03990 03991 _dbus_string_init_const (&dotdir, ".dbus-keyrings"); 03992 if (!_dbus_concat_dir_and_file (&homedir, 03993 &dotdir)) 03994 goto failed; 03995 03996 if (!_dbus_string_copy (&homedir, 0, 03997 directory, _dbus_string_get_length (directory))) { 03998 goto failed; 03999 } 04000 04001 _dbus_string_free (&homedir); 04002 return TRUE; 04003 04004 failed: 04005 _dbus_string_free (&homedir); 04006 return FALSE; 04007 } 04008 04009 //PENDING(kdab) docs 04010 dbus_bool_t 04011 _dbus_daemon_publish_session_bus_address (const char* addr, 04012 const char *scope) 04013 { 04014 return TRUE; 04015 } 04016 04017 //PENDING(kdab) docs 04018 void 04019 _dbus_daemon_unpublish_session_bus_address (void) 04020 { 04021 04022 } 04023 04030 dbus_bool_t 04031 _dbus_get_is_errno_eagain_or_ewouldblock (void) 04032 { 04033 return errno == EAGAIN || errno == EWOULDBLOCK; 04034 } 04035 04043 dbus_bool_t 04044 _dbus_delete_directory (const DBusString *filename, 04045 DBusError *error) 04046 { 04047 const char *filename_c; 04048 04049 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 04050 04051 filename_c = _dbus_string_get_const_data (filename); 04052 04053 if (rmdir (filename_c) != 0) 04054 { 04055 dbus_set_error (error, DBUS_ERROR_FAILED, 04056 "Failed to remove directory %s: %s\n", 04057 filename_c, _dbus_strerror (errno)); 04058 return FALSE; 04059 } 04060 04061 return TRUE; 04062 } 04063 04071 dbus_bool_t 04072 _dbus_socket_can_pass_unix_fd(int fd) { 04073 04074 #ifdef SCM_RIGHTS 04075 union { 04076 struct sockaddr sa; 04077 struct sockaddr_storage storage; 04078 struct sockaddr_un un; 04079 } sa_buf; 04080 04081 socklen_t sa_len = sizeof(sa_buf); 04082 04083 _DBUS_ZERO(sa_buf); 04084 04085 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0) 04086 return FALSE; 04087 04088 return sa_buf.sa.sa_family == AF_UNIX; 04089 04090 #else 04091 return FALSE; 04092 04093 #endif 04094 } 04095 04096 04097 /* 04098 * replaces the term DBUS_PREFIX in configure_time_path by the 04099 * current dbus installation directory. On unix this function is a noop 04100 * 04101 * @param configure_time_path 04102 * @return real path 04103 */ 04104 const char * 04105 _dbus_replace_install_prefix (const char *configure_time_path) 04106 { 04107 return configure_time_path; 04108 } 04109 04114 void 04115 _dbus_close_all (void) 04116 { 04117 int maxfds, i; 04118 04119 #ifdef __linux__ 04120 DIR *d; 04121 04122 /* On Linux we can optimize this a bit if /proc is available. If it 04123 isn't available, fall back to the brute force way. */ 04124 04125 d = opendir ("/proc/self/fd"); 04126 if (d) 04127 { 04128 for (;;) 04129 { 04130 struct dirent buf, *de; 04131 int k, fd; 04132 long l; 04133 char *e = NULL; 04134 04135 k = readdir_r (d, &buf, &de); 04136 if (k != 0 || !de) 04137 break; 04138 04139 if (de->d_name[0] == '.') 04140 continue; 04141 04142 errno = 0; 04143 l = strtol (de->d_name, &e, 10); 04144 if (errno != 0 || e == NULL || *e != '\0') 04145 continue; 04146 04147 fd = (int) l; 04148 if (fd < 3) 04149 continue; 04150 04151 if (fd == dirfd (d)) 04152 continue; 04153 04154 close (fd); 04155 } 04156 04157 closedir (d); 04158 return; 04159 } 04160 #endif 04161 04162 maxfds = sysconf (_SC_OPEN_MAX); 04163 04164 /* Pick something reasonable if for some reason sysconf says 04165 * unlimited. 04166 */ 04167 if (maxfds < 0) 04168 maxfds = 1024; 04169 04170 /* close all inherited fds */ 04171 for (i = 3; i < maxfds; i++) 04172 close (i); 04173 } 04174 04184 dbus_bool_t 04185 _dbus_check_setuid (void) 04186 { 04187 /* TODO: get __libc_enable_secure exported from glibc. 04188 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1 04189 */ 04190 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE) 04191 { 04192 /* See glibc/include/unistd.h */ 04193 extern int __libc_enable_secure; 04194 return __libc_enable_secure; 04195 } 04196 #elif defined(HAVE_ISSETUGID) 04197 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */ 04198 return issetugid (); 04199 #else 04200 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */ 04201 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */ 04202 04203 static dbus_bool_t check_setuid_initialised; 04204 static dbus_bool_t is_setuid; 04205 04206 if (_DBUS_UNLIKELY (!check_setuid_initialised)) 04207 { 04208 #ifdef HAVE_GETRESUID 04209 if (getresuid (&ruid, &euid, &suid) != 0 || 04210 getresgid (&rgid, &egid, &sgid) != 0) 04211 #endif /* HAVE_GETRESUID */ 04212 { 04213 suid = ruid = getuid (); 04214 sgid = rgid = getgid (); 04215 euid = geteuid (); 04216 egid = getegid (); 04217 } 04218 04219 check_setuid_initialised = TRUE; 04220 is_setuid = (ruid != euid || ruid != suid || 04221 rgid != egid || rgid != sgid); 04222 04223 } 04224 return is_setuid; 04225 #endif 04226 } 04227 04228 /* tests in dbus-sysdeps-util.c */
1.7.6.1