D-Bus 1.6.12
|
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) 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 again: 00319 00320 bytes_read = recvmsg(fd, &m, 0 00321 #ifdef MSG_CMSG_CLOEXEC 00322 |MSG_CMSG_CLOEXEC 00323 #endif 00324 ); 00325 00326 if (bytes_read < 0) 00327 { 00328 if (errno == EINTR) 00329 goto again; 00330 else 00331 { 00332 /* put length back (note that this doesn't actually realloc anything) */ 00333 _dbus_string_set_length (buffer, start); 00334 return -1; 00335 } 00336 } 00337 else 00338 { 00339 struct cmsghdr *cm; 00340 dbus_bool_t found = FALSE; 00341 00342 if (m.msg_flags & MSG_CTRUNC) 00343 { 00344 /* Hmm, apparently the control data was truncated. The bad 00345 thing is that we might have completely lost a couple of fds 00346 without chance to recover them. Hence let's treat this as a 00347 serious error. */ 00348 00349 errno = ENOSPC; 00350 _dbus_string_set_length (buffer, start); 00351 return -1; 00352 } 00353 00354 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) 00355 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) 00356 { 00357 unsigned i; 00358 00359 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int))); 00360 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int); 00361 00362 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int)); 00363 found = TRUE; 00364 00365 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually 00366 worked, hence we need to go through this list and set 00367 CLOEXEC everywhere in any case */ 00368 for (i = 0; i < *n_fds; i++) 00369 _dbus_fd_set_close_on_exec(fds[i]); 00370 00371 break; 00372 } 00373 00374 if (!found) 00375 *n_fds = 0; 00376 00377 /* put length back (doesn't actually realloc) */ 00378 _dbus_string_set_length (buffer, start + bytes_read); 00379 00380 #if 0 00381 if (bytes_read > 0) 00382 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00383 #endif 00384 00385 return bytes_read; 00386 } 00387 #endif 00388 } 00389 00390 int 00391 _dbus_write_socket_with_unix_fds(int fd, 00392 const DBusString *buffer, 00393 int start, 00394 int len, 00395 const int *fds, 00396 int n_fds) { 00397 00398 #ifndef HAVE_UNIX_FD_PASSING 00399 00400 if (n_fds > 0) { 00401 errno = ENOTSUP; 00402 return -1; 00403 } 00404 00405 return _dbus_write_socket(fd, buffer, start, len); 00406 #else 00407 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds); 00408 #endif 00409 } 00410 00411 int 00412 _dbus_write_socket_with_unix_fds_two(int fd, 00413 const DBusString *buffer1, 00414 int start1, 00415 int len1, 00416 const DBusString *buffer2, 00417 int start2, 00418 int len2, 00419 const int *fds, 00420 int n_fds) { 00421 00422 #ifndef HAVE_UNIX_FD_PASSING 00423 00424 if (n_fds > 0) { 00425 errno = ENOTSUP; 00426 return -1; 00427 } 00428 00429 return _dbus_write_socket_two(fd, 00430 buffer1, start1, len1, 00431 buffer2, start2, len2); 00432 #else 00433 00434 struct msghdr m; 00435 struct cmsghdr *cm; 00436 struct iovec iov[2]; 00437 int bytes_written; 00438 00439 _dbus_assert (len1 >= 0); 00440 _dbus_assert (len2 >= 0); 00441 _dbus_assert (n_fds >= 0); 00442 00443 _DBUS_ZERO(iov); 00444 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1); 00445 iov[0].iov_len = len1; 00446 00447 if (buffer2) 00448 { 00449 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2); 00450 iov[1].iov_len = len2; 00451 } 00452 00453 _DBUS_ZERO(m); 00454 m.msg_iov = iov; 00455 m.msg_iovlen = buffer2 ? 2 : 1; 00456 00457 if (n_fds > 0) 00458 { 00459 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int)); 00460 m.msg_control = alloca(m.msg_controllen); 00461 memset(m.msg_control, 0, m.msg_controllen); 00462 00463 cm = CMSG_FIRSTHDR(&m); 00464 cm->cmsg_level = SOL_SOCKET; 00465 cm->cmsg_type = SCM_RIGHTS; 00466 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int)); 00467 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int)); 00468 } 00469 00470 again: 00471 00472 bytes_written = sendmsg (fd, &m, 0 00473 #if HAVE_DECL_MSG_NOSIGNAL 00474 |MSG_NOSIGNAL 00475 #endif 00476 ); 00477 00478 if (bytes_written < 0 && errno == EINTR) 00479 goto again; 00480 00481 #if 0 00482 if (bytes_written > 0) 00483 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00484 #endif 00485 00486 return bytes_written; 00487 #endif 00488 } 00489 00503 int 00504 _dbus_write_socket_two (int fd, 00505 const DBusString *buffer1, 00506 int start1, 00507 int len1, 00508 const DBusString *buffer2, 00509 int start2, 00510 int len2) 00511 { 00512 #if HAVE_DECL_MSG_NOSIGNAL 00513 struct iovec vectors[2]; 00514 const char *data1; 00515 const char *data2; 00516 int bytes_written; 00517 struct msghdr m; 00518 00519 _dbus_assert (buffer1 != NULL); 00520 _dbus_assert (start1 >= 0); 00521 _dbus_assert (start2 >= 0); 00522 _dbus_assert (len1 >= 0); 00523 _dbus_assert (len2 >= 0); 00524 00525 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00526 00527 if (buffer2 != NULL) 00528 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00529 else 00530 { 00531 data2 = NULL; 00532 start2 = 0; 00533 len2 = 0; 00534 } 00535 00536 vectors[0].iov_base = (char*) data1; 00537 vectors[0].iov_len = len1; 00538 vectors[1].iov_base = (char*) data2; 00539 vectors[1].iov_len = len2; 00540 00541 _DBUS_ZERO(m); 00542 m.msg_iov = vectors; 00543 m.msg_iovlen = data2 ? 2 : 1; 00544 00545 again: 00546 00547 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL); 00548 00549 if (bytes_written < 0 && errno == EINTR) 00550 goto again; 00551 00552 return bytes_written; 00553 00554 #else 00555 return _dbus_write_two (fd, buffer1, start1, len1, 00556 buffer2, start2, len2); 00557 #endif 00558 } 00559 00560 dbus_bool_t 00561 _dbus_socket_is_invalid (int fd) 00562 { 00563 return fd < 0 ? TRUE : FALSE; 00564 } 00565 00582 int 00583 _dbus_read (int fd, 00584 DBusString *buffer, 00585 int count) 00586 { 00587 int bytes_read; 00588 int start; 00589 char *data; 00590 00591 _dbus_assert (count >= 0); 00592 00593 start = _dbus_string_get_length (buffer); 00594 00595 if (!_dbus_string_lengthen (buffer, count)) 00596 { 00597 errno = ENOMEM; 00598 return -1; 00599 } 00600 00601 data = _dbus_string_get_data_len (buffer, start, count); 00602 00603 again: 00604 00605 bytes_read = read (fd, data, count); 00606 00607 if (bytes_read < 0) 00608 { 00609 if (errno == EINTR) 00610 goto again; 00611 else 00612 { 00613 /* put length back (note that this doesn't actually realloc anything) */ 00614 _dbus_string_set_length (buffer, start); 00615 return -1; 00616 } 00617 } 00618 else 00619 { 00620 /* put length back (doesn't actually realloc) */ 00621 _dbus_string_set_length (buffer, start + bytes_read); 00622 00623 #if 0 00624 if (bytes_read > 0) 00625 _dbus_verbose_bytes_of_string (buffer, start, bytes_read); 00626 #endif 00627 00628 return bytes_read; 00629 } 00630 } 00631 00642 int 00643 _dbus_write (int fd, 00644 const DBusString *buffer, 00645 int start, 00646 int len) 00647 { 00648 const char *data; 00649 int bytes_written; 00650 00651 data = _dbus_string_get_const_data_len (buffer, start, len); 00652 00653 again: 00654 00655 bytes_written = write (fd, data, len); 00656 00657 if (bytes_written < 0 && errno == EINTR) 00658 goto again; 00659 00660 #if 0 00661 if (bytes_written > 0) 00662 _dbus_verbose_bytes_of_string (buffer, start, bytes_written); 00663 #endif 00664 00665 return bytes_written; 00666 } 00667 00688 int 00689 _dbus_write_two (int fd, 00690 const DBusString *buffer1, 00691 int start1, 00692 int len1, 00693 const DBusString *buffer2, 00694 int start2, 00695 int len2) 00696 { 00697 _dbus_assert (buffer1 != NULL); 00698 _dbus_assert (start1 >= 0); 00699 _dbus_assert (start2 >= 0); 00700 _dbus_assert (len1 >= 0); 00701 _dbus_assert (len2 >= 0); 00702 00703 #ifdef HAVE_WRITEV 00704 { 00705 struct iovec vectors[2]; 00706 const char *data1; 00707 const char *data2; 00708 int bytes_written; 00709 00710 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1); 00711 00712 if (buffer2 != NULL) 00713 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2); 00714 else 00715 { 00716 data2 = NULL; 00717 start2 = 0; 00718 len2 = 0; 00719 } 00720 00721 vectors[0].iov_base = (char*) data1; 00722 vectors[0].iov_len = len1; 00723 vectors[1].iov_base = (char*) data2; 00724 vectors[1].iov_len = len2; 00725 00726 again: 00727 00728 bytes_written = writev (fd, 00729 vectors, 00730 data2 ? 2 : 1); 00731 00732 if (bytes_written < 0 && errno == EINTR) 00733 goto again; 00734 00735 return bytes_written; 00736 } 00737 #else /* HAVE_WRITEV */ 00738 { 00739 int ret1; 00740 00741 ret1 = _dbus_write (fd, buffer1, start1, len1); 00742 if (ret1 == len1 && buffer2 != NULL) 00743 { 00744 ret2 = _dbus_write (fd, buffer2, start2, len2); 00745 if (ret2 < 0) 00746 ret2 = 0; /* we can't report an error as the first write was OK */ 00747 00748 return ret1 + ret2; 00749 } 00750 else 00751 return ret1; 00752 } 00753 #endif /* !HAVE_WRITEV */ 00754 } 00755 00756 #define _DBUS_MAX_SUN_PATH_LENGTH 99 00757 00787 int 00788 _dbus_connect_unix_socket (const char *path, 00789 dbus_bool_t abstract, 00790 DBusError *error) 00791 { 00792 int fd; 00793 size_t path_len; 00794 struct sockaddr_un addr; 00795 00796 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00797 00798 _dbus_verbose ("connecting to unix socket %s abstract=%d\n", 00799 path, abstract); 00800 00801 00802 if (!_dbus_open_unix_socket (&fd, error)) 00803 { 00804 _DBUS_ASSERT_ERROR_IS_SET(error); 00805 return -1; 00806 } 00807 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 00808 00809 _DBUS_ZERO (addr); 00810 addr.sun_family = AF_UNIX; 00811 path_len = strlen (path); 00812 00813 if (abstract) 00814 { 00815 #ifdef HAVE_ABSTRACT_SOCKETS 00816 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 00817 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 00818 00819 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00820 { 00821 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00822 "Abstract socket name too long\n"); 00823 _dbus_close (fd, NULL); 00824 return -1; 00825 } 00826 00827 strncpy (&addr.sun_path[1], path, path_len); 00828 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 00829 #else /* HAVE_ABSTRACT_SOCKETS */ 00830 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 00831 "Operating system does not support abstract socket namespace\n"); 00832 _dbus_close (fd, NULL); 00833 return -1; 00834 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 00835 } 00836 else 00837 { 00838 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 00839 { 00840 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 00841 "Socket name too long\n"); 00842 _dbus_close (fd, NULL); 00843 return -1; 00844 } 00845 00846 strncpy (addr.sun_path, path, path_len); 00847 } 00848 00849 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 00850 { 00851 dbus_set_error (error, 00852 _dbus_error_from_errno (errno), 00853 "Failed to connect to socket %s: %s", 00854 path, _dbus_strerror (errno)); 00855 00856 _dbus_close (fd, NULL); 00857 return -1; 00858 } 00859 00860 if (!_dbus_set_fd_nonblocking (fd, error)) 00861 { 00862 _DBUS_ASSERT_ERROR_IS_SET (error); 00863 00864 _dbus_close (fd, NULL); 00865 return -1; 00866 } 00867 00868 return fd; 00869 } 00870 00883 int 00884 _dbus_connect_exec (const char *path, 00885 char *const argv[], 00886 DBusError *error) 00887 { 00888 int fds[2]; 00889 pid_t pid; 00890 00891 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00892 00893 _dbus_verbose ("connecting to process %s\n", path); 00894 00895 if (socketpair (AF_UNIX, SOCK_STREAM 00896 #ifdef SOCK_CLOEXEC 00897 |SOCK_CLOEXEC 00898 #endif 00899 , 0, fds) < 0) 00900 { 00901 dbus_set_error (error, 00902 _dbus_error_from_errno (errno), 00903 "Failed to create socket pair: %s", 00904 _dbus_strerror (errno)); 00905 return -1; 00906 } 00907 00908 _dbus_fd_set_close_on_exec (fds[0]); 00909 _dbus_fd_set_close_on_exec (fds[1]); 00910 00911 pid = fork (); 00912 if (pid < 0) 00913 { 00914 dbus_set_error (error, 00915 _dbus_error_from_errno (errno), 00916 "Failed to fork() to call %s: %s", 00917 path, _dbus_strerror (errno)); 00918 close (fds[0]); 00919 close (fds[1]); 00920 return -1; 00921 } 00922 00923 if (pid == 0) 00924 { 00925 /* child */ 00926 close (fds[0]); 00927 00928 dup2 (fds[1], STDIN_FILENO); 00929 dup2 (fds[1], STDOUT_FILENO); 00930 00931 if (fds[1] != STDIN_FILENO && 00932 fds[1] != STDOUT_FILENO) 00933 close (fds[1]); 00934 00935 /* Inherit STDERR and the controlling terminal from the 00936 parent */ 00937 00938 _dbus_close_all (); 00939 00940 execvp (path, argv); 00941 00942 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno)); 00943 00944 _exit(1); 00945 } 00946 00947 /* parent */ 00948 close (fds[1]); 00949 00950 if (!_dbus_set_fd_nonblocking (fds[0], error)) 00951 { 00952 _DBUS_ASSERT_ERROR_IS_SET (error); 00953 00954 close (fds[0]); 00955 return -1; 00956 } 00957 00958 return fds[0]; 00959 } 00960 00970 static dbus_bool_t 00971 _dbus_set_local_creds (int fd, dbus_bool_t on) 00972 { 00973 dbus_bool_t retval = TRUE; 00974 00975 #if defined(HAVE_CMSGCRED) 00976 /* NOOP just to make sure only one codepath is used 00977 * and to prefer CMSGCRED 00978 */ 00979 #elif defined(LOCAL_CREDS) 00980 int val = on ? 1 : 0; 00981 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0) 00982 { 00983 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd); 00984 retval = FALSE; 00985 } 00986 else 00987 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n", 00988 on ? "enabled" : "disabled", fd); 00989 #endif 00990 00991 return retval; 00992 } 00993 01011 int 01012 _dbus_listen_unix_socket (const char *path, 01013 dbus_bool_t abstract, 01014 DBusError *error) 01015 { 01016 int listen_fd; 01017 struct sockaddr_un addr; 01018 size_t path_len; 01019 unsigned int reuseaddr; 01020 01021 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01022 01023 _dbus_verbose ("listening on unix socket %s abstract=%d\n", 01024 path, abstract); 01025 01026 if (!_dbus_open_unix_socket (&listen_fd, error)) 01027 { 01028 _DBUS_ASSERT_ERROR_IS_SET(error); 01029 return -1; 01030 } 01031 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01032 01033 _DBUS_ZERO (addr); 01034 addr.sun_family = AF_UNIX; 01035 path_len = strlen (path); 01036 01037 if (abstract) 01038 { 01039 #ifdef HAVE_ABSTRACT_SOCKETS 01040 /* remember that abstract names aren't nul-terminated so we rely 01041 * on sun_path being filled in with zeroes above. 01042 */ 01043 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */ 01044 path_len++; /* Account for the extra nul byte added to the start of sun_path */ 01045 01046 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 01047 { 01048 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01049 "Abstract socket name too long\n"); 01050 _dbus_close (listen_fd, NULL); 01051 return -1; 01052 } 01053 01054 strncpy (&addr.sun_path[1], path, path_len); 01055 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */ 01056 #else /* HAVE_ABSTRACT_SOCKETS */ 01057 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, 01058 "Operating system does not support abstract socket namespace\n"); 01059 _dbus_close (listen_fd, NULL); 01060 return -1; 01061 #endif /* ! HAVE_ABSTRACT_SOCKETS */ 01062 } 01063 else 01064 { 01065 /* Discussed security implications of this with Nalin, 01066 * and we couldn't think of where it would kick our ass, but 01067 * it still seems a bit sucky. It also has non-security suckage; 01068 * really we'd prefer to exit if the socket is already in use. 01069 * But there doesn't seem to be a good way to do this. 01070 * 01071 * Just to be extra careful, I threw in the stat() - clearly 01072 * the stat() can't *fix* any security issue, but it at least 01073 * avoids inadvertent/accidental data loss. 01074 */ 01075 { 01076 struct stat sb; 01077 01078 if (stat (path, &sb) == 0 && 01079 S_ISSOCK (sb.st_mode)) 01080 unlink (path); 01081 } 01082 01083 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH) 01084 { 01085 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01086 "Abstract socket name too long\n"); 01087 _dbus_close (listen_fd, NULL); 01088 return -1; 01089 } 01090 01091 strncpy (addr.sun_path, path, path_len); 01092 } 01093 01094 reuseaddr = 1; 01095 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01096 { 01097 _dbus_warn ("Failed to set socket option\"%s\": %s", 01098 path, _dbus_strerror (errno)); 01099 } 01100 01101 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0) 01102 { 01103 dbus_set_error (error, _dbus_error_from_errno (errno), 01104 "Failed to bind socket \"%s\": %s", 01105 path, _dbus_strerror (errno)); 01106 _dbus_close (listen_fd, NULL); 01107 return -1; 01108 } 01109 01110 if (listen (listen_fd, 30 /* backlog */) < 0) 01111 { 01112 dbus_set_error (error, _dbus_error_from_errno (errno), 01113 "Failed to listen on socket \"%s\": %s", 01114 path, _dbus_strerror (errno)); 01115 _dbus_close (listen_fd, NULL); 01116 return -1; 01117 } 01118 01119 if (!_dbus_set_local_creds (listen_fd, TRUE)) 01120 { 01121 dbus_set_error (error, _dbus_error_from_errno (errno), 01122 "Failed to enable LOCAL_CREDS on socket \"%s\": %s", 01123 path, _dbus_strerror (errno)); 01124 close (listen_fd); 01125 return -1; 01126 } 01127 01128 if (!_dbus_set_fd_nonblocking (listen_fd, error)) 01129 { 01130 _DBUS_ASSERT_ERROR_IS_SET (error); 01131 _dbus_close (listen_fd, NULL); 01132 return -1; 01133 } 01134 01135 /* Try opening up the permissions, but if we can't, just go ahead 01136 * and continue, maybe it will be good enough. 01137 */ 01138 if (!abstract && chmod (path, 0777) < 0) 01139 _dbus_warn ("Could not set mode 0777 on socket %s\n", 01140 path); 01141 01142 return listen_fd; 01143 } 01144 01155 int 01156 _dbus_listen_systemd_sockets (int **fds, 01157 DBusError *error) 01158 { 01159 int r, n; 01160 unsigned fd; 01161 int *new_fds; 01162 01163 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01164 01165 n = sd_listen_fds (TRUE); 01166 if (n < 0) 01167 { 01168 dbus_set_error (error, _dbus_error_from_errno (-n), 01169 "Failed to acquire systemd socket: %s", 01170 _dbus_strerror (-n)); 01171 return -1; 01172 } 01173 01174 if (n <= 0) 01175 { 01176 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01177 "No socket received."); 01178 return -1; 01179 } 01180 01181 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01182 { 01183 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1); 01184 if (r < 0) 01185 { 01186 dbus_set_error (error, _dbus_error_from_errno (-r), 01187 "Failed to verify systemd socket type: %s", 01188 _dbus_strerror (-r)); 01189 return -1; 01190 } 01191 01192 if (!r) 01193 { 01194 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, 01195 "Passed socket has wrong type."); 01196 return -1; 01197 } 01198 } 01199 01200 /* OK, the file descriptors are all good, so let's take posession of 01201 them then. */ 01202 01203 new_fds = dbus_new (int, n); 01204 if (!new_fds) 01205 { 01206 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, 01207 "Failed to allocate file handle array."); 01208 goto fail; 01209 } 01210 01211 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01212 { 01213 if (!_dbus_set_local_creds (fd, TRUE)) 01214 { 01215 dbus_set_error (error, _dbus_error_from_errno (errno), 01216 "Failed to enable LOCAL_CREDS on systemd socket: %s", 01217 _dbus_strerror (errno)); 01218 goto fail; 01219 } 01220 01221 if (!_dbus_set_fd_nonblocking (fd, error)) 01222 { 01223 _DBUS_ASSERT_ERROR_IS_SET (error); 01224 goto fail; 01225 } 01226 01227 new_fds[fd - SD_LISTEN_FDS_START] = fd; 01228 } 01229 01230 *fds = new_fds; 01231 return n; 01232 01233 fail: 01234 01235 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) 01236 { 01237 _dbus_close (fd, NULL); 01238 } 01239 01240 dbus_free (new_fds); 01241 return -1; 01242 } 01243 01257 int 01258 _dbus_connect_tcp_socket (const char *host, 01259 const char *port, 01260 const char *family, 01261 DBusError *error) 01262 { 01263 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error); 01264 } 01265 01266 int 01267 _dbus_connect_tcp_socket_with_nonce (const char *host, 01268 const char *port, 01269 const char *family, 01270 const char *noncefile, 01271 DBusError *error) 01272 { 01273 int saved_errno = 0; 01274 int fd = -1, res; 01275 struct addrinfo hints; 01276 struct addrinfo *ai, *tmp; 01277 01278 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01279 01280 _DBUS_ZERO (hints); 01281 01282 if (!family) 01283 hints.ai_family = AF_UNSPEC; 01284 else if (!strcmp(family, "ipv4")) 01285 hints.ai_family = AF_INET; 01286 else if (!strcmp(family, "ipv6")) 01287 hints.ai_family = AF_INET6; 01288 else 01289 { 01290 dbus_set_error (error, 01291 DBUS_ERROR_BAD_ADDRESS, 01292 "Unknown address family %s", family); 01293 return -1; 01294 } 01295 hints.ai_protocol = IPPROTO_TCP; 01296 hints.ai_socktype = SOCK_STREAM; 01297 hints.ai_flags = AI_ADDRCONFIG; 01298 01299 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0) 01300 { 01301 dbus_set_error (error, 01302 _dbus_error_from_errno (errno), 01303 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01304 host, port, gai_strerror(res), res); 01305 return -1; 01306 } 01307 01308 tmp = ai; 01309 while (tmp) 01310 { 01311 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01312 { 01313 freeaddrinfo(ai); 01314 _DBUS_ASSERT_ERROR_IS_SET(error); 01315 return -1; 01316 } 01317 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01318 01319 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01320 { 01321 saved_errno = errno; 01322 _dbus_close(fd, NULL); 01323 fd = -1; 01324 tmp = tmp->ai_next; 01325 continue; 01326 } 01327 01328 break; 01329 } 01330 freeaddrinfo(ai); 01331 01332 if (fd == -1) 01333 { 01334 dbus_set_error (error, 01335 _dbus_error_from_errno (saved_errno), 01336 "Failed to connect to socket \"%s:%s\" %s", 01337 host, port, _dbus_strerror(saved_errno)); 01338 return -1; 01339 } 01340 01341 if (noncefile != NULL) 01342 { 01343 DBusString noncefileStr; 01344 dbus_bool_t ret; 01345 _dbus_string_init_const (&noncefileStr, noncefile); 01346 ret = _dbus_send_nonce (fd, &noncefileStr, error); 01347 _dbus_string_free (&noncefileStr); 01348 01349 if (!ret) 01350 { 01351 _dbus_close (fd, NULL); 01352 return -1; 01353 } 01354 } 01355 01356 if (!_dbus_set_fd_nonblocking (fd, error)) 01357 { 01358 _dbus_close (fd, NULL); 01359 return -1; 01360 } 01361 01362 return fd; 01363 } 01364 01381 int 01382 _dbus_listen_tcp_socket (const char *host, 01383 const char *port, 01384 const char *family, 01385 DBusString *retport, 01386 int **fds_p, 01387 DBusError *error) 01388 { 01389 int saved_errno; 01390 int nlisten_fd = 0, *listen_fd = NULL, res, i; 01391 struct addrinfo hints; 01392 struct addrinfo *ai, *tmp; 01393 unsigned int reuseaddr; 01394 01395 *fds_p = NULL; 01396 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01397 01398 _DBUS_ZERO (hints); 01399 01400 if (!family) 01401 hints.ai_family = AF_UNSPEC; 01402 else if (!strcmp(family, "ipv4")) 01403 hints.ai_family = AF_INET; 01404 else if (!strcmp(family, "ipv6")) 01405 hints.ai_family = AF_INET6; 01406 else 01407 { 01408 dbus_set_error (error, 01409 DBUS_ERROR_BAD_ADDRESS, 01410 "Unknown address family %s", family); 01411 return -1; 01412 } 01413 01414 hints.ai_protocol = IPPROTO_TCP; 01415 hints.ai_socktype = SOCK_STREAM; 01416 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; 01417 01418 redo_lookup_with_port: 01419 ai = NULL; 01420 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai) 01421 { 01422 dbus_set_error (error, 01423 _dbus_error_from_errno (errno), 01424 "Failed to lookup host/port: \"%s:%s\": %s (%d)", 01425 host ? host : "*", port, gai_strerror(res), res); 01426 goto failed; 01427 } 01428 01429 tmp = ai; 01430 while (tmp) 01431 { 01432 int fd = -1, *newlisten_fd; 01433 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error)) 01434 { 01435 _DBUS_ASSERT_ERROR_IS_SET(error); 01436 goto failed; 01437 } 01438 _DBUS_ASSERT_ERROR_IS_CLEAR(error); 01439 01440 reuseaddr = 1; 01441 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1) 01442 { 01443 _dbus_warn ("Failed to set socket option \"%s:%s\": %s", 01444 host ? host : "*", port, _dbus_strerror (errno)); 01445 } 01446 01447 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0) 01448 { 01449 saved_errno = errno; 01450 _dbus_close(fd, NULL); 01451 if (saved_errno == EADDRINUSE) 01452 { 01453 /* Depending on kernel policy, it may or may not 01454 be neccessary to bind to both IPv4 & 6 addresses 01455 so ignore EADDRINUSE here */ 01456 tmp = tmp->ai_next; 01457 continue; 01458 } 01459 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01460 "Failed to bind socket \"%s:%s\": %s", 01461 host ? host : "*", port, _dbus_strerror (saved_errno)); 01462 goto failed; 01463 } 01464 01465 if (listen (fd, 30 /* backlog */) < 0) 01466 { 01467 saved_errno = errno; 01468 _dbus_close (fd, NULL); 01469 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01470 "Failed to listen on socket \"%s:%s\": %s", 01471 host ? host : "*", port, _dbus_strerror (saved_errno)); 01472 goto failed; 01473 } 01474 01475 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1)); 01476 if (!newlisten_fd) 01477 { 01478 saved_errno = errno; 01479 _dbus_close (fd, NULL); 01480 dbus_set_error (error, _dbus_error_from_errno (saved_errno), 01481 "Failed to allocate file handle array: %s", 01482 _dbus_strerror (saved_errno)); 01483 goto failed; 01484 } 01485 listen_fd = newlisten_fd; 01486 listen_fd[nlisten_fd] = fd; 01487 nlisten_fd++; 01488 01489 if (!_dbus_string_get_length(retport)) 01490 { 01491 /* If the user didn't specify a port, or used 0, then 01492 the kernel chooses a port. After the first address 01493 is bound to, we need to force all remaining addresses 01494 to use the same port */ 01495 if (!port || !strcmp(port, "0")) 01496 { 01497 int result; 01498 struct sockaddr_storage addr; 01499 socklen_t addrlen; 01500 char portbuf[50]; 01501 01502 addrlen = sizeof(addr); 01503 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen); 01504 01505 if (result == -1 || 01506 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0, 01507 portbuf, sizeof(portbuf), 01508 NI_NUMERICHOST)) != 0) 01509 { 01510 dbus_set_error (error, _dbus_error_from_errno (errno), 01511 "Failed to resolve port \"%s:%s\": %s (%s)", 01512 host ? host : "*", port, gai_strerror(res), res); 01513 goto failed; 01514 } 01515 if (!_dbus_string_append(retport, portbuf)) 01516 { 01517 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01518 goto failed; 01519 } 01520 01521 /* Release current address list & redo lookup */ 01522 port = _dbus_string_get_const_data(retport); 01523 freeaddrinfo(ai); 01524 goto redo_lookup_with_port; 01525 } 01526 else 01527 { 01528 if (!_dbus_string_append(retport, port)) 01529 { 01530 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01531 goto failed; 01532 } 01533 } 01534 } 01535 01536 tmp = tmp->ai_next; 01537 } 01538 freeaddrinfo(ai); 01539 ai = NULL; 01540 01541 if (!nlisten_fd) 01542 { 01543 errno = EADDRINUSE; 01544 dbus_set_error (error, _dbus_error_from_errno (errno), 01545 "Failed to bind socket \"%s:%s\": %s", 01546 host ? host : "*", port, _dbus_strerror (errno)); 01547 goto failed; 01548 } 01549 01550 for (i = 0 ; i < nlisten_fd ; i++) 01551 { 01552 if (!_dbus_set_fd_nonblocking (listen_fd[i], error)) 01553 { 01554 goto failed; 01555 } 01556 } 01557 01558 *fds_p = listen_fd; 01559 01560 return nlisten_fd; 01561 01562 failed: 01563 if (ai) 01564 freeaddrinfo(ai); 01565 for (i = 0 ; i < nlisten_fd ; i++) 01566 _dbus_close(listen_fd[i], NULL); 01567 dbus_free(listen_fd); 01568 return -1; 01569 } 01570 01571 static dbus_bool_t 01572 write_credentials_byte (int server_fd, 01573 DBusError *error) 01574 { 01575 int bytes_written; 01576 char buf[1] = { '\0' }; 01577 #if defined(HAVE_CMSGCRED) 01578 union { 01579 struct cmsghdr hdr; 01580 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01581 } cmsg; 01582 struct iovec iov; 01583 struct msghdr msg; 01584 iov.iov_base = buf; 01585 iov.iov_len = 1; 01586 01587 _DBUS_ZERO(msg); 01588 msg.msg_iov = &iov; 01589 msg.msg_iovlen = 1; 01590 01591 msg.msg_control = (caddr_t) &cmsg; 01592 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01593 _DBUS_ZERO(cmsg); 01594 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred)); 01595 cmsg.hdr.cmsg_level = SOL_SOCKET; 01596 cmsg.hdr.cmsg_type = SCM_CREDS; 01597 #endif 01598 01599 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01600 01601 again: 01602 01603 #if defined(HAVE_CMSGCRED) 01604 bytes_written = sendmsg (server_fd, &msg, 0 01605 #if HAVE_DECL_MSG_NOSIGNAL 01606 |MSG_NOSIGNAL 01607 #endif 01608 ); 01609 #else 01610 bytes_written = send (server_fd, buf, 1, 0 01611 #if HAVE_DECL_MSG_NOSIGNAL 01612 |MSG_NOSIGNAL 01613 #endif 01614 ); 01615 #endif 01616 01617 if (bytes_written < 0 && errno == EINTR) 01618 goto again; 01619 01620 if (bytes_written < 0) 01621 { 01622 dbus_set_error (error, _dbus_error_from_errno (errno), 01623 "Failed to write credentials byte: %s", 01624 _dbus_strerror (errno)); 01625 return FALSE; 01626 } 01627 else if (bytes_written == 0) 01628 { 01629 dbus_set_error (error, DBUS_ERROR_IO_ERROR, 01630 "wrote zero bytes writing credentials byte"); 01631 return FALSE; 01632 } 01633 else 01634 { 01635 _dbus_assert (bytes_written == 1); 01636 _dbus_verbose ("wrote credentials byte\n"); 01637 return TRUE; 01638 } 01639 } 01640 01662 dbus_bool_t 01663 _dbus_read_credentials_socket (int client_fd, 01664 DBusCredentials *credentials, 01665 DBusError *error) 01666 { 01667 struct msghdr msg; 01668 struct iovec iov; 01669 char buf; 01670 dbus_uid_t uid_read; 01671 dbus_pid_t pid_read; 01672 int bytes_read; 01673 01674 #ifdef HAVE_CMSGCRED 01675 union { 01676 struct cmsghdr hdr; 01677 char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; 01678 } cmsg; 01679 01680 #elif defined(LOCAL_CREDS) 01681 struct { 01682 struct cmsghdr hdr; 01683 struct sockcred cred; 01684 } cmsg; 01685 #endif 01686 01687 uid_read = DBUS_UID_UNSET; 01688 pid_read = DBUS_PID_UNSET; 01689 01690 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01691 01692 /* The POSIX spec certainly doesn't promise this, but 01693 * we need these assertions to fail as soon as we're wrong about 01694 * it so we can do the porting fixups 01695 */ 01696 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 01697 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 01698 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 01699 01700 _dbus_credentials_clear (credentials); 01701 01702 /* Systems supporting LOCAL_CREDS are configured to have this feature 01703 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting 01704 * the connection. Therefore, the received message must carry the 01705 * credentials information without doing anything special. 01706 */ 01707 01708 iov.iov_base = &buf; 01709 iov.iov_len = 1; 01710 01711 _DBUS_ZERO(msg); 01712 msg.msg_iov = &iov; 01713 msg.msg_iovlen = 1; 01714 01715 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01716 _DBUS_ZERO(cmsg); 01717 msg.msg_control = (caddr_t) &cmsg; 01718 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); 01719 #endif 01720 01721 again: 01722 bytes_read = recvmsg (client_fd, &msg, 0); 01723 01724 if (bytes_read < 0) 01725 { 01726 if (errno == EINTR) 01727 goto again; 01728 01729 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would 01730 * normally only call read_credentials if the socket was ready 01731 * for reading 01732 */ 01733 01734 dbus_set_error (error, _dbus_error_from_errno (errno), 01735 "Failed to read credentials byte: %s", 01736 _dbus_strerror (errno)); 01737 return FALSE; 01738 } 01739 else if (bytes_read == 0) 01740 { 01741 /* this should not happen unless we are using recvmsg wrong, 01742 * so is essentially here for paranoia 01743 */ 01744 dbus_set_error (error, DBUS_ERROR_FAILED, 01745 "Failed to read credentials byte (zero-length read)"); 01746 return FALSE; 01747 } 01748 else if (buf != '\0') 01749 { 01750 dbus_set_error (error, DBUS_ERROR_FAILED, 01751 "Credentials byte was not nul"); 01752 return FALSE; 01753 } 01754 01755 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) 01756 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) 01757 || cmsg.hdr.cmsg_type != SCM_CREDS) 01758 { 01759 dbus_set_error (error, DBUS_ERROR_FAILED, 01760 "Message from recvmsg() was not SCM_CREDS"); 01761 return FALSE; 01762 } 01763 #endif 01764 01765 _dbus_verbose ("read credentials byte\n"); 01766 01767 { 01768 #ifdef SO_PEERCRED 01769 #ifdef __OpenBSD__ 01770 struct sockpeercred cr; 01771 #else 01772 struct ucred cr; 01773 #endif 01774 int cr_len = sizeof (cr); 01775 01776 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && 01777 cr_len == sizeof (cr)) 01778 { 01779 pid_read = cr.pid; 01780 uid_read = cr.uid; 01781 } 01782 else 01783 { 01784 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", 01785 cr_len, (int) sizeof (cr), _dbus_strerror (errno)); 01786 } 01787 #elif defined(HAVE_CMSGCRED) 01788 struct cmsgcred *cred; 01789 01790 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr); 01791 pid_read = cred->cmcred_pid; 01792 uid_read = cred->cmcred_euid; 01793 #elif defined(LOCAL_CREDS) 01794 pid_read = DBUS_PID_UNSET; 01795 uid_read = cmsg.cred.sc_uid; 01796 /* Since we have already got the credentials from this socket, we can 01797 * disable its LOCAL_CREDS flag if it was ever set. */ 01798 _dbus_set_local_creds (client_fd, FALSE); 01799 #elif defined(HAVE_GETPEEREID) 01800 uid_t euid; 01801 gid_t egid; 01802 if (getpeereid (client_fd, &euid, &egid) == 0) 01803 { 01804 uid_read = euid; 01805 } 01806 else 01807 { 01808 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno)); 01809 } 01810 #elif defined(HAVE_GETPEERUCRED) 01811 ucred_t * ucred = NULL; 01812 if (getpeerucred (client_fd, &ucred) == 0) 01813 { 01814 pid_read = ucred_getpid (ucred); 01815 uid_read = ucred_geteuid (ucred); 01816 #ifdef HAVE_ADT 01817 /* generate audit session data based on socket ucred */ 01818 adt_session_data_t *adth = NULL; 01819 adt_export_data_t *data = NULL; 01820 size_t size = 0; 01821 if (adt_start_session (&adth, NULL, 0) || (adth == NULL)) 01822 { 01823 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno)); 01824 } 01825 else 01826 { 01827 if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 01828 { 01829 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno)); 01830 } 01831 else 01832 { 01833 size = adt_export_session_data (adth, &data); 01834 if (size <= 0) 01835 { 01836 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno)); 01837 } 01838 else 01839 { 01840 _dbus_credentials_add_adt_audit_data (credentials, data, size); 01841 free (data); 01842 } 01843 } 01844 (void) adt_end_session (adth); 01845 } 01846 #endif /* HAVE_ADT */ 01847 } 01848 else 01849 { 01850 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno)); 01851 } 01852 if (ucred != NULL) 01853 ucred_free (ucred); 01854 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ 01855 _dbus_verbose ("Socket credentials not supported on this OS\n"); 01856 #endif 01857 } 01858 01859 _dbus_verbose ("Credentials:" 01860 " pid "DBUS_PID_FORMAT 01861 " uid "DBUS_UID_FORMAT 01862 "\n", 01863 pid_read, 01864 uid_read); 01865 01866 if (pid_read != DBUS_PID_UNSET) 01867 { 01868 if (!_dbus_credentials_add_unix_pid (credentials, pid_read)) 01869 { 01870 _DBUS_SET_OOM (error); 01871 return FALSE; 01872 } 01873 } 01874 01875 if (uid_read != DBUS_UID_UNSET) 01876 { 01877 if (!_dbus_credentials_add_unix_uid (credentials, uid_read)) 01878 { 01879 _DBUS_SET_OOM (error); 01880 return FALSE; 01881 } 01882 } 01883 01884 return TRUE; 01885 } 01886 01904 dbus_bool_t 01905 _dbus_send_credentials_socket (int server_fd, 01906 DBusError *error) 01907 { 01908 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01909 01910 if (write_credentials_byte (server_fd, error)) 01911 return TRUE; 01912 else 01913 return FALSE; 01914 } 01915 01925 int 01926 _dbus_accept (int listen_fd) 01927 { 01928 int client_fd; 01929 struct sockaddr addr; 01930 socklen_t addrlen; 01931 #ifdef HAVE_ACCEPT4 01932 dbus_bool_t cloexec_done; 01933 #endif 01934 01935 addrlen = sizeof (addr); 01936 01937 retry: 01938 01939 #ifdef HAVE_ACCEPT4 01940 /* We assume that if accept4 is available SOCK_CLOEXEC is too */ 01941 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC); 01942 cloexec_done = client_fd >= 0; 01943 01944 if (client_fd < 0 && errno == ENOSYS) 01945 #endif 01946 { 01947 client_fd = accept (listen_fd, &addr, &addrlen); 01948 } 01949 01950 if (client_fd < 0) 01951 { 01952 if (errno == EINTR) 01953 goto retry; 01954 } 01955 01956 _dbus_verbose ("client fd %d accepted\n", client_fd); 01957 01958 #ifdef HAVE_ACCEPT4 01959 if (!cloexec_done) 01960 #endif 01961 { 01962 _dbus_fd_set_close_on_exec(client_fd); 01963 } 01964 01965 return client_fd; 01966 } 01967 01976 dbus_bool_t 01977 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error) 01978 { 01979 const char *directory; 01980 struct stat sb; 01981 01982 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01983 01984 directory = _dbus_string_get_const_data (dir); 01985 01986 if (stat (directory, &sb) < 0) 01987 { 01988 dbus_set_error (error, _dbus_error_from_errno (errno), 01989 "%s", _dbus_strerror (errno)); 01990 01991 return FALSE; 01992 } 01993 01994 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) || 01995 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode)) 01996 { 01997 dbus_set_error (error, DBUS_ERROR_FAILED, 01998 "%s directory is not private to the user", directory); 01999 return FALSE; 02000 } 02001 02002 return TRUE; 02003 } 02004 02005 static dbus_bool_t 02006 fill_user_info_from_passwd (struct passwd *p, 02007 DBusUserInfo *info, 02008 DBusError *error) 02009 { 02010 _dbus_assert (p->pw_name != NULL); 02011 _dbus_assert (p->pw_dir != NULL); 02012 02013 info->uid = p->pw_uid; 02014 info->primary_gid = p->pw_gid; 02015 info->username = _dbus_strdup (p->pw_name); 02016 info->homedir = _dbus_strdup (p->pw_dir); 02017 02018 if (info->username == NULL || 02019 info->homedir == NULL) 02020 { 02021 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02022 return FALSE; 02023 } 02024 02025 return TRUE; 02026 } 02027 02028 static dbus_bool_t 02029 fill_user_info (DBusUserInfo *info, 02030 dbus_uid_t uid, 02031 const DBusString *username, 02032 DBusError *error) 02033 { 02034 const char *username_c; 02035 02036 /* exactly one of username/uid provided */ 02037 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET); 02038 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET); 02039 02040 info->uid = DBUS_UID_UNSET; 02041 info->primary_gid = DBUS_GID_UNSET; 02042 info->group_ids = NULL; 02043 info->n_group_ids = 0; 02044 info->username = NULL; 02045 info->homedir = NULL; 02046 02047 if (username != NULL) 02048 username_c = _dbus_string_get_const_data (username); 02049 else 02050 username_c = NULL; 02051 02052 /* For now assuming that the getpwnam() and getpwuid() flavors 02053 * are always symmetrical, if not we have to add more configure 02054 * checks 02055 */ 02056 02057 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R) 02058 { 02059 struct passwd *p; 02060 int result; 02061 size_t buflen; 02062 char *buf; 02063 struct passwd p_str; 02064 02065 /* retrieve maximum needed size for buf */ 02066 buflen = sysconf (_SC_GETPW_R_SIZE_MAX); 02067 02068 /* sysconf actually returns a long, but everything else expects size_t, 02069 * so just recast here. 02070 * https://bugs.freedesktop.org/show_bug.cgi?id=17061 02071 */ 02072 if ((long) buflen <= 0) 02073 buflen = 1024; 02074 02075 result = -1; 02076 while (1) 02077 { 02078 buf = dbus_malloc (buflen); 02079 if (buf == NULL) 02080 { 02081 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02082 return FALSE; 02083 } 02084 02085 p = NULL; 02086 #ifdef HAVE_POSIX_GETPWNAM_R 02087 if (uid != DBUS_UID_UNSET) 02088 result = getpwuid_r (uid, &p_str, buf, buflen, 02089 &p); 02090 else 02091 result = getpwnam_r (username_c, &p_str, buf, buflen, 02092 &p); 02093 #else 02094 if (uid != DBUS_UID_UNSET) 02095 p = getpwuid_r (uid, &p_str, buf, buflen); 02096 else 02097 p = getpwnam_r (username_c, &p_str, buf, buflen); 02098 result = 0; 02099 #endif /* !HAVE_POSIX_GETPWNAM_R */ 02100 //Try a bigger buffer if ERANGE was returned 02101 if (result == ERANGE && buflen < 512 * 1024) 02102 { 02103 dbus_free (buf); 02104 buflen *= 2; 02105 } 02106 else 02107 { 02108 break; 02109 } 02110 } 02111 if (result == 0 && p == &p_str) 02112 { 02113 if (!fill_user_info_from_passwd (p, info, error)) 02114 { 02115 dbus_free (buf); 02116 return FALSE; 02117 } 02118 dbus_free (buf); 02119 } 02120 else 02121 { 02122 dbus_set_error (error, _dbus_error_from_errno (errno), 02123 "User \"%s\" unknown or no memory to allocate password entry\n", 02124 username_c ? username_c : "???"); 02125 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02126 dbus_free (buf); 02127 return FALSE; 02128 } 02129 } 02130 #else /* ! HAVE_GETPWNAM_R */ 02131 { 02132 /* I guess we're screwed on thread safety here */ 02133 struct passwd *p; 02134 02135 if (uid != DBUS_UID_UNSET) 02136 p = getpwuid (uid); 02137 else 02138 p = getpwnam (username_c); 02139 02140 if (p != NULL) 02141 { 02142 if (!fill_user_info_from_passwd (p, info, error)) 02143 { 02144 return FALSE; 02145 } 02146 } 02147 else 02148 { 02149 dbus_set_error (error, _dbus_error_from_errno (errno), 02150 "User \"%s\" unknown or no memory to allocate password entry\n", 02151 username_c ? username_c : "???"); 02152 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???"); 02153 return FALSE; 02154 } 02155 } 02156 #endif /* ! HAVE_GETPWNAM_R */ 02157 02158 /* Fill this in so we can use it to get groups */ 02159 username_c = info->username; 02160 02161 #ifdef HAVE_GETGROUPLIST 02162 { 02163 gid_t *buf; 02164 int buf_count; 02165 int i; 02166 int initial_buf_count; 02167 02168 initial_buf_count = 17; 02169 buf_count = initial_buf_count; 02170 buf = dbus_new (gid_t, buf_count); 02171 if (buf == NULL) 02172 { 02173 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02174 goto failed; 02175 } 02176 02177 if (getgrouplist (username_c, 02178 info->primary_gid, 02179 buf, &buf_count) < 0) 02180 { 02181 gid_t *new; 02182 /* Presumed cause of negative return code: buf has insufficient 02183 entries to hold the entire group list. The Linux behavior in this 02184 case is to pass back the actual number of groups in buf_count, but 02185 on Mac OS X 10.5, buf_count is unhelpfully left alone. 02186 So as a hack, try to help out a bit by guessing a larger 02187 number of groups, within reason.. might still fail, of course, 02188 but we can at least print a more informative message. I looked up 02189 the "right way" to do this by downloading Apple's own source code 02190 for the "id" command, and it turns out that they use an 02191 undocumented library function getgrouplist_2 (!) which is not 02192 declared in any header in /usr/include (!!). That did not seem 02193 like the way to go here. 02194 */ 02195 if (buf_count == initial_buf_count) 02196 { 02197 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */ 02198 } 02199 new = dbus_realloc (buf, buf_count * sizeof (buf[0])); 02200 if (new == NULL) 02201 { 02202 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02203 dbus_free (buf); 02204 goto failed; 02205 } 02206 02207 buf = new; 02208 02209 errno = 0; 02210 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0) 02211 { 02212 if (errno == 0) 02213 { 02214 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.", 02215 username_c, buf_count, buf_count); 02216 } 02217 else 02218 { 02219 dbus_set_error (error, 02220 _dbus_error_from_errno (errno), 02221 "Failed to get groups for username \"%s\" primary GID " 02222 DBUS_GID_FORMAT ": %s\n", 02223 username_c, info->primary_gid, 02224 _dbus_strerror (errno)); 02225 dbus_free (buf); 02226 goto failed; 02227 } 02228 } 02229 } 02230 02231 info->group_ids = dbus_new (dbus_gid_t, buf_count); 02232 if (info->group_ids == NULL) 02233 { 02234 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02235 dbus_free (buf); 02236 goto failed; 02237 } 02238 02239 for (i = 0; i < buf_count; ++i) 02240 info->group_ids[i] = buf[i]; 02241 02242 info->n_group_ids = buf_count; 02243 02244 dbus_free (buf); 02245 } 02246 #else /* HAVE_GETGROUPLIST */ 02247 { 02248 /* We just get the one group ID */ 02249 info->group_ids = dbus_new (dbus_gid_t, 1); 02250 if (info->group_ids == NULL) 02251 { 02252 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 02253 goto failed; 02254 } 02255 02256 info->n_group_ids = 1; 02257 02258 (info->group_ids)[0] = info->primary_gid; 02259 } 02260 #endif /* HAVE_GETGROUPLIST */ 02261 02262 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02263 02264 return TRUE; 02265 02266 failed: 02267 _DBUS_ASSERT_ERROR_IS_SET (error); 02268 return FALSE; 02269 } 02270 02279 dbus_bool_t 02280 _dbus_user_info_fill (DBusUserInfo *info, 02281 const DBusString *username, 02282 DBusError *error) 02283 { 02284 return fill_user_info (info, DBUS_UID_UNSET, 02285 username, error); 02286 } 02287 02296 dbus_bool_t 02297 _dbus_user_info_fill_uid (DBusUserInfo *info, 02298 dbus_uid_t uid, 02299 DBusError *error) 02300 { 02301 return fill_user_info (info, uid, 02302 NULL, error); 02303 } 02304 02312 dbus_bool_t 02313 _dbus_credentials_add_from_current_process (DBusCredentials *credentials) 02314 { 02315 /* The POSIX spec certainly doesn't promise this, but 02316 * we need these assertions to fail as soon as we're wrong about 02317 * it so we can do the porting fixups 02318 */ 02319 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t)); 02320 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t)); 02321 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t)); 02322 02323 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid())) 02324 return FALSE; 02325 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid())) 02326 return FALSE; 02327 02328 return TRUE; 02329 } 02330 02342 dbus_bool_t 02343 _dbus_append_user_from_current_process (DBusString *str) 02344 { 02345 return _dbus_string_append_uint (str, 02346 _dbus_geteuid ()); 02347 } 02348 02353 dbus_pid_t 02354 _dbus_getpid (void) 02355 { 02356 return getpid (); 02357 } 02358 02362 dbus_uid_t 02363 _dbus_getuid (void) 02364 { 02365 return getuid (); 02366 } 02367 02371 dbus_uid_t 02372 _dbus_geteuid (void) 02373 { 02374 return geteuid (); 02375 } 02376 02383 unsigned long 02384 _dbus_pid_for_log (void) 02385 { 02386 return getpid (); 02387 } 02388 02396 dbus_bool_t 02397 _dbus_parse_uid (const DBusString *uid_str, 02398 dbus_uid_t *uid) 02399 { 02400 int end; 02401 long val; 02402 02403 if (_dbus_string_get_length (uid_str) == 0) 02404 { 02405 _dbus_verbose ("UID string was zero length\n"); 02406 return FALSE; 02407 } 02408 02409 val = -1; 02410 end = 0; 02411 if (!_dbus_string_parse_int (uid_str, 0, &val, 02412 &end)) 02413 { 02414 _dbus_verbose ("could not parse string as a UID\n"); 02415 return FALSE; 02416 } 02417 02418 if (end != _dbus_string_get_length (uid_str)) 02419 { 02420 _dbus_verbose ("string contained trailing stuff after UID\n"); 02421 return FALSE; 02422 } 02423 02424 *uid = val; 02425 02426 return TRUE; 02427 } 02428 02429 #if !DBUS_USE_SYNC 02430 _DBUS_DEFINE_GLOBAL_LOCK (atomic); 02431 #endif 02432 02439 dbus_int32_t 02440 _dbus_atomic_inc (DBusAtomic *atomic) 02441 { 02442 #if DBUS_USE_SYNC 02443 return __sync_add_and_fetch(&atomic->value, 1)-1; 02444 #else 02445 dbus_int32_t res; 02446 _DBUS_LOCK (atomic); 02447 res = atomic->value; 02448 atomic->value += 1; 02449 _DBUS_UNLOCK (atomic); 02450 return res; 02451 #endif 02452 } 02453 02460 dbus_int32_t 02461 _dbus_atomic_dec (DBusAtomic *atomic) 02462 { 02463 #if DBUS_USE_SYNC 02464 return __sync_sub_and_fetch(&atomic->value, 1)+1; 02465 #else 02466 dbus_int32_t res; 02467 02468 _DBUS_LOCK (atomic); 02469 res = atomic->value; 02470 atomic->value -= 1; 02471 _DBUS_UNLOCK (atomic); 02472 return res; 02473 #endif 02474 } 02475 02483 dbus_int32_t 02484 _dbus_atomic_get (DBusAtomic *atomic) 02485 { 02486 #if DBUS_USE_SYNC 02487 __sync_synchronize (); 02488 return atomic->value; 02489 #else 02490 dbus_int32_t res; 02491 02492 _DBUS_LOCK (atomic); 02493 res = atomic->value; 02494 _DBUS_UNLOCK (atomic); 02495 return res; 02496 #endif 02497 } 02498 02507 int 02508 _dbus_poll (DBusPollFD *fds, 02509 int n_fds, 02510 int timeout_milliseconds) 02511 { 02512 #if defined(HAVE_POLL) && !defined(BROKEN_POLL) 02513 /* This big thing is a constant expression and should get optimized 02514 * out of existence. So it's more robust than a configure check at 02515 * no cost. 02516 */ 02517 if (_DBUS_POLLIN == POLLIN && 02518 _DBUS_POLLPRI == POLLPRI && 02519 _DBUS_POLLOUT == POLLOUT && 02520 _DBUS_POLLERR == POLLERR && 02521 _DBUS_POLLHUP == POLLHUP && 02522 _DBUS_POLLNVAL == POLLNVAL && 02523 sizeof (DBusPollFD) == sizeof (struct pollfd) && 02524 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) == 02525 _DBUS_STRUCT_OFFSET (struct pollfd, fd) && 02526 _DBUS_STRUCT_OFFSET (DBusPollFD, events) == 02527 _DBUS_STRUCT_OFFSET (struct pollfd, events) && 02528 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == 02529 _DBUS_STRUCT_OFFSET (struct pollfd, revents)) 02530 { 02531 return poll ((struct pollfd*) fds, 02532 n_fds, 02533 timeout_milliseconds); 02534 } 02535 else 02536 { 02537 /* We have to convert the DBusPollFD to an array of 02538 * struct pollfd, poll, and convert back. 02539 */ 02540 _dbus_warn ("didn't implement poll() properly for this system yet\n"); 02541 return -1; 02542 } 02543 #else /* ! HAVE_POLL */ 02544 02545 fd_set read_set, write_set, err_set; 02546 int max_fd = 0; 02547 int i; 02548 struct timeval tv; 02549 int ready; 02550 02551 FD_ZERO (&read_set); 02552 FD_ZERO (&write_set); 02553 FD_ZERO (&err_set); 02554 02555 for (i = 0; i < n_fds; i++) 02556 { 02557 DBusPollFD *fdp = &fds[i]; 02558 02559 if (fdp->events & _DBUS_POLLIN) 02560 FD_SET (fdp->fd, &read_set); 02561 02562 if (fdp->events & _DBUS_POLLOUT) 02563 FD_SET (fdp->fd, &write_set); 02564 02565 FD_SET (fdp->fd, &err_set); 02566 02567 max_fd = MAX (max_fd, fdp->fd); 02568 } 02569 02570 tv.tv_sec = timeout_milliseconds / 1000; 02571 tv.tv_usec = (timeout_milliseconds % 1000) * 1000; 02572 02573 ready = select (max_fd + 1, &read_set, &write_set, &err_set, 02574 timeout_milliseconds < 0 ? NULL : &tv); 02575 02576 if (ready > 0) 02577 { 02578 for (i = 0; i < n_fds; i++) 02579 { 02580 DBusPollFD *fdp = &fds[i]; 02581 02582 fdp->revents = 0; 02583 02584 if (FD_ISSET (fdp->fd, &read_set)) 02585 fdp->revents |= _DBUS_POLLIN; 02586 02587 if (FD_ISSET (fdp->fd, &write_set)) 02588 fdp->revents |= _DBUS_POLLOUT; 02589 02590 if (FD_ISSET (fdp->fd, &err_set)) 02591 fdp->revents |= _DBUS_POLLERR; 02592 } 02593 } 02594 02595 return ready; 02596 #endif 02597 } 02598 02606 void 02607 _dbus_get_monotonic_time (long *tv_sec, 02608 long *tv_usec) 02609 { 02610 #ifdef HAVE_MONOTONIC_CLOCK 02611 struct timespec ts; 02612 clock_gettime (CLOCK_MONOTONIC, &ts); 02613 02614 if (tv_sec) 02615 *tv_sec = ts.tv_sec; 02616 if (tv_usec) 02617 *tv_usec = ts.tv_nsec / 1000; 02618 #else 02619 struct timeval t; 02620 02621 gettimeofday (&t, NULL); 02622 02623 if (tv_sec) 02624 *tv_sec = t.tv_sec; 02625 if (tv_usec) 02626 *tv_usec = t.tv_usec; 02627 #endif 02628 } 02629 02637 void 02638 _dbus_get_real_time (long *tv_sec, 02639 long *tv_usec) 02640 { 02641 struct timeval t; 02642 02643 gettimeofday (&t, NULL); 02644 02645 if (tv_sec) 02646 *tv_sec = t.tv_sec; 02647 if (tv_usec) 02648 *tv_usec = t.tv_usec; 02649 } 02650 02659 dbus_bool_t 02660 _dbus_create_directory (const DBusString *filename, 02661 DBusError *error) 02662 { 02663 const char *filename_c; 02664 02665 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02666 02667 filename_c = _dbus_string_get_const_data (filename); 02668 02669 if (mkdir (filename_c, 0700) < 0) 02670 { 02671 if (errno == EEXIST) 02672 return TRUE; 02673 02674 dbus_set_error (error, DBUS_ERROR_FAILED, 02675 "Failed to create directory %s: %s\n", 02676 filename_c, _dbus_strerror (errno)); 02677 return FALSE; 02678 } 02679 else 02680 return TRUE; 02681 } 02682 02693 dbus_bool_t 02694 _dbus_concat_dir_and_file (DBusString *dir, 02695 const DBusString *next_component) 02696 { 02697 dbus_bool_t dir_ends_in_slash; 02698 dbus_bool_t file_starts_with_slash; 02699 02700 if (_dbus_string_get_length (dir) == 0 || 02701 _dbus_string_get_length (next_component) == 0) 02702 return TRUE; 02703 02704 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir, 02705 _dbus_string_get_length (dir) - 1); 02706 02707 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0); 02708 02709 if (dir_ends_in_slash && file_starts_with_slash) 02710 { 02711 _dbus_string_shorten (dir, 1); 02712 } 02713 else if (!(dir_ends_in_slash || file_starts_with_slash)) 02714 { 02715 if (!_dbus_string_append_byte (dir, '/')) 02716 return FALSE; 02717 } 02718 02719 return _dbus_string_copy (next_component, 0, dir, 02720 _dbus_string_get_length (dir)); 02721 } 02722 02724 #define NANOSECONDS_PER_SECOND 1000000000 02725 02726 #define MICROSECONDS_PER_SECOND 1000000 02727 02728 #define MILLISECONDS_PER_SECOND 1000 02729 02730 #define NANOSECONDS_PER_MILLISECOND 1000000 02731 02732 #define MICROSECONDS_PER_MILLISECOND 1000 02733 02738 void 02739 _dbus_sleep_milliseconds (int milliseconds) 02740 { 02741 #ifdef HAVE_NANOSLEEP 02742 struct timespec req; 02743 struct timespec rem; 02744 02745 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND; 02746 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND; 02747 rem.tv_sec = 0; 02748 rem.tv_nsec = 0; 02749 02750 while (nanosleep (&req, &rem) < 0 && errno == EINTR) 02751 req = rem; 02752 #elif defined (HAVE_USLEEP) 02753 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND); 02754 #else /* ! HAVE_USLEEP */ 02755 sleep (MAX (milliseconds / 1000, 1)); 02756 #endif 02757 } 02758 02759 static dbus_bool_t 02760 _dbus_generate_pseudorandom_bytes (DBusString *str, 02761 int n_bytes) 02762 { 02763 int old_len; 02764 char *p; 02765 02766 old_len = _dbus_string_get_length (str); 02767 02768 if (!_dbus_string_lengthen (str, n_bytes)) 02769 return FALSE; 02770 02771 p = _dbus_string_get_data_len (str, old_len, n_bytes); 02772 02773 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes); 02774 02775 return TRUE; 02776 } 02777 02786 dbus_bool_t 02787 _dbus_generate_random_bytes (DBusString *str, 02788 int n_bytes) 02789 { 02790 int old_len; 02791 int fd; 02792 02793 /* FALSE return means "no memory", if it could 02794 * mean something else then we'd need to return 02795 * a DBusError. So we always fall back to pseudorandom 02796 * if the I/O fails. 02797 */ 02798 02799 old_len = _dbus_string_get_length (str); 02800 fd = -1; 02801 02802 /* note, urandom on linux will fall back to pseudorandom */ 02803 fd = open ("/dev/urandom", O_RDONLY); 02804 if (fd < 0) 02805 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02806 02807 _dbus_verbose ("/dev/urandom fd %d opened\n", fd); 02808 02809 if (_dbus_read (fd, str, n_bytes) != n_bytes) 02810 { 02811 _dbus_close (fd, NULL); 02812 _dbus_string_set_length (str, old_len); 02813 return _dbus_generate_pseudorandom_bytes (str, n_bytes); 02814 } 02815 02816 _dbus_verbose ("Read %d bytes from /dev/urandom\n", 02817 n_bytes); 02818 02819 _dbus_close (fd, NULL); 02820 02821 return TRUE; 02822 } 02823 02829 void 02830 _dbus_exit (int code) 02831 { 02832 _exit (code); 02833 } 02834 02843 const char* 02844 _dbus_strerror (int error_number) 02845 { 02846 const char *msg; 02847 02848 msg = strerror (error_number); 02849 if (msg == NULL) 02850 msg = "unknown"; 02851 02852 return msg; 02853 } 02854 02858 void 02859 _dbus_disable_sigpipe (void) 02860 { 02861 signal (SIGPIPE, SIG_IGN); 02862 } 02863 02871 void 02872 _dbus_fd_set_close_on_exec (intptr_t fd) 02873 { 02874 int val; 02875 02876 val = fcntl (fd, F_GETFD, 0); 02877 02878 if (val < 0) 02879 return; 02880 02881 val |= FD_CLOEXEC; 02882 02883 fcntl (fd, F_SETFD, val); 02884 } 02885 02893 dbus_bool_t 02894 _dbus_close (int fd, 02895 DBusError *error) 02896 { 02897 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02898 02899 again: 02900 if (close (fd) < 0) 02901 { 02902 if (errno == EINTR) 02903 goto again; 02904 02905 dbus_set_error (error, _dbus_error_from_errno (errno), 02906 "Could not close fd %d", fd); 02907 return FALSE; 02908 } 02909 02910 return TRUE; 02911 } 02912 02920 int 02921 _dbus_dup(int fd, 02922 DBusError *error) 02923 { 02924 int new_fd; 02925 02926 #ifdef F_DUPFD_CLOEXEC 02927 dbus_bool_t cloexec_done; 02928 02929 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); 02930 cloexec_done = new_fd >= 0; 02931 02932 if (new_fd < 0 && errno == EINVAL) 02933 #endif 02934 { 02935 new_fd = fcntl(fd, F_DUPFD, 3); 02936 } 02937 02938 if (new_fd < 0) { 02939 02940 dbus_set_error (error, _dbus_error_from_errno (errno), 02941 "Could not duplicate fd %d", fd); 02942 return -1; 02943 } 02944 02945 #ifdef F_DUPFD_CLOEXEC 02946 if (!cloexec_done) 02947 #endif 02948 { 02949 _dbus_fd_set_close_on_exec(new_fd); 02950 } 02951 02952 return new_fd; 02953 } 02954 02962 dbus_bool_t 02963 _dbus_set_fd_nonblocking (int fd, 02964 DBusError *error) 02965 { 02966 int val; 02967 02968 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 02969 02970 val = fcntl (fd, F_GETFL, 0); 02971 if (val < 0) 02972 { 02973 dbus_set_error (error, _dbus_error_from_errno (errno), 02974 "Failed to get flags from file descriptor %d: %s", 02975 fd, _dbus_strerror (errno)); 02976 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 02977 _dbus_strerror (errno)); 02978 return FALSE; 02979 } 02980 02981 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 02982 { 02983 dbus_set_error (error, _dbus_error_from_errno (errno), 02984 "Failed to set nonblocking flag of file descriptor %d: %s", 02985 fd, _dbus_strerror (errno)); 02986 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 02987 fd, _dbus_strerror (errno)); 02988 02989 return FALSE; 02990 } 02991 02992 return TRUE; 02993 } 02994 03000 void 03001 _dbus_print_backtrace (void) 03002 { 03003 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC) 03004 void *bt[500]; 03005 int bt_size; 03006 int i; 03007 char **syms; 03008 03009 bt_size = backtrace (bt, 500); 03010 03011 syms = backtrace_symbols (bt, bt_size); 03012 03013 i = 0; 03014 while (i < bt_size) 03015 { 03016 /* don't use dbus_warn since it can _dbus_abort() */ 03017 fprintf (stderr, " %s\n", syms[i]); 03018 ++i; 03019 } 03020 fflush (stderr); 03021 03022 free (syms); 03023 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC) 03024 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n"); 03025 #else 03026 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n"); 03027 #endif 03028 } 03029 03042 dbus_bool_t 03043 _dbus_full_duplex_pipe (int *fd1, 03044 int *fd2, 03045 dbus_bool_t blocking, 03046 DBusError *error) 03047 { 03048 #ifdef HAVE_SOCKETPAIR 03049 int fds[2]; 03050 int retval; 03051 03052 #ifdef SOCK_CLOEXEC 03053 dbus_bool_t cloexec_done; 03054 03055 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds); 03056 cloexec_done = retval >= 0; 03057 03058 if (retval < 0 && errno == EINVAL) 03059 #endif 03060 { 03061 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 03062 } 03063 03064 if (retval < 0) 03065 { 03066 dbus_set_error (error, _dbus_error_from_errno (errno), 03067 "Could not create full-duplex pipe"); 03068 return FALSE; 03069 } 03070 03071 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03072 03073 #ifdef SOCK_CLOEXEC 03074 if (!cloexec_done) 03075 #endif 03076 { 03077 _dbus_fd_set_close_on_exec (fds[0]); 03078 _dbus_fd_set_close_on_exec (fds[1]); 03079 } 03080 03081 if (!blocking && 03082 (!_dbus_set_fd_nonblocking (fds[0], NULL) || 03083 !_dbus_set_fd_nonblocking (fds[1], NULL))) 03084 { 03085 dbus_set_error (error, _dbus_error_from_errno (errno), 03086 "Could not set full-duplex pipe nonblocking"); 03087 03088 _dbus_close (fds[0], NULL); 03089 _dbus_close (fds[1], NULL); 03090 03091 return FALSE; 03092 } 03093 03094 *fd1 = fds[0]; 03095 *fd2 = fds[1]; 03096 03097 _dbus_verbose ("full-duplex pipe %d <-> %d\n", 03098 *fd1, *fd2); 03099 03100 return TRUE; 03101 #else 03102 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n"); 03103 dbus_set_error (error, DBUS_ERROR_FAILED, 03104 "_dbus_full_duplex_pipe() not implemented on this OS"); 03105 return FALSE; 03106 #endif 03107 } 03108 03117 int 03118 _dbus_printf_string_upper_bound (const char *format, 03119 va_list args) 03120 { 03121 char static_buf[1024]; 03122 int bufsize = sizeof (static_buf); 03123 int len; 03124 va_list args_copy; 03125 03126 DBUS_VA_COPY (args_copy, args); 03127 len = vsnprintf (static_buf, bufsize, format, args_copy); 03128 va_end (args_copy); 03129 03130 /* If vsnprintf() returned non-negative, then either the string fits in 03131 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf 03132 * returns the number of characters that were needed, or this OS returns the 03133 * truncated length. 03134 * 03135 * We ignore the possibility that snprintf might just ignore the length and 03136 * overrun the buffer (64-bit Solaris 7), because that's pathological. 03137 * If your libc is really that bad, come back when you have a better one. */ 03138 if (len == bufsize) 03139 { 03140 /* This could be the truncated length (Tru64 and IRIX have this bug), 03141 * or the real length could be coincidentally the same. Which is it? 03142 * If vsnprintf returns the truncated length, we'll go to the slow 03143 * path. */ 03144 DBUS_VA_COPY (args_copy, args); 03145 03146 if (vsnprintf (static_buf, 1, format, args_copy) == 1) 03147 len = -1; 03148 03149 va_end (args_copy); 03150 } 03151 03152 /* If vsnprintf() returned negative, we have to do more work. 03153 * HP-UX returns negative. */ 03154 while (len < 0) 03155 { 03156 char *buf; 03157 03158 bufsize *= 2; 03159 03160 buf = dbus_malloc (bufsize); 03161 03162 if (buf == NULL) 03163 return -1; 03164 03165 DBUS_VA_COPY (args_copy, args); 03166 len = vsnprintf (buf, bufsize, format, args_copy); 03167 va_end (args_copy); 03168 03169 dbus_free (buf); 03170 03171 /* If the reported length is exactly the buffer size, round up to the 03172 * next size, in case vsnprintf has been returning the truncated 03173 * length */ 03174 if (len == bufsize) 03175 len = -1; 03176 } 03177 03178 return len; 03179 } 03180 03187 const char* 03188 _dbus_get_tmpdir(void) 03189 { 03190 static const char* tmpdir = NULL; 03191 03192 if (tmpdir == NULL) 03193 { 03194 /* TMPDIR is what glibc uses, then 03195 * glibc falls back to the P_tmpdir macro which 03196 * just expands to "/tmp" 03197 */ 03198 if (tmpdir == NULL) 03199 tmpdir = getenv("TMPDIR"); 03200 03201 /* These two env variables are probably 03202 * broken, but maybe some OS uses them? 03203 */ 03204 if (tmpdir == NULL) 03205 tmpdir = getenv("TMP"); 03206 if (tmpdir == NULL) 03207 tmpdir = getenv("TEMP"); 03208 03209 /* And this is the sane fallback. */ 03210 if (tmpdir == NULL) 03211 tmpdir = "/tmp"; 03212 } 03213 03214 _dbus_assert(tmpdir != NULL); 03215 03216 return tmpdir; 03217 } 03218 03238 static dbus_bool_t 03239 _read_subprocess_line_argv (const char *progpath, 03240 dbus_bool_t path_fallback, 03241 char * const *argv, 03242 DBusString *result, 03243 DBusError *error) 03244 { 03245 int result_pipe[2] = { -1, -1 }; 03246 int errors_pipe[2] = { -1, -1 }; 03247 pid_t pid; 03248 int ret; 03249 int status; 03250 int orig_len; 03251 03252 dbus_bool_t retval; 03253 sigset_t new_set, old_set; 03254 03255 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03256 retval = FALSE; 03257 03258 /* We need to block any existing handlers for SIGCHLD temporarily; they 03259 * will cause waitpid() below to fail. 03260 * https://bugs.freedesktop.org/show_bug.cgi?id=21347 03261 */ 03262 sigemptyset (&new_set); 03263 sigaddset (&new_set, SIGCHLD); 03264 sigprocmask (SIG_BLOCK, &new_set, &old_set); 03265 03266 orig_len = _dbus_string_get_length (result); 03267 03268 #define READ_END 0 03269 #define WRITE_END 1 03270 if (pipe (result_pipe) < 0) 03271 { 03272 dbus_set_error (error, _dbus_error_from_errno (errno), 03273 "Failed to create a pipe to call %s: %s", 03274 progpath, _dbus_strerror (errno)); 03275 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03276 progpath, _dbus_strerror (errno)); 03277 goto out; 03278 } 03279 if (pipe (errors_pipe) < 0) 03280 { 03281 dbus_set_error (error, _dbus_error_from_errno (errno), 03282 "Failed to create a pipe to call %s: %s", 03283 progpath, _dbus_strerror (errno)); 03284 _dbus_verbose ("Failed to create a pipe to call %s: %s\n", 03285 progpath, _dbus_strerror (errno)); 03286 goto out; 03287 } 03288 03289 pid = fork (); 03290 if (pid < 0) 03291 { 03292 dbus_set_error (error, _dbus_error_from_errno (errno), 03293 "Failed to fork() to call %s: %s", 03294 progpath, _dbus_strerror (errno)); 03295 _dbus_verbose ("Failed to fork() to call %s: %s\n", 03296 progpath, _dbus_strerror (errno)); 03297 goto out; 03298 } 03299 03300 if (pid == 0) 03301 { 03302 /* child process */ 03303 int fd; 03304 03305 fd = open ("/dev/null", O_RDWR); 03306 if (fd == -1) 03307 /* huh?! can't open /dev/null? */ 03308 _exit (1); 03309 03310 _dbus_verbose ("/dev/null fd %d opened\n", fd); 03311 03312 /* set-up stdXXX */ 03313 close (result_pipe[READ_END]); 03314 close (errors_pipe[READ_END]); 03315 close (0); /* close stdin */ 03316 close (1); /* close stdout */ 03317 close (2); /* close stderr */ 03318 03319 if (dup2 (fd, 0) == -1) 03320 _exit (1); 03321 if (dup2 (result_pipe[WRITE_END], 1) == -1) 03322 _exit (1); 03323 if (dup2 (errors_pipe[WRITE_END], 2) == -1) 03324 _exit (1); 03325 03326 _dbus_close_all (); 03327 03328 sigprocmask (SIG_SETMASK, &old_set, NULL); 03329 03330 /* If it looks fully-qualified, try execv first */ 03331 if (progpath[0] == '/') 03332 { 03333 execv (progpath, argv); 03334 /* Ok, that failed. Now if path_fallback is given, let's 03335 * try unqualified. This is mostly a hack to work 03336 * around systems which ship dbus-launch in /usr/bin 03337 * but everything else in /bin (because dbus-launch 03338 * depends on X11). 03339 */ 03340 if (path_fallback) 03341 /* We must have a slash, because we checked above */ 03342 execvp (strrchr (progpath, '/')+1, argv); 03343 } 03344 else 03345 execvp (progpath, argv); 03346 03347 /* still nothing, we failed */ 03348 _exit (1); 03349 } 03350 03351 /* parent process */ 03352 close (result_pipe[WRITE_END]); 03353 close (errors_pipe[WRITE_END]); 03354 result_pipe[WRITE_END] = -1; 03355 errors_pipe[WRITE_END] = -1; 03356 03357 ret = 0; 03358 do 03359 { 03360 ret = _dbus_read (result_pipe[READ_END], result, 1024); 03361 } 03362 while (ret > 0); 03363 03364 /* reap the child process to avoid it lingering as zombie */ 03365 do 03366 { 03367 ret = waitpid (pid, &status, 0); 03368 } 03369 while (ret == -1 && errno == EINTR); 03370 03371 /* We succeeded if the process exited with status 0 and 03372 anything was read */ 03373 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ) 03374 { 03375 /* The process ended with error */ 03376 DBusString error_message; 03377 if (!_dbus_string_init (&error_message)) 03378 { 03379 _DBUS_SET_OOM (error); 03380 goto out; 03381 } 03382 03383 ret = 0; 03384 do 03385 { 03386 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024); 03387 } 03388 while (ret > 0); 03389 03390 _dbus_string_set_length (result, orig_len); 03391 if (_dbus_string_get_length (&error_message) > 0) 03392 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03393 "%s terminated abnormally with the following error: %s", 03394 progpath, _dbus_string_get_data (&error_message)); 03395 else 03396 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED, 03397 "%s terminated abnormally without any error message", 03398 progpath); 03399 goto out; 03400 } 03401 03402 retval = TRUE; 03403 03404 out: 03405 sigprocmask (SIG_SETMASK, &old_set, NULL); 03406 03407 if (retval) 03408 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03409 else 03410 _DBUS_ASSERT_ERROR_IS_SET (error); 03411 03412 if (result_pipe[0] != -1) 03413 close (result_pipe[0]); 03414 if (result_pipe[1] != -1) 03415 close (result_pipe[1]); 03416 if (errors_pipe[0] != -1) 03417 close (errors_pipe[0]); 03418 if (errors_pipe[1] != -1) 03419 close (errors_pipe[1]); 03420 03421 return retval; 03422 } 03423 03435 dbus_bool_t 03436 _dbus_get_autolaunch_address (const char *scope, 03437 DBusString *address, 03438 DBusError *error) 03439 { 03440 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH 03441 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch, 03442 * but that's done elsewhere, and if it worked, this function wouldn't 03443 * be called.) */ 03444 const char *display; 03445 static char *argv[6]; 03446 int i; 03447 DBusString uuid; 03448 dbus_bool_t retval; 03449 03450 if (_dbus_check_setuid ()) 03451 { 03452 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03453 "Unable to autolaunch when setuid"); 03454 return FALSE; 03455 } 03456 03457 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03458 retval = FALSE; 03459 03460 /* fd.o #19997: if $DISPLAY isn't set to something useful, then 03461 * dbus-launch-x11 is just going to fail. Rather than trying to 03462 * run it, we might as well bail out early with a nice error. */ 03463 display = _dbus_getenv ("DISPLAY"); 03464 03465 if (display == NULL || display[0] == '\0') 03466 { 03467 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03468 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11"); 03469 return FALSE; 03470 } 03471 03472 if (!_dbus_string_init (&uuid)) 03473 { 03474 _DBUS_SET_OOM (error); 03475 return FALSE; 03476 } 03477 03478 if (!_dbus_get_local_machine_uuid_encoded (&uuid)) 03479 { 03480 _DBUS_SET_OOM (error); 03481 goto out; 03482 } 03483 03484 i = 0; 03485 argv[i] = "dbus-launch"; 03486 ++i; 03487 argv[i] = "--autolaunch"; 03488 ++i; 03489 argv[i] = _dbus_string_get_data (&uuid); 03490 ++i; 03491 argv[i] = "--binary-syntax"; 03492 ++i; 03493 argv[i] = "--close-stderr"; 03494 ++i; 03495 argv[i] = NULL; 03496 ++i; 03497 03498 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03499 03500 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch", 03501 TRUE, 03502 argv, address, error); 03503 03504 out: 03505 _dbus_string_free (&uuid); 03506 return retval; 03507 #else 03508 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03509 "Using X11 for dbus-daemon autolaunch was disabled at compile time, " 03510 "set your DBUS_SESSION_BUS_ADDRESS instead"); 03511 return FALSE; 03512 #endif 03513 } 03514 03533 dbus_bool_t 03534 _dbus_read_local_machine_uuid (DBusGUID *machine_id, 03535 dbus_bool_t create_if_not_found, 03536 DBusError *error) 03537 { 03538 DBusString filename; 03539 dbus_bool_t b; 03540 03541 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE); 03542 03543 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error); 03544 if (b) 03545 return TRUE; 03546 03547 dbus_error_free (error); 03548 03549 /* Fallback to the system machine ID */ 03550 _dbus_string_init_const (&filename, "/etc/machine-id"); 03551 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error); 03552 } 03553 03554 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services" 03555 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services" 03556 03563 dbus_bool_t 03564 _dbus_lookup_launchd_socket (DBusString *socket_path, 03565 const char *launchd_env_var, 03566 DBusError *error) 03567 { 03568 #ifdef DBUS_ENABLE_LAUNCHD 03569 char *argv[4]; 03570 int i; 03571 03572 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03573 03574 if (_dbus_check_setuid ()) 03575 { 03576 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03577 "Unable to find launchd socket when setuid"); 03578 return FALSE; 03579 } 03580 03581 i = 0; 03582 argv[i] = "launchctl"; 03583 ++i; 03584 argv[i] = "getenv"; 03585 ++i; 03586 argv[i] = (char*)launchd_env_var; 03587 ++i; 03588 argv[i] = NULL; 03589 ++i; 03590 03591 _dbus_assert (i == _DBUS_N_ELEMENTS (argv)); 03592 03593 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error)) 03594 { 03595 return FALSE; 03596 } 03597 03598 /* no error, but no result either */ 03599 if (_dbus_string_get_length(socket_path) == 0) 03600 { 03601 return FALSE; 03602 } 03603 03604 /* strip the carriage-return */ 03605 _dbus_string_shorten(socket_path, 1); 03606 return TRUE; 03607 #else /* DBUS_ENABLE_LAUNCHD */ 03608 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED, 03609 "can't lookup socket from launchd; launchd support not compiled in"); 03610 return FALSE; 03611 #endif 03612 } 03613 03614 #ifdef DBUS_ENABLE_LAUNCHD 03615 static dbus_bool_t 03616 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error) 03617 { 03618 dbus_bool_t valid_socket; 03619 DBusString socket_path; 03620 03621 if (_dbus_check_setuid ()) 03622 { 03623 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED, 03624 "Unable to find launchd socket when setuid"); 03625 return FALSE; 03626 } 03627 03628 if (!_dbus_string_init (&socket_path)) 03629 { 03630 _DBUS_SET_OOM (error); 03631 return FALSE; 03632 } 03633 03634 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error); 03635 03636 if (dbus_error_is_set(error)) 03637 { 03638 _dbus_string_free(&socket_path); 03639 return FALSE; 03640 } 03641 03642 if (!valid_socket) 03643 { 03644 dbus_set_error(error, "no socket path", 03645 "launchd did not provide a socket path, " 03646 "verify that org.freedesktop.dbus-session.plist is loaded!"); 03647 _dbus_string_free(&socket_path); 03648 return FALSE; 03649 } 03650 if (!_dbus_string_append (address, "unix:path=")) 03651 { 03652 _DBUS_SET_OOM (error); 03653 _dbus_string_free(&socket_path); 03654 return FALSE; 03655 } 03656 if (!_dbus_string_copy (&socket_path, 0, address, 03657 _dbus_string_get_length (address))) 03658 { 03659 _DBUS_SET_OOM (error); 03660 _dbus_string_free(&socket_path); 03661 return FALSE; 03662 } 03663 03664 _dbus_string_free(&socket_path); 03665 return TRUE; 03666 } 03667 #endif 03668 03688 dbus_bool_t 03689 _dbus_lookup_session_address (dbus_bool_t *supported, 03690 DBusString *address, 03691 DBusError *error) 03692 { 03693 #ifdef DBUS_ENABLE_LAUNCHD 03694 *supported = TRUE; 03695 return _dbus_lookup_session_address_launchd (address, error); 03696 #else 03697 /* On non-Mac Unix platforms, if the session address isn't already 03698 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and 03699 * fall back to the autolaunch: global default; see 03700 * init_session_address in dbus/dbus-bus.c. */ 03701 *supported = FALSE; 03702 return TRUE; 03703 #endif 03704 } 03705 03723 dbus_bool_t 03724 _dbus_get_standard_session_servicedirs (DBusList **dirs) 03725 { 03726 const char *xdg_data_home; 03727 const char *xdg_data_dirs; 03728 DBusString servicedir_path; 03729 03730 if (!_dbus_string_init (&servicedir_path)) 03731 return FALSE; 03732 03733 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME"); 03734 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS"); 03735 03736 if (xdg_data_home != NULL) 03737 { 03738 if (!_dbus_string_append (&servicedir_path, xdg_data_home)) 03739 goto oom; 03740 } 03741 else 03742 { 03743 const DBusString *homedir; 03744 DBusString local_share; 03745 03746 if (!_dbus_homedir_from_current_process (&homedir)) 03747 goto oom; 03748 03749 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir))) 03750 goto oom; 03751 03752 _dbus_string_init_const (&local_share, "/.local/share"); 03753 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share)) 03754 goto oom; 03755 } 03756 03757 if (!_dbus_string_append (&servicedir_path, ":")) 03758 goto oom; 03759 03760 if (xdg_data_dirs != NULL) 03761 { 03762 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs)) 03763 goto oom; 03764 03765 if (!_dbus_string_append (&servicedir_path, ":")) 03766 goto oom; 03767 } 03768 else 03769 { 03770 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:")) 03771 goto oom; 03772 } 03773 03774 /* 03775 * add configured datadir to defaults 03776 * this may be the same as an xdg dir 03777 * however the config parser should take 03778 * care of duplicates 03779 */ 03780 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR)) 03781 goto oom; 03782 03783 if (!_dbus_split_paths_and_append (&servicedir_path, 03784 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 03785 dirs)) 03786 goto oom; 03787 03788 _dbus_string_free (&servicedir_path); 03789 return TRUE; 03790 03791 oom: 03792 _dbus_string_free (&servicedir_path); 03793 return FALSE; 03794 } 03795 03796 03815 dbus_bool_t 03816 _dbus_get_standard_system_servicedirs (DBusList **dirs) 03817 { 03818 /* 03819 * DBUS_DATADIR may be the same as one of the standard directories. However, 03820 * the config parser should take care of the duplicates. 03821 * 03822 * Also, append /lib as counterpart of /usr/share on the root 03823 * directory (the root directory does not know /share), in order to 03824 * facilitate early boot system bus activation where /usr might not 03825 * be available. 03826 */ 03827 static const char standard_search_path[] = 03828 "/usr/local/share:" 03829 "/usr/share:" 03830 DBUS_DATADIR ":" 03831 "/lib"; 03832 DBusString servicedir_path; 03833 03834 _dbus_string_init_const (&servicedir_path, standard_search_path); 03835 03836 return _dbus_split_paths_and_append (&servicedir_path, 03837 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 03838 dirs); 03839 } 03840 03849 dbus_bool_t 03850 _dbus_append_system_config_file (DBusString *str) 03851 { 03852 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE); 03853 } 03854 03861 dbus_bool_t 03862 _dbus_append_session_config_file (DBusString *str) 03863 { 03864 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE); 03865 } 03866 03874 void 03875 _dbus_flush_caches (void) 03876 { 03877 _dbus_user_database_flush_system (); 03878 } 03879 03893 dbus_bool_t 03894 _dbus_append_keyring_directory_for_credentials (DBusString *directory, 03895 DBusCredentials *credentials) 03896 { 03897 DBusString homedir; 03898 DBusString dotdir; 03899 dbus_uid_t uid; 03900 03901 _dbus_assert (credentials != NULL); 03902 _dbus_assert (!_dbus_credentials_are_anonymous (credentials)); 03903 03904 if (!_dbus_string_init (&homedir)) 03905 return FALSE; 03906 03907 uid = _dbus_credentials_get_unix_uid (credentials); 03908 _dbus_assert (uid != DBUS_UID_UNSET); 03909 03910 if (!_dbus_homedir_from_uid (uid, &homedir)) 03911 goto failed; 03912 03913 #ifdef DBUS_BUILD_TESTS 03914 { 03915 const char *override; 03916 03917 override = _dbus_getenv ("DBUS_TEST_HOMEDIR"); 03918 if (override != NULL && *override != '\0') 03919 { 03920 _dbus_string_set_length (&homedir, 0); 03921 if (!_dbus_string_append (&homedir, override)) 03922 goto failed; 03923 03924 _dbus_verbose ("Using fake homedir for testing: %s\n", 03925 _dbus_string_get_const_data (&homedir)); 03926 } 03927 else 03928 { 03929 static dbus_bool_t already_warned = FALSE; 03930 if (!already_warned) 03931 { 03932 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n"); 03933 already_warned = TRUE; 03934 } 03935 } 03936 } 03937 #endif 03938 03939 _dbus_string_init_const (&dotdir, ".dbus-keyrings"); 03940 if (!_dbus_concat_dir_and_file (&homedir, 03941 &dotdir)) 03942 goto failed; 03943 03944 if (!_dbus_string_copy (&homedir, 0, 03945 directory, _dbus_string_get_length (directory))) { 03946 goto failed; 03947 } 03948 03949 _dbus_string_free (&homedir); 03950 return TRUE; 03951 03952 failed: 03953 _dbus_string_free (&homedir); 03954 return FALSE; 03955 } 03956 03957 //PENDING(kdab) docs 03958 dbus_bool_t 03959 _dbus_daemon_publish_session_bus_address (const char* addr, 03960 const char *scope) 03961 { 03962 return TRUE; 03963 } 03964 03965 //PENDING(kdab) docs 03966 void 03967 _dbus_daemon_unpublish_session_bus_address (void) 03968 { 03969 03970 } 03971 03978 dbus_bool_t 03979 _dbus_get_is_errno_eagain_or_ewouldblock (void) 03980 { 03981 return errno == EAGAIN || errno == EWOULDBLOCK; 03982 } 03983 03991 dbus_bool_t 03992 _dbus_delete_directory (const DBusString *filename, 03993 DBusError *error) 03994 { 03995 const char *filename_c; 03996 03997 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 03998 03999 filename_c = _dbus_string_get_const_data (filename); 04000 04001 if (rmdir (filename_c) != 0) 04002 { 04003 dbus_set_error (error, DBUS_ERROR_FAILED, 04004 "Failed to remove directory %s: %s\n", 04005 filename_c, _dbus_strerror (errno)); 04006 return FALSE; 04007 } 04008 04009 return TRUE; 04010 } 04011 04019 dbus_bool_t 04020 _dbus_socket_can_pass_unix_fd(int fd) { 04021 04022 #ifdef SCM_RIGHTS 04023 union { 04024 struct sockaddr sa; 04025 struct sockaddr_storage storage; 04026 struct sockaddr_un un; 04027 } sa_buf; 04028 04029 socklen_t sa_len = sizeof(sa_buf); 04030 04031 _DBUS_ZERO(sa_buf); 04032 04033 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0) 04034 return FALSE; 04035 04036 return sa_buf.sa.sa_family == AF_UNIX; 04037 04038 #else 04039 return FALSE; 04040 04041 #endif 04042 } 04043 04044 04045 /* 04046 * replaces the term DBUS_PREFIX in configure_time_path by the 04047 * current dbus installation directory. On unix this function is a noop 04048 * 04049 * @param configure_time_path 04050 * @return real path 04051 */ 04052 const char * 04053 _dbus_replace_install_prefix (const char *configure_time_path) 04054 { 04055 return configure_time_path; 04056 } 04057 04062 void 04063 _dbus_close_all (void) 04064 { 04065 int maxfds, i; 04066 04067 #ifdef __linux__ 04068 DIR *d; 04069 04070 /* On Linux we can optimize this a bit if /proc is available. If it 04071 isn't available, fall back to the brute force way. */ 04072 04073 d = opendir ("/proc/self/fd"); 04074 if (d) 04075 { 04076 for (;;) 04077 { 04078 struct dirent buf, *de; 04079 int k, fd; 04080 long l; 04081 char *e = NULL; 04082 04083 k = readdir_r (d, &buf, &de); 04084 if (k != 0 || !de) 04085 break; 04086 04087 if (de->d_name[0] == '.') 04088 continue; 04089 04090 errno = 0; 04091 l = strtol (de->d_name, &e, 10); 04092 if (errno != 0 || e == NULL || *e != '\0') 04093 continue; 04094 04095 fd = (int) l; 04096 if (fd < 3) 04097 continue; 04098 04099 if (fd == dirfd (d)) 04100 continue; 04101 04102 close (fd); 04103 } 04104 04105 closedir (d); 04106 return; 04107 } 04108 #endif 04109 04110 maxfds = sysconf (_SC_OPEN_MAX); 04111 04112 /* Pick something reasonable if for some reason sysconf says 04113 * unlimited. 04114 */ 04115 if (maxfds < 0) 04116 maxfds = 1024; 04117 04118 /* close all inherited fds */ 04119 for (i = 3; i < maxfds; i++) 04120 close (i); 04121 } 04122 04132 dbus_bool_t 04133 _dbus_check_setuid (void) 04134 { 04135 /* TODO: get __libc_enable_secure exported from glibc. 04136 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1 04137 */ 04138 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE) 04139 { 04140 /* See glibc/include/unistd.h */ 04141 extern int __libc_enable_secure; 04142 return __libc_enable_secure; 04143 } 04144 #elif defined(HAVE_ISSETUGID) 04145 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */ 04146 return issetugid (); 04147 #else 04148 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */ 04149 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */ 04150 04151 static dbus_bool_t check_setuid_initialised; 04152 static dbus_bool_t is_setuid; 04153 04154 if (_DBUS_UNLIKELY (!check_setuid_initialised)) 04155 { 04156 #ifdef HAVE_GETRESUID 04157 if (getresuid (&ruid, &euid, &suid) != 0 || 04158 getresgid (&rgid, &egid, &sgid) != 0) 04159 #endif /* HAVE_GETRESUID */ 04160 { 04161 suid = ruid = getuid (); 04162 sgid = rgid = getgid (); 04163 euid = geteuid (); 04164 egid = getegid (); 04165 } 04166 04167 check_setuid_initialised = TRUE; 04168 is_setuid = (ruid != euid || ruid != suid || 04169 rgid != egid || rgid != sgid); 04170 04171 } 04172 return is_setuid; 04173 #endif 04174 } 04175 04176 /* tests in dbus-sysdeps-util.c */