D-Bus 1.4.10
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation) 00003 * 00004 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. 00005 * Copyright (C) 2003 CodeFactory AB 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 */ 00024 00025 #include <config.h> 00026 00027 #include "dbus-internals.h" 00028 #include "dbus-sysdeps.h" 00029 #include "dbus-sysdeps-unix.h" 00030 #include "dbus-threads.h" 00031 #include "dbus-protocol.h" 00032 #include "dbus-transport.h" 00033 #include "dbus-string.h" 00034 #include "dbus-userdb.h" 00035 #include "dbus-list.h" 00036 #include "dbus-credentials.h" 00037 #include "dbus-nonce.h" 00038 00039 #include <sys/types.h> 00040 #include <stdlib.h> 00041 #include <string.h> 00042 #include <signal.h> 00043 #include <unistd.h> 00044 #include <stdio.h> 00045 #include <fcntl.h> 00046 #include <sys/socket.h> 00047 #include <dirent.h> 00048 #include <sys/un.h> 00049 #include <pwd.h> 00050 #include <time.h> 00051 #include <locale.h> 00052 #include <sys/time.h> 00053 #include <sys/stat.h> 00054 #include <sys/wait.h> 00055 #include <netinet/in.h> 00056 #include <netdb.h> 00057 #include <grp.h> 00058 00059 #ifdef HAVE_ERRNO_H 00060 #include <errno.h> 00061 #endif 00062 #ifdef HAVE_WRITEV 00063 #include <sys/uio.h> 00064 #endif 00065 #ifdef HAVE_POLL 00066 #include <sys/poll.h> 00067 #endif 00068 #ifdef HAVE_BACKTRACE 00069 #include <execinfo.h> 00070 #endif 00071 #ifdef HAVE_GETPEERUCRED 00072 #include <ucred.h> 00073 #endif 00074 00075 #ifdef HAVE_ADT 00076 #include <bsm/adt.h> 00077 #endif 00078 00079 #include "sd-daemon.h" 00080 00081 #ifndef O_BINARY 00082 #define O_BINARY 0 00083 #endif 00084 00085 #ifndef AI_ADDRCONFIG 00086 #define AI_ADDRCONFIG 0 00087 #endif 00088 00089 #ifndef HAVE_SOCKLEN_T 00090 #define socklen_t int 00091 #endif 00092 00093 static dbus_bool_t 00094 _dbus_open_socket (int *fd_p, 00095 int domain, 00096 int type, 00097 int protocol, 00098 DBusError *error) 00099 { 00100 #ifdef SOCK_CLOEXEC 00101 dbus_bool_t cloexec_done; 00102 00103 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol); 00104 cloexec_done = *fd_p >= 0; 00105 00106 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */ 00107 if (*fd_p < 0 && errno == EINVAL) 00108 #endif 00109 { 00110 *fd_p = socket (domain, type, protocol); 00111 } 00112 00113 if (*fd_p >= 0) 00114 { 00115 #ifdef SOCK_CLOEXEC 00116 if (!cloexec_done) 00117 #endif 00118 { 00119 _dbus_fd_set_close_on_exec(*fd_p); 00120 } 00121 00122 _dbus_verbose ("socket fd %d opened\n", *fd_p); 00123 return TRUE; 00124 } 00125 else 00126 { 00127 dbus_set_error(error, 00128 _dbus_error_from_errno (errno), 00129 "Failed to open socket: %s", 00130 _dbus_strerror (errno)); 00131 return FALSE; 00132 } 00133 } 00134 00135 dbus_bool_t 00136 _dbus_open_tcp_socket (int *fd, 00137 DBusError *error) 00138 { 00139 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error); 00140 } 00141 00152 dbus_bool_t 00153 _dbus_open_unix_socket (int *fd, 00154 DBusError *error) 00155 { 00156 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error); 00157 } 00158 00167 dbus_bool_t 00168 _dbus_close_socket (int fd, 00169 DBusError *error) 00170 { 00171 return _dbus_close (fd, error); 00172 } 00173 00183 int 00184 _dbus_read_socket (int fd, 00185 DBusString *buffer, 00186 int count) 00187 { 00188 return _dbus_read (fd, buffer, count); 00189 } 00190 00201 int 00202 _dbus_write_socket (int fd, 00203 const DBusString *buffer, 00204 int start, 00205 int len) 00206 { 00207 #if HAVE_DECL_MSG_NOSIGNAL 00208 const char *data; 00209 int bytes_written; 00210 00211 data = _dbus_string_get_const_data_len (buffer, start, len); 00212 00213 again: 00214 00215 bytes_written = send (fd, data, len, MSG_NOSIGNAL); 00216 00217 if (bytes_written < 0 && errno == EINTR) 00218 goto again; 00219 00220 return bytes_written; 00221 00222 #else 00223 return _dbus_write (fd, buffer, start, len); 00224 #endif 00225 } 00226 00239 int 00240 _dbus_read_socket_with_unix_fds (int fd, 00241 DBusString *buffer, 00242 int count, 00243 int *fds, 00244 int *n_fds) { 00245 #ifndef HAVE_UNIX_FD_PASSING 00246 int r; 00247 00248 if ((r = _dbus_read_socket(fd, buffer, count)) < 0) 00249 return r; 00250 00251 *n_fds = 0; 00252 return r; 00253 00254 #else 00255 int bytes_read; 00256 int start; 00257 struct msghdr m; 00258 struct iovec iov; 00259 00260 _dbus_assert (count >= 0); 00261 _dbus_assert (*n_fds >= 0); 00262 00263 start = _dbus_string_get_length (buffer); 00264 00265 if (!_dbus_string_lengthen (buffer, count)) 00266 { 00267 errno = ENOMEM; 00268 return -1; 00269 } 00270 00271 _DBUS_ZERO(iov); 00272 iov.iov_base = _dbus_string_get_data_len (buffer, start, count); 00273 iov.iov_len = count; 00274 00275 _DBUS_ZERO(m); 00276 m.msg_iov = &iov; 00277 m.msg_iovlen = 1; 00278 00279 /* Hmm, we have no clue how long the control data will actually be 00280 that is queued for us. The least we can do is assume that the 00281 caller knows. Hence let's make space for the number of fds that 00282 we shall read at max plus the cmsg header. */ 00283 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int)); 00284 00285 /* It's probably safe to assume that systems with SCM_RIGHTS also 00286 know alloca() */ 00287 m.msg_control = alloca(m.msg_controllen); 00288 memset(m.msg_control, 0, m.msg_controllen); 00289 00290 again: 00291 00292 bytes_read = recvmsg(fd, &m, 0 00293 #ifdef MSG_CMSG_CLOEXEC 00294 |MSG_CMSG_CLOEXEC 00295 #endif 00296 ); 00297 00298 if (bytes_read < 0) 00299 { 00300 if (errno == EINTR) 00301 goto again; 00302 else 00303 { 00304 /* put length back (note that this doesn't actually realloc anything) */ 00305 _dbus_string_set_length (buffer, start); 00306 return -1; 00307 } 00308 } 00309 else 00310 { 00311 struct cmsghdr *cm; 00312 dbus_bool_t found = FALSE; 00313 00314 if (m.msg_flags & MSG_CTRUNC) 00315 { 00316 /* Hmm, apparently the control data was truncated. The bad 00317 thing is that we might have completely lost a couple of fds 00318 without chance to recover them. Hence let's treat this as a 00319 serious error. */ 00320 00321 errno = ENOSPC; 00322 _dbus_string_set_length (buffer, start); 00323 return -1; 00324 } 00325 00326 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) 00327 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) 00328 { 00329 unsigned i; 00330 00331 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int))); 00332 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int); 00333 00334 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int)); 00335 found = TRUE; 00336 00337 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually 00338 worked, hence we need to go through this list and set 00339 CLOEXEC everywhere in any case */ 00340 for (i = 0; i < *n_fds; i++) 00341 _dbus_fd_set_close_on_exec(fds[i]); 00342 00343 break; 00344 } 00345 00346 if (!found) 00347 *n_fds = 0; 00348 00349 /* put length back (doesn't actually realloc) */ 00350 _dbus_string_set_length (buffer, start + bytes_read); 00351 00352 #if 0 00353 if (bytes_read > 0) 00354 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00355 #endif 00356 00357 return bytes_read; 00358 } 00359 #endif 00360 } 00361 00362 int 00363 _dbus_write_socket_with_unix_fds(int fd, 00364 const DBusString *buffer, 00365 int start, 00366 int len, 00367 const int *fds, 00368 int n_fds) { 00369 00370 #ifndef HAVE_UNIX_FD_PASSING 00371 00372 if (n_fds > 0) { 00373 errno = ENOTSUP; 00374 return -1; 00375 } 00376 00377 return _dbus_write_socket(fd, buffer, start, len); 00378 #else 00379 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds); 00380 #endif 00381 } 00382 00383 int 00384 _dbus_write_socket_with_unix_fds_two(int fd, 00385 const DBusString *buffer1, 00386 int start1, 00387 int len1, 00388 const DBusString *buffer2, 00389 int start2, 00390 int len2, 00391 const int *fds, 00392 int n_fds) { 00393 00394 #ifndef HAVE_UNIX_FD_PASSING 00395 00396 if (n_fds > 0) { 00397 errno = ENOTSUP; 00398 return -1; 00399 } 00400 00401 return _dbus_write_socket_two(fd, 00402 buffer1, start1, len1, 00403 buffer2, start2, len2); 00404 #else 00405 00406 struct msghdr m; 00407 struct cmsghdr *cm; 00408 struct iovec iov[2]; 00409 int bytes_written; 00410 00411 _dbus_assert (len1 >= 0); 00412 _dbus_assert (len2 >= 0); 00413 _dbus_assert (n_fds >= 0); 00414 00415 _DBUS_ZERO(iov); 00416 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1); 00417 iov[0].iov_len = len1; 00418 00419 if (buffer2) 00420 { 00421 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2); 00422 iov[1].iov_len = len2; 00423 } 00424 00425 _DBUS_ZERO(m); 00426 m.msg_iov = iov; 00427 m.msg_iovlen = buffer2 ? 2 : 1; 00428 00429 if (n_fds > 0) 00430 { 00431 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int)); 00432 m.msg_control = alloca(m.msg_controllen); 00433 memset(m.msg_control, 0, m.msg_controllen); 00434 00435 cm = CMSG_FIRSTHDR(&m); 00436 cm->cmsg_level = SOL_SOCKET; 00437 cm->cmsg_type = SCM_RIGHTS; 00438 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int)); 00439 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int)); 00440 } 00441 00442 again: 00443 00444 bytes_written = sendmsg (fd, &m, 0 00445 #if HAVE_DECL_MSG_NOSIGNAL 00446 |MSG_NOSIGNAL 00447 #endif 00448 ); 00449 00450 if (bytes_written < 0 && errno == EINTR) 00451 goto again; 00452 00453 #if 0 00454 if (bytes_written > 0) 00455 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00456 #endif 00457 00458 return bytes_written; 00459 #endif 00460 } 00461 00475 int 00476 _dbus_write_socket_two (int fd, 00477 const DBusString *buffer1, 00478 int start1, 00479 int len1, 00480 const DBusString *buffer2, 00481 int start2, 00482 int len2) 00483 { 00484 #if HAVE_DECL_MSG_NOSIGNAL 00485 struct iovec vectors[2]; 00486 const char *data1; 00487 const char *data2; 00488 int bytes_written; 00489 struct msghdr m; 00490 00491 _dbus_assert (buffer1 != NULL); 00492 _dbus_assert (start1 >= 0); 00493 _dbus_assert (start2 >= 0); 00494 _dbus_assert (len1 >= 0); 00495 _dbus_assert (len2 >= 0); 00496 00497 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00498 00499 if (buffer2 != NULL) 00500 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00501 else 00502 { 00503 data2 = NULL; 00504 start2 = 0; 00505 len2 = 0; 00506 } 00507 00508 vectors[0].iov_base = (char*) data1; 00509 vectors[0].iov_len = len1; 00510 vectors[1].iov_base = (char*) data2; 00511 vectors[1].iov_len = len2; 00512 00513 _DBUS_ZERO(m); 00514 m.msg_iov = vectors; 00515 m.msg_iovlen = data2 ? 2 : 1; 00516 00517 again: 00518 00519 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL); 00520 00521 if (bytes_written < 0 && errno == EINTR) 00522 goto again; 00523 00524 return bytes_written; 00525 00526 #else 00527 return _dbus_write_two (fd, buffer1, start1, len1, 00528 buffer2, start2, len2); 00529 #endif 00530 } 00531 00532 dbus_bool_t 00533 _dbus_socket_is_invalid (int fd) 00534 { 00535 return fd < 0 ? TRUE : FALSE; 00536 } 00537 00554 int 00555 _dbus_read (int fd, 00556 DBusString *buffer, 00557 int count) 00558 { 00559 int bytes_read; 00560 int start; 00561 char *data; 00562 00563 _dbus_assert (count >= 0); 00564 00565 start = _dbus_string_get_length (buffer); 00566 00567 if (!_dbus_string_lengthen (buffer, count)) 00568 { 00569 errno = ENOMEM; 00570 return -1; 00571 } 00572 00573 data = _dbus_string_get_data_len (buffer, start, count); 00574 00575 again: 00576 00577 bytes_read = read (fd, data, count); 00578 00579 if (bytes_read < 0) 00580 { 00581 if (errno == EINTR) 00582 goto again; 00583 else 00584 { 00585 /* put length back (note that this doesn't actually realloc anything) */ 00586 _dbus_string_set_length (buffer, start); 00587 return -1; 00588 } 00589 } 00590 else 00591 { 00592 /* put length back (doesn't actually realloc) */ 00593 _dbus_string_set_length (buffer, start + bytes_read); 00594 00595 #if 0 00596 if (bytes_read > 0) 00597 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00598 #endif 00599 00600 return bytes_read; 00601 } 00602 } 00603 00614 int 00615 _dbus_write (int fd, 00616 const DBusString *buffer, 00617 int start, 00618 int len) 00619 { 00620 const char *data; 00621 int bytes_written; 00622 00623 data = _dbus_string_get_const_data_len (buffer, start, len); 00624 00625 again: 00626 00627 bytes_written = write (fd, data, len); 00628 00629 if (bytes_written < 0 && errno == EINTR) 00630 goto again; 00631 00632 #if 0 00633 if (bytes_written > 0) 00634 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00635 #endif 00636 00637 return bytes_written; 00638 } 00639 00660 int 00661 _dbus_write_two (int fd, 00662 const DBusString *buffer1, 00663 int start1, 00664 int len1, 00665 const DBusString *buffer2, 00666 int start2, 00667 int len2) 00668 { 00669 _dbus_assert (buffer1 != NULL); 00670 _dbus_assert (start1 >= 0); 00671 _dbus_assert (start2 >= 0); 00672 _dbus_assert (len1 >= 0); 00673 _dbus_assert (len2 >= 0); 00674 00675 #ifdef HAVE_WRITEV 00676 { 00677 struct iovec vectors[2]; 00678 const char *data1; 00679 const char *data2; 00680 int bytes_written; 00681 00682 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00683 00684 if (buffer2 != NULL) 00685 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00686 else 00687 { 00688 data2 = NULL; 00689 start2 = 0; 00690 len2 = 0; 00691 } 00692 00693 vectors[0].iov_base = (char*) data1; 00694 vectors[0].iov_len = len1; 00695 vectors[1].iov_base = (char*) data2; 00696 vectors[1].iov_len = len2; 00697 00698 again: 00699 00700 bytes_written = writev (fd, 00701 vectors, 00702 data2 ? 2 : 1); 00703 00704 if (bytes_written < 0 && errno == EINTR) 00705 goto again; 00706 00707 return bytes_written; 00708 } 00709 #else /* HAVE_WRITEV */ 00710 { 00711 int ret1; 00712 00713 ret1 = _dbus_write (fd, buffer1, start1, len1); 00714 if (ret1 == len1 && buffer2 != NULL) 00715 { 00716 ret2 = _dbus_write (fd, buffer2, start2, len2); 00717 if (ret2 < 0) 00718 ret2 = 0; /* we can't report an error as the first write was OK */ 00719 00720 return ret1 + ret2; 00721 } 00722 else 00723 return ret1; 00724 } 00725 #endif /* !HAVE_WRITEV */ 00726 } 00727 00728 #define _DBUS_MAX_SUN_PATH_LENGTH 99 00729 00759 int 00760 _dbus_connect_unix_socket (const char *path, 00761 dbus_bool_t abstract, 00762 DBusError *error) 00763 { 00764 int fd; 00765 size_t path_len; 00766 struct sockaddr_un addr; 00767 00768 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00769 00770 _dbus_verbose ("connecting to unix socket %s abstract=%d\n", 00771 path, abstract); 00772 00773 00774 if (!_dbus_open_unix_socket (&fd, error)) 00775 { 00776 _DBUS_ASSERT_ERROR_IS_SET(error); 00777 return -1; 00778 } 00779 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00780 00781 _DBUS_ZERO (addr); 00782 addr.sun_family = AF_UNIX; 00783 path_len = strlen (path); 00784 00785 if (abstract) 00786 { 00787 #ifdef HAVE_ABSTRACT_SOCKETS 00788 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 00789 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 00790 00791 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00792 { 00793 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00794 "Abstract socket name too long\n"); 00795 _dbus_close (fd, NULL); 00796 return -1; 00797 } 00798 00799 strncpy (&addr.sun_path[1], path, path_len); 00800 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 00801 #else /* HAVE_ABSTRACT_SOCKETS */ 00802 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 00803 "Operating system does not support abstract socket namespace\n"); 00804 _dbus_close (fd, NULL); 00805 return -1; 00806 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 00807 } 00808 else 00809 { 00810 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00811 { 00812 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00813 "Socket name too long\n"); 00814 _dbus_close (fd, NULL); 00815 return -1; 00816 } 00817 00818 strncpy (addr.sun_path, path, path_len); 00819 } 00820 00821 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 00822 { 00823 dbus_set_error (error, 00824 _dbus_error_from_errno (errno), 00825 "Failed to connect to socket %s: %s", 00826 path, _dbus_strerror (errno)); 00827 00828 _dbus_close (fd, NULL); 00829 fd = -1; 00830 00831 return -1; 00832 } 00833 00834 if (!_dbus_set_fd_nonblocking (fd, error)) 00835 { 00836 _DBUS_ASSERT_ERROR_IS_SET (error); 00837 00838 _dbus_close (fd, NULL); 00839 fd = -1; 00840 00841 return -1; 00842 } 00843 00844 return fd; 00845 } 00846 00856 static dbus_bool_t 00857 _dbus_set_local_creds (int fd, dbus_bool_t on) 00858 { 00859 dbus_bool_t retval = TRUE; 00860 00861 #if defined(HAVE_CMSGCRED) 00862 /* NOOP just to make sure only one codepath is used 00863 * and to prefer CMSGCRED 00864 */ 00865 #elif defined(LOCAL_CREDS) 00866 int val = on ? 1 : 0; 00867 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0) 00868 { 00869 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd); 00870 retval = FALSE; 00871 } 00872 else 00873 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n", 00874 on ? "enabled" : "disabled", fd); 00875 #endif 00876 00877 return retval; 00878 } 00879 00897 int 00898 _dbus_listen_unix_socket (const char *path, 00899 dbus_bool_t abstract, 00900 DBusError *error) 00901 { 00902 int listen_fd; 00903 struct sockaddr_un addr; 00904 size_t path_len; 00905 unsigned int reuseaddr; 00906 00907 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00908 00909 _dbus_verbose ("listening on unix socket %s abstract=%d\n", 00910 path, abstract); 00911 00912 if (!_dbus_open_unix_socket (&listen_fd, error)) 00913 { 00914 _DBUS_ASSERT_ERROR_IS_SET(error); 00915 return -1; 00916 } 00917 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00918 00919 _DBUS_ZERO (addr); 00920 addr.sun_family = AF_UNIX; 00921 path_len = strlen (path); 00922 00923 if (abstract) 00924 { 00925 #ifdef HAVE_ABSTRACT_SOCKETS 00926 /* remember that abstract names aren't nul-terminated so we rely 00927 * on sun_path being filled in with zeroes above. 00928 */ 00929 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 00930 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 00931 00932 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00933 { 00934 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00935 "Abstract socket name too long\n"); 00936 _dbus_close (listen_fd, NULL); 00937 return -1; 00938 } 00939 00940 strncpy (&addr.sun_path[1], path, path_len); 00941 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 00942 #else /* HAVE_ABSTRACT_SOCKETS */ 00943 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 00944 "Operating system does not support abstract socket namespace\n"); 00945 _dbus_close (listen_fd, NULL); 00946 return -1; 00947 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 00948 } 00949 else 00950 { 00951 /* Discussed security implications of this with Nalin, 00952 * and we couldn't think of where it would kick our ass, but 00953 * it still seems a bit sucky. It also has non-security suckage; 00954 * really we'd prefer to exit if the socket is already in use. 00955 * But there doesn't seem to be a good way to do this. 00956 * 00957 * Just to be extra careful, I threw in the stat() - clearly 00958 * the stat() can't *fix* any security issue, but it at least 00959 * avoids inadvertent/accidental data loss. 00960 */ 00961 { 00962 struct stat sb; 00963 00964 if (stat (path, &sb) == 0 && 00965 S_ISSOCK (sb.st_mode)) 00966 unlink (path); 00967 } 00968 00969 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00970 { 00971 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00972 "Abstract socket name too long\n"); 00973 _dbus_close (listen_fd, NULL); 00974 return -1; 00975 } 00976 00977 strncpy (addr.sun_path, path, path_len); 00978 } 00979 00980 reuseaddr = 1; 00981 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 00982 { 00983 _dbus_warn ("Failed to set socket option\"%s\": %s", 00984 path, _dbus_strerror (errno)); 00985 } 00986 00987 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 00988 { 00989 dbus_set_error (error, _dbus_error_from_errno (errno), 00990 "Failed to bind socket \"%s\": %s", 00991 path, _dbus_strerror (errno)); 00992 _dbus_close (listen_fd, NULL); 00993 return -1; 00994 } 00995 00996 if (listen (listen_fd, 30 /* backlog */) < 0) 00997 { 00998 dbus_set_error (error, _dbus_error_from_errno (errno), 00999 "Failed to listen on socket \"%s\": %s", 01000 path, _dbus_strerror (errno)); 01001 _dbus_close (listen_fd, NULL); 01002 return -1; 01003 } 01004 01005 if (!_dbus_set_local_creds (listen_fd, TRUE)) 01006 { 01007 dbus_set_error (error, _dbus_error_from_errno (errno), 01008 "Failed to enable LOCAL_CREDS on socket \"%s\": %s", 01009 path, _dbus_strerror (errno)); 01010 close (listen_fd); 01011 return -1; 01012 } 01013 01014 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 01015 { 01016 _DBUS_ASSERT_ERROR_IS_SET (error); 01017 _dbus_close (listen_fd, NULL); 01018 return -1; 01019 } 01020 01021 /* Try opening up the permissions, but if we can't, just go ahead 01022 * and continue, maybe it will be good enough. 01023 */ 01024 if (!abstract && chmod (path, 0777) < 0) 01025 _dbus_warn ("Could not set mode 0777 on socket %s\n", 01026 path); 01027 01028 return listen_fd; 01029 } 01030 01041 int 01042 _dbus_listen_systemd_sockets (int **fds, 01043 DBusError *error) 01044 { 01045 int r, n; 01046 unsigned fd; 01047 int *new_fds; 01048 01049 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01050 01051 n = sd_listen_fds (TRUE); 01052 if (n < 0) 01053 { 01054 dbus_set_error (error, _dbus_error_from_errno (-n), 01055 "Failed to acquire systemd socket: %s", 01056 _dbus_strerror (-n)); 01057 return -1; 01058 } 01059 01060 if (n <= 0) 01061 { 01062 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01063 "No socket received."); 01064 return -1; 01065 } 01066 01067 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01068 { 01069 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1); 01070 if (r < 0) 01071 { 01072 dbus_set_error (error, _dbus_error_from_errno (-r), 01073 "Failed to verify systemd socket type: %s", 01074 _dbus_strerror (-r)); 01075 return -1; 01076 } 01077 01078 if (!r) 01079 { 01080 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01081 "Passed socket has wrong type."); 01082 return -1; 01083 } 01084 } 01085 01086 /* OK, the file descriptors are all good, so let's take posession of 01087 them then. */ 01088 01089 new_fds = dbus_new (int, n); 01090 if (!new_fds) 01091 { 01092 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 01093 "Failed to allocate file handle array."); 01094 goto fail; 01095 } 01096 01097 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01098 { 01099 if (!_dbus_set_local_creds (fd, TRUE)) 01100 { 01101 dbus_set_error (error, _dbus_error_from_errno (errno), 01102 "Failed to enable LOCAL_CREDS on systemd socket: %s", 01103 _dbus_strerror (errno)); 01104 goto fail; 01105 } 01106 01107 if (!_dbus_set_fd_nonblocking (fd, error)) 01108 { 01109 _DBUS_ASSERT_ERROR_IS_SET (error); 01110 goto fail; 01111 } 01112 01113 new_fds[fd - SD_LISTEN_FDS_START] = fd; 01114 } 01115 01116 *fds = new_fds; 01117 return n; 01118 01119 fail: 01120 01121 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01122 { 01123 _dbus_close (fd, NULL); 01124 } 01125 01126 dbus_free (new_fds); 01127 return -1; 01128 } 01129 01143 int 01144 _dbus_connect_tcp_socket (const char *host, 01145 const char *port, 01146 const char *family, 01147 DBusError *error) 01148 { 01149 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error); 01150 } 01151 01152 int 01153 _dbus_connect_tcp_socket_with_nonce (const char *host, 01154 const char *port, 01155 const char *family, 01156 const char *noncefile, 01157 DBusError *error) 01158 { 01159 int saved_errno = 0; 01160 int fd = -1, res; 01161 struct addrinfo hints; 01162 struct addrinfo *ai, *tmp; 01163 01164 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01165 01166 if (!_dbus_open_tcp_socket (&fd, error)) 01167 { 01168 _DBUS_ASSERT_ERROR_IS_SET(error); 01169 return -1; 01170 } 01171 01172 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01173 01174 _DBUS_ZERO (hints); 01175 01176 if (!family) 01177 hints.ai_family = AF_UNSPEC; 01178 else if (!strcmp(family, "ipv4")) 01179 hints.ai_family = AF_INET; 01180 else if (!strcmp(family, "ipv6")) 01181 hints.ai_family = AF_INET6; 01182 else 01183 { 01184 dbus_set_error (error, 01185 DBUS_ERROR_BAD_ADDRESS, 01186 "Unknown address family %s", family); 01187 return -1; 01188 } 01189 hints.ai_protocol = IPPROTO_TCP; 01190 hints.ai_socktype = SOCK_STREAM; 01191 hints.ai_flags = AI_ADDRCONFIG; 01192 01193 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0) 01194 { 01195 dbus_set_error (error, 01196 _dbus_error_from_errno (errno), 01197 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01198 host, port, gai_strerror(res), res); 01199 _dbus_close (fd, NULL); 01200 return -1; 01201 } 01202 01203 tmp = ai; 01204 while (tmp) 01205 { 01206 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01207 { 01208 freeaddrinfo(ai); 01209 _DBUS_ASSERT_ERROR_IS_SET(error); 01210 return -1; 01211 } 01212 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01213 01214 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01215 { 01216 saved_errno = errno; 01217 _dbus_close(fd, NULL); 01218 fd = -1; 01219 tmp = tmp->ai_next; 01220 continue; 01221 } 01222 01223 break; 01224 } 01225 freeaddrinfo(ai); 01226 01227 if (fd == -1) 01228 { 01229 dbus_set_error (error, 01230 _dbus_error_from_errno (saved_errno), 01231 "Failed to connect to socket \"%s:%s\" %s", 01232 host, port, _dbus_strerror(saved_errno)); 01233 return -1; 01234 } 01235 01236 if (noncefile != NULL) 01237 { 01238 DBusString noncefileStr; 01239 dbus_bool_t ret; 01240 _dbus_string_init_const (&noncefileStr, noncefile); 01241 ret = _dbus_send_nonce (fd, &noncefileStr, error); 01242 _dbus_string_free (&noncefileStr); 01243 01244 if (!ret) 01245 { 01246 _dbus_close (fd, NULL); 01247 return -1; 01248 } 01249 } 01250 01251 if (!_dbus_set_fd_nonblocking (fd, error)) 01252 { 01253 _dbus_close (fd, NULL); 01254 return -1; 01255 } 01256 01257 return fd; 01258 } 01259 01276 int 01277 _dbus_listen_tcp_socket (const char *host, 01278 const char *port, 01279 const char *family, 01280 DBusString *retport, 01281 int **fds_p, 01282 DBusError *error) 01283 { 01284 int saved_errno; 01285 int nlisten_fd = 0, *listen_fd = NULL, res, i; 01286 struct addrinfo hints; 01287 struct addrinfo *ai, *tmp; 01288 unsigned int reuseaddr; 01289 01290 *fds_p = NULL; 01291 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01292 01293 _DBUS_ZERO (hints); 01294 01295 if (!family) 01296 hints.ai_family = AF_UNSPEC; 01297 else if (!strcmp(family, "ipv4")) 01298 hints.ai_family = AF_INET; 01299 else if (!strcmp(family, "ipv6")) 01300 hints.ai_family = AF_INET6; 01301 else 01302 { 01303 dbus_set_error (error, 01304 DBUS_ERROR_BAD_ADDRESS, 01305 "Unknown address family %s", family); 01306 return -1; 01307 } 01308 01309 hints.ai_protocol = IPPROTO_TCP; 01310 hints.ai_socktype = SOCK_STREAM; 01311 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; 01312 01313 redo_lookup_with_port: 01314 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai) 01315 { 01316 dbus_set_error (error, 01317 _dbus_error_from_errno (errno), 01318 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01319 host ? host : "*", port, gai_strerror(res), res); 01320 return -1; 01321 } 01322 01323 tmp = ai; 01324 while (tmp) 01325 { 01326 int fd = -1, *newlisten_fd; 01327 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01328 { 01329 _DBUS_ASSERT_ERROR_IS_SET(error); 01330 goto failed; 01331 } 01332 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01333 01334 reuseaddr = 1; 01335 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01336 { 01337 _dbus_warn ("Failed to set socket option \"%s:%s\": %s", 01338 host ? host : "*", port, _dbus_strerror (errno)); 01339 } 01340 01341 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01342 { 01343 saved_errno = errno; 01344 _dbus_close(fd, NULL); 01345 if (saved_errno == EADDRINUSE) 01346 { 01347 /* Depending on kernel policy, it may or may not 01348 be neccessary to bind to both IPv4 & 6 addresses 01349 so ignore EADDRINUSE here */ 01350 tmp = tmp->ai_next; 01351 continue; 01352 } 01353 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01354 "Failed to bind socket \"%s:%s\": %s", 01355 host ? host : "*", port, _dbus_strerror (saved_errno)); 01356 goto failed; 01357 } 01358 01359 if (listen (fd, 30 /* backlog */) < 0) 01360 { 01361 saved_errno = errno; 01362 _dbus_close (fd, NULL); 01363 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01364 "Failed to listen on socket \"%s:%s\": %s", 01365 host ? host : "*", port, _dbus_strerror (saved_errno)); 01366 goto failed; 01367 } 01368 01369 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); 01370 if (!newlisten_fd) 01371 { 01372 saved_errno = errno; 01373 _dbus_close (fd, NULL); 01374 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01375 "Failed to allocate file handle array: %s", 01376 _dbus_strerror (saved_errno)); 01377 goto failed; 01378 } 01379 listen_fd = newlisten_fd; 01380 listen_fd[nlisten_fd] = fd; 01381 nlisten_fd++; 01382 01383 if (!_dbus_string_get_length(retport)) 01384 { 01385 /* If the user didn't specify a port, or used 0, then 01386 the kernel chooses a port. After the first address 01387 is bound to, we need to force all remaining addresses 01388 to use the same port */ 01389 if (!port || !strcmp(port, "0")) 01390 { 01391 int result; 01392 struct sockaddr_storage addr; 01393 socklen_t addrlen; 01394 char portbuf[50]; 01395 01396 addrlen = sizeof(addr); 01397 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen); 01398 01399 if (result == -1 || 01400 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0, 01401 portbuf, sizeof(portbuf), 01402 NI_NUMERICHOST)) != 0) 01403 { 01404 dbus_set_error (error, _dbus_error_from_errno (errno), 01405 "Failed to resolve port \"%s:%s\": %s (%s)", 01406 host ? host : "*", port, gai_strerror(res), res); 01407 goto failed; 01408 } 01409 if (!_dbus_string_append(retport, portbuf)) 01410 { 01411 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01412 goto failed; 01413 } 01414 01415 /* Release current address list & redo lookup */ 01416 port = _dbus_string_get_const_data(retport); 01417 freeaddrinfo(ai); 01418 goto redo_lookup_with_port; 01419 } 01420 else 01421 { 01422 if (!_dbus_string_append(retport, port)) 01423 { 01424 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01425 goto failed; 01426 } 01427 } 01428 } 01429 01430 tmp = tmp->ai_next; 01431 } 01432 freeaddrinfo(ai); 01433 ai = NULL; 01434 01435 if (!nlisten_fd) 01436 { 01437 errno = EADDRINUSE; 01438 dbus_set_error (error, _dbus_error_from_errno (errno), 01439 "Failed to bind socket \"%s:%s\": %s", 01440 host ? host : "*", port, _dbus_strerror (errno)); 01441 goto failed; 01442 } 01443 01444 for (i = 0 ; i < nlisten_fd ; i++) 01445 { 01446 if (!_dbus_set_fd_nonblocking (listen_fd[i], error)) 01447 { 01448 goto failed; 01449 } 01450 } 01451 01452 *fds_p = listen_fd; 01453 01454 return nlisten_fd; 01455 01456 failed: 01457 if (ai) 01458 freeaddrinfo(ai); 01459 for (i = 0 ; i < nlisten_fd ; i++) 01460 _dbus_close(listen_fd[i], NULL); 01461 dbus_free(listen_fd); 01462 return -1; 01463 } 01464 01465 static dbus_bool_t 01466 write_credentials_byte (int server_fd, 01467 DBusError *error) 01468 { 01469 int bytes_written; 01470 char buf[1] = { '\0' }; 01471 #if defined(HAVE_CMSGCRED) 01472 union { 01473 struct cmsghdr hdr; 01474 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01475 } cmsg; 01476 struct iovec iov; 01477 struct msghdr msg; 01478 iov.iov_base = buf; 01479 iov.iov_len = 1; 01480 01481 _DBUS_ZERO(msg); 01482 msg.msg_iov = &iov; 01483 msg.msg_iovlen = 1; 01484 01485 msg.msg_control = (caddr_t) &cmsg; 01486 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01487 _DBUS_ZERO(cmsg); 01488 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); 01489 cmsg.hdr.cmsg_level = SOL_SOCKET; 01490 cmsg.hdr.cmsg_type = SCM_CREDS; 01491 #endif 01492 01493 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01494 01495 again: 01496 01497 #if defined(HAVE_CMSGCRED) 01498 bytes_written = sendmsg (server_fd, &msg, 0 01499 #if HAVE_DECL_MSG_NOSIGNAL 01500 |MSG_NOSIGNAL 01501 #endif 01502 ); 01503 #else 01504 bytes_written = send (server_fd, buf, 1, 0 01505 #if HAVE_DECL_MSG_NOSIGNAL 01506 |MSG_NOSIGNAL 01507 #endif 01508 ); 01509 #endif 01510 01511 if (bytes_written < 0 && errno == EINTR) 01512 goto again; 01513 01514 if (bytes_written < 0) 01515 { 01516 dbus_set_error (error, _dbus_error_from_errno (errno), 01517 "Failed to write credentials byte: %s", 01518 _dbus_strerror (errno)); 01519 return FALSE; 01520 } 01521 else if (bytes_written == 0) 01522 { 01523 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 01524 "wrote zero bytes writing credentials byte"); 01525 return FALSE; 01526 } 01527 else 01528 { 01529 _dbus_assert (bytes_written == 1); 01530 _dbus_verbose ("wrote credentials byte\n"); 01531 return TRUE; 01532 } 01533 } 01534 01556 dbus_bool_t 01557 _dbus_read_credentials_socket (int client_fd, 01558 DBusCredentials *credentials, 01559 DBusError *error) 01560 { 01561 struct msghdr msg; 01562 struct iovec iov; 01563 char buf; 01564 dbus_uid_t uid_read; 01565 dbus_pid_t pid_read; 01566 int bytes_read; 01567 01568 #ifdef HAVE_CMSGCRED 01569 union { 01570 struct cmsghdr hdr; 01571 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01572 } cmsg; 01573 01574 #elif defined(LOCAL_CREDS) 01575 struct { 01576 struct cmsghdr hdr; 01577 struct sockcred cred; 01578 } cmsg; 01579 #endif 01580 01581 uid_read = DBUS_UID_UNSET; 01582 pid_read = DBUS_PID_UNSET; 01583 01584 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01585 01586 /* The POSIX spec certainly doesn't promise this, but 01587 * we need these assertions to fail as soon as we're wrong about 01588 * it so we can do the porting fixups 01589 */ 01590 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 01591 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 01592 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 01593 01594 _dbus_credentials_clear (credentials); 01595 01596 /* Systems supporting LOCAL_CREDS are configured to have this feature 01597 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting 01598 * the connection. Therefore, the received message must carry the 01599 * credentials information without doing anything special. 01600 */ 01601 01602 iov.iov_base = &buf; 01603 iov.iov_len = 1; 01604 01605 _DBUS_ZERO(msg); 01606 msg.msg_iov = &iov; 01607 msg.msg_iovlen = 1; 01608 01609 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01610 _DBUS_ZERO(cmsg); 01611 msg.msg_control = (caddr_t) &cmsg; 01612 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01613 #endif 01614 01615 again: 01616 bytes_read = recvmsg (client_fd, &msg, 0); 01617 01618 if (bytes_read < 0) 01619 { 01620 if (errno == EINTR) 01621 goto again; 01622 01623 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would 01624 * normally only call read_credentials if the socket was ready 01625 * for reading 01626 */ 01627 01628 dbus_set_error (error, _dbus_error_from_errno (errno), 01629 "Failed to read credentials byte: %s", 01630 _dbus_strerror (errno)); 01631 return FALSE; 01632 } 01633 else if (bytes_read == 0) 01634 { 01635 /* this should not happen unless we are using recvmsg wrong, 01636 * so is essentially here for paranoia 01637 */ 01638 dbus_set_error (error, DBUS_ERROR_FAILED, 01639 "Failed to read credentials byte (zero-length read)"); 01640 return FALSE; 01641 } 01642 else if (buf != '\0') 01643 { 01644 dbus_set_error (error, DBUS_ERROR_FAILED, 01645 "Credentials byte was not nul"); 01646 return FALSE; 01647 } 01648 01649 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01650 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) 01651 || cmsg.hdr.cmsg_type != SCM_CREDS) 01652 { 01653 dbus_set_error (error, DBUS_ERROR_FAILED, 01654 "Message from recvmsg() was not SCM_CREDS"); 01655 return FALSE; 01656 } 01657 #endif 01658 01659 _dbus_verbose ("read credentials byte\n"); 01660 01661 { 01662 #ifdef SO_PEERCRED 01663 #ifdef __OpenBSD__ 01664 struct sockpeercred cr; 01665 #else 01666 struct ucred cr; 01667 #endif 01668 int cr_len = sizeof (cr); 01669 01670 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && 01671 cr_len == sizeof (cr)) 01672 { 01673 pid_read = cr.pid; 01674 uid_read = cr.uid; 01675 } 01676 else 01677 { 01678 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", 01679 cr_len, (int) sizeof (cr), _dbus_strerror (errno)); 01680 } 01681 #elif defined(HAVE_CMSGCRED) 01682 struct cmsgcred *cred; 01683 01684 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr); 01685 pid_read = cred->cmcred_pid; 01686 uid_read = cred->cmcred_euid; 01687 #elif defined(LOCAL_CREDS) 01688 pid_read = DBUS_PID_UNSET; 01689 uid_read = cmsg.cred.sc_uid; 01690 /* Since we have already got the credentials from this socket, we can 01691 * disable its LOCAL_CREDS flag if it was ever set. */ 01692 _dbus_set_local_creds (client_fd, FALSE); 01693 #elif defined(HAVE_GETPEEREID) 01694 uid_t euid; 01695 gid_t egid; 01696 if (getpeereid (client_fd, &euid, &egid) == 0) 01697 { 01698 uid_read = euid; 01699 } 01700 else 01701 { 01702 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno)); 01703 } 01704 #elif defined(HAVE_GETPEERUCRED) 01705 ucred_t * ucred = NULL; 01706 if (getpeerucred (client_fd, &ucred) == 0) 01707 { 01708 pid_read = ucred_getpid (ucred); 01709 uid_read = ucred_geteuid (ucred); 01710 #ifdef HAVE_ADT 01711 /* generate audit session data based on socket ucred */ 01712 adt_session_data_t *adth = NULL; 01713 adt_export_data_t *data = NULL; 01714 size_t size = 0; 01715 if (adt_start_session (&adth, NULL, 0) || (adth == NULL)) 01716 { 01717 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno)); 01718 } 01719 else 01720 { 01721 if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 01722 { 01723 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno)); 01724 } 01725 else 01726 { 01727 size = adt_export_session_data (adth, &data); 01728 if (size <= 0) 01729 { 01730 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno)); 01731 } 01732 else 01733 { 01734 _dbus_credentials_add_adt_audit_data (credentials, data, size); 01735 free (data); 01736 } 01737 } 01738 (void) adt_end_session (adth); 01739 } 01740 #endif /* HAVE_ADT */ 01741 } 01742 else 01743 { 01744 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno)); 01745 } 01746 if (ucred != NULL) 01747 ucred_free (ucred); 01748 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ 01749 _dbus_verbose ("Socket credentials not supported on this OS\n"); 01750 #endif 01751 } 01752 01753 _dbus_verbose ("Credentials:" 01754 " pid "DBUS_PID_FORMAT 01755 " uid "DBUS_UID_FORMAT 01756 "\n", 01757 pid_read, 01758 uid_read); 01759 01760 if (pid_read != DBUS_PID_UNSET) 01761 { 01762 if (!_dbus_credentials_add_unix_pid (credentials, pid_read)) 01763 { 01764 _DBUS_SET_OOM (error); 01765 return FALSE; 01766 } 01767 } 01768 01769 if (uid_read != DBUS_UID_UNSET) 01770 { 01771 if (!_dbus_credentials_add_unix_uid (credentials, uid_read)) 01772 { 01773 _DBUS_SET_OOM (error); 01774 return FALSE; 01775 } 01776 } 01777 01778 return TRUE; 01779 } 01780 01798 dbus_bool_t 01799 _dbus_send_credentials_socket (int server_fd, 01800 DBusError *error) 01801 { 01802 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01803 01804 if (write_credentials_byte (server_fd, error)) 01805 return TRUE; 01806 else 01807 return FALSE; 01808 } 01809 01819 int 01820 _dbus_accept (int listen_fd) 01821 { 01822 int client_fd; 01823 struct sockaddr addr; 01824 socklen_t addrlen; 01825 #ifdef HAVE_ACCEPT4 01826 dbus_bool_t cloexec_done; 01827 #endif 01828 01829 addrlen = sizeof (addr); 01830 01831 retry: 01832 01833 #ifdef HAVE_ACCEPT4 01834 /* We assume that if accept4 is available SOCK_CLOEXEC is too */ 01835 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC); 01836 cloexec_done = client_fd >= 0; 01837 01838 if (client_fd < 0 && errno == ENOSYS) 01839 #endif 01840 { 01841 client_fd = accept (listen_fd, &addr, &addrlen); 01842 } 01843 01844 if (client_fd < 0) 01845 { 01846 if (errno == EINTR) 01847 goto retry; 01848 } 01849 01850 _dbus_verbose ("client fd %d accepted\n", client_fd); 01851 01852 #ifdef HAVE_ACCEPT4 01853 if (!cloexec_done) 01854 #endif 01855 { 01856 _dbus_fd_set_close_on_exec(client_fd); 01857 } 01858 01859 return client_fd; 01860 } 01861 01870 dbus_bool_t 01871 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) 01872 { 01873 const char *directory; 01874 struct stat sb; 01875 01876 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01877 01878 directory = _dbus_string_get_const_data (dir); 01879 01880 if (stat (directory, &sb) < 0) 01881 { 01882 dbus_set_error (error, _dbus_error_from_errno (errno), 01883 "%s", _dbus_strerror (errno)); 01884 01885 return FALSE; 01886 } 01887 01888 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) || 01889 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode)) 01890 { 01891 dbus_set_error (error, DBUS_ERROR_FAILED, 01892 "%s directory is not private to the user", directory); 01893 return FALSE; 01894 } 01895 01896 return TRUE; 01897 } 01898 01899 static dbus_bool_t 01900 fill_user_info_from_passwd (struct passwd *p, 01901 DBusUserInfo *info, 01902 DBusError *error) 01903 { 01904 _dbus_assert (p->pw_name != NULL); 01905 _dbus_assert (p->pw_dir != NULL); 01906 01907 info->uid = p->pw_uid; 01908 info->primary_gid = p->pw_gid; 01909 info->username = _dbus_strdup (p->pw_name); 01910 info->homedir = _dbus_strdup (p->pw_dir); 01911 01912 if (info->username == NULL || 01913 info->homedir == NULL) 01914 { 01915 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01916 return FALSE; 01917 } 01918 01919 return TRUE; 01920 } 01921 01922 static dbus_bool_t 01923 fill_user_info (DBusUserInfo *info, 01924 dbus_uid_t uid, 01925 const DBusString *username, 01926 DBusError *error) 01927 { 01928 const char *username_c; 01929 01930 /* exactly one of username/uid provided */ 01931 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET); 01932 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET); 01933 01934 info->uid = DBUS_UID_UNSET; 01935 info->primary_gid = DBUS_GID_UNSET; 01936 info->group_ids = NULL; 01937 info->n_group_ids = 0; 01938 info->username = NULL; 01939 info->homedir = NULL; 01940 01941 if (username != NULL) 01942 username_c = _dbus_string_get_const_data (username); 01943 else 01944 username_c = NULL; 01945 01946 /* For now assuming that the getpwnam() and getpwuid() flavors 01947 * are always symmetrical, if not we have to add more configure 01948 * checks 01949 */ 01950 01951 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R) 01952 { 01953 struct passwd *p; 01954 int result; 01955 size_t buflen; 01956 char *buf; 01957 struct passwd p_str; 01958 01959 /* retrieve maximum needed size for buf */ 01960 buflen = sysconf (_SC_GETPW_R_SIZE_MAX); 01961 01962 /* sysconf actually returns a long, but everything else expects size_t, 01963 * so just recast here. 01964 * https://bugs.freedesktop.org/show_bug.cgi?id=17061 01965 */ 01966 if ((long) buflen <= 0) 01967 buflen = 1024; 01968 01969 result = -1; 01970 while (1) 01971 { 01972 buf = dbus_malloc (buflen); 01973 if (buf == NULL) 01974 { 01975 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01976 return FALSE; 01977 } 01978 01979 p = NULL; 01980 #ifdef HAVE_POSIX_GETPWNAM_R 01981 if (uid != DBUS_UID_UNSET) 01982 result = getpwuid_r (uid, &p_str, buf, buflen, 01983 &p); 01984 else 01985 result = getpwnam_r (username_c, &p_str, buf, buflen, 01986 &p); 01987 #else 01988 if (uid != DBUS_UID_UNSET) 01989 p = getpwuid_r (uid, &p_str, buf, buflen); 01990 else 01991 p = getpwnam_r (username_c, &p_str, buf, buflen); 01992 result = 0; 01993 #endif /* !HAVE_POSIX_GETPWNAM_R */ 01994 //Try a bigger buffer if ERANGE was returned 01995 if (result == ERANGE && buflen < 512 * 1024) 01996 { 01997 dbus_free (buf); 01998 buflen *= 2; 01999 } 02000 else 02001 { 02002 break; 02003 } 02004 } 02005 if (result == 0 && p == &p_str) 02006 { 02007 if (!fill_user_info_from_passwd (p, info, error)) 02008 { 02009 dbus_free (buf); 02010 return FALSE; 02011 } 02012 dbus_free (buf); 02013 } 02014 else 02015 { 02016 dbus_set_error (error, _dbus_error_from_errno (errno), 02017 "User \"%s\" unknown or no memory to allocate password entry\n", 02018 username_c ? username_c : "???"); 02019 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02020 dbus_free (buf); 02021 return FALSE; 02022 } 02023 } 02024 #else /* ! HAVE_GETPWNAM_R */ 02025 { 02026 /* I guess we're screwed on thread safety here */ 02027 struct passwd *p; 02028 02029 if (uid != DBUS_UID_UNSET) 02030 p = getpwuid (uid); 02031 else 02032 p = getpwnam (username_c); 02033 02034 if (p != NULL) 02035 { 02036 if (!fill_user_info_from_passwd (p, info, error)) 02037 { 02038 return FALSE; 02039 } 02040 } 02041 else 02042 { 02043 dbus_set_error (error, _dbus_error_from_errno (errno), 02044 "User \"%s\" unknown or no memory to allocate password entry\n", 02045 username_c ? username_c : "???"); 02046 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02047 return FALSE; 02048 } 02049 } 02050 #endif /* ! HAVE_GETPWNAM_R */ 02051 02052 /* Fill this in so we can use it to get groups */ 02053 username_c = info->username; 02054 02055 #ifdef HAVE_GETGROUPLIST 02056 { 02057 gid_t *buf; 02058 int buf_count; 02059 int i; 02060 int initial_buf_count; 02061 02062 initial_buf_count = 17; 02063 buf_count = initial_buf_count; 02064 buf = dbus_new (gid_t, buf_count); 02065 if (buf == NULL) 02066 { 02067 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02068 goto failed; 02069 } 02070 02071 if (getgrouplist (username_c, 02072 info->primary_gid, 02073 buf, &buf_count) < 0) 02074 { 02075 gid_t *new; 02076 /* Presumed cause of negative return code: buf has insufficient 02077 entries to hold the entire group list. The Linux behavior in this 02078 case is to pass back the actual number of groups in buf_count, but 02079 on Mac OS X 10.5, buf_count is unhelpfully left alone. 02080 So as a hack, try to help out a bit by guessing a larger 02081 number of groups, within reason.. might still fail, of course, 02082 but we can at least print a more informative message. I looked up 02083 the "right way" to do this by downloading Apple's own source code 02084 for the "id" command, and it turns out that they use an 02085 undocumented library function getgrouplist_2 (!) which is not 02086 declared in any header in /usr/include (!!). That did not seem 02087 like the way to go here. 02088 */ 02089 if (buf_count == initial_buf_count) 02090 { 02091 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */ 02092 } 02093 new = dbus_realloc (buf, buf_count * sizeof (buf[0])); 02094 if (new == NULL) 02095 { 02096 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02097 dbus_free (buf); 02098 goto failed; 02099 } 02100 02101 buf = new; 02102 02103 errno = 0; 02104 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0) 02105 { 02106 if (errno == 0) 02107 { 02108 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.", 02109 username_c, buf_count, buf_count); 02110 } 02111 else 02112 { 02113 dbus_set_error (error, 02114 _dbus_error_from_errno (errno), 02115 "Failed to get groups for username \"%s\" primary GID " 02116 DBUS_GID_FORMAT ": %s\n", 02117 username_c, info->primary_gid, 02118 _dbus_strerror (errno)); 02119 dbus_free (buf); 02120 goto failed; 02121 } 02122 } 02123 } 02124 02125 info->group_ids = dbus_new (dbus_gid_t, buf_count); 02126 if (info->group_ids == NULL) 02127 { 02128 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02129 dbus_free (buf); 02130 goto failed; 02131 } 02132 02133 for (i = 0; i < buf_count; ++i) 02134 info->group_ids[i] = buf[i]; 02135 02136 info->n_group_ids = buf_count; 02137 02138 dbus_free (buf); 02139 } 02140 #else /* HAVE_GETGROUPLIST */ 02141 { 02142 /* We just get the one group ID */ 02143 info->group_ids = dbus_new (dbus_gid_t, 1); 02144 if (info->group_ids == NULL) 02145 { 02146 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02147 goto failed; 02148 } 02149 02150 info->n_group_ids = 1; 02151 02152 (info->group_ids)[0] = info->primary_gid; 02153 } 02154 #endif /* HAVE_GETGROUPLIST */ 02155 02156 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02157 02158 return TRUE; 02159 02160 failed: 02161 _DBUS_ASSERT_ERROR_IS_SET (error); 02162 return FALSE; 02163 } 02164 02173 dbus_bool_t 02174 _dbus_user_info_fill (DBusUserInfo *info, 02175 const DBusString *username, 02176 DBusError *error) 02177 { 02178 return fill_user_info (info, DBUS_UID_UNSET, 02179 username, error); 02180 } 02181 02190 dbus_bool_t 02191 _dbus_user_info_fill_uid (DBusUserInfo *info, 02192 dbus_uid_t uid, 02193 DBusError *error) 02194 { 02195 return fill_user_info (info, uid, 02196 NULL, error); 02197 } 02198 02206 dbus_bool_t 02207 _dbus_credentials_add_from_current_process (DBusCredentials *credentials) 02208 { 02209 /* The POSIX spec certainly doesn't promise this, but 02210 * we need these assertions to fail as soon as we're wrong about 02211 * it so we can do the porting fixups 02212 */ 02213 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 02214 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 02215 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 02216 02217 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) 02218 return FALSE; 02219 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid())) 02220 return FALSE; 02221 02222 return TRUE; 02223 } 02224 02236 dbus_bool_t 02237 _dbus_append_user_from_current_process (DBusString *str) 02238 { 02239 return _dbus_string_append_uint (str, 02240 _dbus_geteuid ()); 02241 } 02242 02247 dbus_pid_t 02248 _dbus_getpid (void) 02249 { 02250 return getpid (); 02251 } 02252 02256 dbus_uid_t 02257 _dbus_getuid (void) 02258 { 02259 return getuid (); 02260 } 02261 02265 dbus_uid_t 02266 _dbus_geteuid (void) 02267 { 02268 return geteuid (); 02269 } 02270 02277 unsigned long 02278 _dbus_pid_for_log (void) 02279 { 02280 return getpid (); 02281 } 02282 02290 dbus_bool_t 02291 _dbus_parse_uid (const DBusString *uid_str, 02292 dbus_uid_t *uid) 02293 { 02294 int end; 02295 long val; 02296 02297 if (_dbus_string_get_length (uid_str) == 0) 02298 { 02299 _dbus_verbose ("UID string was zero length\n"); 02300 return FALSE; 02301 } 02302 02303 val = -1; 02304 end = 0; 02305 if (!_dbus_string_parse_int (uid_str, 0, &val, 02306 &end)) 02307 { 02308 _dbus_verbose ("could not parse string as a UID\n"); 02309 return FALSE; 02310 } 02311 02312 if (end != _dbus_string_get_length (uid_str)) 02313 { 02314 _dbus_verbose ("string contained trailing stuff after UID\n"); 02315 return FALSE; 02316 } 02317 02318 *uid = val; 02319 02320 return TRUE; 02321 } 02322 02323 #if !DBUS_USE_SYNC 02324 _DBUS_DEFINE_GLOBAL_LOCK (atomic); 02325 #endif 02326 02333 dbus_int32_t 02334 _dbus_atomic_inc (DBusAtomic *atomic) 02335 { 02336 #if DBUS_USE_SYNC 02337 return __sync_add_and_fetch(&atomic->value, 1)-1; 02338 #else 02339 dbus_int32_t res; 02340 _DBUS_LOCK (atomic); 02341 res = atomic->value; 02342 atomic->value += 1; 02343 _DBUS_UNLOCK (atomic); 02344 return res; 02345 #endif 02346 } 02347 02354 dbus_int32_t 02355 _dbus_atomic_dec (DBusAtomic *atomic) 02356 { 02357 #if DBUS_USE_SYNC 02358 return __sync_sub_and_fetch(&atomic->value, 1)+1; 02359 #else 02360 dbus_int32_t res; 02361 02362 _DBUS_LOCK (atomic); 02363 res = atomic->value; 02364 atomic->value -= 1; 02365 _DBUS_UNLOCK (atomic); 02366 return res; 02367 #endif 02368 } 02369 02370 #ifdef DBUS_BUILD_TESTS 02371 02374 dbus_gid_t 02375 _dbus_getgid (void) 02376 { 02377 return getgid (); 02378 } 02379 #endif 02380 02389 int 02390 _dbus_poll (DBusPollFD *fds, 02391 int n_fds, 02392 int timeout_milliseconds) 02393 { 02394 #if defined(HAVE_POLL) && !defined(BROKEN_POLL) 02395 /* This big thing is a constant expression and should get optimized 02396 * out of existence. So it's more robust than a configure check at 02397 * no cost. 02398 */ 02399 if (_DBUS_POLLIN == POLLIN && 02400 _DBUS_POLLPRI == POLLPRI && 02401 _DBUS_POLLOUT == POLLOUT && 02402 _DBUS_POLLERR == POLLERR && 02403 _DBUS_POLLHUP == POLLHUP && 02404 _DBUS_POLLNVAL == POLLNVAL && 02405 sizeof (DBusPollFD) == sizeof (struct pollfd) && 02406 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) == 02407 _DBUS_STRUCT_OFFSET (struct pollfd, fd) && 02408 _DBUS_STRUCT_OFFSET (DBusPollFD, events) == 02409 _DBUS_STRUCT_OFFSET (struct pollfd, events) && 02410 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == 02411 _DBUS_STRUCT_OFFSET (struct pollfd, revents)) 02412 { 02413 return poll ((struct pollfd*) fds, 02414 n_fds, 02415 timeout_milliseconds); 02416 } 02417 else 02418 { 02419 /* We have to convert the DBusPollFD to an array of 02420 * struct pollfd, poll, and convert back. 02421 */ 02422 _dbus_warn ("didn't implement poll() properly for this system yet\n"); 02423 return -1; 02424 } 02425 #else /* ! HAVE_POLL */ 02426 02427 fd_set read_set, write_set, err_set; 02428 int max_fd = 0; 02429 int i; 02430 struct timeval tv; 02431 int ready; 02432 02433 FD_ZERO (&read_set); 02434 FD_ZERO (&write_set); 02435 FD_ZERO (&err_set); 02436 02437 for (i = 0; i < n_fds; i++) 02438 { 02439 DBusPollFD *fdp = &fds[i]; 02440 02441 if (fdp->events & _DBUS_POLLIN) 02442 FD_SET (fdp->fd, &read_set); 02443 02444 if (fdp->events & _DBUS_POLLOUT) 02445 FD_SET (fdp->fd, &write_set); 02446 02447 FD_SET (fdp->fd, &err_set); 02448 02449 max_fd = MAX (max_fd, fdp->fd); 02450 } 02451 02452 tv.tv_sec = timeout_milliseconds / 1000; 02453 tv.tv_usec = (timeout_milliseconds % 1000) * 1000; 02454 02455 ready = select (max_fd + 1, &read_set, &write_set, &err_set, 02456 timeout_milliseconds < 0 ? NULL : &tv); 02457 02458 if (ready > 0) 02459 { 02460 for (i = 0; i < n_fds; i++) 02461 { 02462 DBusPollFD *fdp = &fds[i]; 02463 02464 fdp->revents = 0; 02465 02466 if (FD_ISSET (fdp->fd, &read_set)) 02467 fdp->revents |= _DBUS_POLLIN; 02468 02469 if (FD_ISSET (fdp->fd, &write_set)) 02470 fdp->revents |= _DBUS_POLLOUT; 02471 02472 if (FD_ISSET (fdp->fd, &err_set)) 02473 fdp->revents |= _DBUS_POLLERR; 02474 } 02475 } 02476 02477 return ready; 02478 #endif 02479 } 02480 02488 void 02489 _dbus_get_current_time (long *tv_sec, 02490 long *tv_usec) 02491 { 02492 struct timeval t; 02493 02494 #ifdef HAVE_MONOTONIC_CLOCK 02495 struct timespec ts; 02496 clock_gettime (CLOCK_MONOTONIC, &ts); 02497 02498 if (tv_sec) 02499 *tv_sec = ts.tv_sec; 02500 if (tv_usec) 02501 *tv_usec = ts.tv_nsec / 1000; 02502 #else 02503 gettimeofday (&t, NULL); 02504 02505 if (tv_sec) 02506 *tv_sec = t.tv_sec; 02507 if (tv_usec) 02508 *tv_usec = t.tv_usec; 02509 #endif 02510 } 02511 02520 dbus_bool_t 02521 _dbus_create_directory (const DBusString *filename, 02522 DBusError *error) 02523 { 02524 const char *filename_c; 02525 02526 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02527 02528 filename_c = _dbus_string_get_const_data (filename); 02529 02530 if (mkdir (filename_c, 0700) < 0) 02531 { 02532 if (errno == EEXIST) 02533 return TRUE; 02534 02535 dbus_set_error (error, DBUS_ERROR_FAILED, 02536 "Failed to create directory %s: %s\n", 02537 filename_c, _dbus_strerror (errno)); 02538 return FALSE; 02539 } 02540 else 02541 return TRUE; 02542 } 02543 02554 dbus_bool_t 02555 _dbus_concat_dir_and_file (DBusString *dir, 02556 const DBusString *next_component) 02557 { 02558 dbus_bool_t dir_ends_in_slash; 02559 dbus_bool_t file_starts_with_slash; 02560 02561 if (_dbus_string_get_length (dir) == 0 || 02562 _dbus_string_get_length (next_component) == 0) 02563 return TRUE; 02564 02565 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, 02566 _dbus_string_get_length (dir) - 1); 02567 02568 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); 02569 02570 if (dir_ends_in_slash && file_starts_with_slash) 02571 { 02572 _dbus_string_shorten (dir, 1); 02573 } 02574 else if (!(dir_ends_in_slash || file_starts_with_slash)) 02575 { 02576 if (!_dbus_string_append_byte (dir, '/')) 02577 return FALSE; 02578 } 02579 02580 return _dbus_string_copy (next_component, 0, dir, 02581 _dbus_string_get_length (dir)); 02582 } 02583 02585 #define NANOSECONDS_PER_SECOND 1000000000 02586 02587 #define MICROSECONDS_PER_SECOND 1000000 02588 02589 #define MILLISECONDS_PER_SECOND 1000 02590 02591 #define NANOSECONDS_PER_MILLISECOND 1000000 02592 02593 #define MICROSECONDS_PER_MILLISECOND 1000 02594 02599 void 02600 _dbus_sleep_milliseconds (int milliseconds) 02601 { 02602 #ifdef HAVE_NANOSLEEP 02603 struct timespec req; 02604 struct timespec rem; 02605 02606 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND; 02607 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; 02608 rem.tv_sec = 0; 02609 rem.tv_nsec = 0; 02610 02611 while (nanosleep (&req, &rem) < 0 && errno == EINTR) 02612 req = rem; 02613 #elif defined (HAVE_USLEEP) 02614 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND); 02615 #else /* ! HAVE_USLEEP */ 02616 sleep (MAX (milliseconds / 1000, 1)); 02617 #endif 02618 } 02619 02620 static dbus_bool_t 02621 _dbus_generate_pseudorandom_bytes (DBusString *str, 02622 int n_bytes) 02623 { 02624 int old_len; 02625 char *p; 02626 02627 old_len = _dbus_string_get_length (str); 02628 02629 if (!_dbus_string_lengthen (str, n_bytes)) 02630 return FALSE; 02631 02632 p = _dbus_string_get_data_len (str, old_len, n_bytes); 02633 02634 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes); 02635 02636 return TRUE; 02637 } 02638 02647 dbus_bool_t 02648 _dbus_generate_random_bytes (DBusString *str, 02649 int n_bytes) 02650 { 02651 int old_len; 02652 int fd; 02653 02654 /* FALSE return means "no memory", if it could 02655 * mean something else then we'd need to return 02656 * a DBusError. So we always fall back to pseudorandom 02657 * if the I/O fails. 02658 */ 02659 02660 old_len = _dbus_string_get_length (str); 02661 fd = -1; 02662 02663 /* note, urandom on linux will fall back to pseudorandom */ 02664 fd = open ("/dev/urandom", O_RDONLY); 02665 if (fd < 0) 02666 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02667 02668 _dbus_verbose ("/dev/urandom fd %d opened\n", fd); 02669 02670 if (_dbus_read (fd, str, n_bytes) != n_bytes) 02671 { 02672 _dbus_close (fd, NULL); 02673 _dbus_string_set_length (str, old_len); 02674 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02675 } 02676 02677 _dbus_verbose ("Read %d bytes from /dev/urandom\n", 02678 n_bytes); 02679 02680 _dbus_close (fd, NULL); 02681 02682 return TRUE; 02683 } 02684 02690 void 02691 _dbus_exit (int code) 02692 { 02693 _exit (code); 02694 } 02695 02704 const char* 02705 _dbus_strerror (int error_number) 02706 { 02707 const char *msg; 02708 02709 msg = strerror (error_number); 02710 if (msg == NULL) 02711 msg = "unknown"; 02712 02713 return msg; 02714 } 02715 02719 void 02720 _dbus_disable_sigpipe (void) 02721 { 02722 signal (SIGPIPE, SIG_IGN); 02723 } 02724 02732 void 02733 _dbus_fd_set_close_on_exec (intptr_t fd) 02734 { 02735 int val; 02736 02737 val = fcntl (fd, F_GETFD, 0); 02738 02739 if (val < 0) 02740 return; 02741 02742 val |= FD_CLOEXEC; 02743 02744 fcntl (fd, F_SETFD, val); 02745 } 02746 02754 dbus_bool_t 02755 _dbus_close (int fd, 02756 DBusError *error) 02757 { 02758 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02759 02760 again: 02761 if (close (fd) < 0) 02762 { 02763 if (errno == EINTR) 02764 goto again; 02765 02766 dbus_set_error (error, _dbus_error_from_errno (errno), 02767 "Could not close fd %d", fd); 02768 return FALSE; 02769 } 02770 02771 return TRUE; 02772 } 02773 02781 int 02782 _dbus_dup(int fd, 02783 DBusError *error) 02784 { 02785 int new_fd; 02786 02787 #ifdef F_DUPFD_CLOEXEC 02788 dbus_bool_t cloexec_done; 02789 02790 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); 02791 cloexec_done = new_fd >= 0; 02792 02793 if (new_fd < 0 && errno == EINVAL) 02794 #endif 02795 { 02796 new_fd = fcntl(fd, F_DUPFD, 3); 02797 } 02798 02799 if (new_fd < 0) { 02800 02801 dbus_set_error (error, _dbus_error_from_errno (errno), 02802 "Could not duplicate fd %d", fd); 02803 return -1; 02804 } 02805 02806 #ifdef F_DUPFD_CLOEXEC 02807 if (!cloexec_done) 02808 #endif 02809 { 02810 _dbus_fd_set_close_on_exec(new_fd); 02811 } 02812 02813 return new_fd; 02814 } 02815 02823 dbus_bool_t 02824 _dbus_set_fd_nonblocking (int fd, 02825 DBusError *error) 02826 { 02827 int val; 02828 02829 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02830 02831 val = fcntl (fd, F_GETFL, 0); 02832 if (val < 0) 02833 { 02834 dbus_set_error (error, _dbus_error_from_errno (errno), 02835 "Failed to get flags from file descriptor %d: %s", 02836 fd, _dbus_strerror (errno)); 02837 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 02838 _dbus_strerror (errno)); 02839 return FALSE; 02840 } 02841 02842 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 02843 { 02844 dbus_set_error (error, _dbus_error_from_errno (errno), 02845 "Failed to set nonblocking flag of file descriptor %d: %s", 02846 fd, _dbus_strerror (errno)); 02847 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 02848 fd, _dbus_strerror (errno)); 02849 02850 return FALSE; 02851 } 02852 02853 return TRUE; 02854 } 02855 02861 void 02862 _dbus_print_backtrace (void) 02863 { 02864 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC) 02865 void *bt[500]; 02866 int bt_size; 02867 int i; 02868 char **syms; 02869 02870 bt_size = backtrace (bt, 500); 02871 02872 syms = backtrace_symbols (bt, bt_size); 02873 02874 i = 0; 02875 while (i < bt_size) 02876 { 02877 /* don't use dbus_warn since it can _dbus_abort() */ 02878 fprintf (stderr, " %s\n", syms[i]); 02879 ++i; 02880 } 02881 fflush (stderr); 02882 02883 free (syms); 02884 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC) 02885 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n"); 02886 #else 02887 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n"); 02888 #endif 02889 } 02890 02908 dbus_bool_t 02909 _dbus_full_duplex_pipe (int *fd1, 02910 int *fd2, 02911 dbus_bool_t blocking, 02912 DBusError *error) 02913 { 02914 #ifdef HAVE_SOCKETPAIR 02915 int fds[2]; 02916 int retval; 02917 02918 #ifdef SOCK_CLOEXEC 02919 dbus_bool_t cloexec_done; 02920 02921 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); 02922 cloexec_done = retval >= 0; 02923 02924 if (retval < 0 && errno == EINVAL) 02925 #endif 02926 { 02927 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 02928 } 02929 02930 if (retval < 0) 02931 { 02932 dbus_set_error (error, _dbus_error_from_errno (errno), 02933 "Could not create full-duplex pipe"); 02934 return FALSE; 02935 } 02936 02937 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02938 02939 #ifdef SOCK_CLOEXEC 02940 if (!cloexec_done) 02941 #endif 02942 { 02943 _dbus_fd_set_close_on_exec (fds[0]); 02944 _dbus_fd_set_close_on_exec (fds[1]); 02945 } 02946 02947 if (!blocking && 02948 (!_dbus_set_fd_nonblocking (fds[0], NULL) || 02949 !_dbus_set_fd_nonblocking (fds[1], NULL))) 02950 { 02951 dbus_set_error (error, _dbus_error_from_errno (errno), 02952 "Could not set full-duplex pipe nonblocking"); 02953 02954 _dbus_close (fds[0], NULL); 02955 _dbus_close (fds[1], NULL); 02956 02957 return FALSE; 02958 } 02959 02960 *fd1 = fds[0]; 02961 *fd2 = fds[1]; 02962 02963 _dbus_verbose ("full-duplex pipe %d <-> %d\n", 02964 *fd1, *fd2); 02965 02966 return TRUE; 02967 #else 02968 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n"); 02969 dbus_set_error (error, DBUS_ERROR_FAILED, 02970 "_dbus_full_duplex_pipe() not implemented on this OS"); 02971 return FALSE; 02972 #endif 02973 } 02974 02983 int 02984 _dbus_printf_string_upper_bound (const char *format, 02985 va_list args) 02986 { 02987 char c; 02988 return vsnprintf (&c, 1, format, args); 02989 } 02990 02997 const char* 02998 _dbus_get_tmpdir(void) 02999 { 03000 static const char* tmpdir = NULL; 03001 03002 if (tmpdir == NULL) 03003 { 03004 /* TMPDIR is what glibc uses, then 03005 * glibc falls back to the P_tmpdir macro which 03006 * just expands to "/tmp" 03007 */ 03008 if (tmpdir == NULL) 03009 tmpdir = getenv("TMPDIR"); 03010 03011 /* These two env variables are probably 03012 * broken, but maybe some OS uses them? 03013 */ 03014 if (tmpdir == NULL) 03015 tmpdir = getenv("TMP"); 03016 if (tmpdir == NULL) 03017 tmpdir = getenv("TEMP"); 03018 03019 /* And this is the sane fallback. */ 03020 if (tmpdir == NULL) 03021 tmpdir = "/tmp"; 03022 } 03023 03024 _dbus_assert(tmpdir != NULL); 03025 03026 return tmpdir; 03027 } 03028 03048 static dbus_bool_t 03049 _read_subprocess_line_argv (const char *progpath, 03050 dbus_bool_t path_fallback, 03051 char * const *argv, 03052 DBusString *result, 03053 DBusError *error) 03054 { 03055 int result_pipe[2] = { -1, -1 }; 03056 int errors_pipe[2] = { -1, -1 }; 03057 pid_t pid; 03058 int ret; 03059 int status; 03060 int orig_len; 03061 int i; 03062 03063 dbus_bool_t retval; 03064 sigset_t new_set, old_set; 03065 03066 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03067 retval = FALSE; 03068 03069 /* We need to block any existing handlers for SIGCHLD temporarily; they 03070 * will cause waitpid() below to fail. 03071 * https://bugs.freedesktop.org/show_bug.cgi?id=21347 03072 */ 03073 sigemptyset (&new_set); 03074 sigaddset (&new_set, SIGCHLD); 03075 sigprocmask (SIG_BLOCK, &new_set, &old_set); 03076 03077 orig_len = _dbus_string_get_length (result); 03078 03079 #define READ_END 0 03080 #define WRITE_END 1 03081 if (pipe (result_pipe) < 0) 03082 { 03083 dbus_set_error (error, _dbus_error_from_errno (errno), 03084 "Failed to create a pipe to call %s: %s", 03085 progpath, _dbus_strerror (errno)); 03086 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03087 progpath, _dbus_strerror (errno)); 03088 goto out; 03089 } 03090 if (pipe (errors_pipe) < 0) 03091 { 03092 dbus_set_error (error, _dbus_error_from_errno (errno), 03093 "Failed to create a pipe to call %s: %s", 03094 progpath, _dbus_strerror (errno)); 03095 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03096 progpath, _dbus_strerror (errno)); 03097 goto out; 03098 } 03099 03100 pid = fork (); 03101 if (pid < 0) 03102 { 03103 dbus_set_error (error, _dbus_error_from_errno (errno), 03104 "Failed to fork() to call %s: %s", 03105 progpath, _dbus_strerror (errno)); 03106 _dbus_verbose ("Failed to fork() to call %s: %s\n", 03107 progpath, _dbus_strerror (errno)); 03108 goto out; 03109 } 03110 03111 if (pid == 0) 03112 { 03113 /* child process */ 03114 int maxfds; 03115 int fd; 03116 03117 fd = open ("/dev/null", O_RDWR); 03118 if (fd == -1) 03119 /* huh?! can't open /dev/null? */ 03120 _exit (1); 03121 03122 _dbus_verbose ("/dev/null fd %d opened\n", fd); 03123 03124 /* set-up stdXXX */ 03125 close (result_pipe[READ_END]); 03126 close (errors_pipe[READ_END]); 03127 close (0); /* close stdin */ 03128 close (1); /* close stdout */ 03129 close (2); /* close stderr */ 03130 03131 if (dup2 (fd, 0) == -1) 03132 _exit (1); 03133 if (dup2 (result_pipe[WRITE_END], 1) == -1) 03134 _exit (1); 03135 if (dup2 (errors_pipe[WRITE_END], 2) == -1) 03136 _exit (1); 03137 03138 maxfds = sysconf (_SC_OPEN_MAX); 03139 /* Pick something reasonable if for some reason sysconf 03140 * says unlimited. 03141 */ 03142 if (maxfds < 0) 03143 maxfds = 1024; 03144 /* close all inherited fds */ 03145 for (i = 3; i < maxfds; i++) 03146 close (i); 03147 03148 sigprocmask (SIG_SETMASK, &old_set, NULL); 03149 03150 /* If it looks fully-qualified, try execv first */ 03151 if (progpath[0] == '/') 03152 { 03153 execv (progpath, argv); 03154 /* Ok, that failed. Now if path_fallback is given, let's 03155 * try unqualified. This is mostly a hack to work 03156 * around systems which ship dbus-launch in /usr/bin 03157 * but everything else in /bin (because dbus-launch 03158 * depends on X11). 03159 */ 03160 if (path_fallback) 03161 /* We must have a slash, because we checked above */ 03162 execvp (strrchr (progpath, '/')+1, argv); 03163 } 03164 else 03165 execvp (progpath, argv); 03166 03167 /* still nothing, we failed */ 03168 _exit (1); 03169 } 03170 03171 /* parent process */ 03172 close (result_pipe[WRITE_END]); 03173 close (errors_pipe[WRITE_END]); 03174 result_pipe[WRITE_END] = -1; 03175 errors_pipe[WRITE_END] = -1; 03176 03177 ret = 0; 03178 do 03179 { 03180 ret = _dbus_read (result_pipe[READ_END], result, 1024); 03181 } 03182 while (ret > 0); 03183 03184 /* reap the child process to avoid it lingering as zombie */ 03185 do 03186 { 03187 ret = waitpid (pid, &status, 0); 03188 } 03189 while (ret == -1 && errno == EINTR); 03190 03191 /* We succeeded if the process exited with status 0 and 03192 anything was read */ 03193 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ) 03194 { 03195 /* The process ended with error */ 03196 DBusString error_message; 03197 if (!_dbus_string_init (&error_message)) 03198 { 03199 _DBUS_SET_OOM (error); 03200 goto out; 03201 } 03202 03203 ret = 0; 03204 do 03205 { 03206 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024); 03207 } 03208 while (ret > 0); 03209 03210 _dbus_string_set_length (result, orig_len); 03211 if (_dbus_string_get_length (&error_message) > 0) 03212 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03213 "%s terminated abnormally with the following error: %s", 03214 progpath, _dbus_string_get_data (&error_message)); 03215 else 03216 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03217 "%s terminated abnormally without any error message", 03218 progpath); 03219 goto out; 03220 } 03221 03222 retval = TRUE; 03223 03224 out: 03225 sigprocmask (SIG_SETMASK, &old_set, NULL); 03226 03227 if (retval) 03228 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03229 else 03230 _DBUS_ASSERT_ERROR_IS_SET (error); 03231 03232 if (result_pipe[0] != -1) 03233 close (result_pipe[0]); 03234 if (result_pipe[1] != -1) 03235 close (result_pipe[1]); 03236 if (errors_pipe[0] != -1) 03237 close (errors_pipe[0]); 03238 if (errors_pipe[1] != -1) 03239 close (errors_pipe[1]); 03240 03241 return retval; 03242 } 03243 03255 dbus_bool_t 03256 _dbus_get_autolaunch_address (const char *scope, 03257 DBusString *address, 03258 DBusError *error) 03259 { 03260 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH 03261 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch, 03262 * but that's done elsewhere, and if it worked, this function wouldn't 03263 * be called.) */ 03264 const char *display; 03265 static char *argv[6]; 03266 int i; 03267 DBusString uuid; 03268 dbus_bool_t retval; 03269 03270 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03271 retval = FALSE; 03272 03273 /* fd.o #19997: if $DISPLAY isn't set to something useful, then 03274 * dbus-launch-x11 is just going to fail. Rather than trying to 03275 * run it, we might as well bail out early with a nice error. */ 03276 display = _dbus_getenv ("DISPLAY"); 03277 03278 if (display == NULL || display[0] == '\0') 03279 { 03280 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03281 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11"); 03282 return FALSE; 03283 } 03284 03285 if (!_dbus_string_init (&uuid)) 03286 { 03287 _DBUS_SET_OOM (error); 03288 return FALSE; 03289 } 03290 03291 if (!_dbus_get_local_machine_uuid_encoded (&uuid)) 03292 { 03293 _DBUS_SET_OOM (error); 03294 goto out; 03295 } 03296 03297 i = 0; 03298 argv[i] = "dbus-launch"; 03299 ++i; 03300 argv[i] = "--autolaunch"; 03301 ++i; 03302 argv[i] = _dbus_string_get_data (&uuid); 03303 ++i; 03304 argv[i] = "--binary-syntax"; 03305 ++i; 03306 argv[i] = "--close-stderr"; 03307 ++i; 03308 argv[i] = NULL; 03309 ++i; 03310 03311 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03312 03313 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch", 03314 TRUE, 03315 argv, address, error); 03316 03317 out: 03318 _dbus_string_free (&uuid); 03319 return retval; 03320 #else 03321 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03322 "Using X11 for dbus-daemon autolaunch was disabled at compile time, " 03323 "set your DBUS_SESSION_BUS_ADDRESS instead"); 03324 return FALSE; 03325 #endif 03326 } 03327 03346 dbus_bool_t 03347 _dbus_read_local_machine_uuid (DBusGUID *machine_id, 03348 dbus_bool_t create_if_not_found, 03349 DBusError *error) 03350 { 03351 DBusString filename; 03352 dbus_bool_t b; 03353 03354 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE); 03355 03356 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error); 03357 if (b) 03358 return TRUE; 03359 03360 dbus_error_free (error); 03361 03362 /* Fallback to the system machine ID */ 03363 _dbus_string_init_const (&filename, "/etc/machine-id"); 03364 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error); 03365 } 03366 03367 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" 03368 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" 03369 03376 dbus_bool_t 03377 _dbus_lookup_launchd_socket (DBusString *socket_path, 03378 const char *launchd_env_var, 03379 DBusError *error) 03380 { 03381 #ifdef DBUS_ENABLE_LAUNCHD 03382 char *argv[4]; 03383 int i; 03384 03385 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03386 03387 i = 0; 03388 argv[i] = "launchctl"; 03389 ++i; 03390 argv[i] = "getenv"; 03391 ++i; 03392 argv[i] = (char*)launchd_env_var; 03393 ++i; 03394 argv[i] = NULL; 03395 ++i; 03396 03397 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03398 03399 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error)) 03400 { 03401 return FALSE; 03402 } 03403 03404 /* no error, but no result either */ 03405 if (_dbus_string_get_length(socket_path) == 0) 03406 { 03407 return FALSE; 03408 } 03409 03410 /* strip the carriage-return */ 03411 _dbus_string_shorten(socket_path, 1); 03412 return TRUE; 03413 #else /* DBUS_ENABLE_LAUNCHD */ 03414 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, 03415 "can't lookup socket from launchd; launchd support not compiled in"); 03416 return FALSE; 03417 #endif 03418 } 03419 03420 static dbus_bool_t 03421 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error) 03422 { 03423 #ifdef DBUS_ENABLE_LAUNCHD 03424 dbus_bool_t valid_socket; 03425 DBusString socket_path; 03426 03427 if (!_dbus_string_init (&socket_path)) 03428 { 03429 _DBUS_SET_OOM (error); 03430 return FALSE; 03431 } 03432 03433 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error); 03434 03435 if (dbus_error_is_set(error)) 03436 { 03437 _dbus_string_free(&socket_path); 03438 return FALSE; 03439 } 03440 03441 if (!valid_socket) 03442 { 03443 dbus_set_error(error, "no socket path", 03444 "launchd did not provide a socket path, " 03445 "verify that org.freedesktop.dbus-session.plist is loaded!"); 03446 _dbus_string_free(&socket_path); 03447 return FALSE; 03448 } 03449 if (!_dbus_string_append (address, "unix:path=")) 03450 { 03451 _DBUS_SET_OOM (error); 03452 _dbus_string_free(&socket_path); 03453 return FALSE; 03454 } 03455 if (!_dbus_string_copy (&socket_path, 0, address, 03456 _dbus_string_get_length (address))) 03457 { 03458 _DBUS_SET_OOM (error); 03459 _dbus_string_free(&socket_path); 03460 return FALSE; 03461 } 03462 03463 _dbus_string_free(&socket_path); 03464 return TRUE; 03465 #else 03466 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, 03467 "can't lookup session address from launchd; launchd support not compiled in"); 03468 return FALSE; 03469 #endif 03470 } 03471 03491 dbus_bool_t 03492 _dbus_lookup_session_address (dbus_bool_t *supported, 03493 DBusString *address, 03494 DBusError *error) 03495 { 03496 #ifdef DBUS_ENABLE_LAUNCHD 03497 *supported = TRUE; 03498 return _dbus_lookup_session_address_launchd (address, error); 03499 #else 03500 /* On non-Mac Unix platforms, if the session address isn't already 03501 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and 03502 * fall back to the autolaunch: global default; see 03503 * init_session_address in dbus/dbus-bus.c. */ 03504 *supported = FALSE; 03505 return TRUE; 03506 #endif 03507 } 03508 03526 dbus_bool_t 03527 _dbus_get_standard_session_servicedirs (DBusList **dirs) 03528 { 03529 const char *xdg_data_home; 03530 const char *xdg_data_dirs; 03531 DBusString servicedir_path; 03532 03533 if (!_dbus_string_init (&servicedir_path)) 03534 return FALSE; 03535 03536 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); 03537 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 03538 03539 if (xdg_data_home != NULL) 03540 { 03541 if (!_dbus_string_append (&servicedir_path, xdg_data_home)) 03542 goto oom; 03543 } 03544 else 03545 { 03546 const DBusString *homedir; 03547 DBusString local_share; 03548 03549 if (!_dbus_homedir_from_current_process (&homedir)) 03550 goto oom; 03551 03552 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) 03553 goto oom; 03554 03555 _dbus_string_init_const (&local_share, "/.local/share"); 03556 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) 03557 goto oom; 03558 } 03559 03560 if (!_dbus_string_append (&servicedir_path, ":")) 03561 goto oom; 03562 03563 if (xdg_data_dirs != NULL) 03564 { 03565 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 03566 goto oom; 03567 03568 if (!_dbus_string_append (&servicedir_path, ":")) 03569 goto oom; 03570 } 03571 else 03572 { 03573 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 03574 goto oom; 03575 } 03576 03577 /* 03578 * add configured datadir to defaults 03579 * this may be the same as an xdg dir 03580 * however the config parser should take 03581 * care of duplicates 03582 */ 03583 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR)) 03584 goto oom; 03585 03586 if (!_dbus_split_paths_and_append (&servicedir_path, 03587 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 03588 dirs)) 03589 goto oom; 03590 03591 _dbus_string_free (&servicedir_path); 03592 return TRUE; 03593 03594 oom: 03595 _dbus_string_free (&servicedir_path); 03596 return FALSE; 03597 } 03598 03599 03618 dbus_bool_t 03619 _dbus_get_standard_system_servicedirs (DBusList **dirs) 03620 { 03621 const char *xdg_data_dirs; 03622 DBusString servicedir_path; 03623 03624 if (!_dbus_string_init (&servicedir_path)) 03625 return FALSE; 03626 03627 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 03628 03629 if (xdg_data_dirs != NULL) 03630 { 03631 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 03632 goto oom; 03633 03634 if (!_dbus_string_append (&servicedir_path, ":")) 03635 goto oom; 03636 } 03637 else 03638 { 03639 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 03640 goto oom; 03641 } 03642 03643 /* 03644 * add configured datadir to defaults 03645 * this may be the same as an xdg dir 03646 * however the config parser should take 03647 * care of duplicates 03648 */ 03649 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":")) 03650 goto oom; 03651 03652 if (!_dbus_split_paths_and_append (&servicedir_path, 03653 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 03654 dirs)) 03655 goto oom; 03656 03657 _dbus_string_free (&servicedir_path); 03658 return TRUE; 03659 03660 oom: 03661 _dbus_string_free (&servicedir_path); 03662 return FALSE; 03663 } 03664 03673 dbus_bool_t 03674 _dbus_append_system_config_file (DBusString *str) 03675 { 03676 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE); 03677 } 03678 03685 dbus_bool_t 03686 _dbus_append_session_config_file (DBusString *str) 03687 { 03688 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); 03689 } 03690 03698 void 03699 _dbus_flush_caches (void) 03700 { 03701 _dbus_user_database_flush_system (); 03702 } 03703 03717 dbus_bool_t 03718 _dbus_append_keyring_directory_for_credentials (DBusString *directory, 03719 DBusCredentials *credentials) 03720 { 03721 DBusString homedir; 03722 DBusString dotdir; 03723 dbus_uid_t uid; 03724 03725 _dbus_assert (credentials != NULL); 03726 _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); 03727 03728 if (!_dbus_string_init (&homedir)) 03729 return FALSE; 03730 03731 uid = _dbus_credentials_get_unix_uid (credentials); 03732 _dbus_assert (uid != DBUS_UID_UNSET); 03733 03734 if (!_dbus_homedir_from_uid (uid, &homedir)) 03735 goto failed; 03736 03737 #ifdef DBUS_BUILD_TESTS 03738 { 03739 const char *override; 03740 03741 override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); 03742 if (override != NULL && *override != '\0') 03743 { 03744 _dbus_string_set_length (&homedir, 0); 03745 if (!_dbus_string_append (&homedir, override)) 03746 goto failed; 03747 03748 _dbus_verbose ("Using fake homedir for testing: %s\n", 03749 _dbus_string_get_const_data (&homedir)); 03750 } 03751 else 03752 { 03753 static dbus_bool_t already_warned = FALSE; 03754 if (!already_warned) 03755 { 03756 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); 03757 already_warned = TRUE; 03758 } 03759 } 03760 } 03761 #endif 03762 03763 _dbus_string_init_const (&dotdir, ".dbus-keyrings"); 03764 if (!_dbus_concat_dir_and_file (&homedir, 03765 &dotdir)) 03766 goto failed; 03767 03768 if (!_dbus_string_copy (&homedir, 0, 03769 directory, _dbus_string_get_length (directory))) { 03770 goto failed; 03771 } 03772 03773 _dbus_string_free (&homedir); 03774 return TRUE; 03775 03776 failed: 03777 _dbus_string_free (&homedir); 03778 return FALSE; 03779 } 03780 03781 //PENDING(kdab) docs 03782 dbus_bool_t 03783 _dbus_daemon_publish_session_bus_address (const char* addr, 03784 const char *scope) 03785 { 03786 return TRUE; 03787 } 03788 03789 //PENDING(kdab) docs 03790 void 03791 _dbus_daemon_unpublish_session_bus_address (void) 03792 { 03793 03794 } 03795 03802 dbus_bool_t 03803 _dbus_get_is_errno_eagain_or_ewouldblock (void) 03804 { 03805 return errno == EAGAIN || errno == EWOULDBLOCK; 03806 } 03807 03815 dbus_bool_t 03816 _dbus_delete_directory (const DBusString *filename, 03817 DBusError *error) 03818 { 03819 const char *filename_c; 03820 03821 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03822 03823 filename_c = _dbus_string_get_const_data (filename); 03824 03825 if (rmdir (filename_c) != 0) 03826 { 03827 dbus_set_error (error, DBUS_ERROR_FAILED, 03828 "Failed to remove directory %s: %s\n", 03829 filename_c, _dbus_strerror (errno)); 03830 return FALSE; 03831 } 03832 03833 return TRUE; 03834 } 03835 03843 dbus_bool_t 03844 _dbus_socket_can_pass_unix_fd(int fd) { 03845 03846 #ifdef SCM_RIGHTS 03847 union { 03848 struct sockaddr sa; 03849 struct sockaddr_storage storage; 03850 struct sockaddr_un un; 03851 } sa_buf; 03852 03853 socklen_t sa_len = sizeof(sa_buf); 03854 03855 _DBUS_ZERO(sa_buf); 03856 03857 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0) 03858 return FALSE; 03859 03860 return sa_buf.sa.sa_family == AF_UNIX; 03861 03862 #else 03863 return FALSE; 03864 03865 #endif 03866 } 03867 03868 03869 /* 03870 * replaces the term DBUS_PREFIX in configure_time_path by the 03871 * current dbus installation directory. On unix this function is a noop 03872 * 03873 * @param configure_time_path 03874 * @return real path 03875 */ 03876 const char * 03877 _dbus_replace_install_prefix (const char *configure_time_path) 03878 { 03879 return configure_time_path; 03880 } 03881 03882 /* tests in dbus-sysdeps-util.c */