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-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037 #include "dbus-nonce.h"
00038
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 #include <stdio.h>
00045 #include <fcntl.h>
00046 #include <sys/socket.h>
00047 #include <dirent.h>
00048 #include <sys/un.h>
00049 #include <pwd.h>
00050 #include <time.h>
00051 #include <locale.h>
00052 #include <sys/time.h>
00053 #include <sys/stat.h>
00054 #include <sys/wait.h>
00055 #include <netinet/in.h>
00056 #include <netdb.h>
00057 #include <grp.h>
00058
00059 #ifdef HAVE_ERRNO_H
00060 #include <errno.h>
00061 #endif
00062 #ifdef HAVE_WRITEV
00063 #include <sys/uio.h>
00064 #endif
00065 #ifdef HAVE_POLL
00066 #include <sys/poll.h>
00067 #endif
00068 #ifdef HAVE_BACKTRACE
00069 #include <execinfo.h>
00070 #endif
00071 #ifdef HAVE_GETPEERUCRED
00072 #include <ucred.h>
00073 #endif
00074
00075 #ifdef HAVE_ADT
00076 #include <bsm/adt.h>
00077 #endif
00078
00079 #include "sd-daemon.h"
00080
00081 #ifndef O_BINARY
00082 #define O_BINARY 0
00083 #endif
00084
00085 #ifndef AI_ADDRCONFIG
00086 #define AI_ADDRCONFIG 0
00087 #endif
00088
00089 #ifndef HAVE_SOCKLEN_T
00090 #define socklen_t int
00091 #endif
00092
00093 static dbus_bool_t
00094 _dbus_open_socket (int *fd_p,
00095 int domain,
00096 int type,
00097 int protocol,
00098 DBusError *error)
00099 {
00100 #ifdef SOCK_CLOEXEC
00101 dbus_bool_t cloexec_done;
00102
00103 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00104 cloexec_done = *fd_p >= 0;
00105
00106
00107 if (*fd_p < 0 && errno == EINVAL)
00108 #endif
00109 {
00110 *fd_p = socket (domain, type, protocol);
00111 }
00112
00113 if (*fd_p >= 0)
00114 {
00115 #ifdef SOCK_CLOEXEC
00116 if (!cloexec_done)
00117 #endif
00118 {
00119 _dbus_fd_set_close_on_exec(*fd_p);
00120 }
00121
00122 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00123 return TRUE;
00124 }
00125 else
00126 {
00127 dbus_set_error(error,
00128 _dbus_error_from_errno (errno),
00129 "Failed to open socket: %s",
00130 _dbus_strerror (errno));
00131 return FALSE;
00132 }
00133 }
00134
00135 dbus_bool_t
00136 _dbus_open_tcp_socket (int *fd,
00137 DBusError *error)
00138 {
00139 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00140 }
00141
00152 dbus_bool_t
00153 _dbus_open_unix_socket (int *fd,
00154 DBusError *error)
00155 {
00156 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00157 }
00158
00167 dbus_bool_t
00168 _dbus_close_socket (int fd,
00169 DBusError *error)
00170 {
00171 return _dbus_close (fd, error);
00172 }
00173
00183 int
00184 _dbus_read_socket (int fd,
00185 DBusString *buffer,
00186 int count)
00187 {
00188 return _dbus_read (fd, buffer, count);
00189 }
00190
00201 int
00202 _dbus_write_socket (int fd,
00203 const DBusString *buffer,
00204 int start,
00205 int len)
00206 {
00207 #ifdef HAVE_DECL_MSG_NOSIGNAL
00208 const char *data;
00209 int bytes_written;
00210
00211 data = _dbus_string_get_const_data_len (buffer, start, len);
00212
00213 again:
00214
00215 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00216
00217 if (bytes_written < 0 && errno == EINTR)
00218 goto again;
00219
00220 return bytes_written;
00221
00222 #else
00223 return _dbus_write (fd, buffer, start, len);
00224 #endif
00225 }
00226
00239 int
00240 _dbus_read_socket_with_unix_fds (int fd,
00241 DBusString *buffer,
00242 int count,
00243 int *fds,
00244 int *n_fds) {
00245 #ifndef HAVE_UNIX_FD_PASSING
00246 int r;
00247
00248 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00249 return r;
00250
00251 *n_fds = 0;
00252 return r;
00253
00254 #else
00255 int bytes_read;
00256 int start;
00257 struct msghdr m;
00258 struct iovec iov;
00259
00260 _dbus_assert (count >= 0);
00261 _dbus_assert (*n_fds >= 0);
00262
00263 start = _dbus_string_get_length (buffer);
00264
00265 if (!_dbus_string_lengthen (buffer, count))
00266 {
00267 errno = ENOMEM;
00268 return -1;
00269 }
00270
00271 _DBUS_ZERO(iov);
00272 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00273 iov.iov_len = count;
00274
00275 _DBUS_ZERO(m);
00276 m.msg_iov = &iov;
00277 m.msg_iovlen = 1;
00278
00279
00280
00281
00282
00283 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00284
00285
00286
00287 m.msg_control = alloca(m.msg_controllen);
00288 memset(m.msg_control, 0, m.msg_controllen);
00289
00290 again:
00291
00292 bytes_read = recvmsg(fd, &m, 0
00293 #ifdef MSG_CMSG_CLOEXEC
00294 |MSG_CMSG_CLOEXEC
00295 #endif
00296 );
00297
00298 if (bytes_read < 0)
00299 {
00300 if (errno == EINTR)
00301 goto again;
00302 else
00303 {
00304
00305 _dbus_string_set_length (buffer, start);
00306 return -1;
00307 }
00308 }
00309 else
00310 {
00311 struct cmsghdr *cm;
00312 dbus_bool_t found = FALSE;
00313
00314 if (m.msg_flags & MSG_CTRUNC)
00315 {
00316
00317
00318
00319
00320
00321 errno = ENOSPC;
00322 _dbus_string_set_length (buffer, start);
00323 return -1;
00324 }
00325
00326 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00327 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00328 {
00329 unsigned i;
00330
00331 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
00332 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
00333
00334 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
00335 found = TRUE;
00336
00337
00338
00339
00340 for (i = 0; i < *n_fds; i++)
00341 _dbus_fd_set_close_on_exec(fds[i]);
00342
00343 break;
00344 }
00345
00346 if (!found)
00347 *n_fds = 0;
00348
00349
00350 _dbus_string_set_length (buffer, start + bytes_read);
00351
00352 #if 0
00353 if (bytes_read > 0)
00354 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00355 #endif
00356
00357 return bytes_read;
00358 }
00359 #endif
00360 }
00361
00362 int
00363 _dbus_write_socket_with_unix_fds(int fd,
00364 const DBusString *buffer,
00365 int start,
00366 int len,
00367 const int *fds,
00368 int n_fds) {
00369
00370 #ifndef HAVE_UNIX_FD_PASSING
00371
00372 if (n_fds > 0) {
00373 errno = ENOTSUP;
00374 return -1;
00375 }
00376
00377 return _dbus_write_socket(fd, buffer, start, len);
00378 #else
00379 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00380 #endif
00381 }
00382
00383 int
00384 _dbus_write_socket_with_unix_fds_two(int fd,
00385 const DBusString *buffer1,
00386 int start1,
00387 int len1,
00388 const DBusString *buffer2,
00389 int start2,
00390 int len2,
00391 const int *fds,
00392 int n_fds) {
00393
00394 #ifndef HAVE_UNIX_FD_PASSING
00395
00396 if (n_fds > 0) {
00397 errno = ENOTSUP;
00398 return -1;
00399 }
00400
00401 return _dbus_write_socket_two(fd,
00402 buffer1, start1, len1,
00403 buffer2, start2, len2);
00404 #else
00405
00406 struct msghdr m;
00407 struct cmsghdr *cm;
00408 struct iovec iov[2];
00409 int bytes_written;
00410
00411 _dbus_assert (len1 >= 0);
00412 _dbus_assert (len2 >= 0);
00413 _dbus_assert (n_fds >= 0);
00414
00415 _DBUS_ZERO(iov);
00416 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00417 iov[0].iov_len = len1;
00418
00419 if (buffer2)
00420 {
00421 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00422 iov[1].iov_len = len2;
00423 }
00424
00425 _DBUS_ZERO(m);
00426 m.msg_iov = iov;
00427 m.msg_iovlen = buffer2 ? 2 : 1;
00428
00429 if (n_fds > 0)
00430 {
00431 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00432 m.msg_control = alloca(m.msg_controllen);
00433 memset(m.msg_control, 0, m.msg_controllen);
00434
00435 cm = CMSG_FIRSTHDR(&m);
00436 cm->cmsg_level = SOL_SOCKET;
00437 cm->cmsg_type = SCM_RIGHTS;
00438 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00439 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00440 }
00441
00442 again:
00443
00444 bytes_written = sendmsg (fd, &m, 0
00445 #ifdef HAVE_DECL_MSG_NOSIGNAL
00446 |MSG_NOSIGNAL
00447 #endif
00448 );
00449
00450 if (bytes_written < 0 && errno == EINTR)
00451 goto again;
00452
00453 #if 0
00454 if (bytes_written > 0)
00455 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00456 #endif
00457
00458 return bytes_written;
00459 #endif
00460 }
00461
00475 int
00476 _dbus_write_socket_two (int fd,
00477 const DBusString *buffer1,
00478 int start1,
00479 int len1,
00480 const DBusString *buffer2,
00481 int start2,
00482 int len2)
00483 {
00484 #ifdef HAVE_DECL_MSG_NOSIGNAL
00485 struct iovec vectors[2];
00486 const char *data1;
00487 const char *data2;
00488 int bytes_written;
00489 struct msghdr m;
00490
00491 _dbus_assert (buffer1 != NULL);
00492 _dbus_assert (start1 >= 0);
00493 _dbus_assert (start2 >= 0);
00494 _dbus_assert (len1 >= 0);
00495 _dbus_assert (len2 >= 0);
00496
00497 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00498
00499 if (buffer2 != NULL)
00500 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00501 else
00502 {
00503 data2 = NULL;
00504 start2 = 0;
00505 len2 = 0;
00506 }
00507
00508 vectors[0].iov_base = (char*) data1;
00509 vectors[0].iov_len = len1;
00510 vectors[1].iov_base = (char*) data2;
00511 vectors[1].iov_len = len2;
00512
00513 _DBUS_ZERO(m);
00514 m.msg_iov = vectors;
00515 m.msg_iovlen = data2 ? 2 : 1;
00516
00517 again:
00518
00519 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00520
00521 if (bytes_written < 0 && errno == EINTR)
00522 goto again;
00523
00524 return bytes_written;
00525
00526 #else
00527 return _dbus_write_two (fd, buffer1, start1, len1,
00528 buffer2, start2, len2);
00529 #endif
00530 }
00531
00532 dbus_bool_t
00533 _dbus_socket_is_invalid (int fd)
00534 {
00535 return fd < 0 ? TRUE : FALSE;
00536 }
00537
00554 int
00555 _dbus_read (int fd,
00556 DBusString *buffer,
00557 int count)
00558 {
00559 int bytes_read;
00560 int start;
00561 char *data;
00562
00563 _dbus_assert (count >= 0);
00564
00565 start = _dbus_string_get_length (buffer);
00566
00567 if (!_dbus_string_lengthen (buffer, count))
00568 {
00569 errno = ENOMEM;
00570 return -1;
00571 }
00572
00573 data = _dbus_string_get_data_len (buffer, start, count);
00574
00575 again:
00576
00577 bytes_read = read (fd, data, count);
00578
00579 if (bytes_read < 0)
00580 {
00581 if (errno == EINTR)
00582 goto again;
00583 else
00584 {
00585
00586 _dbus_string_set_length (buffer, start);
00587 return -1;
00588 }
00589 }
00590 else
00591 {
00592
00593 _dbus_string_set_length (buffer, start + bytes_read);
00594
00595 #if 0
00596 if (bytes_read > 0)
00597 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00598 #endif
00599
00600 return bytes_read;
00601 }
00602 }
00603
00614 int
00615 _dbus_write (int fd,
00616 const DBusString *buffer,
00617 int start,
00618 int len)
00619 {
00620 const char *data;
00621 int bytes_written;
00622
00623 data = _dbus_string_get_const_data_len (buffer, start, len);
00624
00625 again:
00626
00627 bytes_written = write (fd, data, len);
00628
00629 if (bytes_written < 0 && errno == EINTR)
00630 goto again;
00631
00632 #if 0
00633 if (bytes_written > 0)
00634 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00635 #endif
00636
00637 return bytes_written;
00638 }
00639
00660 int
00661 _dbus_write_two (int fd,
00662 const DBusString *buffer1,
00663 int start1,
00664 int len1,
00665 const DBusString *buffer2,
00666 int start2,
00667 int len2)
00668 {
00669 _dbus_assert (buffer1 != NULL);
00670 _dbus_assert (start1 >= 0);
00671 _dbus_assert (start2 >= 0);
00672 _dbus_assert (len1 >= 0);
00673 _dbus_assert (len2 >= 0);
00674
00675 #ifdef HAVE_WRITEV
00676 {
00677 struct iovec vectors[2];
00678 const char *data1;
00679 const char *data2;
00680 int bytes_written;
00681
00682 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00683
00684 if (buffer2 != NULL)
00685 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00686 else
00687 {
00688 data2 = NULL;
00689 start2 = 0;
00690 len2 = 0;
00691 }
00692
00693 vectors[0].iov_base = (char*) data1;
00694 vectors[0].iov_len = len1;
00695 vectors[1].iov_base = (char*) data2;
00696 vectors[1].iov_len = len2;
00697
00698 again:
00699
00700 bytes_written = writev (fd,
00701 vectors,
00702 data2 ? 2 : 1);
00703
00704 if (bytes_written < 0 && errno == EINTR)
00705 goto again;
00706
00707 return bytes_written;
00708 }
00709 #else
00710 {
00711 int ret1;
00712
00713 ret1 = _dbus_write (fd, buffer1, start1, len1);
00714 if (ret1 == len1 && buffer2 != NULL)
00715 {
00716 ret2 = _dbus_write (fd, buffer2, start2, len2);
00717 if (ret2 < 0)
00718 ret2 = 0;
00719
00720 return ret1 + ret2;
00721 }
00722 else
00723 return ret1;
00724 }
00725 #endif
00726 }
00727
00728 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00729
00759 int
00760 _dbus_connect_unix_socket (const char *path,
00761 dbus_bool_t abstract,
00762 DBusError *error)
00763 {
00764 int fd;
00765 size_t path_len;
00766 struct sockaddr_un addr;
00767
00768 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00769
00770 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00771 path, abstract);
00772
00773
00774 if (!_dbus_open_unix_socket (&fd, error))
00775 {
00776 _DBUS_ASSERT_ERROR_IS_SET(error);
00777 return -1;
00778 }
00779 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00780
00781 _DBUS_ZERO (addr);
00782 addr.sun_family = AF_UNIX;
00783 path_len = strlen (path);
00784
00785 if (abstract)
00786 {
00787 #ifdef HAVE_ABSTRACT_SOCKETS
00788 addr.sun_path[0] = '\0';
00789 path_len++;
00790
00791 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00792 {
00793 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00794 "Abstract socket name too long\n");
00795 _dbus_close (fd, NULL);
00796 return -1;
00797 }
00798
00799 strncpy (&addr.sun_path[1], path, path_len);
00800
00801 #else
00802 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00803 "Operating system does not support abstract socket namespace\n");
00804 _dbus_close (fd, NULL);
00805 return -1;
00806 #endif
00807 }
00808 else
00809 {
00810 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00811 {
00812 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00813 "Socket name too long\n");
00814 _dbus_close (fd, NULL);
00815 return -1;
00816 }
00817
00818 strncpy (addr.sun_path, path, path_len);
00819 }
00820
00821 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00822 {
00823 dbus_set_error (error,
00824 _dbus_error_from_errno (errno),
00825 "Failed to connect to socket %s: %s",
00826 path, _dbus_strerror (errno));
00827
00828 _dbus_close (fd, NULL);
00829 fd = -1;
00830
00831 return -1;
00832 }
00833
00834 if (!_dbus_set_fd_nonblocking (fd, error))
00835 {
00836 _DBUS_ASSERT_ERROR_IS_SET (error);
00837
00838 _dbus_close (fd, NULL);
00839 fd = -1;
00840
00841 return -1;
00842 }
00843
00844 return fd;
00845 }
00846
00856 static dbus_bool_t
00857 _dbus_set_local_creds (int fd, dbus_bool_t on)
00858 {
00859 dbus_bool_t retval = TRUE;
00860
00861 #if defined(HAVE_CMSGCRED)
00862
00863
00864
00865 #elif defined(LOCAL_CREDS)
00866 int val = on ? 1 : 0;
00867 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00868 {
00869 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00870 retval = FALSE;
00871 }
00872 else
00873 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00874 on ? "enabled" : "disabled", fd);
00875 #endif
00876
00877 return retval;
00878 }
00879
00897 int
00898 _dbus_listen_unix_socket (const char *path,
00899 dbus_bool_t abstract,
00900 DBusError *error)
00901 {
00902 int listen_fd;
00903 struct sockaddr_un addr;
00904 size_t path_len;
00905 unsigned int reuseaddr;
00906
00907 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00908
00909 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00910 path, abstract);
00911
00912 if (!_dbus_open_unix_socket (&listen_fd, error))
00913 {
00914 _DBUS_ASSERT_ERROR_IS_SET(error);
00915 return -1;
00916 }
00917 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00918
00919 _DBUS_ZERO (addr);
00920 addr.sun_family = AF_UNIX;
00921 path_len = strlen (path);
00922
00923 if (abstract)
00924 {
00925 #ifdef HAVE_ABSTRACT_SOCKETS
00926
00927
00928
00929 addr.sun_path[0] = '\0';
00930 path_len++;
00931
00932 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00933 {
00934 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00935 "Abstract socket name too long\n");
00936 _dbus_close (listen_fd, NULL);
00937 return -1;
00938 }
00939
00940 strncpy (&addr.sun_path[1], path, path_len);
00941
00942 #else
00943 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00944 "Operating system does not support abstract socket namespace\n");
00945 _dbus_close (listen_fd, NULL);
00946 return -1;
00947 #endif
00948 }
00949 else
00950 {
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 {
00962 struct stat sb;
00963
00964 if (stat (path, &sb) == 0 &&
00965 S_ISSOCK (sb.st_mode))
00966 unlink (path);
00967 }
00968
00969 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00970 {
00971 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00972 "Abstract socket name too long\n");
00973 _dbus_close (listen_fd, NULL);
00974 return -1;
00975 }
00976
00977 strncpy (addr.sun_path, path, path_len);
00978 }
00979
00980 reuseaddr = 1;
00981 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
00982 {
00983 _dbus_warn ("Failed to set socket option\"%s\": %s",
00984 path, _dbus_strerror (errno));
00985 }
00986
00987 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00988 {
00989 dbus_set_error (error, _dbus_error_from_errno (errno),
00990 "Failed to bind socket \"%s\": %s",
00991 path, _dbus_strerror (errno));
00992 _dbus_close (listen_fd, NULL);
00993 return -1;
00994 }
00995
00996 if (listen (listen_fd, 30 ) < 0)
00997 {
00998 dbus_set_error (error, _dbus_error_from_errno (errno),
00999 "Failed to listen on socket \"%s\": %s",
01000 path, _dbus_strerror (errno));
01001 _dbus_close (listen_fd, NULL);
01002 return -1;
01003 }
01004
01005 if (!_dbus_set_local_creds (listen_fd, TRUE))
01006 {
01007 dbus_set_error (error, _dbus_error_from_errno (errno),
01008 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01009 path, _dbus_strerror (errno));
01010 close (listen_fd);
01011 return -1;
01012 }
01013
01014 if (!_dbus_set_fd_nonblocking (listen_fd, error))
01015 {
01016 _DBUS_ASSERT_ERROR_IS_SET (error);
01017 _dbus_close (listen_fd, NULL);
01018 return -1;
01019 }
01020
01021
01022
01023
01024 if (!abstract && chmod (path, 0777) < 0)
01025 _dbus_warn ("Could not set mode 0777 on socket %s\n",
01026 path);
01027
01028 return listen_fd;
01029 }
01030
01041 int
01042 _dbus_listen_systemd_sockets (int **fds,
01043 DBusError *error)
01044 {
01045 int r, n;
01046 unsigned fd;
01047 int *new_fds;
01048
01049 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01050
01051 n = sd_listen_fds (TRUE);
01052 if (n < 0)
01053 {
01054 dbus_set_error (error, _dbus_error_from_errno (-n),
01055 "Failed to acquire systemd socket: %s",
01056 _dbus_strerror (-n));
01057 return -1;
01058 }
01059
01060 if (n <= 0)
01061 {
01062 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01063 "No socket received.");
01064 return -1;
01065 }
01066
01067 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01068 {
01069 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01070 if (r < 0)
01071 {
01072 dbus_set_error (error, _dbus_error_from_errno (-r),
01073 "Failed to verify systemd socket type: %s",
01074 _dbus_strerror (-r));
01075 return -1;
01076 }
01077
01078 if (!r)
01079 {
01080 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01081 "Passed socket has wrong type.");
01082 return -1;
01083 }
01084 }
01085
01086
01087
01088
01089 new_fds = dbus_new (int, n);
01090 if (!new_fds)
01091 {
01092 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01093 "Failed to allocate file handle array.");
01094 goto fail;
01095 }
01096
01097 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01098 {
01099 if (!_dbus_set_local_creds (fd, TRUE))
01100 {
01101 dbus_set_error (error, _dbus_error_from_errno (errno),
01102 "Failed to enable LOCAL_CREDS on systemd socket: %s",
01103 _dbus_strerror (errno));
01104 goto fail;
01105 }
01106
01107 if (!_dbus_set_fd_nonblocking (fd, error))
01108 {
01109 _DBUS_ASSERT_ERROR_IS_SET (error);
01110 goto fail;
01111 }
01112
01113 new_fds[fd - SD_LISTEN_FDS_START] = fd;
01114 }
01115
01116 *fds = new_fds;
01117 return n;
01118
01119 fail:
01120
01121 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01122 {
01123 _dbus_close (fd, NULL);
01124 }
01125
01126 dbus_free (new_fds);
01127 return -1;
01128 }
01129
01143 int
01144 _dbus_connect_tcp_socket (const char *host,
01145 const char *port,
01146 const char *family,
01147 DBusError *error)
01148 {
01149 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01150 }
01151
01152 int
01153 _dbus_connect_tcp_socket_with_nonce (const char *host,
01154 const char *port,
01155 const char *family,
01156 const char *noncefile,
01157 DBusError *error)
01158 {
01159 int saved_errno = 0;
01160 int fd = -1, res;
01161 struct addrinfo hints;
01162 struct addrinfo *ai, *tmp;
01163
01164 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01165
01166 if (!_dbus_open_tcp_socket (&fd, error))
01167 {
01168 _DBUS_ASSERT_ERROR_IS_SET(error);
01169 return -1;
01170 }
01171
01172 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01173
01174 _DBUS_ZERO (hints);
01175
01176 if (!family)
01177 hints.ai_family = AF_UNSPEC;
01178 else if (!strcmp(family, "ipv4"))
01179 hints.ai_family = AF_INET;
01180 else if (!strcmp(family, "ipv6"))
01181 hints.ai_family = AF_INET6;
01182 else
01183 {
01184 dbus_set_error (error,
01185 DBUS_ERROR_BAD_ADDRESS,
01186 "Unknown address family %s", family);
01187 return -1;
01188 }
01189 hints.ai_protocol = IPPROTO_TCP;
01190 hints.ai_socktype = SOCK_STREAM;
01191 hints.ai_flags = AI_ADDRCONFIG;
01192
01193 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01194 {
01195 dbus_set_error (error,
01196 _dbus_error_from_errno (errno),
01197 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01198 host, port, gai_strerror(res), res);
01199 _dbus_close (fd, NULL);
01200 return -1;
01201 }
01202
01203 tmp = ai;
01204 while (tmp)
01205 {
01206 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01207 {
01208 freeaddrinfo(ai);
01209 _DBUS_ASSERT_ERROR_IS_SET(error);
01210 return -1;
01211 }
01212 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01213
01214 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01215 {
01216 saved_errno = errno;
01217 _dbus_close(fd, NULL);
01218 fd = -1;
01219 tmp = tmp->ai_next;
01220 continue;
01221 }
01222
01223 break;
01224 }
01225 freeaddrinfo(ai);
01226
01227 if (fd == -1)
01228 {
01229 dbus_set_error (error,
01230 _dbus_error_from_errno (saved_errno),
01231 "Failed to connect to socket \"%s:%s\" %s",
01232 host, port, _dbus_strerror(saved_errno));
01233 return -1;
01234 }
01235
01236 if (noncefile != NULL)
01237 {
01238 DBusString noncefileStr;
01239 dbus_bool_t ret;
01240 _dbus_string_init_const (&noncefileStr, noncefile);
01241 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01242 _dbus_string_free (&noncefileStr);
01243
01244 if (!ret)
01245 {
01246 _dbus_close (fd, NULL);
01247 return -1;
01248 }
01249 }
01250
01251 if (!_dbus_set_fd_nonblocking (fd, error))
01252 {
01253 _dbus_close (fd, NULL);
01254 return -1;
01255 }
01256
01257 return fd;
01258 }
01259
01276 int
01277 _dbus_listen_tcp_socket (const char *host,
01278 const char *port,
01279 const char *family,
01280 DBusString *retport,
01281 int **fds_p,
01282 DBusError *error)
01283 {
01284 int saved_errno;
01285 int nlisten_fd = 0, *listen_fd = NULL, res, i;
01286 struct addrinfo hints;
01287 struct addrinfo *ai, *tmp;
01288 unsigned int reuseaddr;
01289
01290 *fds_p = NULL;
01291 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01292
01293 _DBUS_ZERO (hints);
01294
01295 if (!family)
01296 hints.ai_family = AF_UNSPEC;
01297 else if (!strcmp(family, "ipv4"))
01298 hints.ai_family = AF_INET;
01299 else if (!strcmp(family, "ipv6"))
01300 hints.ai_family = AF_INET6;
01301 else
01302 {
01303 dbus_set_error (error,
01304 DBUS_ERROR_BAD_ADDRESS,
01305 "Unknown address family %s", family);
01306 return -1;
01307 }
01308
01309 hints.ai_protocol = IPPROTO_TCP;
01310 hints.ai_socktype = SOCK_STREAM;
01311 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01312
01313 redo_lookup_with_port:
01314 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01315 {
01316 dbus_set_error (error,
01317 _dbus_error_from_errno (errno),
01318 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01319 host ? host : "*", port, gai_strerror(res), res);
01320 return -1;
01321 }
01322
01323 tmp = ai;
01324 while (tmp)
01325 {
01326 int fd = -1, *newlisten_fd;
01327 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01328 {
01329 _DBUS_ASSERT_ERROR_IS_SET(error);
01330 goto failed;
01331 }
01332 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01333
01334 reuseaddr = 1;
01335 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01336 {
01337 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01338 host ? host : "*", port, _dbus_strerror (errno));
01339 }
01340
01341 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01342 {
01343 saved_errno = errno;
01344 _dbus_close(fd, NULL);
01345 if (saved_errno == EADDRINUSE)
01346 {
01347
01348
01349
01350 tmp = tmp->ai_next;
01351 continue;
01352 }
01353 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01354 "Failed to bind socket \"%s:%s\": %s",
01355 host ? host : "*", port, _dbus_strerror (saved_errno));
01356 goto failed;
01357 }
01358
01359 if (listen (fd, 30 ) < 0)
01360 {
01361 saved_errno = errno;
01362 _dbus_close (fd, NULL);
01363 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01364 "Failed to listen on socket \"%s:%s\": %s",
01365 host ? host : "*", port, _dbus_strerror (saved_errno));
01366 goto failed;
01367 }
01368
01369 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01370 if (!newlisten_fd)
01371 {
01372 saved_errno = errno;
01373 _dbus_close (fd, NULL);
01374 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01375 "Failed to allocate file handle array: %s",
01376 _dbus_strerror (saved_errno));
01377 goto failed;
01378 }
01379 listen_fd = newlisten_fd;
01380 listen_fd[nlisten_fd] = fd;
01381 nlisten_fd++;
01382
01383 if (!_dbus_string_get_length(retport))
01384 {
01385
01386
01387
01388
01389 if (!port || !strcmp(port, "0"))
01390 {
01391 struct sockaddr_storage addr;
01392 socklen_t addrlen;
01393 char portbuf[50];
01394
01395 addrlen = sizeof(addr);
01396 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01397
01398 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
01399 portbuf, sizeof(portbuf),
01400 NI_NUMERICHOST)) != 0)
01401 {
01402 dbus_set_error (error, _dbus_error_from_errno (errno),
01403 "Failed to resolve port \"%s:%s\": %s (%s)",
01404 host ? host : "*", port, gai_strerror(res), res);
01405 goto failed;
01406 }
01407 if (!_dbus_string_append(retport, portbuf))
01408 {
01409 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01410 goto failed;
01411 }
01412
01413
01414 port = _dbus_string_get_const_data(retport);
01415 freeaddrinfo(ai);
01416 goto redo_lookup_with_port;
01417 }
01418 else
01419 {
01420 if (!_dbus_string_append(retport, port))
01421 {
01422 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01423 goto failed;
01424 }
01425 }
01426 }
01427
01428 tmp = tmp->ai_next;
01429 }
01430 freeaddrinfo(ai);
01431 ai = NULL;
01432
01433 if (!nlisten_fd)
01434 {
01435 errno = EADDRINUSE;
01436 dbus_set_error (error, _dbus_error_from_errno (errno),
01437 "Failed to bind socket \"%s:%s\": %s",
01438 host ? host : "*", port, _dbus_strerror (errno));
01439 return -1;
01440 }
01441
01442 for (i = 0 ; i < nlisten_fd ; i++)
01443 {
01444 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01445 {
01446 goto failed;
01447 }
01448 }
01449
01450 *fds_p = listen_fd;
01451
01452 return nlisten_fd;
01453
01454 failed:
01455 if (ai)
01456 freeaddrinfo(ai);
01457 for (i = 0 ; i < nlisten_fd ; i++)
01458 _dbus_close(listen_fd[i], NULL);
01459 dbus_free(listen_fd);
01460 return -1;
01461 }
01462
01463 static dbus_bool_t
01464 write_credentials_byte (int server_fd,
01465 DBusError *error)
01466 {
01467 int bytes_written;
01468 char buf[1] = { '\0' };
01469 #if defined(HAVE_CMSGCRED)
01470 union {
01471 struct cmsghdr hdr;
01472 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01473 } cmsg;
01474 struct iovec iov;
01475 struct msghdr msg;
01476 iov.iov_base = buf;
01477 iov.iov_len = 1;
01478
01479 _DBUS_ZERO(msg);
01480 msg.msg_iov = &iov;
01481 msg.msg_iovlen = 1;
01482
01483 msg.msg_control = (caddr_t) &cmsg;
01484 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01485 _DBUS_ZERO(cmsg);
01486 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01487 cmsg.hdr.cmsg_level = SOL_SOCKET;
01488 cmsg.hdr.cmsg_type = SCM_CREDS;
01489 #endif
01490
01491 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01492
01493 again:
01494
01495 #if defined(HAVE_CMSGCRED)
01496 bytes_written = sendmsg (server_fd, &msg, 0
01497 #ifdef HAVE_DECL_MSG_NOSIGNAL
01498 |MSG_NOSIGNAL
01499 #endif
01500 );
01501 #else
01502 bytes_written = send (server_fd, buf, 1, 0
01503 #ifdef HAVE_DECL_MSG_NOSIGNAL
01504 |MSG_NOSIGNAL
01505 #endif
01506 );
01507 #endif
01508
01509 if (bytes_written < 0 && errno == EINTR)
01510 goto again;
01511
01512 if (bytes_written < 0)
01513 {
01514 dbus_set_error (error, _dbus_error_from_errno (errno),
01515 "Failed to write credentials byte: %s",
01516 _dbus_strerror (errno));
01517 return FALSE;
01518 }
01519 else if (bytes_written == 0)
01520 {
01521 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01522 "wrote zero bytes writing credentials byte");
01523 return FALSE;
01524 }
01525 else
01526 {
01527 _dbus_assert (bytes_written == 1);
01528 _dbus_verbose ("wrote credentials byte\n");
01529 return TRUE;
01530 }
01531 }
01532
01554 dbus_bool_t
01555 _dbus_read_credentials_socket (int client_fd,
01556 DBusCredentials *credentials,
01557 DBusError *error)
01558 {
01559 struct msghdr msg;
01560 struct iovec iov;
01561 char buf;
01562 dbus_uid_t uid_read;
01563 dbus_pid_t pid_read;
01564 int bytes_read;
01565
01566 #ifdef HAVE_CMSGCRED
01567 union {
01568 struct cmsghdr hdr;
01569 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01570 } cmsg;
01571
01572 #elif defined(LOCAL_CREDS)
01573 struct {
01574 struct cmsghdr hdr;
01575 struct sockcred cred;
01576 } cmsg;
01577 #endif
01578
01579 uid_read = DBUS_UID_UNSET;
01580 pid_read = DBUS_PID_UNSET;
01581
01582 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01583
01584
01585
01586
01587
01588 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01589 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01590 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01591
01592 _dbus_credentials_clear (credentials);
01593
01594
01595
01596
01597
01598
01599
01600 iov.iov_base = &buf;
01601 iov.iov_len = 1;
01602
01603 _DBUS_ZERO(msg);
01604 msg.msg_iov = &iov;
01605 msg.msg_iovlen = 1;
01606
01607 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01608 _DBUS_ZERO(cmsg);
01609 msg.msg_control = (caddr_t) &cmsg;
01610 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01611 #endif
01612
01613 again:
01614 bytes_read = recvmsg (client_fd, &msg, 0);
01615
01616 if (bytes_read < 0)
01617 {
01618 if (errno == EINTR)
01619 goto again;
01620
01621
01622
01623
01624
01625
01626 dbus_set_error (error, _dbus_error_from_errno (errno),
01627 "Failed to read credentials byte: %s",
01628 _dbus_strerror (errno));
01629 return FALSE;
01630 }
01631 else if (bytes_read == 0)
01632 {
01633
01634
01635
01636 dbus_set_error (error, DBUS_ERROR_FAILED,
01637 "Failed to read credentials byte (zero-length read)");
01638 return FALSE;
01639 }
01640 else if (buf != '\0')
01641 {
01642 dbus_set_error (error, DBUS_ERROR_FAILED,
01643 "Credentials byte was not nul");
01644 return FALSE;
01645 }
01646
01647 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01648 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01649 || cmsg.hdr.cmsg_type != SCM_CREDS)
01650 {
01651 dbus_set_error (error, DBUS_ERROR_FAILED,
01652 "Message from recvmsg() was not SCM_CREDS");
01653 return FALSE;
01654 }
01655 #endif
01656
01657 _dbus_verbose ("read credentials byte\n");
01658
01659 {
01660 #ifdef SO_PEERCRED
01661 struct ucred cr;
01662 int cr_len = sizeof (cr);
01663
01664 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01665 cr_len == sizeof (cr))
01666 {
01667 pid_read = cr.pid;
01668 uid_read = cr.uid;
01669 }
01670 else
01671 {
01672 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01673 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01674 }
01675 #elif defined(HAVE_CMSGCRED)
01676 struct cmsgcred *cred;
01677
01678 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01679 pid_read = cred->cmcred_pid;
01680 uid_read = cred->cmcred_euid;
01681 #elif defined(LOCAL_CREDS)
01682 pid_read = DBUS_PID_UNSET;
01683 uid_read = cmsg.cred.sc_uid;
01684
01685
01686 _dbus_set_local_creds (client_fd, FALSE);
01687 #elif defined(HAVE_GETPEEREID)
01688 uid_t euid;
01689 gid_t egid;
01690 if (getpeereid (client_fd, &euid, &egid) == 0)
01691 {
01692 uid_read = euid;
01693 }
01694 else
01695 {
01696 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01697 }
01698 #elif defined(HAVE_GETPEERUCRED)
01699 ucred_t * ucred = NULL;
01700 if (getpeerucred (client_fd, &ucred) == 0)
01701 {
01702 pid_read = ucred_getpid (ucred);
01703 uid_read = ucred_geteuid (ucred);
01704 #ifdef HAVE_ADT
01705
01706 adt_session_data_t *adth = NULL;
01707 adt_export_data_t *data = NULL;
01708 size_t size = 0;
01709 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01710 {
01711 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01712 }
01713 else
01714 {
01715 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01716 {
01717 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01718 }
01719 else
01720 {
01721 size = adt_export_session_data (adth, &data);
01722 if (size <= 0)
01723 {
01724 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01725 }
01726 else
01727 {
01728 _dbus_credentials_add_adt_audit_data (credentials, data, size);
01729 free (data);
01730 }
01731 }
01732 (void) adt_end_session (adth);
01733 }
01734 #endif
01735 }
01736 else
01737 {
01738 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01739 }
01740 if (ucred != NULL)
01741 ucred_free (ucred);
01742 #else
01743 _dbus_verbose ("Socket credentials not supported on this OS\n");
01744 #endif
01745 }
01746
01747 _dbus_verbose ("Credentials:"
01748 " pid "DBUS_PID_FORMAT
01749 " uid "DBUS_UID_FORMAT
01750 "\n",
01751 pid_read,
01752 uid_read);
01753
01754 if (pid_read != DBUS_PID_UNSET)
01755 {
01756 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01757 {
01758 _DBUS_SET_OOM (error);
01759 return FALSE;
01760 }
01761 }
01762
01763 if (uid_read != DBUS_UID_UNSET)
01764 {
01765 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01766 {
01767 _DBUS_SET_OOM (error);
01768 return FALSE;
01769 }
01770 }
01771
01772 return TRUE;
01773 }
01774
01792 dbus_bool_t
01793 _dbus_send_credentials_socket (int server_fd,
01794 DBusError *error)
01795 {
01796 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01797
01798 if (write_credentials_byte (server_fd, error))
01799 return TRUE;
01800 else
01801 return FALSE;
01802 }
01803
01813 int
01814 _dbus_accept (int listen_fd)
01815 {
01816 int client_fd;
01817 struct sockaddr addr;
01818 socklen_t addrlen;
01819 #ifdef HAVE_ACCEPT4
01820 dbus_bool_t cloexec_done;
01821 #endif
01822
01823 addrlen = sizeof (addr);
01824
01825 retry:
01826
01827 #ifdef HAVE_ACCEPT4
01828
01829 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01830 cloexec_done = client_fd >= 0;
01831
01832 if (client_fd < 0 && errno == ENOSYS)
01833 #endif
01834 {
01835 client_fd = accept (listen_fd, &addr, &addrlen);
01836 }
01837
01838 if (client_fd < 0)
01839 {
01840 if (errno == EINTR)
01841 goto retry;
01842 }
01843
01844 _dbus_verbose ("client fd %d accepted\n", client_fd);
01845
01846 #ifdef HAVE_ACCEPT4
01847 if (!cloexec_done)
01848 #endif
01849 {
01850 _dbus_fd_set_close_on_exec(client_fd);
01851 }
01852
01853 return client_fd;
01854 }
01855
01864 dbus_bool_t
01865 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01866 {
01867 const char *directory;
01868 struct stat sb;
01869
01870 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01871
01872 directory = _dbus_string_get_const_data (dir);
01873
01874 if (stat (directory, &sb) < 0)
01875 {
01876 dbus_set_error (error, _dbus_error_from_errno (errno),
01877 "%s", _dbus_strerror (errno));
01878
01879 return FALSE;
01880 }
01881
01882 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01883 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01884 {
01885 dbus_set_error (error, DBUS_ERROR_FAILED,
01886 "%s directory is not private to the user", directory);
01887 return FALSE;
01888 }
01889
01890 return TRUE;
01891 }
01892
01893 static dbus_bool_t
01894 fill_user_info_from_passwd (struct passwd *p,
01895 DBusUserInfo *info,
01896 DBusError *error)
01897 {
01898 _dbus_assert (p->pw_name != NULL);
01899 _dbus_assert (p->pw_dir != NULL);
01900
01901 info->uid = p->pw_uid;
01902 info->primary_gid = p->pw_gid;
01903 info->username = _dbus_strdup (p->pw_name);
01904 info->homedir = _dbus_strdup (p->pw_dir);
01905
01906 if (info->username == NULL ||
01907 info->homedir == NULL)
01908 {
01909 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01910 return FALSE;
01911 }
01912
01913 return TRUE;
01914 }
01915
01916 static dbus_bool_t
01917 fill_user_info (DBusUserInfo *info,
01918 dbus_uid_t uid,
01919 const DBusString *username,
01920 DBusError *error)
01921 {
01922 const char *username_c;
01923
01924
01925 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01926 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01927
01928 info->uid = DBUS_UID_UNSET;
01929 info->primary_gid = DBUS_GID_UNSET;
01930 info->group_ids = NULL;
01931 info->n_group_ids = 0;
01932 info->username = NULL;
01933 info->homedir = NULL;
01934
01935 if (username != NULL)
01936 username_c = _dbus_string_get_const_data (username);
01937 else
01938 username_c = NULL;
01939
01940
01941
01942
01943
01944
01945 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01946 {
01947 struct passwd *p;
01948 int result;
01949 size_t buflen;
01950 char *buf;
01951 struct passwd p_str;
01952
01953
01954 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01955
01956
01957
01958
01959
01960 if ((long) buflen <= 0)
01961 buflen = 1024;
01962
01963 result = -1;
01964 while (1)
01965 {
01966 buf = dbus_malloc (buflen);
01967 if (buf == NULL)
01968 {
01969 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01970 return FALSE;
01971 }
01972
01973 p = NULL;
01974 #ifdef HAVE_POSIX_GETPWNAM_R
01975 if (uid != DBUS_UID_UNSET)
01976 result = getpwuid_r (uid, &p_str, buf, buflen,
01977 &p);
01978 else
01979 result = getpwnam_r (username_c, &p_str, buf, buflen,
01980 &p);
01981 #else
01982 if (uid != DBUS_UID_UNSET)
01983 p = getpwuid_r (uid, &p_str, buf, buflen);
01984 else
01985 p = getpwnam_r (username_c, &p_str, buf, buflen);
01986 result = 0;
01987 #endif
01988
01989 if (result == ERANGE && buflen < 512 * 1024)
01990 {
01991 dbus_free (buf);
01992 buflen *= 2;
01993 }
01994 else
01995 {
01996 break;
01997 }
01998 }
01999 if (result == 0 && p == &p_str)
02000 {
02001 if (!fill_user_info_from_passwd (p, info, error))
02002 {
02003 dbus_free (buf);
02004 return FALSE;
02005 }
02006 dbus_free (buf);
02007 }
02008 else
02009 {
02010 dbus_set_error (error, _dbus_error_from_errno (errno),
02011 "User \"%s\" unknown or no memory to allocate password entry\n",
02012 username_c ? username_c : "???");
02013 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02014 dbus_free (buf);
02015 return FALSE;
02016 }
02017 }
02018 #else
02019 {
02020
02021 struct passwd *p;
02022
02023 if (uid != DBUS_UID_UNSET)
02024 p = getpwuid (uid);
02025 else
02026 p = getpwnam (username_c);
02027
02028 if (p != NULL)
02029 {
02030 if (!fill_user_info_from_passwd (p, info, error))
02031 {
02032 return FALSE;
02033 }
02034 }
02035 else
02036 {
02037 dbus_set_error (error, _dbus_error_from_errno (errno),
02038 "User \"%s\" unknown or no memory to allocate password entry\n",
02039 username_c ? username_c : "???");
02040 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02041 return FALSE;
02042 }
02043 }
02044 #endif
02045
02046
02047 username_c = info->username;
02048
02049 #ifdef HAVE_GETGROUPLIST
02050 {
02051 gid_t *buf;
02052 int buf_count;
02053 int i;
02054 int initial_buf_count;
02055
02056 initial_buf_count = 17;
02057 buf_count = initial_buf_count;
02058 buf = dbus_new (gid_t, buf_count);
02059 if (buf == NULL)
02060 {
02061 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02062 goto failed;
02063 }
02064
02065 if (getgrouplist (username_c,
02066 info->primary_gid,
02067 buf, &buf_count) < 0)
02068 {
02069 gid_t *new;
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083 if (buf_count == initial_buf_count)
02084 {
02085 buf_count *= 16;
02086 }
02087 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02088 if (new == NULL)
02089 {
02090 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02091 dbus_free (buf);
02092 goto failed;
02093 }
02094
02095 buf = new;
02096
02097 errno = 0;
02098 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02099 {
02100 if (errno == 0)
02101 {
02102 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02103 username_c, buf_count, buf_count);
02104 }
02105 else
02106 {
02107 dbus_set_error (error,
02108 _dbus_error_from_errno (errno),
02109 "Failed to get groups for username \"%s\" primary GID "
02110 DBUS_GID_FORMAT ": %s\n",
02111 username_c, info->primary_gid,
02112 _dbus_strerror (errno));
02113 dbus_free (buf);
02114 goto failed;
02115 }
02116 }
02117 }
02118
02119 info->group_ids = dbus_new (dbus_gid_t, buf_count);
02120 if (info->group_ids == NULL)
02121 {
02122 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02123 dbus_free (buf);
02124 goto failed;
02125 }
02126
02127 for (i = 0; i < buf_count; ++i)
02128 info->group_ids[i] = buf[i];
02129
02130 info->n_group_ids = buf_count;
02131
02132 dbus_free (buf);
02133 }
02134 #else
02135 {
02136
02137 info->group_ids = dbus_new (dbus_gid_t, 1);
02138 if (info->group_ids == NULL)
02139 {
02140 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02141 goto failed;
02142 }
02143
02144 info->n_group_ids = 1;
02145
02146 (info->group_ids)[0] = info->primary_gid;
02147 }
02148 #endif
02149
02150 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02151
02152 return TRUE;
02153
02154 failed:
02155 _DBUS_ASSERT_ERROR_IS_SET (error);
02156 return FALSE;
02157 }
02158
02167 dbus_bool_t
02168 _dbus_user_info_fill (DBusUserInfo *info,
02169 const DBusString *username,
02170 DBusError *error)
02171 {
02172 return fill_user_info (info, DBUS_UID_UNSET,
02173 username, error);
02174 }
02175
02184 dbus_bool_t
02185 _dbus_user_info_fill_uid (DBusUserInfo *info,
02186 dbus_uid_t uid,
02187 DBusError *error)
02188 {
02189 return fill_user_info (info, uid,
02190 NULL, error);
02191 }
02192
02200 dbus_bool_t
02201 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02202 {
02203
02204
02205
02206
02207 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02208 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02209 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02210
02211 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02212 return FALSE;
02213 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02214 return FALSE;
02215
02216 return TRUE;
02217 }
02218
02230 dbus_bool_t
02231 _dbus_append_user_from_current_process (DBusString *str)
02232 {
02233 return _dbus_string_append_uint (str,
02234 _dbus_geteuid ());
02235 }
02236
02241 dbus_pid_t
02242 _dbus_getpid (void)
02243 {
02244 return getpid ();
02245 }
02246
02250 dbus_uid_t
02251 _dbus_getuid (void)
02252 {
02253 return getuid ();
02254 }
02255
02259 dbus_uid_t
02260 _dbus_geteuid (void)
02261 {
02262 return geteuid ();
02263 }
02264
02271 unsigned long
02272 _dbus_pid_for_log (void)
02273 {
02274 return getpid ();
02275 }
02276
02284 dbus_bool_t
02285 _dbus_parse_uid (const DBusString *uid_str,
02286 dbus_uid_t *uid)
02287 {
02288 int end;
02289 long val;
02290
02291 if (_dbus_string_get_length (uid_str) == 0)
02292 {
02293 _dbus_verbose ("UID string was zero length\n");
02294 return FALSE;
02295 }
02296
02297 val = -1;
02298 end = 0;
02299 if (!_dbus_string_parse_int (uid_str, 0, &val,
02300 &end))
02301 {
02302 _dbus_verbose ("could not parse string as a UID\n");
02303 return FALSE;
02304 }
02305
02306 if (end != _dbus_string_get_length (uid_str))
02307 {
02308 _dbus_verbose ("string contained trailing stuff after UID\n");
02309 return FALSE;
02310 }
02311
02312 *uid = val;
02313
02314 return TRUE;
02315 }
02316
02317 #if !DBUS_USE_SYNC
02318 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02319 #endif
02320
02327 dbus_int32_t
02328 _dbus_atomic_inc (DBusAtomic *atomic)
02329 {
02330 #if DBUS_USE_SYNC
02331 return __sync_add_and_fetch(&atomic->value, 1)-1;
02332 #else
02333 dbus_int32_t res;
02334 _DBUS_LOCK (atomic);
02335 res = atomic->value;
02336 atomic->value += 1;
02337 _DBUS_UNLOCK (atomic);
02338 return res;
02339 #endif
02340 }
02341
02348 dbus_int32_t
02349 _dbus_atomic_dec (DBusAtomic *atomic)
02350 {
02351 #if DBUS_USE_SYNC
02352 return __sync_sub_and_fetch(&atomic->value, 1)+1;
02353 #else
02354 dbus_int32_t res;
02355
02356 _DBUS_LOCK (atomic);
02357 res = atomic->value;
02358 atomic->value -= 1;
02359 _DBUS_UNLOCK (atomic);
02360 return res;
02361 #endif
02362 }
02363
02364 #ifdef DBUS_BUILD_TESTS
02365
02368 dbus_gid_t
02369 _dbus_getgid (void)
02370 {
02371 return getgid ();
02372 }
02373 #endif
02374
02383 int
02384 _dbus_poll (DBusPollFD *fds,
02385 int n_fds,
02386 int timeout_milliseconds)
02387 {
02388 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02389
02390
02391
02392
02393 if (_DBUS_POLLIN == POLLIN &&
02394 _DBUS_POLLPRI == POLLPRI &&
02395 _DBUS_POLLOUT == POLLOUT &&
02396 _DBUS_POLLERR == POLLERR &&
02397 _DBUS_POLLHUP == POLLHUP &&
02398 _DBUS_POLLNVAL == POLLNVAL &&
02399 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02400 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02401 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02402 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02403 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02404 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02405 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02406 {
02407 return poll ((struct pollfd*) fds,
02408 n_fds,
02409 timeout_milliseconds);
02410 }
02411 else
02412 {
02413
02414
02415
02416 _dbus_warn ("didn't implement poll() properly for this system yet\n");
02417 return -1;
02418 }
02419 #else
02420
02421 fd_set read_set, write_set, err_set;
02422 int max_fd = 0;
02423 int i;
02424 struct timeval tv;
02425 int ready;
02426
02427 FD_ZERO (&read_set);
02428 FD_ZERO (&write_set);
02429 FD_ZERO (&err_set);
02430
02431 for (i = 0; i < n_fds; i++)
02432 {
02433 DBusPollFD *fdp = &fds[i];
02434
02435 if (fdp->events & _DBUS_POLLIN)
02436 FD_SET (fdp->fd, &read_set);
02437
02438 if (fdp->events & _DBUS_POLLOUT)
02439 FD_SET (fdp->fd, &write_set);
02440
02441 FD_SET (fdp->fd, &err_set);
02442
02443 max_fd = MAX (max_fd, fdp->fd);
02444 }
02445
02446 tv.tv_sec = timeout_milliseconds / 1000;
02447 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02448
02449 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02450 timeout_milliseconds < 0 ? NULL : &tv);
02451
02452 if (ready > 0)
02453 {
02454 for (i = 0; i < n_fds; i++)
02455 {
02456 DBusPollFD *fdp = &fds[i];
02457
02458 fdp->revents = 0;
02459
02460 if (FD_ISSET (fdp->fd, &read_set))
02461 fdp->revents |= _DBUS_POLLIN;
02462
02463 if (FD_ISSET (fdp->fd, &write_set))
02464 fdp->revents |= _DBUS_POLLOUT;
02465
02466 if (FD_ISSET (fdp->fd, &err_set))
02467 fdp->revents |= _DBUS_POLLERR;
02468 }
02469 }
02470
02471 return ready;
02472 #endif
02473 }
02474
02482 void
02483 _dbus_get_current_time (long *tv_sec,
02484 long *tv_usec)
02485 {
02486 struct timeval t;
02487
02488 #ifdef HAVE_MONOTONIC_CLOCK
02489 struct timespec ts;
02490 clock_gettime (CLOCK_MONOTONIC, &ts);
02491
02492 if (tv_sec)
02493 *tv_sec = ts.tv_sec;
02494 if (tv_usec)
02495 *tv_usec = ts.tv_nsec / 1000;
02496 #else
02497 gettimeofday (&t, NULL);
02498
02499 if (tv_sec)
02500 *tv_sec = t.tv_sec;
02501 if (tv_usec)
02502 *tv_usec = t.tv_usec;
02503 #endif
02504 }
02505
02514 dbus_bool_t
02515 _dbus_create_directory (const DBusString *filename,
02516 DBusError *error)
02517 {
02518 const char *filename_c;
02519
02520 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02521
02522 filename_c = _dbus_string_get_const_data (filename);
02523
02524 if (mkdir (filename_c, 0700) < 0)
02525 {
02526 if (errno == EEXIST)
02527 return TRUE;
02528
02529 dbus_set_error (error, DBUS_ERROR_FAILED,
02530 "Failed to create directory %s: %s\n",
02531 filename_c, _dbus_strerror (errno));
02532 return FALSE;
02533 }
02534 else
02535 return TRUE;
02536 }
02537
02548 dbus_bool_t
02549 _dbus_concat_dir_and_file (DBusString *dir,
02550 const DBusString *next_component)
02551 {
02552 dbus_bool_t dir_ends_in_slash;
02553 dbus_bool_t file_starts_with_slash;
02554
02555 if (_dbus_string_get_length (dir) == 0 ||
02556 _dbus_string_get_length (next_component) == 0)
02557 return TRUE;
02558
02559 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02560 _dbus_string_get_length (dir) - 1);
02561
02562 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02563
02564 if (dir_ends_in_slash && file_starts_with_slash)
02565 {
02566 _dbus_string_shorten (dir, 1);
02567 }
02568 else if (!(dir_ends_in_slash || file_starts_with_slash))
02569 {
02570 if (!_dbus_string_append_byte (dir, '/'))
02571 return FALSE;
02572 }
02573
02574 return _dbus_string_copy (next_component, 0, dir,
02575 _dbus_string_get_length (dir));
02576 }
02577
02579 #define NANOSECONDS_PER_SECOND 1000000000
02580
02581 #define MICROSECONDS_PER_SECOND 1000000
02582
02583 #define MILLISECONDS_PER_SECOND 1000
02584
02585 #define NANOSECONDS_PER_MILLISECOND 1000000
02586
02587 #define MICROSECONDS_PER_MILLISECOND 1000
02588
02593 void
02594 _dbus_sleep_milliseconds (int milliseconds)
02595 {
02596 #ifdef HAVE_NANOSLEEP
02597 struct timespec req;
02598 struct timespec rem;
02599
02600 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02601 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02602 rem.tv_sec = 0;
02603 rem.tv_nsec = 0;
02604
02605 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02606 req = rem;
02607 #elif defined (HAVE_USLEEP)
02608 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02609 #else
02610 sleep (MAX (milliseconds / 1000, 1));
02611 #endif
02612 }
02613
02614 static dbus_bool_t
02615 _dbus_generate_pseudorandom_bytes (DBusString *str,
02616 int n_bytes)
02617 {
02618 int old_len;
02619 char *p;
02620
02621 old_len = _dbus_string_get_length (str);
02622
02623 if (!_dbus_string_lengthen (str, n_bytes))
02624 return FALSE;
02625
02626 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02627
02628 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02629
02630 return TRUE;
02631 }
02632
02641 dbus_bool_t
02642 _dbus_generate_random_bytes (DBusString *str,
02643 int n_bytes)
02644 {
02645 int old_len;
02646 int fd;
02647
02648
02649
02650
02651
02652
02653
02654 old_len = _dbus_string_get_length (str);
02655 fd = -1;
02656
02657
02658 fd = open ("/dev/urandom", O_RDONLY);
02659 if (fd < 0)
02660 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02661
02662 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02663
02664 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02665 {
02666 _dbus_close (fd, NULL);
02667 _dbus_string_set_length (str, old_len);
02668 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02669 }
02670
02671 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02672 n_bytes);
02673
02674 _dbus_close (fd, NULL);
02675
02676 return TRUE;
02677 }
02678
02684 void
02685 _dbus_exit (int code)
02686 {
02687 _exit (code);
02688 }
02689
02698 const char*
02699 _dbus_strerror (int error_number)
02700 {
02701 const char *msg;
02702
02703 msg = strerror (error_number);
02704 if (msg == NULL)
02705 msg = "unknown";
02706
02707 return msg;
02708 }
02709
02713 void
02714 _dbus_disable_sigpipe (void)
02715 {
02716 signal (SIGPIPE, SIG_IGN);
02717 }
02718
02726 void
02727 _dbus_fd_set_close_on_exec (intptr_t fd)
02728 {
02729 int val;
02730
02731 val = fcntl (fd, F_GETFD, 0);
02732
02733 if (val < 0)
02734 return;
02735
02736 val |= FD_CLOEXEC;
02737
02738 fcntl (fd, F_SETFD, val);
02739 }
02740
02748 dbus_bool_t
02749 _dbus_close (int fd,
02750 DBusError *error)
02751 {
02752 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02753
02754 again:
02755 if (close (fd) < 0)
02756 {
02757 if (errno == EINTR)
02758 goto again;
02759
02760 dbus_set_error (error, _dbus_error_from_errno (errno),
02761 "Could not close fd %d", fd);
02762 return FALSE;
02763 }
02764
02765 return TRUE;
02766 }
02767
02775 int
02776 _dbus_dup(int fd,
02777 DBusError *error)
02778 {
02779 int new_fd;
02780
02781 #ifdef F_DUPFD_CLOEXEC
02782 dbus_bool_t cloexec_done;
02783
02784 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02785 cloexec_done = new_fd >= 0;
02786
02787 if (new_fd < 0 && errno == EINVAL)
02788 #endif
02789 {
02790 new_fd = fcntl(fd, F_DUPFD, 3);
02791 }
02792
02793 if (new_fd < 0) {
02794
02795 dbus_set_error (error, _dbus_error_from_errno (errno),
02796 "Could not duplicate fd %d", fd);
02797 return -1;
02798 }
02799
02800 #ifdef F_DUPFD_CLOEXEC
02801 if (!cloexec_done)
02802 #endif
02803 {
02804 _dbus_fd_set_close_on_exec(new_fd);
02805 }
02806
02807 return new_fd;
02808 }
02809
02817 dbus_bool_t
02818 _dbus_set_fd_nonblocking (int fd,
02819 DBusError *error)
02820 {
02821 int val;
02822
02823 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02824
02825 val = fcntl (fd, F_GETFL, 0);
02826 if (val < 0)
02827 {
02828 dbus_set_error (error, _dbus_error_from_errno (errno),
02829 "Failed to get flags from file descriptor %d: %s",
02830 fd, _dbus_strerror (errno));
02831 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02832 _dbus_strerror (errno));
02833 return FALSE;
02834 }
02835
02836 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02837 {
02838 dbus_set_error (error, _dbus_error_from_errno (errno),
02839 "Failed to set nonblocking flag of file descriptor %d: %s",
02840 fd, _dbus_strerror (errno));
02841 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02842 fd, _dbus_strerror (errno));
02843
02844 return FALSE;
02845 }
02846
02847 return TRUE;
02848 }
02849
02855 void
02856 _dbus_print_backtrace (void)
02857 {
02858 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02859 void *bt[500];
02860 int bt_size;
02861 int i;
02862 char **syms;
02863
02864 bt_size = backtrace (bt, 500);
02865
02866 syms = backtrace_symbols (bt, bt_size);
02867
02868 i = 0;
02869 while (i < bt_size)
02870 {
02871
02872 fprintf (stderr, " %s\n", syms[i]);
02873 ++i;
02874 }
02875 fflush (stderr);
02876
02877 free (syms);
02878 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02879 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02880 #else
02881 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02882 #endif
02883 }
02884
02902 dbus_bool_t
02903 _dbus_full_duplex_pipe (int *fd1,
02904 int *fd2,
02905 dbus_bool_t blocking,
02906 DBusError *error)
02907 {
02908 #ifdef HAVE_SOCKETPAIR
02909 int fds[2];
02910 int retval;
02911
02912 #ifdef SOCK_CLOEXEC
02913 dbus_bool_t cloexec_done;
02914
02915 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02916 cloexec_done = retval >= 0;
02917
02918 if (retval < 0 && errno == EINVAL)
02919 #endif
02920 {
02921 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02922 }
02923
02924 if (retval < 0)
02925 {
02926 dbus_set_error (error, _dbus_error_from_errno (errno),
02927 "Could not create full-duplex pipe");
02928 return FALSE;
02929 }
02930
02931 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02932
02933 #ifdef SOCK_CLOEXEC
02934 if (!cloexec_done)
02935 #endif
02936 {
02937 _dbus_fd_set_close_on_exec (fds[0]);
02938 _dbus_fd_set_close_on_exec (fds[1]);
02939 }
02940
02941 if (!blocking &&
02942 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02943 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02944 {
02945 dbus_set_error (error, _dbus_error_from_errno (errno),
02946 "Could not set full-duplex pipe nonblocking");
02947
02948 _dbus_close (fds[0], NULL);
02949 _dbus_close (fds[1], NULL);
02950
02951 return FALSE;
02952 }
02953
02954 *fd1 = fds[0];
02955 *fd2 = fds[1];
02956
02957 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02958 *fd1, *fd2);
02959
02960 return TRUE;
02961 #else
02962 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02963 dbus_set_error (error, DBUS_ERROR_FAILED,
02964 "_dbus_full_duplex_pipe() not implemented on this OS");
02965 return FALSE;
02966 #endif
02967 }
02968
02977 int
02978 _dbus_printf_string_upper_bound (const char *format,
02979 va_list args)
02980 {
02981 char c;
02982 return vsnprintf (&c, 1, format, args);
02983 }
02984
02991 const char*
02992 _dbus_get_tmpdir(void)
02993 {
02994 static const char* tmpdir = NULL;
02995
02996 if (tmpdir == NULL)
02997 {
02998
02999
03000
03001
03002 if (tmpdir == NULL)
03003 tmpdir = getenv("TMPDIR");
03004
03005
03006
03007
03008 if (tmpdir == NULL)
03009 tmpdir = getenv("TMP");
03010 if (tmpdir == NULL)
03011 tmpdir = getenv("TEMP");
03012
03013
03014 if (tmpdir == NULL)
03015 tmpdir = "/tmp";
03016 }
03017
03018 _dbus_assert(tmpdir != NULL);
03019
03020 return tmpdir;
03021 }
03022
03042 static dbus_bool_t
03043 _read_subprocess_line_argv (const char *progpath,
03044 dbus_bool_t path_fallback,
03045 char * const *argv,
03046 DBusString *result,
03047 DBusError *error)
03048 {
03049 int result_pipe[2] = { -1, -1 };
03050 int errors_pipe[2] = { -1, -1 };
03051 pid_t pid;
03052 int ret;
03053 int status;
03054 int orig_len;
03055 int i;
03056
03057 dbus_bool_t retval;
03058 sigset_t new_set, old_set;
03059
03060 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03061 retval = FALSE;
03062
03063
03064
03065
03066
03067 sigemptyset (&new_set);
03068 sigaddset (&new_set, SIGCHLD);
03069 sigprocmask (SIG_BLOCK, &new_set, &old_set);
03070
03071 orig_len = _dbus_string_get_length (result);
03072
03073 #define READ_END 0
03074 #define WRITE_END 1
03075 if (pipe (result_pipe) < 0)
03076 {
03077 dbus_set_error (error, _dbus_error_from_errno (errno),
03078 "Failed to create a pipe to call %s: %s",
03079 progpath, _dbus_strerror (errno));
03080 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03081 progpath, _dbus_strerror (errno));
03082 goto out;
03083 }
03084 if (pipe (errors_pipe) < 0)
03085 {
03086 dbus_set_error (error, _dbus_error_from_errno (errno),
03087 "Failed to create a pipe to call %s: %s",
03088 progpath, _dbus_strerror (errno));
03089 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03090 progpath, _dbus_strerror (errno));
03091 goto out;
03092 }
03093
03094 pid = fork ();
03095 if (pid < 0)
03096 {
03097 dbus_set_error (error, _dbus_error_from_errno (errno),
03098 "Failed to fork() to call %s: %s",
03099 progpath, _dbus_strerror (errno));
03100 _dbus_verbose ("Failed to fork() to call %s: %s\n",
03101 progpath, _dbus_strerror (errno));
03102 goto out;
03103 }
03104
03105 if (pid == 0)
03106 {
03107
03108 int maxfds;
03109 int fd;
03110
03111 fd = open ("/dev/null", O_RDWR);
03112 if (fd == -1)
03113
03114 _exit (1);
03115
03116 _dbus_verbose ("/dev/null fd %d opened\n", fd);
03117
03118
03119 close (result_pipe[READ_END]);
03120 close (errors_pipe[READ_END]);
03121 close (0);
03122 close (1);
03123 close (2);
03124
03125 if (dup2 (fd, 0) == -1)
03126 _exit (1);
03127 if (dup2 (result_pipe[WRITE_END], 1) == -1)
03128 _exit (1);
03129 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03130 _exit (1);
03131
03132 maxfds = sysconf (_SC_OPEN_MAX);
03133
03134
03135
03136 if (maxfds < 0)
03137 maxfds = 1024;
03138
03139 for (i = 3; i < maxfds; i++)
03140 close (i);
03141
03142 sigprocmask (SIG_SETMASK, &old_set, NULL);
03143
03144
03145 if (progpath[0] == '/')
03146 {
03147 execv (progpath, argv);
03148
03149
03150
03151
03152
03153
03154 if (path_fallback)
03155
03156 execvp (strrchr (progpath, '/')+1, argv);
03157 }
03158 else
03159 execvp (progpath, argv);
03160
03161
03162 _exit (1);
03163 }
03164
03165
03166 close (result_pipe[WRITE_END]);
03167 close (errors_pipe[WRITE_END]);
03168 result_pipe[WRITE_END] = -1;
03169 errors_pipe[WRITE_END] = -1;
03170
03171 ret = 0;
03172 do
03173 {
03174 ret = _dbus_read (result_pipe[READ_END], result, 1024);
03175 }
03176 while (ret > 0);
03177
03178
03179 do
03180 {
03181 ret = waitpid (pid, &status, 0);
03182 }
03183 while (ret == -1 && errno == EINTR);
03184
03185
03186
03187 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03188 {
03189
03190 DBusString error_message;
03191 _dbus_string_init (&error_message);
03192 ret = 0;
03193 do
03194 {
03195 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03196 }
03197 while (ret > 0);
03198
03199 _dbus_string_set_length (result, orig_len);
03200 if (_dbus_string_get_length (&error_message) > 0)
03201 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03202 "%s terminated abnormally with the following error: %s",
03203 progpath, _dbus_string_get_data (&error_message));
03204 else
03205 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03206 "%s terminated abnormally without any error message",
03207 progpath);
03208 goto out;
03209 }
03210
03211 retval = TRUE;
03212
03213 out:
03214 sigprocmask (SIG_SETMASK, &old_set, NULL);
03215
03216 if (retval)
03217 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03218 else
03219 _DBUS_ASSERT_ERROR_IS_SET (error);
03220
03221 if (result_pipe[0] != -1)
03222 close (result_pipe[0]);
03223 if (result_pipe[1] != -1)
03224 close (result_pipe[1]);
03225 if (errors_pipe[0] != -1)
03226 close (errors_pipe[0]);
03227 if (errors_pipe[1] != -1)
03228 close (errors_pipe[1]);
03229
03230 return retval;
03231 }
03232
03244 dbus_bool_t
03245 _dbus_get_autolaunch_address (const char *scope,
03246 DBusString *address,
03247 DBusError *error)
03248 {
03249 static char *argv[6];
03250 int i;
03251 DBusString uuid;
03252 dbus_bool_t retval;
03253
03254 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03255 retval = FALSE;
03256
03257 if (!_dbus_string_init (&uuid))
03258 {
03259 _DBUS_SET_OOM (error);
03260 return FALSE;
03261 }
03262
03263 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03264 {
03265 _DBUS_SET_OOM (error);
03266 goto out;
03267 }
03268
03269 i = 0;
03270 argv[i] = "dbus-launch";
03271 ++i;
03272 argv[i] = "--autolaunch";
03273 ++i;
03274 argv[i] = _dbus_string_get_data (&uuid);
03275 ++i;
03276 argv[i] = "--binary-syntax";
03277 ++i;
03278 argv[i] = "--close-stderr";
03279 ++i;
03280 argv[i] = NULL;
03281 ++i;
03282
03283 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03284
03285 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03286 TRUE,
03287 argv, address, error);
03288
03289 out:
03290 _dbus_string_free (&uuid);
03291 return retval;
03292 }
03293
03312 dbus_bool_t
03313 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
03314 dbus_bool_t create_if_not_found,
03315 DBusError *error)
03316 {
03317 DBusString filename;
03318 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03319 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03320 }
03321
03322 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03323 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03324
03331 dbus_bool_t
03332 _dbus_lookup_launchd_socket (DBusString *socket_path,
03333 const char *launchd_env_var,
03334 DBusError *error)
03335 {
03336 #ifdef DBUS_ENABLE_LAUNCHD
03337 char *argv[4];
03338 int i;
03339
03340 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03341
03342 i = 0;
03343 argv[i] = "launchctl";
03344 ++i;
03345 argv[i] = "getenv";
03346 ++i;
03347 argv[i] = (char*)launchd_env_var;
03348 ++i;
03349 argv[i] = NULL;
03350 ++i;
03351
03352 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03353
03354 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03355 {
03356 return FALSE;
03357 }
03358
03359
03360 if (_dbus_string_get_length(socket_path) == 0)
03361 {
03362 return FALSE;
03363 }
03364
03365
03366 _dbus_string_shorten(socket_path, 1);
03367 return TRUE;
03368 #else
03369 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03370 "can't lookup socket from launchd; launchd support not compiled in");
03371 return FALSE;
03372 #endif
03373 }
03374
03375 static dbus_bool_t
03376 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
03377 {
03378 #ifdef DBUS_ENABLE_LAUNCHD
03379 dbus_bool_t valid_socket;
03380 DBusString socket_path;
03381
03382 if (!_dbus_string_init (&socket_path))
03383 {
03384 _DBUS_SET_OOM (error);
03385 return FALSE;
03386 }
03387
03388 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03389
03390 if (dbus_error_is_set(error))
03391 {
03392 _dbus_string_free(&socket_path);
03393 return FALSE;
03394 }
03395
03396 if (!valid_socket)
03397 {
03398 dbus_set_error(error, "no socket path",
03399 "launchd did not provide a socket path, "
03400 "verify that org.freedesktop.dbus-session.plist is loaded!");
03401 _dbus_string_free(&socket_path);
03402 return FALSE;
03403 }
03404 if (!_dbus_string_append (address, "unix:path="))
03405 {
03406 _DBUS_SET_OOM (error);
03407 _dbus_string_free(&socket_path);
03408 return FALSE;
03409 }
03410 if (!_dbus_string_copy (&socket_path, 0, address,
03411 _dbus_string_get_length (address)))
03412 {
03413 _DBUS_SET_OOM (error);
03414 _dbus_string_free(&socket_path);
03415 return FALSE;
03416 }
03417
03418 _dbus_string_free(&socket_path);
03419 return TRUE;
03420 #else
03421 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03422 "can't lookup session address from launchd; launchd support not compiled in");
03423 return FALSE;
03424 #endif
03425 }
03426
03446 dbus_bool_t
03447 _dbus_lookup_session_address (dbus_bool_t *supported,
03448 DBusString *address,
03449 DBusError *error)
03450 {
03451 #ifdef DBUS_ENABLE_LAUNCHD
03452 *supported = TRUE;
03453 return _dbus_lookup_session_address_launchd (address, error);
03454 #else
03455
03456
03457
03458
03459 *supported = FALSE;
03460 return TRUE;
03461 #endif
03462 }
03463
03481 dbus_bool_t
03482 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03483 {
03484 const char *xdg_data_home;
03485 const char *xdg_data_dirs;
03486 DBusString servicedir_path;
03487
03488 if (!_dbus_string_init (&servicedir_path))
03489 return FALSE;
03490
03491 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03492 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03493
03494 if (xdg_data_dirs != NULL)
03495 {
03496 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03497 goto oom;
03498
03499 if (!_dbus_string_append (&servicedir_path, ":"))
03500 goto oom;
03501 }
03502 else
03503 {
03504 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03505 goto oom;
03506 }
03507
03508
03509
03510
03511
03512
03513
03514 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03515 goto oom;
03516
03517 if (xdg_data_home != NULL)
03518 {
03519 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03520 goto oom;
03521 }
03522 else
03523 {
03524 const DBusString *homedir;
03525 DBusString local_share;
03526
03527 if (!_dbus_homedir_from_current_process (&homedir))
03528 goto oom;
03529
03530 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03531 goto oom;
03532
03533 _dbus_string_init_const (&local_share, "/.local/share");
03534 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03535 goto oom;
03536 }
03537
03538 if (!_dbus_split_paths_and_append (&servicedir_path,
03539 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03540 dirs))
03541 goto oom;
03542
03543 _dbus_string_free (&servicedir_path);
03544 return TRUE;
03545
03546 oom:
03547 _dbus_string_free (&servicedir_path);
03548 return FALSE;
03549 }
03550
03551
03570 dbus_bool_t
03571 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03572 {
03573 const char *xdg_data_dirs;
03574 DBusString servicedir_path;
03575
03576 if (!_dbus_string_init (&servicedir_path))
03577 return FALSE;
03578
03579 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03580
03581 if (xdg_data_dirs != NULL)
03582 {
03583 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03584 goto oom;
03585
03586 if (!_dbus_string_append (&servicedir_path, ":"))
03587 goto oom;
03588 }
03589 else
03590 {
03591 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03592 goto oom;
03593 }
03594
03595
03596
03597
03598
03599
03600
03601 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03602 goto oom;
03603
03604 if (!_dbus_split_paths_and_append (&servicedir_path,
03605 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03606 dirs))
03607 goto oom;
03608
03609 _dbus_string_free (&servicedir_path);
03610 return TRUE;
03611
03612 oom:
03613 _dbus_string_free (&servicedir_path);
03614 return FALSE;
03615 }
03616
03625 dbus_bool_t
03626 _dbus_append_system_config_file (DBusString *str)
03627 {
03628 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03629 }
03630
03637 dbus_bool_t
03638 _dbus_append_session_config_file (DBusString *str)
03639 {
03640 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03641 }
03642
03650 void
03651 _dbus_flush_caches (void)
03652 {
03653 _dbus_user_database_flush_system ();
03654 }
03655
03669 dbus_bool_t
03670 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03671 DBusCredentials *credentials)
03672 {
03673 DBusString homedir;
03674 DBusString dotdir;
03675 dbus_uid_t uid;
03676
03677 _dbus_assert (credentials != NULL);
03678 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03679
03680 if (!_dbus_string_init (&homedir))
03681 return FALSE;
03682
03683 uid = _dbus_credentials_get_unix_uid (credentials);
03684 _dbus_assert (uid != DBUS_UID_UNSET);
03685
03686 if (!_dbus_homedir_from_uid (uid, &homedir))
03687 goto failed;
03688
03689 #ifdef DBUS_BUILD_TESTS
03690 {
03691 const char *override;
03692
03693 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03694 if (override != NULL && *override != '\0')
03695 {
03696 _dbus_string_set_length (&homedir, 0);
03697 if (!_dbus_string_append (&homedir, override))
03698 goto failed;
03699
03700 _dbus_verbose ("Using fake homedir for testing: %s\n",
03701 _dbus_string_get_const_data (&homedir));
03702 }
03703 else
03704 {
03705 static dbus_bool_t already_warned = FALSE;
03706 if (!already_warned)
03707 {
03708 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03709 already_warned = TRUE;
03710 }
03711 }
03712 }
03713 #endif
03714
03715 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03716 if (!_dbus_concat_dir_and_file (&homedir,
03717 &dotdir))
03718 goto failed;
03719
03720 if (!_dbus_string_copy (&homedir, 0,
03721 directory, _dbus_string_get_length (directory))) {
03722 goto failed;
03723 }
03724
03725 _dbus_string_free (&homedir);
03726 return TRUE;
03727
03728 failed:
03729 _dbus_string_free (&homedir);
03730 return FALSE;
03731 }
03732
03733
03734 dbus_bool_t
03735 _dbus_daemon_publish_session_bus_address (const char* addr,
03736 const char *scope)
03737 {
03738 return TRUE;
03739 }
03740
03741
03742 void
03743 _dbus_daemon_unpublish_session_bus_address (void)
03744 {
03745
03746 }
03747
03754 dbus_bool_t
03755 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03756 {
03757 return errno == EAGAIN || errno == EWOULDBLOCK;
03758 }
03759
03767 dbus_bool_t
03768 _dbus_delete_directory (const DBusString *filename,
03769 DBusError *error)
03770 {
03771 const char *filename_c;
03772
03773 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03774
03775 filename_c = _dbus_string_get_const_data (filename);
03776
03777 if (rmdir (filename_c) != 0)
03778 {
03779 dbus_set_error (error, DBUS_ERROR_FAILED,
03780 "Failed to remove directory %s: %s\n",
03781 filename_c, _dbus_strerror (errno));
03782 return FALSE;
03783 }
03784
03785 return TRUE;
03786 }
03787
03795 dbus_bool_t
03796 _dbus_socket_can_pass_unix_fd(int fd) {
03797
03798 #ifdef SCM_RIGHTS
03799 union {
03800 struct sockaddr sa;
03801 struct sockaddr_storage storage;
03802 struct sockaddr_un un;
03803 } sa_buf;
03804
03805 socklen_t sa_len = sizeof(sa_buf);
03806
03807 _DBUS_ZERO(sa_buf);
03808
03809 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03810 return FALSE;
03811
03812 return sa_buf.sa.sa_family == AF_UNIX;
03813
03814 #else
03815 return FALSE;
03816
03817 #endif
03818 }
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828 const char *
03829 _dbus_replace_install_prefix (const char *configure_time_path)
03830 {
03831 return configure_time_path;
03832 }
03833
03834