00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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-file.h"
00033 #include "dbus-transport.h"
00034 #include "dbus-string.h"
00035 #include "dbus-userdb.h"
00036 #include "dbus-list.h"
00037 #include "dbus-credentials.h"
00038 #include "dbus-nonce.h"
00039
00040 #include <dlfcn.h>
00041 #include <sys/types.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <signal.h>
00045 #include <unistd.h>
00046 #include <stdio.h>
00047 #include <fcntl.h>
00048 #include <sys/socket.h>
00049 #include <dirent.h>
00050 #include <sys/un.h>
00051 #include <pwd.h>
00052 #include <time.h>
00053 #include <locale.h>
00054 #include <sys/time.h>
00055 #include <sys/stat.h>
00056 #include <sys/wait.h>
00057 #include <netinet/in.h>
00058 #include <netinet/tcp.h>
00059 #include <netdb.h>
00060 #include <grp.h>
00061 #include <arpa/inet.h>
00062
00063 #ifdef HAVE_ERRNO_H
00064 #include <errno.h>
00065 #endif
00066 #ifdef HAVE_WRITEV
00067 #include <sys/uio.h>
00068 #endif
00069 #ifdef HAVE_POLL
00070 #include <sys/poll.h>
00071 #endif
00072 #ifdef HAVE_BACKTRACE
00073 #include <execinfo.h>
00074 #endif
00075 #ifdef HAVE_GETPEERUCRED
00076 #include <ucred.h>
00077 #endif
00078 #ifdef HAVE_ALLOCA_H
00079 #include <alloca.h>
00080 #endif
00081
00082 #ifdef HAVE_ADT
00083 #include <bsm/adt.h>
00084 #endif
00085
00086 #ifdef HAVE_SYSTEMD
00087 #include <systemd/sd-daemon.h>
00088 #endif
00089
00090 #if !DBUS_USE_SYNC
00091 #include <pthread.h>
00092 #endif
00093
00094 #ifndef O_BINARY
00095 #define O_BINARY 0
00096 #endif
00097
00098 #ifndef AI_ADDRCONFIG
00099 #define AI_ADDRCONFIG 0
00100 #endif
00101
00102 #ifndef HAVE_SOCKLEN_T
00103 #define socklen_t int
00104 #endif
00105
00106 #if defined (__sun) || defined (__sun__)
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 # ifndef CMSG_ALIGN
00118 # ifdef __sun__
00119 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00120 # else
00121
00122 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00123 ~(sizeof (long) - 1))
00124 # endif
00125 # endif
00126
00127 # ifndef CMSG_SPACE
00128 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00129 CMSG_ALIGN (len))
00130 # endif
00131
00132 # ifndef CMSG_LEN
00133 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00134 # endif
00135
00136 #endif
00137
00152 dbus_bool_t
00153 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
00154 const char **error_str_p)
00155 {
00156 static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
00157 DBUS_FORCE_STDOUT_NULL,
00158 DBUS_FORCE_STDERR_NULL };
00159
00160 const char *error_str = "Failed mysteriously";
00161 int devnull = -1;
00162 int saved_errno;
00163
00164 _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
00165 _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
00166 _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
00167 int i;
00168
00169 for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
00170 {
00171
00172
00173
00174 if (devnull < i)
00175 devnull = open ("/dev/null", O_RDWR);
00176
00177 if (devnull < 0)
00178 {
00179 error_str = "Failed to open /dev/null";
00180 goto out;
00181 }
00182
00183
00184
00185
00186 _dbus_assert (devnull >= i);
00187
00188 if (devnull != i && (flags & relevant_flag[i]) != 0)
00189 {
00190 if (dup2 (devnull, i) < 0)
00191 {
00192 error_str = "Failed to dup2 /dev/null onto a standard fd";
00193 goto out;
00194 }
00195 }
00196 }
00197
00198 error_str = NULL;
00199
00200 out:
00201 saved_errno = errno;
00202
00203 if (devnull > STDERR_FILENO)
00204 close (devnull);
00205
00206 if (error_str_p != NULL)
00207 *error_str_p = error_str;
00208
00209 errno = saved_errno;
00210 return (error_str == NULL);
00211 }
00212
00213 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
00214 DBusError *error);
00215
00216 static dbus_bool_t
00217 _dbus_open_socket (int *fd_p,
00218 int domain,
00219 int type,
00220 int protocol,
00221 DBusError *error)
00222 {
00223 #ifdef SOCK_CLOEXEC
00224 dbus_bool_t cloexec_done;
00225
00226 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00227 cloexec_done = *fd_p >= 0;
00228
00229
00230 if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
00231 #endif
00232 {
00233 *fd_p = socket (domain, type, protocol);
00234 }
00235
00236 if (*fd_p >= 0)
00237 {
00238 #ifdef SOCK_CLOEXEC
00239 if (!cloexec_done)
00240 #endif
00241 {
00242 _dbus_fd_set_close_on_exec(*fd_p);
00243 }
00244
00245 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00246 return TRUE;
00247 }
00248 else
00249 {
00250 dbus_set_error(error,
00251 _dbus_error_from_errno (errno),
00252 "Failed to open socket: %s",
00253 _dbus_strerror (errno));
00254 return FALSE;
00255 }
00256 }
00257
00268 static dbus_bool_t
00269 _dbus_open_unix_socket (int *fd,
00270 DBusError *error)
00271 {
00272 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00273 }
00274
00283 dbus_bool_t
00284 _dbus_close_socket (DBusSocket fd,
00285 DBusError *error)
00286 {
00287 return _dbus_close (fd.fd, error);
00288 }
00289
00299 int
00300 _dbus_read_socket (DBusSocket fd,
00301 DBusString *buffer,
00302 int count)
00303 {
00304 return _dbus_read (fd.fd, buffer, count);
00305 }
00306
00317 int
00318 _dbus_write_socket (DBusSocket fd,
00319 const DBusString *buffer,
00320 int start,
00321 int len)
00322 {
00323 #if HAVE_DECL_MSG_NOSIGNAL
00324 const char *data;
00325 int bytes_written;
00326
00327 data = _dbus_string_get_const_data_len (buffer, start, len);
00328
00329 again:
00330
00331 bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
00332
00333 if (bytes_written < 0 && errno == EINTR)
00334 goto again;
00335
00336 return bytes_written;
00337
00338 #else
00339 return _dbus_write (fd.fd, buffer, start, len);
00340 #endif
00341 }
00342
00355 int
00356 _dbus_read_socket_with_unix_fds (DBusSocket fd,
00357 DBusString *buffer,
00358 int count,
00359 int *fds,
00360 int *n_fds) {
00361 #ifndef HAVE_UNIX_FD_PASSING
00362 int r;
00363
00364 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00365 return r;
00366
00367 *n_fds = 0;
00368 return r;
00369
00370 #else
00371 int bytes_read;
00372 int start;
00373 struct msghdr m;
00374 struct iovec iov;
00375
00376 _dbus_assert (count >= 0);
00377 _dbus_assert (*n_fds >= 0);
00378
00379 start = _dbus_string_get_length (buffer);
00380
00381 if (!_dbus_string_lengthen (buffer, count))
00382 {
00383 errno = ENOMEM;
00384 return -1;
00385 }
00386
00387 _DBUS_ZERO(iov);
00388 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00389 iov.iov_len = count;
00390
00391 _DBUS_ZERO(m);
00392 m.msg_iov = &iov;
00393 m.msg_iovlen = 1;
00394
00395
00396
00397
00398
00399 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00400
00401
00402
00403 m.msg_control = alloca(m.msg_controllen);
00404 memset(m.msg_control, 0, m.msg_controllen);
00405
00406
00407
00408
00409
00410 m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
00411
00412 again:
00413
00414 bytes_read = recvmsg (fd.fd, &m, 0
00415 #ifdef MSG_CMSG_CLOEXEC
00416 |MSG_CMSG_CLOEXEC
00417 #endif
00418 );
00419
00420 if (bytes_read < 0)
00421 {
00422 if (errno == EINTR)
00423 goto again;
00424 else
00425 {
00426
00427 _dbus_string_set_length (buffer, start);
00428 return -1;
00429 }
00430 }
00431 else
00432 {
00433 struct cmsghdr *cm;
00434 dbus_bool_t found = FALSE;
00435
00436 if (m.msg_flags & MSG_CTRUNC)
00437 {
00438
00439
00440
00441
00442
00443 errno = ENOSPC;
00444 _dbus_string_set_length (buffer, start);
00445 return -1;
00446 }
00447
00448 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00449 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00450 {
00451 size_t i;
00452 int *payload = (int *) CMSG_DATA (cm);
00453 size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
00454 size_t payload_len_fds = payload_len_bytes / sizeof (int);
00455 size_t fds_to_use;
00456
00457
00458
00459
00460 _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
00461
00462 if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
00463 {
00464
00465 fds_to_use = payload_len_fds;
00466 }
00467 else
00468 {
00469
00470
00471
00472
00473 fds_to_use = (size_t) *n_fds;
00474
00475
00476
00477
00478 for (i = fds_to_use; i < payload_len_fds; i++)
00479 {
00480 close (payload[i]);
00481 }
00482 }
00483
00484 memcpy (fds, payload, fds_to_use * sizeof (int));
00485 found = TRUE;
00486
00487
00488 *n_fds = (int) fds_to_use;
00489
00490
00491
00492
00493 for (i = 0; i < fds_to_use; i++)
00494 _dbus_fd_set_close_on_exec(fds[i]);
00495
00496 break;
00497 }
00498
00499 if (!found)
00500 *n_fds = 0;
00501
00502
00503 _dbus_string_set_length (buffer, start + bytes_read);
00504
00505 #if 0
00506 if (bytes_read > 0)
00507 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00508 #endif
00509
00510 return bytes_read;
00511 }
00512 #endif
00513 }
00514
00515 int
00516 _dbus_write_socket_with_unix_fds(DBusSocket fd,
00517 const DBusString *buffer,
00518 int start,
00519 int len,
00520 const int *fds,
00521 int n_fds) {
00522
00523 #ifndef HAVE_UNIX_FD_PASSING
00524
00525 if (n_fds > 0) {
00526 errno = ENOTSUP;
00527 return -1;
00528 }
00529
00530 return _dbus_write_socket(fd, buffer, start, len);
00531 #else
00532 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00533 #endif
00534 }
00535
00536 int
00537 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
00538 const DBusString *buffer1,
00539 int start1,
00540 int len1,
00541 const DBusString *buffer2,
00542 int start2,
00543 int len2,
00544 const int *fds,
00545 int n_fds) {
00546
00547 #ifndef HAVE_UNIX_FD_PASSING
00548
00549 if (n_fds > 0) {
00550 errno = ENOTSUP;
00551 return -1;
00552 }
00553
00554 return _dbus_write_socket_two(fd,
00555 buffer1, start1, len1,
00556 buffer2, start2, len2);
00557 #else
00558
00559 struct msghdr m;
00560 struct cmsghdr *cm;
00561 struct iovec iov[2];
00562 int bytes_written;
00563
00564 _dbus_assert (len1 >= 0);
00565 _dbus_assert (len2 >= 0);
00566 _dbus_assert (n_fds >= 0);
00567
00568 _DBUS_ZERO(iov);
00569 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00570 iov[0].iov_len = len1;
00571
00572 if (buffer2)
00573 {
00574 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00575 iov[1].iov_len = len2;
00576 }
00577
00578 _DBUS_ZERO(m);
00579 m.msg_iov = iov;
00580 m.msg_iovlen = buffer2 ? 2 : 1;
00581
00582 if (n_fds > 0)
00583 {
00584 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00585 m.msg_control = alloca(m.msg_controllen);
00586 memset(m.msg_control, 0, m.msg_controllen);
00587
00588 cm = CMSG_FIRSTHDR(&m);
00589 cm->cmsg_level = SOL_SOCKET;
00590 cm->cmsg_type = SCM_RIGHTS;
00591 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00592 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00593 }
00594
00595 again:
00596
00597 bytes_written = sendmsg (fd.fd, &m, 0
00598 #if HAVE_DECL_MSG_NOSIGNAL
00599 |MSG_NOSIGNAL
00600 #endif
00601 );
00602
00603 if (bytes_written < 0 && errno == EINTR)
00604 goto again;
00605
00606 #if 0
00607 if (bytes_written > 0)
00608 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00609 #endif
00610
00611 return bytes_written;
00612 #endif
00613 }
00614
00628 int
00629 _dbus_write_socket_two (DBusSocket fd,
00630 const DBusString *buffer1,
00631 int start1,
00632 int len1,
00633 const DBusString *buffer2,
00634 int start2,
00635 int len2)
00636 {
00637 #if HAVE_DECL_MSG_NOSIGNAL
00638 struct iovec vectors[2];
00639 const char *data1;
00640 const char *data2;
00641 int bytes_written;
00642 struct msghdr m;
00643
00644 _dbus_assert (buffer1 != NULL);
00645 _dbus_assert (start1 >= 0);
00646 _dbus_assert (start2 >= 0);
00647 _dbus_assert (len1 >= 0);
00648 _dbus_assert (len2 >= 0);
00649
00650 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00651
00652 if (buffer2 != NULL)
00653 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00654 else
00655 {
00656 data2 = NULL;
00657 start2 = 0;
00658 len2 = 0;
00659 }
00660
00661 vectors[0].iov_base = (char*) data1;
00662 vectors[0].iov_len = len1;
00663 vectors[1].iov_base = (char*) data2;
00664 vectors[1].iov_len = len2;
00665
00666 _DBUS_ZERO(m);
00667 m.msg_iov = vectors;
00668 m.msg_iovlen = data2 ? 2 : 1;
00669
00670 again:
00671
00672 bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
00673
00674 if (bytes_written < 0 && errno == EINTR)
00675 goto again;
00676
00677 return bytes_written;
00678
00679 #else
00680 return _dbus_write_two (fd.fd, buffer1, start1, len1,
00681 buffer2, start2, len2);
00682 #endif
00683 }
00684
00701 int
00702 _dbus_read (int fd,
00703 DBusString *buffer,
00704 int count)
00705 {
00706 int bytes_read;
00707 int start;
00708 char *data;
00709
00710 _dbus_assert (count >= 0);
00711
00712 start = _dbus_string_get_length (buffer);
00713
00714 if (!_dbus_string_lengthen (buffer, count))
00715 {
00716 errno = ENOMEM;
00717 return -1;
00718 }
00719
00720 data = _dbus_string_get_data_len (buffer, start, count);
00721
00722 again:
00723
00724 bytes_read = read (fd, data, count);
00725
00726 if (bytes_read < 0)
00727 {
00728 if (errno == EINTR)
00729 goto again;
00730 else
00731 {
00732
00733 _dbus_string_set_length (buffer, start);
00734 return -1;
00735 }
00736 }
00737 else
00738 {
00739
00740 _dbus_string_set_length (buffer, start + bytes_read);
00741
00742 #if 0
00743 if (bytes_read > 0)
00744 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00745 #endif
00746
00747 return bytes_read;
00748 }
00749 }
00750
00761 int
00762 _dbus_write (int fd,
00763 const DBusString *buffer,
00764 int start,
00765 int len)
00766 {
00767 const char *data;
00768 int bytes_written;
00769
00770 data = _dbus_string_get_const_data_len (buffer, start, len);
00771
00772 again:
00773
00774 bytes_written = write (fd, data, len);
00775
00776 if (bytes_written < 0 && errno == EINTR)
00777 goto again;
00778
00779 #if 0
00780 if (bytes_written > 0)
00781 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00782 #endif
00783
00784 return bytes_written;
00785 }
00786
00807 int
00808 _dbus_write_two (int fd,
00809 const DBusString *buffer1,
00810 int start1,
00811 int len1,
00812 const DBusString *buffer2,
00813 int start2,
00814 int len2)
00815 {
00816 _dbus_assert (buffer1 != NULL);
00817 _dbus_assert (start1 >= 0);
00818 _dbus_assert (start2 >= 0);
00819 _dbus_assert (len1 >= 0);
00820 _dbus_assert (len2 >= 0);
00821
00822 #ifdef HAVE_WRITEV
00823 {
00824 struct iovec vectors[2];
00825 const char *data1;
00826 const char *data2;
00827 int bytes_written;
00828
00829 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00830
00831 if (buffer2 != NULL)
00832 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00833 else
00834 {
00835 data2 = NULL;
00836 start2 = 0;
00837 len2 = 0;
00838 }
00839
00840 vectors[0].iov_base = (char*) data1;
00841 vectors[0].iov_len = len1;
00842 vectors[1].iov_base = (char*) data2;
00843 vectors[1].iov_len = len2;
00844
00845 again:
00846
00847 bytes_written = writev (fd,
00848 vectors,
00849 data2 ? 2 : 1);
00850
00851 if (bytes_written < 0 && errno == EINTR)
00852 goto again;
00853
00854 return bytes_written;
00855 }
00856 #else
00857 {
00858 int ret1, ret2;
00859
00860 ret1 = _dbus_write (fd, buffer1, start1, len1);
00861 if (ret1 == len1 && buffer2 != NULL)
00862 {
00863 ret2 = _dbus_write (fd, buffer2, start2, len2);
00864 if (ret2 < 0)
00865 ret2 = 0;
00866
00867 return ret1 + ret2;
00868 }
00869 else
00870 return ret1;
00871 }
00872 #endif
00873 }
00874
00875 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00876
00906 int
00907 _dbus_connect_unix_socket (const char *path,
00908 dbus_bool_t abstract,
00909 DBusError *error)
00910 {
00911 int fd;
00912 size_t path_len;
00913 struct sockaddr_un addr;
00914
00915 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00916
00917 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00918 path, abstract);
00919
00920
00921 if (!_dbus_open_unix_socket (&fd, error))
00922 {
00923 _DBUS_ASSERT_ERROR_IS_SET(error);
00924 return -1;
00925 }
00926 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00927
00928 _DBUS_ZERO (addr);
00929 addr.sun_family = AF_UNIX;
00930 path_len = strlen (path);
00931
00932 if (abstract)
00933 {
00934 #ifdef HAVE_ABSTRACT_SOCKETS
00935 addr.sun_path[0] = '\0';
00936 path_len++;
00937
00938 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00939 {
00940 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00941 "Abstract socket name too long\n");
00942 _dbus_close (fd, NULL);
00943 return -1;
00944 }
00945
00946 strncpy (&addr.sun_path[1], path, path_len);
00947
00948 #else
00949 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00950 "Operating system does not support abstract socket namespace\n");
00951 _dbus_close (fd, NULL);
00952 return -1;
00953 #endif
00954 }
00955 else
00956 {
00957 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00958 {
00959 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00960 "Socket name too long\n");
00961 _dbus_close (fd, NULL);
00962 return -1;
00963 }
00964
00965 strncpy (addr.sun_path, path, path_len);
00966 }
00967
00968 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00969 {
00970 dbus_set_error (error,
00971 _dbus_error_from_errno (errno),
00972 "Failed to connect to socket %s: %s",
00973 path, _dbus_strerror (errno));
00974
00975 _dbus_close (fd, NULL);
00976 return -1;
00977 }
00978
00979 if (!_dbus_set_fd_nonblocking (fd, error))
00980 {
00981 _DBUS_ASSERT_ERROR_IS_SET (error);
00982
00983 _dbus_close (fd, NULL);
00984 return -1;
00985 }
00986
00987 return fd;
00988 }
00989
01002 int
01003 _dbus_connect_exec (const char *path,
01004 char *const argv[],
01005 DBusError *error)
01006 {
01007 int fds[2];
01008 pid_t pid;
01009 int retval;
01010 dbus_bool_t cloexec_done = 0;
01011
01012 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01013
01014 _dbus_verbose ("connecting to process %s\n", path);
01015
01016 #ifdef SOCK_CLOEXEC
01017 retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
01018 cloexec_done = (retval >= 0);
01019
01020 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
01021 #endif
01022 {
01023 retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
01024 }
01025
01026 if (retval < 0)
01027 {
01028 dbus_set_error (error,
01029 _dbus_error_from_errno (errno),
01030 "Failed to create socket pair: %s",
01031 _dbus_strerror (errno));
01032 return -1;
01033 }
01034
01035 if (!cloexec_done)
01036 {
01037 _dbus_fd_set_close_on_exec (fds[0]);
01038 _dbus_fd_set_close_on_exec (fds[1]);
01039 }
01040
01041 pid = fork ();
01042 if (pid < 0)
01043 {
01044 dbus_set_error (error,
01045 _dbus_error_from_errno (errno),
01046 "Failed to fork() to call %s: %s",
01047 path, _dbus_strerror (errno));
01048 close (fds[0]);
01049 close (fds[1]);
01050 return -1;
01051 }
01052
01053 if (pid == 0)
01054 {
01055
01056 close (fds[0]);
01057
01058 dup2 (fds[1], STDIN_FILENO);
01059 dup2 (fds[1], STDOUT_FILENO);
01060
01061 if (fds[1] != STDIN_FILENO &&
01062 fds[1] != STDOUT_FILENO)
01063 close (fds[1]);
01064
01065
01066
01067
01068 _dbus_close_all ();
01069
01070 execvp (path, argv);
01071
01072 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
01073
01074 _exit(1);
01075 }
01076
01077
01078 close (fds[1]);
01079
01080 if (!_dbus_set_fd_nonblocking (fds[0], error))
01081 {
01082 _DBUS_ASSERT_ERROR_IS_SET (error);
01083
01084 close (fds[0]);
01085 return -1;
01086 }
01087
01088 return fds[0];
01089 }
01090
01108 int
01109 _dbus_listen_unix_socket (const char *path,
01110 dbus_bool_t abstract,
01111 DBusError *error)
01112 {
01113 int listen_fd;
01114 struct sockaddr_un addr;
01115 size_t path_len;
01116
01117 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01118
01119 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
01120 path, abstract);
01121
01122 if (!_dbus_open_unix_socket (&listen_fd, error))
01123 {
01124 _DBUS_ASSERT_ERROR_IS_SET(error);
01125 return -1;
01126 }
01127 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01128
01129 _DBUS_ZERO (addr);
01130 addr.sun_family = AF_UNIX;
01131 path_len = strlen (path);
01132
01133 if (abstract)
01134 {
01135 #ifdef HAVE_ABSTRACT_SOCKETS
01136
01137
01138
01139 addr.sun_path[0] = '\0';
01140 path_len++;
01141
01142 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01143 {
01144 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01145 "Abstract socket name too long\n");
01146 _dbus_close (listen_fd, NULL);
01147 return -1;
01148 }
01149
01150 strncpy (&addr.sun_path[1], path, path_len);
01151
01152 #else
01153 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
01154 "Operating system does not support abstract socket namespace\n");
01155 _dbus_close (listen_fd, NULL);
01156 return -1;
01157 #endif
01158 }
01159 else
01160 {
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171 {
01172 struct stat sb;
01173
01174 if (stat (path, &sb) == 0 &&
01175 S_ISSOCK (sb.st_mode))
01176 unlink (path);
01177 }
01178
01179 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01180 {
01181 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01182 "Socket name too long\n");
01183 _dbus_close (listen_fd, NULL);
01184 return -1;
01185 }
01186
01187 strncpy (addr.sun_path, path, path_len);
01188 }
01189
01190 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01191 {
01192 dbus_set_error (error, _dbus_error_from_errno (errno),
01193 "Failed to bind socket \"%s\": %s",
01194 path, _dbus_strerror (errno));
01195 _dbus_close (listen_fd, NULL);
01196 return -1;
01197 }
01198
01199 if (listen (listen_fd, 30 ) < 0)
01200 {
01201 dbus_set_error (error, _dbus_error_from_errno (errno),
01202 "Failed to listen on socket \"%s\": %s",
01203 path, _dbus_strerror (errno));
01204 _dbus_close (listen_fd, NULL);
01205 return -1;
01206 }
01207
01208 if (!_dbus_set_fd_nonblocking (listen_fd, error))
01209 {
01210 _DBUS_ASSERT_ERROR_IS_SET (error);
01211 _dbus_close (listen_fd, NULL);
01212 return -1;
01213 }
01214
01215
01216
01217
01218 if (!abstract && chmod (path, 0777) < 0)
01219 _dbus_warn ("Could not set mode 0777 on socket %s\n",
01220 path);
01221
01222 return listen_fd;
01223 }
01224
01235 int
01236 _dbus_listen_systemd_sockets (DBusSocket **fds,
01237 DBusError *error)
01238 {
01239 #ifdef HAVE_SYSTEMD
01240 int r, n;
01241 int fd;
01242 DBusSocket *new_fds;
01243
01244 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01245
01246 n = sd_listen_fds (TRUE);
01247 if (n < 0)
01248 {
01249 dbus_set_error (error, _dbus_error_from_errno (-n),
01250 "Failed to acquire systemd socket: %s",
01251 _dbus_strerror (-n));
01252 return -1;
01253 }
01254
01255 if (n <= 0)
01256 {
01257 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01258 "No socket received.");
01259 return -1;
01260 }
01261
01262 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01263 {
01264 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01265 if (r < 0)
01266 {
01267 dbus_set_error (error, _dbus_error_from_errno (-r),
01268 "Failed to verify systemd socket type: %s",
01269 _dbus_strerror (-r));
01270 return -1;
01271 }
01272
01273 if (!r)
01274 {
01275 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01276 "Passed socket has wrong type.");
01277 return -1;
01278 }
01279 }
01280
01281
01282
01283
01284 new_fds = dbus_new (DBusSocket, n);
01285 if (!new_fds)
01286 {
01287 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01288 "Failed to allocate file handle array.");
01289 goto fail;
01290 }
01291
01292 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01293 {
01294 if (!_dbus_set_fd_nonblocking (fd, error))
01295 {
01296 _DBUS_ASSERT_ERROR_IS_SET (error);
01297 goto fail;
01298 }
01299
01300 new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
01301 }
01302
01303 *fds = new_fds;
01304 return n;
01305
01306 fail:
01307
01308 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01309 {
01310 _dbus_close (fd, NULL);
01311 }
01312
01313 dbus_free (new_fds);
01314 return -1;
01315 #else
01316 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
01317 "dbus was compiled without systemd support");
01318 return -1;
01319 #endif
01320 }
01321
01335 DBusSocket
01336 _dbus_connect_tcp_socket (const char *host,
01337 const char *port,
01338 const char *family,
01339 DBusError *error)
01340 {
01341 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01342 }
01343
01344 DBusSocket
01345 _dbus_connect_tcp_socket_with_nonce (const char *host,
01346 const char *port,
01347 const char *family,
01348 const char *noncefile,
01349 DBusError *error)
01350 {
01351 int saved_errno = 0;
01352 DBusSocket fd = DBUS_SOCKET_INIT;
01353 int res;
01354 struct addrinfo hints;
01355 struct addrinfo *ai, *tmp;
01356
01357 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01358
01359 _DBUS_ZERO (hints);
01360
01361 if (!family)
01362 hints.ai_family = AF_UNSPEC;
01363 else if (!strcmp(family, "ipv4"))
01364 hints.ai_family = AF_INET;
01365 else if (!strcmp(family, "ipv6"))
01366 hints.ai_family = AF_INET6;
01367 else
01368 {
01369 dbus_set_error (error,
01370 DBUS_ERROR_BAD_ADDRESS,
01371 "Unknown address family %s", family);
01372 return _dbus_socket_get_invalid ();
01373 }
01374 hints.ai_protocol = IPPROTO_TCP;
01375 hints.ai_socktype = SOCK_STREAM;
01376 hints.ai_flags = AI_ADDRCONFIG;
01377
01378 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01379 {
01380 dbus_set_error (error,
01381 _dbus_error_from_errno (errno),
01382 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01383 host, port, gai_strerror(res), res);
01384 return _dbus_socket_get_invalid ();
01385 }
01386
01387 tmp = ai;
01388 while (tmp)
01389 {
01390 if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
01391 {
01392 freeaddrinfo(ai);
01393 _DBUS_ASSERT_ERROR_IS_SET(error);
01394 return _dbus_socket_get_invalid ();
01395 }
01396 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01397
01398 if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01399 {
01400 saved_errno = errno;
01401 _dbus_close (fd.fd, NULL);
01402 fd.fd = -1;
01403 tmp = tmp->ai_next;
01404 continue;
01405 }
01406
01407 break;
01408 }
01409 freeaddrinfo(ai);
01410
01411 if (fd.fd == -1)
01412 {
01413 dbus_set_error (error,
01414 _dbus_error_from_errno (saved_errno),
01415 "Failed to connect to socket \"%s:%s\" %s",
01416 host, port, _dbus_strerror(saved_errno));
01417 return _dbus_socket_get_invalid ();
01418 }
01419
01420 if (noncefile != NULL)
01421 {
01422 DBusString noncefileStr;
01423 dbus_bool_t ret;
01424 _dbus_string_init_const (&noncefileStr, noncefile);
01425 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01426 _dbus_string_free (&noncefileStr);
01427
01428 if (!ret)
01429 {
01430 _dbus_close (fd.fd, NULL);
01431 return _dbus_socket_get_invalid ();
01432 }
01433 }
01434
01435 if (!_dbus_set_fd_nonblocking (fd.fd, error))
01436 {
01437 _dbus_close (fd.fd, NULL);
01438 return _dbus_socket_get_invalid ();
01439 }
01440
01441 return fd;
01442 }
01443
01460 int
01461 _dbus_listen_tcp_socket (const char *host,
01462 const char *port,
01463 const char *family,
01464 DBusString *retport,
01465 DBusSocket **fds_p,
01466 DBusError *error)
01467 {
01468 int saved_errno;
01469 int nlisten_fd = 0, res, i;
01470 DBusSocket *listen_fd = NULL;
01471 struct addrinfo hints;
01472 struct addrinfo *ai, *tmp;
01473 unsigned int reuseaddr;
01474
01475 *fds_p = NULL;
01476 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01477
01478 _DBUS_ZERO (hints);
01479
01480 if (!family)
01481 hints.ai_family = AF_UNSPEC;
01482 else if (!strcmp(family, "ipv4"))
01483 hints.ai_family = AF_INET;
01484 else if (!strcmp(family, "ipv6"))
01485 hints.ai_family = AF_INET6;
01486 else
01487 {
01488 dbus_set_error (error,
01489 DBUS_ERROR_BAD_ADDRESS,
01490 "Unknown address family %s", family);
01491 return -1;
01492 }
01493
01494 hints.ai_protocol = IPPROTO_TCP;
01495 hints.ai_socktype = SOCK_STREAM;
01496 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01497
01498 redo_lookup_with_port:
01499 ai = NULL;
01500 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01501 {
01502 dbus_set_error (error,
01503 _dbus_error_from_errno (errno),
01504 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01505 host ? host : "*", port, gai_strerror(res), res);
01506 goto failed;
01507 }
01508
01509 tmp = ai;
01510 while (tmp)
01511 {
01512 int fd = -1, tcp_nodelay_on;
01513 DBusSocket *newlisten_fd;
01514
01515 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01516 {
01517 _DBUS_ASSERT_ERROR_IS_SET(error);
01518 goto failed;
01519 }
01520 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01521
01522 reuseaddr = 1;
01523 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01524 {
01525 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01526 host ? host : "*", port, _dbus_strerror (errno));
01527 }
01528
01529
01530
01531 tcp_nodelay_on = 1;
01532 if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
01533 {
01534 _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
01535 host ? host : "*", port, _dbus_strerror (errno));
01536 }
01537
01538 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01539 {
01540 saved_errno = errno;
01541 _dbus_close(fd, NULL);
01542 if (saved_errno == EADDRINUSE)
01543 {
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 tmp = tmp->ai_next;
01557 continue;
01558 }
01559 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01560 "Failed to bind socket \"%s:%s\": %s",
01561 host ? host : "*", port, _dbus_strerror (saved_errno));
01562 goto failed;
01563 }
01564
01565 if (listen (fd, 30 ) < 0)
01566 {
01567 saved_errno = errno;
01568 _dbus_close (fd, NULL);
01569 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01570 "Failed to listen on socket \"%s:%s\": %s",
01571 host ? host : "*", port, _dbus_strerror (saved_errno));
01572 goto failed;
01573 }
01574
01575 newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
01576 if (!newlisten_fd)
01577 {
01578 saved_errno = errno;
01579 _dbus_close (fd, NULL);
01580 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01581 "Failed to allocate file handle array: %s",
01582 _dbus_strerror (saved_errno));
01583 goto failed;
01584 }
01585 listen_fd = newlisten_fd;
01586 listen_fd[nlisten_fd].fd = fd;
01587 nlisten_fd++;
01588
01589 if (!_dbus_string_get_length(retport))
01590 {
01591
01592
01593
01594
01595 if (!port || !strcmp(port, "0"))
01596 {
01597 int result;
01598 struct sockaddr_storage addr;
01599 socklen_t addrlen;
01600 char portbuf[50];
01601
01602 addrlen = sizeof(addr);
01603 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01604
01605 if (result == -1 ||
01606 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01607 portbuf, sizeof(portbuf),
01608 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
01609 {
01610 dbus_set_error (error, _dbus_error_from_errno (errno),
01611 "Failed to resolve port \"%s:%s\": %s (%s)",
01612 host ? host : "*", port, gai_strerror(res), res);
01613 goto failed;
01614 }
01615 if (!_dbus_string_append(retport, portbuf))
01616 {
01617 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01618 goto failed;
01619 }
01620
01621
01622 port = _dbus_string_get_const_data(retport);
01623 freeaddrinfo(ai);
01624 goto redo_lookup_with_port;
01625 }
01626 else
01627 {
01628 if (!_dbus_string_append(retport, port))
01629 {
01630 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01631 goto failed;
01632 }
01633 }
01634 }
01635
01636 tmp = tmp->ai_next;
01637 }
01638 freeaddrinfo(ai);
01639 ai = NULL;
01640
01641 if (!nlisten_fd)
01642 {
01643 errno = EADDRINUSE;
01644 dbus_set_error (error, _dbus_error_from_errno (errno),
01645 "Failed to bind socket \"%s:%s\": %s",
01646 host ? host : "*", port, _dbus_strerror (errno));
01647 goto failed;
01648 }
01649
01650 for (i = 0 ; i < nlisten_fd ; i++)
01651 {
01652 if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
01653 {
01654 goto failed;
01655 }
01656 }
01657
01658 *fds_p = listen_fd;
01659
01660 return nlisten_fd;
01661
01662 failed:
01663 if (ai)
01664 freeaddrinfo(ai);
01665 for (i = 0 ; i < nlisten_fd ; i++)
01666 _dbus_close(listen_fd[i].fd, NULL);
01667 dbus_free(listen_fd);
01668 return -1;
01669 }
01670
01671 static dbus_bool_t
01672 write_credentials_byte (int server_fd,
01673 DBusError *error)
01674 {
01675 int bytes_written;
01676 char buf[1] = { '\0' };
01677 #if defined(HAVE_CMSGCRED)
01678 union {
01679 struct cmsghdr hdr;
01680 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01681 } cmsg;
01682 struct iovec iov;
01683 struct msghdr msg;
01684 iov.iov_base = buf;
01685 iov.iov_len = 1;
01686
01687 _DBUS_ZERO(msg);
01688 msg.msg_iov = &iov;
01689 msg.msg_iovlen = 1;
01690
01691 msg.msg_control = (caddr_t) &cmsg;
01692 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01693 _DBUS_ZERO(cmsg);
01694 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01695 cmsg.hdr.cmsg_level = SOL_SOCKET;
01696 cmsg.hdr.cmsg_type = SCM_CREDS;
01697 #endif
01698
01699 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01700
01701 again:
01702
01703 #if defined(HAVE_CMSGCRED)
01704 bytes_written = sendmsg (server_fd, &msg, 0
01705 #if HAVE_DECL_MSG_NOSIGNAL
01706 |MSG_NOSIGNAL
01707 #endif
01708 );
01709
01710
01711
01712
01713 if (bytes_written < 0 && errno == EINVAL)
01714 #endif
01715 {
01716 bytes_written = send (server_fd, buf, 1, 0
01717 #if HAVE_DECL_MSG_NOSIGNAL
01718 |MSG_NOSIGNAL
01719 #endif
01720 );
01721 }
01722
01723 if (bytes_written < 0 && errno == EINTR)
01724 goto again;
01725
01726 if (bytes_written < 0)
01727 {
01728 dbus_set_error (error, _dbus_error_from_errno (errno),
01729 "Failed to write credentials byte: %s",
01730 _dbus_strerror (errno));
01731 return FALSE;
01732 }
01733 else if (bytes_written == 0)
01734 {
01735 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01736 "wrote zero bytes writing credentials byte");
01737 return FALSE;
01738 }
01739 else
01740 {
01741 _dbus_assert (bytes_written == 1);
01742 _dbus_verbose ("wrote credentials byte\n");
01743 return TRUE;
01744 }
01745 }
01746
01747
01748 static dbus_bool_t
01749 add_linux_security_label_to_credentials (int client_fd,
01750 DBusCredentials *credentials)
01751 {
01752 #if defined(__linux__) && defined(SO_PEERSEC)
01753 DBusString buf;
01754 socklen_t len = 1024;
01755 dbus_bool_t oom = FALSE;
01756
01757 if (!_dbus_string_init_preallocated (&buf, len) ||
01758 !_dbus_string_set_length (&buf, len))
01759 return FALSE;
01760
01761 while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
01762 _dbus_string_get_data (&buf), &len) < 0)
01763 {
01764 int e = errno;
01765
01766 _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
01767 _dbus_strerror (e), (unsigned long) len);
01768
01769 if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
01770 {
01771 _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
01772 _dbus_strerror (e));
01773 goto out;
01774 }
01775
01776
01777
01778 if (!_dbus_string_set_length (&buf, len))
01779 {
01780 oom = TRUE;
01781 goto out;
01782 }
01783
01784 _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
01785 }
01786
01787 if (len <= 0)
01788 {
01789 _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
01790 (unsigned long) len);
01791 goto out;
01792 }
01793
01794 if (len > _dbus_string_get_length_uint (&buf))
01795 {
01796 _dbus_verbose ("%lu > %u", (unsigned long) len,
01797 _dbus_string_get_length_uint (&buf));
01798 _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
01799 }
01800
01801 if (_dbus_string_get_byte (&buf, len - 1) == 0)
01802 {
01803
01804
01805 _dbus_verbose ("subtracting trailing \\0\n");
01806 len--;
01807 }
01808
01809 if (!_dbus_string_set_length (&buf, len))
01810 {
01811 _dbus_assert_not_reached ("shortening string should not lead to OOM");
01812 oom = TRUE;
01813 goto out;
01814 }
01815
01816 if (strlen (_dbus_string_get_const_data (&buf)) != len)
01817 {
01818
01819
01820
01821 _dbus_verbose ("security label from kernel had an embedded \\0, "
01822 "ignoring it\n");
01823 goto out;
01824 }
01825
01826 _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
01827 (unsigned long) len,
01828 _dbus_string_get_const_data (&buf));
01829
01830 if (!_dbus_credentials_add_linux_security_label (credentials,
01831 _dbus_string_get_const_data (&buf)))
01832 {
01833 oom = TRUE;
01834 goto out;
01835 }
01836
01837 out:
01838 _dbus_string_free (&buf);
01839 return !oom;
01840 #else
01841
01842 return TRUE;
01843 #endif
01844 }
01845
01886 dbus_bool_t
01887 _dbus_read_credentials_socket (DBusSocket client_fd,
01888 DBusCredentials *credentials,
01889 DBusError *error)
01890 {
01891 struct msghdr msg;
01892 struct iovec iov;
01893 char buf;
01894 dbus_uid_t uid_read;
01895 dbus_pid_t pid_read;
01896 int bytes_read;
01897
01898 #ifdef HAVE_CMSGCRED
01899 union {
01900 struct cmsghdr hdr;
01901 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01902 } cmsg;
01903 #endif
01904
01905
01906
01907
01908
01909 _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
01910 _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
01911 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
01912
01913 uid_read = DBUS_UID_UNSET;
01914 pid_read = DBUS_PID_UNSET;
01915
01916 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01917
01918 _dbus_credentials_clear (credentials);
01919
01920 iov.iov_base = &buf;
01921 iov.iov_len = 1;
01922
01923 _DBUS_ZERO(msg);
01924 msg.msg_iov = &iov;
01925 msg.msg_iovlen = 1;
01926
01927 #if defined(HAVE_CMSGCRED)
01928 _DBUS_ZERO(cmsg);
01929 msg.msg_control = (caddr_t) &cmsg;
01930 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01931 #endif
01932
01933 again:
01934 bytes_read = recvmsg (client_fd.fd, &msg, 0);
01935
01936 if (bytes_read < 0)
01937 {
01938 if (errno == EINTR)
01939 goto again;
01940
01941
01942
01943
01944
01945
01946 dbus_set_error (error, _dbus_error_from_errno (errno),
01947 "Failed to read credentials byte: %s",
01948 _dbus_strerror (errno));
01949 return FALSE;
01950 }
01951 else if (bytes_read == 0)
01952 {
01953
01954
01955
01956 dbus_set_error (error, DBUS_ERROR_FAILED,
01957 "Failed to read credentials byte (zero-length read)");
01958 return FALSE;
01959 }
01960 else if (buf != '\0')
01961 {
01962 dbus_set_error (error, DBUS_ERROR_FAILED,
01963 "Credentials byte was not nul");
01964 return FALSE;
01965 }
01966
01967 _dbus_verbose ("read credentials byte\n");
01968
01969 {
01970 #ifdef SO_PEERCRED
01971
01972
01973
01974
01975
01976
01977
01978
01979 #ifdef __OpenBSD__
01980 struct sockpeercred cr;
01981 #else
01982 struct ucred cr;
01983 #endif
01984 int cr_len = sizeof (cr);
01985
01986 if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
01987 {
01988 _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
01989 _dbus_strerror (errno));
01990 }
01991 else if (cr_len != sizeof (cr))
01992 {
01993 _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
01994 cr_len, (int) sizeof (cr));
01995 }
01996 else
01997 {
01998 pid_read = cr.pid;
01999 uid_read = cr.uid;
02000 }
02001 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
02002
02003
02004 struct unpcbid cr;
02005 socklen_t cr_len = sizeof (cr);
02006
02007 if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
02008 {
02009 _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
02010 _dbus_strerror (errno));
02011 }
02012 else if (cr_len != sizeof (cr))
02013 {
02014 _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
02015 cr_len, (int) sizeof (cr));
02016 }
02017 else
02018 {
02019 pid_read = cr.unp_pid;
02020 uid_read = cr.unp_euid;
02021 }
02022 #elif defined(HAVE_CMSGCRED)
02023
02024
02025
02026
02027
02028
02029
02030
02031 struct cmsgcred *cred;
02032 struct cmsghdr *cmsgp;
02033
02034 for (cmsgp = CMSG_FIRSTHDR (&msg);
02035 cmsgp != NULL;
02036 cmsgp = CMSG_NXTHDR (&msg, cmsgp))
02037 {
02038 if (cmsgp->cmsg_type == SCM_CREDS &&
02039 cmsgp->cmsg_level == SOL_SOCKET &&
02040 cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
02041 {
02042 cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
02043 pid_read = cred->cmcred_pid;
02044 uid_read = cred->cmcred_euid;
02045 break;
02046 }
02047 }
02048
02049 #elif defined(HAVE_GETPEERUCRED)
02050
02051
02052
02053 ucred_t * ucred = NULL;
02054 if (getpeerucred (client_fd.fd, &ucred) == 0)
02055 {
02056 pid_read = ucred_getpid (ucred);
02057 uid_read = ucred_geteuid (ucred);
02058 #ifdef HAVE_ADT
02059
02060 adt_session_data_t *adth = NULL;
02061 adt_export_data_t *data = NULL;
02062 size_t size = 0;
02063 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
02064 {
02065 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
02066 }
02067 else
02068 {
02069 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
02070 {
02071 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
02072 }
02073 else
02074 {
02075 size = adt_export_session_data (adth, &data);
02076 if (size <= 0)
02077 {
02078 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
02079 }
02080 else
02081 {
02082 _dbus_credentials_add_adt_audit_data (credentials, data, size);
02083 free (data);
02084 }
02085 }
02086 (void) adt_end_session (adth);
02087 }
02088 #endif
02089 }
02090 else
02091 {
02092 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
02093 }
02094 if (ucred != NULL)
02095 ucred_free (ucred);
02096
02097
02098
02099
02100
02101
02102 #elif defined(HAVE_GETPEEREID)
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118 uid_t euid;
02119 gid_t egid;
02120 if (getpeereid (client_fd.fd, &euid, &egid) == 0)
02121 {
02122 uid_read = euid;
02123 }
02124 else
02125 {
02126 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
02127 }
02128 #else
02129
02130 #warning Socket credentials not supported on this Unix OS
02131 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
02132
02133
02134
02135
02136
02137 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
02138 defined(__linux__) || \
02139 defined(__OpenBSD__) || \
02140 defined(__NetBSD__)
02141 # error Credentials passing not working on this OS is a regression!
02142 #endif
02143
02144 _dbus_verbose ("Socket credentials not supported on this OS\n");
02145 #endif
02146 }
02147
02148 _dbus_verbose ("Credentials:"
02149 " pid "DBUS_PID_FORMAT
02150 " uid "DBUS_UID_FORMAT
02151 "\n",
02152 pid_read,
02153 uid_read);
02154
02155 if (pid_read != DBUS_PID_UNSET)
02156 {
02157 if (!_dbus_credentials_add_pid (credentials, pid_read))
02158 {
02159 _DBUS_SET_OOM (error);
02160 return FALSE;
02161 }
02162 }
02163
02164 if (uid_read != DBUS_UID_UNSET)
02165 {
02166 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
02167 {
02168 _DBUS_SET_OOM (error);
02169 return FALSE;
02170 }
02171 }
02172
02173 if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
02174 {
02175 _DBUS_SET_OOM (error);
02176 return FALSE;
02177 }
02178
02179 return TRUE;
02180 }
02181
02199 dbus_bool_t
02200 _dbus_send_credentials_socket (DBusSocket server_fd,
02201 DBusError *error)
02202 {
02203 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02204
02205 if (write_credentials_byte (server_fd.fd, error))
02206 return TRUE;
02207 else
02208 return FALSE;
02209 }
02210
02220 DBusSocket
02221 _dbus_accept (DBusSocket listen_fd)
02222 {
02223 DBusSocket client_fd;
02224 struct sockaddr addr;
02225 socklen_t addrlen;
02226 #ifdef HAVE_ACCEPT4
02227 dbus_bool_t cloexec_done;
02228 #endif
02229
02230 addrlen = sizeof (addr);
02231
02232 retry:
02233
02234 #ifdef HAVE_ACCEPT4
02235
02236
02237
02238
02239
02240 client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
02241 cloexec_done = client_fd.fd >= 0;
02242
02243 if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
02244 #endif
02245 {
02246 client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
02247 }
02248
02249 if (client_fd.fd < 0)
02250 {
02251 if (errno == EINTR)
02252 goto retry;
02253 }
02254
02255 _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
02256
02257 #ifdef HAVE_ACCEPT4
02258 if (!cloexec_done)
02259 #endif
02260 {
02261 _dbus_fd_set_close_on_exec(client_fd.fd);
02262 }
02263
02264 return client_fd;
02265 }
02266
02275 dbus_bool_t
02276 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
02277 {
02278 const char *directory;
02279 struct stat sb;
02280
02281 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02282
02283 directory = _dbus_string_get_const_data (dir);
02284
02285 if (stat (directory, &sb) < 0)
02286 {
02287 dbus_set_error (error, _dbus_error_from_errno (errno),
02288 "%s", _dbus_strerror (errno));
02289
02290 return FALSE;
02291 }
02292
02293 if (sb.st_uid != geteuid ())
02294 {
02295 dbus_set_error (error, DBUS_ERROR_FAILED,
02296 "%s directory is owned by user %lu, not %lu",
02297 directory,
02298 (unsigned long) sb.st_uid,
02299 (unsigned long) geteuid ());
02300 return FALSE;
02301 }
02302
02303 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
02304 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
02305 {
02306 dbus_set_error (error, DBUS_ERROR_FAILED,
02307 "%s directory is not private to the user", directory);
02308 return FALSE;
02309 }
02310
02311 return TRUE;
02312 }
02313
02314 static dbus_bool_t
02315 fill_user_info_from_passwd (struct passwd *p,
02316 DBusUserInfo *info,
02317 DBusError *error)
02318 {
02319 _dbus_assert (p->pw_name != NULL);
02320 _dbus_assert (p->pw_dir != NULL);
02321
02322 info->uid = p->pw_uid;
02323 info->primary_gid = p->pw_gid;
02324 info->username = _dbus_strdup (p->pw_name);
02325 info->homedir = _dbus_strdup (p->pw_dir);
02326
02327 if (info->username == NULL ||
02328 info->homedir == NULL)
02329 {
02330 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02331 return FALSE;
02332 }
02333
02334 return TRUE;
02335 }
02336
02337 static dbus_bool_t
02338 fill_user_info (DBusUserInfo *info,
02339 dbus_uid_t uid,
02340 const DBusString *username,
02341 DBusError *error)
02342 {
02343 const char *username_c;
02344
02345
02346 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
02347 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
02348
02349 info->uid = DBUS_UID_UNSET;
02350 info->primary_gid = DBUS_GID_UNSET;
02351 info->group_ids = NULL;
02352 info->n_group_ids = 0;
02353 info->username = NULL;
02354 info->homedir = NULL;
02355
02356 if (username != NULL)
02357 username_c = _dbus_string_get_const_data (username);
02358 else
02359 username_c = NULL;
02360
02361
02362
02363
02364
02365
02366 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
02367 {
02368 struct passwd *p;
02369 int result;
02370 size_t buflen;
02371 char *buf;
02372 struct passwd p_str;
02373
02374
02375 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
02376
02377
02378
02379
02380
02381 if ((long) buflen <= 0)
02382 buflen = 1024;
02383
02384 result = -1;
02385 while (1)
02386 {
02387 buf = dbus_malloc (buflen);
02388 if (buf == NULL)
02389 {
02390 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02391 return FALSE;
02392 }
02393
02394 p = NULL;
02395 #ifdef HAVE_POSIX_GETPWNAM_R
02396 if (uid != DBUS_UID_UNSET)
02397 result = getpwuid_r (uid, &p_str, buf, buflen,
02398 &p);
02399 else
02400 result = getpwnam_r (username_c, &p_str, buf, buflen,
02401 &p);
02402 #else
02403 if (uid != DBUS_UID_UNSET)
02404 p = getpwuid_r (uid, &p_str, buf, buflen);
02405 else
02406 p = getpwnam_r (username_c, &p_str, buf, buflen);
02407 result = 0;
02408 #endif
02409
02410 if (result == ERANGE && buflen < 512 * 1024)
02411 {
02412 dbus_free (buf);
02413 buflen *= 2;
02414 }
02415 else
02416 {
02417 break;
02418 }
02419 }
02420 if (result == 0 && p == &p_str)
02421 {
02422 if (!fill_user_info_from_passwd (p, info, error))
02423 {
02424 dbus_free (buf);
02425 return FALSE;
02426 }
02427 dbus_free (buf);
02428 }
02429 else
02430 {
02431 dbus_set_error (error, _dbus_error_from_errno (errno),
02432 "User \"%s\" unknown or no memory to allocate password entry\n",
02433 username_c ? username_c : "???");
02434 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02435 dbus_free (buf);
02436 return FALSE;
02437 }
02438 }
02439 #else
02440 {
02441
02442 struct passwd *p;
02443
02444 if (uid != DBUS_UID_UNSET)
02445 p = getpwuid (uid);
02446 else
02447 p = getpwnam (username_c);
02448
02449 if (p != NULL)
02450 {
02451 if (!fill_user_info_from_passwd (p, info, error))
02452 {
02453 return FALSE;
02454 }
02455 }
02456 else
02457 {
02458 dbus_set_error (error, _dbus_error_from_errno (errno),
02459 "User \"%s\" unknown or no memory to allocate password entry\n",
02460 username_c ? username_c : "???");
02461 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02462 return FALSE;
02463 }
02464 }
02465 #endif
02466
02467
02468 username_c = info->username;
02469
02470 #ifdef HAVE_GETGROUPLIST
02471 {
02472 gid_t *buf;
02473 int buf_count;
02474 int i;
02475 int initial_buf_count;
02476
02477 initial_buf_count = 17;
02478 buf_count = initial_buf_count;
02479 buf = dbus_new (gid_t, buf_count);
02480 if (buf == NULL)
02481 {
02482 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02483 goto failed;
02484 }
02485
02486 if (getgrouplist (username_c,
02487 info->primary_gid,
02488 buf, &buf_count) < 0)
02489 {
02490 gid_t *new;
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504 if (buf_count == initial_buf_count)
02505 {
02506 buf_count *= 16;
02507 }
02508 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02509 if (new == NULL)
02510 {
02511 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02512 dbus_free (buf);
02513 goto failed;
02514 }
02515
02516 buf = new;
02517
02518 errno = 0;
02519 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02520 {
02521 if (errno == 0)
02522 {
02523 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02524 username_c, buf_count, buf_count);
02525 }
02526 else
02527 {
02528 dbus_set_error (error,
02529 _dbus_error_from_errno (errno),
02530 "Failed to get groups for username \"%s\" primary GID "
02531 DBUS_GID_FORMAT ": %s\n",
02532 username_c, info->primary_gid,
02533 _dbus_strerror (errno));
02534 dbus_free (buf);
02535 goto failed;
02536 }
02537 }
02538 }
02539
02540 info->group_ids = dbus_new (dbus_gid_t, buf_count);
02541 if (info->group_ids == NULL)
02542 {
02543 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02544 dbus_free (buf);
02545 goto failed;
02546 }
02547
02548 for (i = 0; i < buf_count; ++i)
02549 info->group_ids[i] = buf[i];
02550
02551 info->n_group_ids = buf_count;
02552
02553 dbus_free (buf);
02554 }
02555 #else
02556 {
02557
02558 info->group_ids = dbus_new (dbus_gid_t, 1);
02559 if (info->group_ids == NULL)
02560 {
02561 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02562 goto failed;
02563 }
02564
02565 info->n_group_ids = 1;
02566
02567 (info->group_ids)[0] = info->primary_gid;
02568 }
02569 #endif
02570
02571 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02572
02573 return TRUE;
02574
02575 failed:
02576 _DBUS_ASSERT_ERROR_IS_SET (error);
02577 return FALSE;
02578 }
02579
02588 dbus_bool_t
02589 _dbus_user_info_fill (DBusUserInfo *info,
02590 const DBusString *username,
02591 DBusError *error)
02592 {
02593 return fill_user_info (info, DBUS_UID_UNSET,
02594 username, error);
02595 }
02596
02605 dbus_bool_t
02606 _dbus_user_info_fill_uid (DBusUserInfo *info,
02607 dbus_uid_t uid,
02608 DBusError *error)
02609 {
02610 return fill_user_info (info, uid,
02611 NULL, error);
02612 }
02613
02621 dbus_bool_t
02622 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02623 {
02624
02625
02626
02627
02628 _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
02629 _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
02630 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
02631
02632 if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
02633 return FALSE;
02634 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02635 return FALSE;
02636
02637 return TRUE;
02638 }
02639
02651 dbus_bool_t
02652 _dbus_append_user_from_current_process (DBusString *str)
02653 {
02654 return _dbus_string_append_uint (str,
02655 _dbus_geteuid ());
02656 }
02657
02662 dbus_pid_t
02663 _dbus_getpid (void)
02664 {
02665 return getpid ();
02666 }
02667
02671 dbus_uid_t
02672 _dbus_getuid (void)
02673 {
02674 return getuid ();
02675 }
02676
02680 dbus_uid_t
02681 _dbus_geteuid (void)
02682 {
02683 return geteuid ();
02684 }
02685
02692 unsigned long
02693 _dbus_pid_for_log (void)
02694 {
02695 return getpid ();
02696 }
02697
02705 dbus_bool_t
02706 _dbus_parse_uid (const DBusString *uid_str,
02707 dbus_uid_t *uid)
02708 {
02709 int end;
02710 long val;
02711
02712 if (_dbus_string_get_length (uid_str) == 0)
02713 {
02714 _dbus_verbose ("UID string was zero length\n");
02715 return FALSE;
02716 }
02717
02718 val = -1;
02719 end = 0;
02720 if (!_dbus_string_parse_int (uid_str, 0, &val,
02721 &end))
02722 {
02723 _dbus_verbose ("could not parse string as a UID\n");
02724 return FALSE;
02725 }
02726
02727 if (end != _dbus_string_get_length (uid_str))
02728 {
02729 _dbus_verbose ("string contained trailing stuff after UID\n");
02730 return FALSE;
02731 }
02732
02733 *uid = val;
02734
02735 return TRUE;
02736 }
02737
02738 #if !DBUS_USE_SYNC
02739
02740
02741
02742
02743
02744 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
02745 #endif
02746
02753 dbus_int32_t
02754 _dbus_atomic_inc (DBusAtomic *atomic)
02755 {
02756 #if DBUS_USE_SYNC
02757 return __sync_add_and_fetch(&atomic->value, 1)-1;
02758 #else
02759 dbus_int32_t res;
02760
02761 pthread_mutex_lock (&atomic_mutex);
02762 res = atomic->value;
02763 atomic->value += 1;
02764 pthread_mutex_unlock (&atomic_mutex);
02765
02766 return res;
02767 #endif
02768 }
02769
02776 dbus_int32_t
02777 _dbus_atomic_dec (DBusAtomic *atomic)
02778 {
02779 #if DBUS_USE_SYNC
02780 return __sync_sub_and_fetch(&atomic->value, 1)+1;
02781 #else
02782 dbus_int32_t res;
02783
02784 pthread_mutex_lock (&atomic_mutex);
02785 res = atomic->value;
02786 atomic->value -= 1;
02787 pthread_mutex_unlock (&atomic_mutex);
02788
02789 return res;
02790 #endif
02791 }
02792
02800 dbus_int32_t
02801 _dbus_atomic_get (DBusAtomic *atomic)
02802 {
02803 #if DBUS_USE_SYNC
02804 __sync_synchronize ();
02805 return atomic->value;
02806 #else
02807 dbus_int32_t res;
02808
02809 pthread_mutex_lock (&atomic_mutex);
02810 res = atomic->value;
02811 pthread_mutex_unlock (&atomic_mutex);
02812
02813 return res;
02814 #endif
02815 }
02816
02825 int
02826 _dbus_poll (DBusPollFD *fds,
02827 int n_fds,
02828 int timeout_milliseconds)
02829 {
02830 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02831
02832 if (timeout_milliseconds < -1)
02833 {
02834 timeout_milliseconds = -1;
02835 }
02836
02837 return poll (fds,
02838 n_fds,
02839 timeout_milliseconds);
02840 #else
02841
02842 fd_set read_set, write_set, err_set;
02843 int max_fd = 0;
02844 int i;
02845 struct timeval tv;
02846 int ready;
02847
02848 FD_ZERO (&read_set);
02849 FD_ZERO (&write_set);
02850 FD_ZERO (&err_set);
02851
02852 for (i = 0; i < n_fds; i++)
02853 {
02854 DBusPollFD *fdp = &fds[i];
02855
02856 if (fdp->events & _DBUS_POLLIN)
02857 FD_SET (fdp->fd, &read_set);
02858
02859 if (fdp->events & _DBUS_POLLOUT)
02860 FD_SET (fdp->fd, &write_set);
02861
02862 FD_SET (fdp->fd, &err_set);
02863
02864 max_fd = MAX (max_fd, fdp->fd);
02865 }
02866
02867 tv.tv_sec = timeout_milliseconds / 1000;
02868 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02869
02870 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02871 timeout_milliseconds < 0 ? NULL : &tv);
02872
02873 if (ready > 0)
02874 {
02875 for (i = 0; i < n_fds; i++)
02876 {
02877 DBusPollFD *fdp = &fds[i];
02878
02879 fdp->revents = 0;
02880
02881 if (FD_ISSET (fdp->fd, &read_set))
02882 fdp->revents |= _DBUS_POLLIN;
02883
02884 if (FD_ISSET (fdp->fd, &write_set))
02885 fdp->revents |= _DBUS_POLLOUT;
02886
02887 if (FD_ISSET (fdp->fd, &err_set))
02888 fdp->revents |= _DBUS_POLLERR;
02889 }
02890 }
02891
02892 return ready;
02893 #endif
02894 }
02895
02903 void
02904 _dbus_get_monotonic_time (long *tv_sec,
02905 long *tv_usec)
02906 {
02907 #ifdef HAVE_MONOTONIC_CLOCK
02908 struct timespec ts;
02909 clock_gettime (CLOCK_MONOTONIC, &ts);
02910
02911 if (tv_sec)
02912 *tv_sec = ts.tv_sec;
02913 if (tv_usec)
02914 *tv_usec = ts.tv_nsec / 1000;
02915 #else
02916 struct timeval t;
02917
02918 gettimeofday (&t, NULL);
02919
02920 if (tv_sec)
02921 *tv_sec = t.tv_sec;
02922 if (tv_usec)
02923 *tv_usec = t.tv_usec;
02924 #endif
02925 }
02926
02934 void
02935 _dbus_get_real_time (long *tv_sec,
02936 long *tv_usec)
02937 {
02938 struct timeval t;
02939
02940 gettimeofday (&t, NULL);
02941
02942 if (tv_sec)
02943 *tv_sec = t.tv_sec;
02944 if (tv_usec)
02945 *tv_usec = t.tv_usec;
02946 }
02947
02956 dbus_bool_t
02957 _dbus_ensure_directory (const DBusString *filename,
02958 DBusError *error)
02959 {
02960 const char *filename_c;
02961
02962 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02963
02964 filename_c = _dbus_string_get_const_data (filename);
02965
02966 if (mkdir (filename_c, 0700) < 0)
02967 {
02968 if (errno == EEXIST)
02969 return TRUE;
02970
02971 dbus_set_error (error, DBUS_ERROR_FAILED,
02972 "Failed to create directory %s: %s\n",
02973 filename_c, _dbus_strerror (errno));
02974 return FALSE;
02975 }
02976 else
02977 return TRUE;
02978 }
02979
02988 dbus_bool_t
02989 _dbus_create_directory (const DBusString *filename,
02990 DBusError *error)
02991 {
02992 const char *filename_c;
02993
02994 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02995
02996 filename_c = _dbus_string_get_const_data (filename);
02997
02998 if (mkdir (filename_c, 0700) < 0)
02999 {
03000 dbus_set_error (error, DBUS_ERROR_FAILED,
03001 "Failed to create directory %s: %s\n",
03002 filename_c, _dbus_strerror (errno));
03003 return FALSE;
03004 }
03005 else
03006 return TRUE;
03007 }
03008
03019 dbus_bool_t
03020 _dbus_concat_dir_and_file (DBusString *dir,
03021 const DBusString *next_component)
03022 {
03023 dbus_bool_t dir_ends_in_slash;
03024 dbus_bool_t file_starts_with_slash;
03025
03026 if (_dbus_string_get_length (dir) == 0 ||
03027 _dbus_string_get_length (next_component) == 0)
03028 return TRUE;
03029
03030 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
03031 _dbus_string_get_length (dir) - 1);
03032
03033 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
03034
03035 if (dir_ends_in_slash && file_starts_with_slash)
03036 {
03037 _dbus_string_shorten (dir, 1);
03038 }
03039 else if (!(dir_ends_in_slash || file_starts_with_slash))
03040 {
03041 if (!_dbus_string_append_byte (dir, '/'))
03042 return FALSE;
03043 }
03044
03045 return _dbus_string_copy (next_component, 0, dir,
03046 _dbus_string_get_length (dir));
03047 }
03048
03050 #define NANOSECONDS_PER_SECOND 1000000000
03051
03052 #define MICROSECONDS_PER_SECOND 1000000
03053
03054 #define MILLISECONDS_PER_SECOND 1000
03055
03056 #define NANOSECONDS_PER_MILLISECOND 1000000
03057
03058 #define MICROSECONDS_PER_MILLISECOND 1000
03059
03064 void
03065 _dbus_sleep_milliseconds (int milliseconds)
03066 {
03067 #ifdef HAVE_NANOSLEEP
03068 struct timespec req;
03069 struct timespec rem;
03070
03071 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
03072 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
03073 rem.tv_sec = 0;
03074 rem.tv_nsec = 0;
03075
03076 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
03077 req = rem;
03078 #elif defined (HAVE_USLEEP)
03079 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
03080 #else
03081 sleep (MAX (milliseconds / 1000, 1));
03082 #endif
03083 }
03084
03094 dbus_bool_t
03095 _dbus_generate_random_bytes (DBusString *str,
03096 int n_bytes,
03097 DBusError *error)
03098 {
03099 int old_len;
03100 int fd;
03101 int result;
03102
03103 old_len = _dbus_string_get_length (str);
03104 fd = -1;
03105
03106
03107 fd = open ("/dev/urandom", O_RDONLY);
03108
03109 if (fd < 0)
03110 {
03111 dbus_set_error (error, _dbus_error_from_errno (errno),
03112 "Could not open /dev/urandom: %s",
03113 _dbus_strerror (errno));
03114 return FALSE;
03115 }
03116
03117 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
03118
03119 result = _dbus_read (fd, str, n_bytes);
03120
03121 if (result != n_bytes)
03122 {
03123 if (result < 0)
03124 dbus_set_error (error, _dbus_error_from_errno (errno),
03125 "Could not read /dev/urandom: %s",
03126 _dbus_strerror (errno));
03127 else
03128 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
03129 "Short read from /dev/urandom");
03130
03131 _dbus_close (fd, NULL);
03132 _dbus_string_set_length (str, old_len);
03133 return FALSE;
03134 }
03135
03136 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
03137 n_bytes);
03138
03139 _dbus_close (fd, NULL);
03140
03141 return TRUE;
03142 }
03143
03149 void
03150 _dbus_exit (int code)
03151 {
03152 _exit (code);
03153 }
03154
03163 const char*
03164 _dbus_strerror (int error_number)
03165 {
03166 const char *msg;
03167
03168 msg = strerror (error_number);
03169 if (msg == NULL)
03170 msg = "unknown";
03171
03172 return msg;
03173 }
03174
03178 void
03179 _dbus_disable_sigpipe (void)
03180 {
03181 signal (SIGPIPE, SIG_IGN);
03182 }
03183
03191 void
03192 _dbus_fd_set_close_on_exec (int fd)
03193 {
03194 int val;
03195
03196 val = fcntl (fd, F_GETFD, 0);
03197
03198 if (val < 0)
03199 return;
03200
03201 val |= FD_CLOEXEC;
03202
03203 fcntl (fd, F_SETFD, val);
03204 }
03205
03213 dbus_bool_t
03214 _dbus_close (int fd,
03215 DBusError *error)
03216 {
03217 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03218
03219 again:
03220 if (close (fd) < 0)
03221 {
03222 if (errno == EINTR)
03223 goto again;
03224
03225 dbus_set_error (error, _dbus_error_from_errno (errno),
03226 "Could not close fd %d", fd);
03227 return FALSE;
03228 }
03229
03230 return TRUE;
03231 }
03232
03241 int
03242 _dbus_dup(int fd,
03243 DBusError *error)
03244 {
03245 int new_fd;
03246
03247 #ifdef F_DUPFD_CLOEXEC
03248 dbus_bool_t cloexec_done;
03249
03250 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
03251 cloexec_done = new_fd >= 0;
03252
03253 if (new_fd < 0 && errno == EINVAL)
03254 #endif
03255 {
03256 new_fd = fcntl(fd, F_DUPFD, 3);
03257 }
03258
03259 if (new_fd < 0) {
03260
03261 dbus_set_error (error, _dbus_error_from_errno (errno),
03262 "Could not duplicate fd %d", fd);
03263 return -1;
03264 }
03265
03266 #ifdef F_DUPFD_CLOEXEC
03267 if (!cloexec_done)
03268 #endif
03269 {
03270 _dbus_fd_set_close_on_exec(new_fd);
03271 }
03272
03273 return new_fd;
03274 }
03275
03283 dbus_bool_t
03284 _dbus_set_socket_nonblocking (DBusSocket fd,
03285 DBusError *error)
03286 {
03287 return _dbus_set_fd_nonblocking (fd.fd, error);
03288 }
03289
03290 static dbus_bool_t
03291 _dbus_set_fd_nonblocking (int fd,
03292 DBusError *error)
03293 {
03294 int val;
03295
03296 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03297
03298 val = fcntl (fd, F_GETFL, 0);
03299 if (val < 0)
03300 {
03301 dbus_set_error (error, _dbus_error_from_errno (errno),
03302 "Failed to get flags from file descriptor %d: %s",
03303 fd, _dbus_strerror (errno));
03304 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
03305 _dbus_strerror (errno));
03306 return FALSE;
03307 }
03308
03309 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
03310 {
03311 dbus_set_error (error, _dbus_error_from_errno (errno),
03312 "Failed to set nonblocking flag of file descriptor %d: %s",
03313 fd, _dbus_strerror (errno));
03314 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
03315 fd, _dbus_strerror (errno));
03316
03317 return FALSE;
03318 }
03319
03320 return TRUE;
03321 }
03322
03328 void
03329 _dbus_print_backtrace (void)
03330 {
03331 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
03332 void *bt[500];
03333 int bt_size;
03334 int i;
03335 char **syms;
03336
03337 bt_size = backtrace (bt, 500);
03338
03339 syms = backtrace_symbols (bt, bt_size);
03340
03341 i = 0;
03342 while (i < bt_size)
03343 {
03344
03345 fprintf (stderr, " %s\n", syms[i]);
03346 ++i;
03347 }
03348 fflush (stderr);
03349
03350 free (syms);
03351 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
03352 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
03353 #else
03354 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
03355 #endif
03356 }
03357
03370 dbus_bool_t
03371 _dbus_socketpair (DBusSocket *fd1,
03372 DBusSocket *fd2,
03373 dbus_bool_t blocking,
03374 DBusError *error)
03375 {
03376 #ifdef HAVE_SOCKETPAIR
03377 int fds[2];
03378 int retval;
03379
03380 #ifdef SOCK_CLOEXEC
03381 dbus_bool_t cloexec_done;
03382
03383 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
03384 cloexec_done = retval >= 0;
03385
03386 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
03387 #endif
03388 {
03389 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
03390 }
03391
03392 if (retval < 0)
03393 {
03394 dbus_set_error (error, _dbus_error_from_errno (errno),
03395 "Could not create full-duplex pipe");
03396 return FALSE;
03397 }
03398
03399 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03400
03401 #ifdef SOCK_CLOEXEC
03402 if (!cloexec_done)
03403 #endif
03404 {
03405 _dbus_fd_set_close_on_exec (fds[0]);
03406 _dbus_fd_set_close_on_exec (fds[1]);
03407 }
03408
03409 if (!blocking &&
03410 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03411 !_dbus_set_fd_nonblocking (fds[1], NULL)))
03412 {
03413 dbus_set_error (error, _dbus_error_from_errno (errno),
03414 "Could not set full-duplex pipe nonblocking");
03415
03416 _dbus_close (fds[0], NULL);
03417 _dbus_close (fds[1], NULL);
03418
03419 return FALSE;
03420 }
03421
03422 fd1->fd = fds[0];
03423 fd2->fd = fds[1];
03424
03425 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03426 fd1->fd, fd2->fd);
03427
03428 return TRUE;
03429 #else
03430 _dbus_warn ("_dbus_socketpair() not implemented on this OS\n");
03431 dbus_set_error (error, DBUS_ERROR_FAILED,
03432 "_dbus_socketpair() not implemented on this OS");
03433 return FALSE;
03434 #endif
03435 }
03436
03445 int
03446 _dbus_printf_string_upper_bound (const char *format,
03447 va_list args)
03448 {
03449 char static_buf[1024];
03450 int bufsize = sizeof (static_buf);
03451 int len;
03452 va_list args_copy;
03453
03454 DBUS_VA_COPY (args_copy, args);
03455 len = vsnprintf (static_buf, bufsize, format, args_copy);
03456 va_end (args_copy);
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466 if (len == bufsize)
03467 {
03468
03469
03470
03471
03472 DBUS_VA_COPY (args_copy, args);
03473
03474 if (vsnprintf (static_buf, 1, format, args_copy) == 1)
03475 len = -1;
03476
03477 va_end (args_copy);
03478 }
03479
03480
03481
03482 while (len < 0)
03483 {
03484 char *buf;
03485
03486 bufsize *= 2;
03487
03488 buf = dbus_malloc (bufsize);
03489
03490 if (buf == NULL)
03491 return -1;
03492
03493 DBUS_VA_COPY (args_copy, args);
03494 len = vsnprintf (buf, bufsize, format, args_copy);
03495 va_end (args_copy);
03496
03497 dbus_free (buf);
03498
03499
03500
03501
03502 if (len == bufsize)
03503 len = -1;
03504 }
03505
03506 return len;
03507 }
03508
03515 const char*
03516 _dbus_get_tmpdir(void)
03517 {
03518
03519 static const char* tmpdir = NULL;
03520
03521 if (!_DBUS_LOCK (sysdeps))
03522 return NULL;
03523
03524 if (tmpdir == NULL)
03525 {
03526
03527
03528
03529
03530 if (tmpdir == NULL)
03531 tmpdir = getenv("TMPDIR");
03532
03533
03534
03535
03536 if (tmpdir == NULL)
03537 tmpdir = getenv("TMP");
03538 if (tmpdir == NULL)
03539 tmpdir = getenv("TEMP");
03540
03541
03542 if (tmpdir == NULL)
03543 tmpdir = "/tmp";
03544 }
03545
03546 _DBUS_UNLOCK (sysdeps);
03547
03548 _dbus_assert(tmpdir != NULL);
03549
03550 return tmpdir;
03551 }
03552
03553 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
03554
03573 static dbus_bool_t
03574 _read_subprocess_line_argv (const char *progpath,
03575 dbus_bool_t path_fallback,
03576 char * const *argv,
03577 DBusString *result,
03578 DBusError *error)
03579 {
03580 int result_pipe[2] = { -1, -1 };
03581 int errors_pipe[2] = { -1, -1 };
03582 pid_t pid;
03583 int ret;
03584 int status;
03585 int orig_len;
03586
03587 dbus_bool_t retval;
03588 sigset_t new_set, old_set;
03589
03590 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03591 retval = FALSE;
03592
03593
03594
03595
03596
03597 sigemptyset (&new_set);
03598 sigaddset (&new_set, SIGCHLD);
03599 sigprocmask (SIG_BLOCK, &new_set, &old_set);
03600
03601 orig_len = _dbus_string_get_length (result);
03602
03603 #define READ_END 0
03604 #define WRITE_END 1
03605 if (pipe (result_pipe) < 0)
03606 {
03607 dbus_set_error (error, _dbus_error_from_errno (errno),
03608 "Failed to create a pipe to call %s: %s",
03609 progpath, _dbus_strerror (errno));
03610 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03611 progpath, _dbus_strerror (errno));
03612 goto out;
03613 }
03614 if (pipe (errors_pipe) < 0)
03615 {
03616 dbus_set_error (error, _dbus_error_from_errno (errno),
03617 "Failed to create a pipe to call %s: %s",
03618 progpath, _dbus_strerror (errno));
03619 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03620 progpath, _dbus_strerror (errno));
03621 goto out;
03622 }
03623
03624 pid = fork ();
03625 if (pid < 0)
03626 {
03627 dbus_set_error (error, _dbus_error_from_errno (errno),
03628 "Failed to fork() to call %s: %s",
03629 progpath, _dbus_strerror (errno));
03630 _dbus_verbose ("Failed to fork() to call %s: %s\n",
03631 progpath, _dbus_strerror (errno));
03632 goto out;
03633 }
03634
03635 if (pid == 0)
03636 {
03637
03638 int fd;
03639
03640 fd = open ("/dev/null", O_RDWR);
03641 if (fd == -1)
03642
03643 _exit (1);
03644
03645 _dbus_verbose ("/dev/null fd %d opened\n", fd);
03646
03647
03648 close (result_pipe[READ_END]);
03649 close (errors_pipe[READ_END]);
03650
03651 if (dup2 (fd, 0) == -1)
03652 _exit (1);
03653 if (dup2 (result_pipe[WRITE_END], 1) == -1)
03654 _exit (1);
03655 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03656 _exit (1);
03657
03658 _dbus_close_all ();
03659
03660 sigprocmask (SIG_SETMASK, &old_set, NULL);
03661
03662
03663 if (progpath[0] == '/')
03664 {
03665 execv (progpath, argv);
03666
03667
03668
03669
03670
03671
03672 if (path_fallback)
03673
03674 execvp (strrchr (progpath, '/')+1, argv);
03675 }
03676 else
03677 execvp (progpath, argv);
03678
03679
03680 _exit (1);
03681 }
03682
03683
03684 close (result_pipe[WRITE_END]);
03685 close (errors_pipe[WRITE_END]);
03686 result_pipe[WRITE_END] = -1;
03687 errors_pipe[WRITE_END] = -1;
03688
03689 ret = 0;
03690 do
03691 {
03692 ret = _dbus_read (result_pipe[READ_END], result, 1024);
03693 }
03694 while (ret > 0);
03695
03696
03697 do
03698 {
03699 ret = waitpid (pid, &status, 0);
03700 }
03701 while (ret == -1 && errno == EINTR);
03702
03703
03704
03705 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03706 {
03707
03708 DBusString error_message;
03709 if (!_dbus_string_init (&error_message))
03710 {
03711 _DBUS_SET_OOM (error);
03712 goto out;
03713 }
03714
03715 ret = 0;
03716 do
03717 {
03718 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03719 }
03720 while (ret > 0);
03721
03722 _dbus_string_set_length (result, orig_len);
03723 if (_dbus_string_get_length (&error_message) > 0)
03724 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03725 "%s terminated abnormally with the following error: %s",
03726 progpath, _dbus_string_get_data (&error_message));
03727 else
03728 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03729 "%s terminated abnormally without any error message",
03730 progpath);
03731 goto out;
03732 }
03733
03734 retval = TRUE;
03735
03736 out:
03737 sigprocmask (SIG_SETMASK, &old_set, NULL);
03738
03739 if (retval)
03740 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03741 else
03742 _DBUS_ASSERT_ERROR_IS_SET (error);
03743
03744 if (result_pipe[0] != -1)
03745 close (result_pipe[0]);
03746 if (result_pipe[1] != -1)
03747 close (result_pipe[1]);
03748 if (errors_pipe[0] != -1)
03749 close (errors_pipe[0]);
03750 if (errors_pipe[1] != -1)
03751 close (errors_pipe[1]);
03752
03753 return retval;
03754 }
03755 #endif
03756
03769 dbus_bool_t
03770 _dbus_get_autolaunch_address (const char *scope,
03771 DBusString *address,
03772 DBusError *error)
03773 {
03774 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03775
03776
03777
03778 const char *display;
03779 char *progpath;
03780 char *argv[6];
03781 int i;
03782 DBusString uuid;
03783 dbus_bool_t retval;
03784
03785 if (_dbus_check_setuid ())
03786 {
03787 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03788 "Unable to autolaunch when setuid");
03789 return FALSE;
03790 }
03791
03792 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03793 retval = FALSE;
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803 display = _dbus_getenv ("DISPLAY");
03804
03805 if (display == NULL || display[0] == '\0')
03806 {
03807 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03808 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03809 return FALSE;
03810 }
03811
03812 if (!_dbus_string_init (&uuid))
03813 {
03814 _DBUS_SET_OOM (error);
03815 return FALSE;
03816 }
03817
03818 if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
03819 {
03820 goto out;
03821 }
03822
03823 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
03824 if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
03825 progpath = TEST_BUS_LAUNCH_BINARY;
03826 else
03827 #endif
03828 progpath = DBUS_BINDIR "/dbus-launch";
03829
03830
03831
03832
03833
03834 i = 0;
03835 argv[i] = "dbus-launch";
03836 ++i;
03837 argv[i] = "--autolaunch";
03838 ++i;
03839 argv[i] = _dbus_string_get_data (&uuid);
03840 ++i;
03841 argv[i] = "--binary-syntax";
03842 ++i;
03843 argv[i] = "--close-stderr";
03844 ++i;
03845 argv[i] = NULL;
03846 ++i;
03847
03848 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03849
03850 retval = _read_subprocess_line_argv (progpath,
03851 TRUE,
03852 argv, address, error);
03853
03854 out:
03855 _dbus_string_free (&uuid);
03856 return retval;
03857 #else
03858 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03859 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03860 "set your DBUS_SESSION_BUS_ADDRESS instead");
03861 return FALSE;
03862 #endif
03863 }
03864
03883 dbus_bool_t
03884 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
03885 dbus_bool_t create_if_not_found,
03886 DBusError *error)
03887 {
03888 DBusString filename;
03889 dbus_bool_t b;
03890 Dl_info info;
03891
03892 if (dladdr(_dbus_read_local_machine_uuid, &info) && info.dli_fname) {
03893 const char *begin = info.dli_fname;
03894 const char *end = strrchr(begin, '/');
03895
03896 if (end) {
03897 _dbus_string_init_const_len (&filename, begin, end - begin);
03898 _dbus_string_append (&filename, "/../var/lib/dbus/machine-id");
03899
03900 if (_dbus_read_uuid_file (&filename, machine_id, FALSE, error))
03901 return TRUE;
03902
03903 dbus_error_free (error);
03904 }
03905 }
03906
03907 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03908
03909 b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03910 if (b)
03911 return TRUE;
03912
03913 dbus_error_free (error);
03914
03915
03916 _dbus_string_init_const (&filename, "/etc/machine-id");
03917 b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03918
03919 if (b)
03920 {
03921
03922
03923 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03924 _dbus_write_uuid_file (&filename, machine_id, NULL);
03925
03926 return TRUE;
03927 }
03928
03929 if (!create_if_not_found)
03930 return FALSE;
03931
03932
03933 dbus_error_free (error);
03934 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03935
03936 if (!_dbus_generate_uuid (machine_id, error))
03937 return FALSE;
03938
03939 return _dbus_write_uuid_file (&filename, machine_id, error);
03940 }
03941
03949 dbus_bool_t
03950 _dbus_lookup_launchd_socket (DBusString *socket_path,
03951 const char *launchd_env_var,
03952 DBusError *error)
03953 {
03954 #ifdef DBUS_ENABLE_LAUNCHD
03955 char *argv[4];
03956 int i;
03957
03958 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03959
03960 if (_dbus_check_setuid ())
03961 {
03962 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03963 "Unable to find launchd socket when setuid");
03964 return FALSE;
03965 }
03966
03967 i = 0;
03968 argv[i] = "launchctl";
03969 ++i;
03970 argv[i] = "getenv";
03971 ++i;
03972 argv[i] = (char*)launchd_env_var;
03973 ++i;
03974 argv[i] = NULL;
03975 ++i;
03976
03977 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03978
03979 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03980 {
03981 return FALSE;
03982 }
03983
03984
03985 if (_dbus_string_get_length(socket_path) == 0)
03986 {
03987 return FALSE;
03988 }
03989
03990
03991 _dbus_string_shorten(socket_path, 1);
03992 return TRUE;
03993 #else
03994 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03995 "can't lookup socket from launchd; launchd support not compiled in");
03996 return FALSE;
03997 #endif
03998 }
03999
04000 #ifdef DBUS_ENABLE_LAUNCHD
04001 static dbus_bool_t
04002 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
04003 {
04004 dbus_bool_t valid_socket;
04005 DBusString socket_path;
04006
04007 if (_dbus_check_setuid ())
04008 {
04009 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
04010 "Unable to find launchd socket when setuid");
04011 return FALSE;
04012 }
04013
04014 if (!_dbus_string_init (&socket_path))
04015 {
04016 _DBUS_SET_OOM (error);
04017 return FALSE;
04018 }
04019
04020 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
04021
04022 if (dbus_error_is_set(error))
04023 {
04024 _dbus_string_free(&socket_path);
04025 return FALSE;
04026 }
04027
04028 if (!valid_socket)
04029 {
04030 dbus_set_error(error, "no socket path",
04031 "launchd did not provide a socket path, "
04032 "verify that org.freedesktop.dbus-session.plist is loaded!");
04033 _dbus_string_free(&socket_path);
04034 return FALSE;
04035 }
04036 if (!_dbus_string_append (address, "unix:path="))
04037 {
04038 _DBUS_SET_OOM (error);
04039 _dbus_string_free(&socket_path);
04040 return FALSE;
04041 }
04042 if (!_dbus_string_copy (&socket_path, 0, address,
04043 _dbus_string_get_length (address)))
04044 {
04045 _DBUS_SET_OOM (error);
04046 _dbus_string_free(&socket_path);
04047 return FALSE;
04048 }
04049
04050 _dbus_string_free(&socket_path);
04051 return TRUE;
04052 }
04053 #endif
04054
04055 dbus_bool_t
04056 _dbus_lookup_user_bus (dbus_bool_t *supported,
04057 DBusString *address,
04058 DBusError *error)
04059 {
04060 const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
04061 dbus_bool_t ret = FALSE;
04062 struct stat stbuf;
04063 DBusString user_bus_path;
04064
04065 if (runtime_dir == NULL)
04066 {
04067 _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
04068 *supported = FALSE;
04069 return TRUE;
04070 }
04071
04072 if (!_dbus_string_init (&user_bus_path))
04073 {
04074 _DBUS_SET_OOM (error);
04075 return FALSE;
04076 }
04077
04078 if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
04079 {
04080 _DBUS_SET_OOM (error);
04081 goto out;
04082 }
04083
04084 if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
04085 {
04086 _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
04087 _dbus_strerror (errno));
04088 *supported = FALSE;
04089 ret = TRUE;
04090 goto out;
04091 }
04092
04093 if (stbuf.st_uid != getuid ())
04094 {
04095 _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
04096 (long) stbuf.st_uid, (long) getuid ());
04097 *supported = FALSE;
04098 ret = TRUE;
04099 goto out;
04100 }
04101
04102 if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
04103 {
04104 _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
04105 (long) stbuf.st_mode);
04106 *supported = FALSE;
04107 ret = TRUE;
04108 goto out;
04109 }
04110
04111 if (!_dbus_string_append (address, "unix:path=") ||
04112 !_dbus_address_append_escaped (address, &user_bus_path))
04113 {
04114 _DBUS_SET_OOM (error);
04115 goto out;
04116 }
04117
04118 *supported = TRUE;
04119 ret = TRUE;
04120
04121 out:
04122 _dbus_string_free (&user_bus_path);
04123 return ret;
04124 }
04125
04145 dbus_bool_t
04146 _dbus_lookup_session_address (dbus_bool_t *supported,
04147 DBusString *address,
04148 DBusError *error)
04149 {
04150 #ifdef DBUS_ENABLE_LAUNCHD
04151 *supported = TRUE;
04152 return _dbus_lookup_session_address_launchd (address, error);
04153 #else
04154 *supported = FALSE;
04155
04156 if (!_dbus_lookup_user_bus (supported, address, error))
04157 return FALSE;
04158 else if (*supported)
04159 return TRUE;
04160
04161
04162
04163
04164
04165
04166 return TRUE;
04167 #endif
04168 }
04169
04177 void
04178 _dbus_flush_caches (void)
04179 {
04180 _dbus_user_database_flush_system ();
04181 }
04182
04196 dbus_bool_t
04197 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
04198 DBusCredentials *credentials)
04199 {
04200 DBusString homedir;
04201 DBusString dotdir;
04202 dbus_uid_t uid;
04203
04204 _dbus_assert (credentials != NULL);
04205 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
04206
04207 if (!_dbus_string_init (&homedir))
04208 return FALSE;
04209
04210 uid = _dbus_credentials_get_unix_uid (credentials);
04211 _dbus_assert (uid != DBUS_UID_UNSET);
04212
04213 if (!_dbus_homedir_from_uid (uid, &homedir))
04214 goto failed;
04215
04216 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
04217 {
04218 const char *override;
04219
04220 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
04221 if (override != NULL && *override != '\0')
04222 {
04223 _dbus_string_set_length (&homedir, 0);
04224 if (!_dbus_string_append (&homedir, override))
04225 goto failed;
04226
04227 _dbus_verbose ("Using fake homedir for testing: %s\n",
04228 _dbus_string_get_const_data (&homedir));
04229 }
04230 else
04231 {
04232
04233
04234 static dbus_bool_t already_warned = FALSE;
04235 if (!already_warned)
04236 {
04237 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
04238 already_warned = TRUE;
04239 }
04240 }
04241 }
04242 #endif
04243
04244 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
04245 if (!_dbus_concat_dir_and_file (&homedir,
04246 &dotdir))
04247 goto failed;
04248
04249 if (!_dbus_string_copy (&homedir, 0,
04250 directory, _dbus_string_get_length (directory))) {
04251 goto failed;
04252 }
04253
04254 _dbus_string_free (&homedir);
04255 return TRUE;
04256
04257 failed:
04258 _dbus_string_free (&homedir);
04259 return FALSE;
04260 }
04261
04262
04263 dbus_bool_t
04264 _dbus_daemon_publish_session_bus_address (const char* addr,
04265 const char *scope)
04266 {
04267 return TRUE;
04268 }
04269
04270
04271 void
04272 _dbus_daemon_unpublish_session_bus_address (void)
04273 {
04274
04275 }
04276
04283 dbus_bool_t
04284 _dbus_get_is_errno_eagain_or_ewouldblock (int e)
04285 {
04286 return e == EAGAIN || e == EWOULDBLOCK;
04287 }
04288
04296 dbus_bool_t
04297 _dbus_delete_directory (const DBusString *filename,
04298 DBusError *error)
04299 {
04300 const char *filename_c;
04301
04302 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
04303
04304 filename_c = _dbus_string_get_const_data (filename);
04305
04306 if (rmdir (filename_c) != 0)
04307 {
04308 dbus_set_error (error, DBUS_ERROR_FAILED,
04309 "Failed to remove directory %s: %s\n",
04310 filename_c, _dbus_strerror (errno));
04311 return FALSE;
04312 }
04313
04314 return TRUE;
04315 }
04316
04324 dbus_bool_t
04325 _dbus_socket_can_pass_unix_fd (DBusSocket fd)
04326 {
04327 #ifdef SCM_RIGHTS
04328 union {
04329 struct sockaddr sa;
04330 struct sockaddr_storage storage;
04331 struct sockaddr_un un;
04332 } sa_buf;
04333
04334 socklen_t sa_len = sizeof(sa_buf);
04335
04336 _DBUS_ZERO(sa_buf);
04337
04338 if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
04339 return FALSE;
04340
04341 return sa_buf.sa.sa_family == AF_UNIX;
04342
04343 #else
04344 return FALSE;
04345
04346 #endif
04347 }
04348
04353 void
04354 _dbus_close_all (void)
04355 {
04356 int maxfds, i;
04357
04358 #ifdef __linux__
04359 DIR *d;
04360
04361
04362
04363
04364 d = opendir ("/proc/self/fd");
04365 if (d)
04366 {
04367 for (;;)
04368 {
04369 struct dirent buf, *de;
04370 int k, fd;
04371 long l;
04372 char *e = NULL;
04373
04374 k = readdir_r (d, &buf, &de);
04375 if (k != 0 || !de)
04376 break;
04377
04378 if (de->d_name[0] == '.')
04379 continue;
04380
04381 errno = 0;
04382 l = strtol (de->d_name, &e, 10);
04383 if (errno != 0 || e == NULL || *e != '\0')
04384 continue;
04385
04386 fd = (int) l;
04387 if (fd < 3)
04388 continue;
04389
04390 if (fd == dirfd (d))
04391 continue;
04392
04393 close (fd);
04394 }
04395
04396 closedir (d);
04397 return;
04398 }
04399 #endif
04400
04401 maxfds = sysconf (_SC_OPEN_MAX);
04402
04403
04404
04405
04406 if (maxfds < 0)
04407 maxfds = 1024;
04408
04409
04410 for (i = 3; i < maxfds; i++)
04411 close (i);
04412 }
04413
04423 dbus_bool_t
04424 _dbus_check_setuid (void)
04425 {
04426
04427
04428
04429 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
04430 {
04431
04432 extern int __libc_enable_secure;
04433 return __libc_enable_secure;
04434 }
04435 #elif defined(HAVE_ISSETUGID)
04436
04437 return issetugid ();
04438 #else
04439 uid_t ruid, euid, suid;
04440 gid_t rgid, egid, sgid;
04441
04442
04443
04444 static dbus_bool_t check_setuid_initialised;
04445 static dbus_bool_t is_setuid;
04446
04447 if (_DBUS_UNLIKELY (!check_setuid_initialised))
04448 {
04449 #ifdef HAVE_GETRESUID
04450 if (getresuid (&ruid, &euid, &suid) != 0 ||
04451 getresgid (&rgid, &egid, &sgid) != 0)
04452 #endif
04453 {
04454 suid = ruid = getuid ();
04455 sgid = rgid = getgid ();
04456 euid = geteuid ();
04457 egid = getegid ();
04458 }
04459
04460 check_setuid_initialised = TRUE;
04461 is_setuid = (ruid != euid || ruid != suid ||
04462 rgid != egid || rgid != sgid);
04463
04464 }
04465 return is_setuid;
04466 #endif
04467 }
04468
04476 dbus_bool_t
04477 _dbus_append_address_from_socket (DBusSocket fd,
04478 DBusString *address,
04479 DBusError *error)
04480 {
04481 union {
04482 struct sockaddr sa;
04483 struct sockaddr_storage storage;
04484 struct sockaddr_un un;
04485 struct sockaddr_in ipv4;
04486 struct sockaddr_in6 ipv6;
04487 } socket;
04488 char hostip[INET6_ADDRSTRLEN];
04489 int size = sizeof (socket);
04490 DBusString path_str;
04491
04492 if (getsockname (fd.fd, &socket.sa, &size))
04493 goto err;
04494
04495 switch (socket.sa.sa_family)
04496 {
04497 case AF_UNIX:
04498 if (socket.un.sun_path[0]=='\0')
04499 {
04500 _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
04501 if (_dbus_string_append (address, "unix:abstract=") &&
04502 _dbus_address_append_escaped (address, &path_str))
04503 return TRUE;
04504 }
04505 else
04506 {
04507 _dbus_string_init_const (&path_str, socket.un.sun_path);
04508 if (_dbus_string_append (address, "unix:path=") &&
04509 _dbus_address_append_escaped (address, &path_str))
04510 return TRUE;
04511 }
04512 break;
04513 case AF_INET:
04514 if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
04515 if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
04516 hostip, ntohs (socket.ipv4.sin_port)))
04517 return TRUE;
04518 break;
04519 #ifdef AF_INET6
04520 case AF_INET6:
04521 _dbus_string_init_const (&path_str, hostip);
04522 if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
04523 if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
04524 ntohs (socket.ipv6.sin6_port)) &&
04525 _dbus_address_append_escaped (address, &path_str))
04526 return TRUE;
04527 break;
04528 #endif
04529 default:
04530 dbus_set_error (error,
04531 _dbus_error_from_errno (EINVAL),
04532 "Failed to read address from socket: Unknown socket type.");
04533 return FALSE;
04534 }
04535 err:
04536 dbus_set_error (error,
04537 _dbus_error_from_errno (errno),
04538 "Failed to open socket: %s",
04539 _dbus_strerror (errno));
04540 return FALSE;
04541 }
04542
04543 int
04544 _dbus_save_socket_errno (void)
04545 {
04546 return errno;
04547 }
04548
04549 void
04550 _dbus_restore_socket_errno (int saved_errno)
04551 {
04552 errno = saved_errno;
04553 }
04554
04555