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 #if HAVE_DECL_MSG_NOSIGNAL
00208 const char *data;
00209 int bytes_written;
00210
00211 data = _dbus_string_get_const_data_len (buffer, start, len);
00212
00213 again:
00214
00215 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00216
00217 if (bytes_written < 0 && errno == EINTR)
00218 goto again;
00219
00220 return bytes_written;
00221
00222 #else
00223 return _dbus_write (fd, buffer, start, len);
00224 #endif
00225 }
00226
00239 int
00240 _dbus_read_socket_with_unix_fds (int fd,
00241 DBusString *buffer,
00242 int count,
00243 int *fds,
00244 int *n_fds) {
00245 #ifndef HAVE_UNIX_FD_PASSING
00246 int r;
00247
00248 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00249 return r;
00250
00251 *n_fds = 0;
00252 return r;
00253
00254 #else
00255 int bytes_read;
00256 int start;
00257 struct msghdr m;
00258 struct iovec iov;
00259
00260 _dbus_assert (count >= 0);
00261 _dbus_assert (*n_fds >= 0);
00262
00263 start = _dbus_string_get_length (buffer);
00264
00265 if (!_dbus_string_lengthen (buffer, count))
00266 {
00267 errno = ENOMEM;
00268 return -1;
00269 }
00270
00271 _DBUS_ZERO(iov);
00272 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00273 iov.iov_len = count;
00274
00275 _DBUS_ZERO(m);
00276 m.msg_iov = &iov;
00277 m.msg_iovlen = 1;
00278
00279
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 #if HAVE_DECL_MSG_NOSIGNAL
00446 |MSG_NOSIGNAL
00447 #endif
00448 );
00449
00450 if (bytes_written < 0 && errno == EINTR)
00451 goto again;
00452
00453 #if 0
00454 if (bytes_written > 0)
00455 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00456 #endif
00457
00458 return bytes_written;
00459 #endif
00460 }
00461
00475 int
00476 _dbus_write_socket_two (int fd,
00477 const DBusString *buffer1,
00478 int start1,
00479 int len1,
00480 const DBusString *buffer2,
00481 int start2,
00482 int len2)
00483 {
00484 #if HAVE_DECL_MSG_NOSIGNAL
00485 struct iovec vectors[2];
00486 const char *data1;
00487 const char *data2;
00488 int bytes_written;
00489 struct msghdr m;
00490
00491 _dbus_assert (buffer1 != NULL);
00492 _dbus_assert (start1 >= 0);
00493 _dbus_assert (start2 >= 0);
00494 _dbus_assert (len1 >= 0);
00495 _dbus_assert (len2 >= 0);
00496
00497 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00498
00499 if (buffer2 != NULL)
00500 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00501 else
00502 {
00503 data2 = NULL;
00504 start2 = 0;
00505 len2 = 0;
00506 }
00507
00508 vectors[0].iov_base = (char*) data1;
00509 vectors[0].iov_len = len1;
00510 vectors[1].iov_base = (char*) data2;
00511 vectors[1].iov_len = len2;
00512
00513 _DBUS_ZERO(m);
00514 m.msg_iov = vectors;
00515 m.msg_iovlen = data2 ? 2 : 1;
00516
00517 again:
00518
00519 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00520
00521 if (bytes_written < 0 && errno == EINTR)
00522 goto again;
00523
00524 return bytes_written;
00525
00526 #else
00527 return _dbus_write_two (fd, buffer1, start1, len1,
00528 buffer2, start2, len2);
00529 #endif
00530 }
00531
00532 dbus_bool_t
00533 _dbus_socket_is_invalid (int fd)
00534 {
00535 return fd < 0 ? TRUE : FALSE;
00536 }
00537
00554 int
00555 _dbus_read (int fd,
00556 DBusString *buffer,
00557 int count)
00558 {
00559 int bytes_read;
00560 int start;
00561 char *data;
00562
00563 _dbus_assert (count >= 0);
00564
00565 start = _dbus_string_get_length (buffer);
00566
00567 if (!_dbus_string_lengthen (buffer, count))
00568 {
00569 errno = ENOMEM;
00570 return -1;
00571 }
00572
00573 data = _dbus_string_get_data_len (buffer, start, count);
00574
00575 again:
00576
00577 bytes_read = read (fd, data, count);
00578
00579 if (bytes_read < 0)
00580 {
00581 if (errno == EINTR)
00582 goto again;
00583 else
00584 {
00585
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 ai = NULL;
01315 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01316 {
01317 dbus_set_error (error,
01318 _dbus_error_from_errno (errno),
01319 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01320 host ? host : "*", port, gai_strerror(res), res);
01321 goto failed;
01322 }
01323
01324 tmp = ai;
01325 while (tmp)
01326 {
01327 int fd = -1, *newlisten_fd;
01328 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01329 {
01330 _DBUS_ASSERT_ERROR_IS_SET(error);
01331 goto failed;
01332 }
01333 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01334
01335 reuseaddr = 1;
01336 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01337 {
01338 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01339 host ? host : "*", port, _dbus_strerror (errno));
01340 }
01341
01342 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01343 {
01344 saved_errno = errno;
01345 _dbus_close(fd, NULL);
01346 if (saved_errno == EADDRINUSE)
01347 {
01348
01349
01350
01351 tmp = tmp->ai_next;
01352 continue;
01353 }
01354 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01355 "Failed to bind socket \"%s:%s\": %s",
01356 host ? host : "*", port, _dbus_strerror (saved_errno));
01357 goto failed;
01358 }
01359
01360 if (listen (fd, 30 ) < 0)
01361 {
01362 saved_errno = errno;
01363 _dbus_close (fd, NULL);
01364 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01365 "Failed to listen on socket \"%s:%s\": %s",
01366 host ? host : "*", port, _dbus_strerror (saved_errno));
01367 goto failed;
01368 }
01369
01370 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01371 if (!newlisten_fd)
01372 {
01373 saved_errno = errno;
01374 _dbus_close (fd, NULL);
01375 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01376 "Failed to allocate file handle array: %s",
01377 _dbus_strerror (saved_errno));
01378 goto failed;
01379 }
01380 listen_fd = newlisten_fd;
01381 listen_fd[nlisten_fd] = fd;
01382 nlisten_fd++;
01383
01384 if (!_dbus_string_get_length(retport))
01385 {
01386
01387
01388
01389
01390 if (!port || !strcmp(port, "0"))
01391 {
01392 int result;
01393 struct sockaddr_storage addr;
01394 socklen_t addrlen;
01395 char portbuf[50];
01396
01397 addrlen = sizeof(addr);
01398 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01399
01400 if (result == -1 ||
01401 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01402 portbuf, sizeof(portbuf),
01403 NI_NUMERICHOST)) != 0)
01404 {
01405 dbus_set_error (error, _dbus_error_from_errno (errno),
01406 "Failed to resolve port \"%s:%s\": %s (%s)",
01407 host ? host : "*", port, gai_strerror(res), res);
01408 goto failed;
01409 }
01410 if (!_dbus_string_append(retport, portbuf))
01411 {
01412 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01413 goto failed;
01414 }
01415
01416
01417 port = _dbus_string_get_const_data(retport);
01418 freeaddrinfo(ai);
01419 goto redo_lookup_with_port;
01420 }
01421 else
01422 {
01423 if (!_dbus_string_append(retport, port))
01424 {
01425 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01426 goto failed;
01427 }
01428 }
01429 }
01430
01431 tmp = tmp->ai_next;
01432 }
01433 freeaddrinfo(ai);
01434 ai = NULL;
01435
01436 if (!nlisten_fd)
01437 {
01438 errno = EADDRINUSE;
01439 dbus_set_error (error, _dbus_error_from_errno (errno),
01440 "Failed to bind socket \"%s:%s\": %s",
01441 host ? host : "*", port, _dbus_strerror (errno));
01442 goto failed;
01443 }
01444
01445 for (i = 0 ; i < nlisten_fd ; i++)
01446 {
01447 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01448 {
01449 goto failed;
01450 }
01451 }
01452
01453 *fds_p = listen_fd;
01454
01455 return nlisten_fd;
01456
01457 failed:
01458 if (ai)
01459 freeaddrinfo(ai);
01460 for (i = 0 ; i < nlisten_fd ; i++)
01461 _dbus_close(listen_fd[i], NULL);
01462 dbus_free(listen_fd);
01463 return -1;
01464 }
01465
01466 static dbus_bool_t
01467 write_credentials_byte (int server_fd,
01468 DBusError *error)
01469 {
01470 int bytes_written;
01471 char buf[1] = { '\0' };
01472 #if defined(HAVE_CMSGCRED)
01473 union {
01474 struct cmsghdr hdr;
01475 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01476 } cmsg;
01477 struct iovec iov;
01478 struct msghdr msg;
01479 iov.iov_base = buf;
01480 iov.iov_len = 1;
01481
01482 _DBUS_ZERO(msg);
01483 msg.msg_iov = &iov;
01484 msg.msg_iovlen = 1;
01485
01486 msg.msg_control = (caddr_t) &cmsg;
01487 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01488 _DBUS_ZERO(cmsg);
01489 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01490 cmsg.hdr.cmsg_level = SOL_SOCKET;
01491 cmsg.hdr.cmsg_type = SCM_CREDS;
01492 #endif
01493
01494 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01495
01496 again:
01497
01498 #if defined(HAVE_CMSGCRED)
01499 bytes_written = sendmsg (server_fd, &msg, 0
01500 #if HAVE_DECL_MSG_NOSIGNAL
01501 |MSG_NOSIGNAL
01502 #endif
01503 );
01504 #else
01505 bytes_written = send (server_fd, buf, 1, 0
01506 #if HAVE_DECL_MSG_NOSIGNAL
01507 |MSG_NOSIGNAL
01508 #endif
01509 );
01510 #endif
01511
01512 if (bytes_written < 0 && errno == EINTR)
01513 goto again;
01514
01515 if (bytes_written < 0)
01516 {
01517 dbus_set_error (error, _dbus_error_from_errno (errno),
01518 "Failed to write credentials byte: %s",
01519 _dbus_strerror (errno));
01520 return FALSE;
01521 }
01522 else if (bytes_written == 0)
01523 {
01524 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01525 "wrote zero bytes writing credentials byte");
01526 return FALSE;
01527 }
01528 else
01529 {
01530 _dbus_assert (bytes_written == 1);
01531 _dbus_verbose ("wrote credentials byte\n");
01532 return TRUE;
01533 }
01534 }
01535
01557 dbus_bool_t
01558 _dbus_read_credentials_socket (int client_fd,
01559 DBusCredentials *credentials,
01560 DBusError *error)
01561 {
01562 struct msghdr msg;
01563 struct iovec iov;
01564 char buf;
01565 dbus_uid_t uid_read;
01566 dbus_pid_t pid_read;
01567 int bytes_read;
01568
01569 #ifdef HAVE_CMSGCRED
01570 union {
01571 struct cmsghdr hdr;
01572 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01573 } cmsg;
01574
01575 #elif defined(LOCAL_CREDS)
01576 struct {
01577 struct cmsghdr hdr;
01578 struct sockcred cred;
01579 } cmsg;
01580 #endif
01581
01582 uid_read = DBUS_UID_UNSET;
01583 pid_read = DBUS_PID_UNSET;
01584
01585 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01586
01587
01588
01589
01590
01591 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01592 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01593 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01594
01595 _dbus_credentials_clear (credentials);
01596
01597
01598
01599
01600
01601
01602
01603 iov.iov_base = &buf;
01604 iov.iov_len = 1;
01605
01606 _DBUS_ZERO(msg);
01607 msg.msg_iov = &iov;
01608 msg.msg_iovlen = 1;
01609
01610 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01611 _DBUS_ZERO(cmsg);
01612 msg.msg_control = (caddr_t) &cmsg;
01613 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01614 #endif
01615
01616 again:
01617 bytes_read = recvmsg (client_fd, &msg, 0);
01618
01619 if (bytes_read < 0)
01620 {
01621 if (errno == EINTR)
01622 goto again;
01623
01624
01625
01626
01627
01628
01629 dbus_set_error (error, _dbus_error_from_errno (errno),
01630 "Failed to read credentials byte: %s",
01631 _dbus_strerror (errno));
01632 return FALSE;
01633 }
01634 else if (bytes_read == 0)
01635 {
01636
01637
01638
01639 dbus_set_error (error, DBUS_ERROR_FAILED,
01640 "Failed to read credentials byte (zero-length read)");
01641 return FALSE;
01642 }
01643 else if (buf != '\0')
01644 {
01645 dbus_set_error (error, DBUS_ERROR_FAILED,
01646 "Credentials byte was not nul");
01647 return FALSE;
01648 }
01649
01650 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01651 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01652 || cmsg.hdr.cmsg_type != SCM_CREDS)
01653 {
01654 dbus_set_error (error, DBUS_ERROR_FAILED,
01655 "Message from recvmsg() was not SCM_CREDS");
01656 return FALSE;
01657 }
01658 #endif
01659
01660 _dbus_verbose ("read credentials byte\n");
01661
01662 {
01663 #ifdef SO_PEERCRED
01664 #ifdef __OpenBSD__
01665 struct sockpeercred cr;
01666 #else
01667 struct ucred cr;
01668 #endif
01669 int cr_len = sizeof (cr);
01670
01671 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01672 cr_len == sizeof (cr))
01673 {
01674 pid_read = cr.pid;
01675 uid_read = cr.uid;
01676 }
01677 else
01678 {
01679 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01680 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01681 }
01682 #elif defined(HAVE_CMSGCRED)
01683 struct cmsgcred *cred;
01684
01685 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01686 pid_read = cred->cmcred_pid;
01687 uid_read = cred->cmcred_euid;
01688 #elif defined(LOCAL_CREDS)
01689 pid_read = DBUS_PID_UNSET;
01690 uid_read = cmsg.cred.sc_uid;
01691
01692
01693 _dbus_set_local_creds (client_fd, FALSE);
01694 #elif defined(HAVE_GETPEEREID)
01695 uid_t euid;
01696 gid_t egid;
01697 if (getpeereid (client_fd, &euid, &egid) == 0)
01698 {
01699 uid_read = euid;
01700 }
01701 else
01702 {
01703 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01704 }
01705 #elif defined(HAVE_GETPEERUCRED)
01706 ucred_t * ucred = NULL;
01707 if (getpeerucred (client_fd, &ucred) == 0)
01708 {
01709 pid_read = ucred_getpid (ucred);
01710 uid_read = ucred_geteuid (ucred);
01711 #ifdef HAVE_ADT
01712
01713 adt_session_data_t *adth = NULL;
01714 adt_export_data_t *data = NULL;
01715 size_t size = 0;
01716 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01717 {
01718 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01719 }
01720 else
01721 {
01722 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01723 {
01724 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01725 }
01726 else
01727 {
01728 size = adt_export_session_data (adth, &data);
01729 if (size <= 0)
01730 {
01731 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01732 }
01733 else
01734 {
01735 _dbus_credentials_add_adt_audit_data (credentials, data, size);
01736 free (data);
01737 }
01738 }
01739 (void) adt_end_session (adth);
01740 }
01741 #endif
01742 }
01743 else
01744 {
01745 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01746 }
01747 if (ucred != NULL)
01748 ucred_free (ucred);
01749 #else
01750 _dbus_verbose ("Socket credentials not supported on this OS\n");
01751 #endif
01752 }
01753
01754 _dbus_verbose ("Credentials:"
01755 " pid "DBUS_PID_FORMAT
01756 " uid "DBUS_UID_FORMAT
01757 "\n",
01758 pid_read,
01759 uid_read);
01760
01761 if (pid_read != DBUS_PID_UNSET)
01762 {
01763 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01764 {
01765 _DBUS_SET_OOM (error);
01766 return FALSE;
01767 }
01768 }
01769
01770 if (uid_read != DBUS_UID_UNSET)
01771 {
01772 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01773 {
01774 _DBUS_SET_OOM (error);
01775 return FALSE;
01776 }
01777 }
01778
01779 return TRUE;
01780 }
01781
01799 dbus_bool_t
01800 _dbus_send_credentials_socket (int server_fd,
01801 DBusError *error)
01802 {
01803 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01804
01805 if (write_credentials_byte (server_fd, error))
01806 return TRUE;
01807 else
01808 return FALSE;
01809 }
01810
01820 int
01821 _dbus_accept (int listen_fd)
01822 {
01823 int client_fd;
01824 struct sockaddr addr;
01825 socklen_t addrlen;
01826 #ifdef HAVE_ACCEPT4
01827 dbus_bool_t cloexec_done;
01828 #endif
01829
01830 addrlen = sizeof (addr);
01831
01832 retry:
01833
01834 #ifdef HAVE_ACCEPT4
01835
01836 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01837 cloexec_done = client_fd >= 0;
01838
01839 if (client_fd < 0 && errno == ENOSYS)
01840 #endif
01841 {
01842 client_fd = accept (listen_fd, &addr, &addrlen);
01843 }
01844
01845 if (client_fd < 0)
01846 {
01847 if (errno == EINTR)
01848 goto retry;
01849 }
01850
01851 _dbus_verbose ("client fd %d accepted\n", client_fd);
01852
01853 #ifdef HAVE_ACCEPT4
01854 if (!cloexec_done)
01855 #endif
01856 {
01857 _dbus_fd_set_close_on_exec(client_fd);
01858 }
01859
01860 return client_fd;
01861 }
01862
01871 dbus_bool_t
01872 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01873 {
01874 const char *directory;
01875 struct stat sb;
01876
01877 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01878
01879 directory = _dbus_string_get_const_data (dir);
01880
01881 if (stat (directory, &sb) < 0)
01882 {
01883 dbus_set_error (error, _dbus_error_from_errno (errno),
01884 "%s", _dbus_strerror (errno));
01885
01886 return FALSE;
01887 }
01888
01889 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01890 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01891 {
01892 dbus_set_error (error, DBUS_ERROR_FAILED,
01893 "%s directory is not private to the user", directory);
01894 return FALSE;
01895 }
01896
01897 return TRUE;
01898 }
01899
01900 static dbus_bool_t
01901 fill_user_info_from_passwd (struct passwd *p,
01902 DBusUserInfo *info,
01903 DBusError *error)
01904 {
01905 _dbus_assert (p->pw_name != NULL);
01906 _dbus_assert (p->pw_dir != NULL);
01907
01908 info->uid = p->pw_uid;
01909 info->primary_gid = p->pw_gid;
01910 info->username = _dbus_strdup (p->pw_name);
01911 info->homedir = _dbus_strdup (p->pw_dir);
01912
01913 if (info->username == NULL ||
01914 info->homedir == NULL)
01915 {
01916 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01917 return FALSE;
01918 }
01919
01920 return TRUE;
01921 }
01922
01923 static dbus_bool_t
01924 fill_user_info (DBusUserInfo *info,
01925 dbus_uid_t uid,
01926 const DBusString *username,
01927 DBusError *error)
01928 {
01929 const char *username_c;
01930
01931
01932 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01933 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01934
01935 info->uid = DBUS_UID_UNSET;
01936 info->primary_gid = DBUS_GID_UNSET;
01937 info->group_ids = NULL;
01938 info->n_group_ids = 0;
01939 info->username = NULL;
01940 info->homedir = NULL;
01941
01942 if (username != NULL)
01943 username_c = _dbus_string_get_const_data (username);
01944 else
01945 username_c = NULL;
01946
01947
01948
01949
01950
01951
01952 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01953 {
01954 struct passwd *p;
01955 int result;
01956 size_t buflen;
01957 char *buf;
01958 struct passwd p_str;
01959
01960
01961 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01962
01963
01964
01965
01966
01967 if ((long) buflen <= 0)
01968 buflen = 1024;
01969
01970 result = -1;
01971 while (1)
01972 {
01973 buf = dbus_malloc (buflen);
01974 if (buf == NULL)
01975 {
01976 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01977 return FALSE;
01978 }
01979
01980 p = NULL;
01981 #ifdef HAVE_POSIX_GETPWNAM_R
01982 if (uid != DBUS_UID_UNSET)
01983 result = getpwuid_r (uid, &p_str, buf, buflen,
01984 &p);
01985 else
01986 result = getpwnam_r (username_c, &p_str, buf, buflen,
01987 &p);
01988 #else
01989 if (uid != DBUS_UID_UNSET)
01990 p = getpwuid_r (uid, &p_str, buf, buflen);
01991 else
01992 p = getpwnam_r (username_c, &p_str, buf, buflen);
01993 result = 0;
01994 #endif
01995
01996 if (result == ERANGE && buflen < 512 * 1024)
01997 {
01998 dbus_free (buf);
01999 buflen *= 2;
02000 }
02001 else
02002 {
02003 break;
02004 }
02005 }
02006 if (result == 0 && p == &p_str)
02007 {
02008 if (!fill_user_info_from_passwd (p, info, error))
02009 {
02010 dbus_free (buf);
02011 return FALSE;
02012 }
02013 dbus_free (buf);
02014 }
02015 else
02016 {
02017 dbus_set_error (error, _dbus_error_from_errno (errno),
02018 "User \"%s\" unknown or no memory to allocate password entry\n",
02019 username_c ? username_c : "???");
02020 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02021 dbus_free (buf);
02022 return FALSE;
02023 }
02024 }
02025 #else
02026 {
02027
02028 struct passwd *p;
02029
02030 if (uid != DBUS_UID_UNSET)
02031 p = getpwuid (uid);
02032 else
02033 p = getpwnam (username_c);
02034
02035 if (p != NULL)
02036 {
02037 if (!fill_user_info_from_passwd (p, info, error))
02038 {
02039 return FALSE;
02040 }
02041 }
02042 else
02043 {
02044 dbus_set_error (error, _dbus_error_from_errno (errno),
02045 "User \"%s\" unknown or no memory to allocate password entry\n",
02046 username_c ? username_c : "???");
02047 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02048 return FALSE;
02049 }
02050 }
02051 #endif
02052
02053
02054 username_c = info->username;
02055
02056 #ifdef HAVE_GETGROUPLIST
02057 {
02058 gid_t *buf;
02059 int buf_count;
02060 int i;
02061 int initial_buf_count;
02062
02063 initial_buf_count = 17;
02064 buf_count = initial_buf_count;
02065 buf = dbus_new (gid_t, buf_count);
02066 if (buf == NULL)
02067 {
02068 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02069 goto failed;
02070 }
02071
02072 if (getgrouplist (username_c,
02073 info->primary_gid,
02074 buf, &buf_count) < 0)
02075 {
02076 gid_t *new;
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090 if (buf_count == initial_buf_count)
02091 {
02092 buf_count *= 16;
02093 }
02094 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02095 if (new == NULL)
02096 {
02097 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02098 dbus_free (buf);
02099 goto failed;
02100 }
02101
02102 buf = new;
02103
02104 errno = 0;
02105 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02106 {
02107 if (errno == 0)
02108 {
02109 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02110 username_c, buf_count, buf_count);
02111 }
02112 else
02113 {
02114 dbus_set_error (error,
02115 _dbus_error_from_errno (errno),
02116 "Failed to get groups for username \"%s\" primary GID "
02117 DBUS_GID_FORMAT ": %s\n",
02118 username_c, info->primary_gid,
02119 _dbus_strerror (errno));
02120 dbus_free (buf);
02121 goto failed;
02122 }
02123 }
02124 }
02125
02126 info->group_ids = dbus_new (dbus_gid_t, buf_count);
02127 if (info->group_ids == NULL)
02128 {
02129 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02130 dbus_free (buf);
02131 goto failed;
02132 }
02133
02134 for (i = 0; i < buf_count; ++i)
02135 info->group_ids[i] = buf[i];
02136
02137 info->n_group_ids = buf_count;
02138
02139 dbus_free (buf);
02140 }
02141 #else
02142 {
02143
02144 info->group_ids = dbus_new (dbus_gid_t, 1);
02145 if (info->group_ids == NULL)
02146 {
02147 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02148 goto failed;
02149 }
02150
02151 info->n_group_ids = 1;
02152
02153 (info->group_ids)[0] = info->primary_gid;
02154 }
02155 #endif
02156
02157 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02158
02159 return TRUE;
02160
02161 failed:
02162 _DBUS_ASSERT_ERROR_IS_SET (error);
02163 return FALSE;
02164 }
02165
02174 dbus_bool_t
02175 _dbus_user_info_fill (DBusUserInfo *info,
02176 const DBusString *username,
02177 DBusError *error)
02178 {
02179 return fill_user_info (info, DBUS_UID_UNSET,
02180 username, error);
02181 }
02182
02191 dbus_bool_t
02192 _dbus_user_info_fill_uid (DBusUserInfo *info,
02193 dbus_uid_t uid,
02194 DBusError *error)
02195 {
02196 return fill_user_info (info, uid,
02197 NULL, error);
02198 }
02199
02207 dbus_bool_t
02208 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02209 {
02210
02211
02212
02213
02214 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02215 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02216 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02217
02218 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02219 return FALSE;
02220 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02221 return FALSE;
02222
02223 return TRUE;
02224 }
02225
02237 dbus_bool_t
02238 _dbus_append_user_from_current_process (DBusString *str)
02239 {
02240 return _dbus_string_append_uint (str,
02241 _dbus_geteuid ());
02242 }
02243
02248 dbus_pid_t
02249 _dbus_getpid (void)
02250 {
02251 return getpid ();
02252 }
02253
02257 dbus_uid_t
02258 _dbus_getuid (void)
02259 {
02260 return getuid ();
02261 }
02262
02266 dbus_uid_t
02267 _dbus_geteuid (void)
02268 {
02269 return geteuid ();
02270 }
02271
02278 unsigned long
02279 _dbus_pid_for_log (void)
02280 {
02281 return getpid ();
02282 }
02283
02291 dbus_bool_t
02292 _dbus_parse_uid (const DBusString *uid_str,
02293 dbus_uid_t *uid)
02294 {
02295 int end;
02296 long val;
02297
02298 if (_dbus_string_get_length (uid_str) == 0)
02299 {
02300 _dbus_verbose ("UID string was zero length\n");
02301 return FALSE;
02302 }
02303
02304 val = -1;
02305 end = 0;
02306 if (!_dbus_string_parse_int (uid_str, 0, &val,
02307 &end))
02308 {
02309 _dbus_verbose ("could not parse string as a UID\n");
02310 return FALSE;
02311 }
02312
02313 if (end != _dbus_string_get_length (uid_str))
02314 {
02315 _dbus_verbose ("string contained trailing stuff after UID\n");
02316 return FALSE;
02317 }
02318
02319 *uid = val;
02320
02321 return TRUE;
02322 }
02323
02324 #if !DBUS_USE_SYNC
02325 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02326 #endif
02327
02334 dbus_int32_t
02335 _dbus_atomic_inc (DBusAtomic *atomic)
02336 {
02337 #if DBUS_USE_SYNC
02338 return __sync_add_and_fetch(&atomic->value, 1)-1;
02339 #else
02340 dbus_int32_t res;
02341 _DBUS_LOCK (atomic);
02342 res = atomic->value;
02343 atomic->value += 1;
02344 _DBUS_UNLOCK (atomic);
02345 return res;
02346 #endif
02347 }
02348
02355 dbus_int32_t
02356 _dbus_atomic_dec (DBusAtomic *atomic)
02357 {
02358 #if DBUS_USE_SYNC
02359 return __sync_sub_and_fetch(&atomic->value, 1)+1;
02360 #else
02361 dbus_int32_t res;
02362
02363 _DBUS_LOCK (atomic);
02364 res = atomic->value;
02365 atomic->value -= 1;
02366 _DBUS_UNLOCK (atomic);
02367 return res;
02368 #endif
02369 }
02370
02378 dbus_int32_t
02379 _dbus_atomic_get (DBusAtomic *atomic)
02380 {
02381 #if DBUS_USE_SYNC
02382 __sync_synchronize ();
02383 return atomic->value;
02384 #else
02385 dbus_int32_t res;
02386
02387 _DBUS_LOCK (atomic);
02388 res = atomic->value;
02389 _DBUS_UNLOCK (atomic);
02390 return res;
02391 #endif
02392 }
02393
02394 #ifdef DBUS_BUILD_TESTS
02395
02398 dbus_gid_t
02399 _dbus_getgid (void)
02400 {
02401 return getgid ();
02402 }
02403 #endif
02404
02413 int
02414 _dbus_poll (DBusPollFD *fds,
02415 int n_fds,
02416 int timeout_milliseconds)
02417 {
02418 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02419
02420
02421
02422
02423 if (_DBUS_POLLIN == POLLIN &&
02424 _DBUS_POLLPRI == POLLPRI &&
02425 _DBUS_POLLOUT == POLLOUT &&
02426 _DBUS_POLLERR == POLLERR &&
02427 _DBUS_POLLHUP == POLLHUP &&
02428 _DBUS_POLLNVAL == POLLNVAL &&
02429 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02430 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02431 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02432 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02433 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02434 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02435 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02436 {
02437 return poll ((struct pollfd*) fds,
02438 n_fds,
02439 timeout_milliseconds);
02440 }
02441 else
02442 {
02443
02444
02445
02446 _dbus_warn ("didn't implement poll() properly for this system yet\n");
02447 return -1;
02448 }
02449 #else
02450
02451 fd_set read_set, write_set, err_set;
02452 int max_fd = 0;
02453 int i;
02454 struct timeval tv;
02455 int ready;
02456
02457 FD_ZERO (&read_set);
02458 FD_ZERO (&write_set);
02459 FD_ZERO (&err_set);
02460
02461 for (i = 0; i < n_fds; i++)
02462 {
02463 DBusPollFD *fdp = &fds[i];
02464
02465 if (fdp->events & _DBUS_POLLIN)
02466 FD_SET (fdp->fd, &read_set);
02467
02468 if (fdp->events & _DBUS_POLLOUT)
02469 FD_SET (fdp->fd, &write_set);
02470
02471 FD_SET (fdp->fd, &err_set);
02472
02473 max_fd = MAX (max_fd, fdp->fd);
02474 }
02475
02476 tv.tv_sec = timeout_milliseconds / 1000;
02477 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02478
02479 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02480 timeout_milliseconds < 0 ? NULL : &tv);
02481
02482 if (ready > 0)
02483 {
02484 for (i = 0; i < n_fds; i++)
02485 {
02486 DBusPollFD *fdp = &fds[i];
02487
02488 fdp->revents = 0;
02489
02490 if (FD_ISSET (fdp->fd, &read_set))
02491 fdp->revents |= _DBUS_POLLIN;
02492
02493 if (FD_ISSET (fdp->fd, &write_set))
02494 fdp->revents |= _DBUS_POLLOUT;
02495
02496 if (FD_ISSET (fdp->fd, &err_set))
02497 fdp->revents |= _DBUS_POLLERR;
02498 }
02499 }
02500
02501 return ready;
02502 #endif
02503 }
02504
02512 void
02513 _dbus_get_current_time (long *tv_sec,
02514 long *tv_usec)
02515 {
02516 struct timeval t;
02517
02518 #ifdef HAVE_MONOTONIC_CLOCK
02519 struct timespec ts;
02520 clock_gettime (CLOCK_MONOTONIC, &ts);
02521
02522 if (tv_sec)
02523 *tv_sec = ts.tv_sec;
02524 if (tv_usec)
02525 *tv_usec = ts.tv_nsec / 1000;
02526 #else
02527 gettimeofday (&t, NULL);
02528
02529 if (tv_sec)
02530 *tv_sec = t.tv_sec;
02531 if (tv_usec)
02532 *tv_usec = t.tv_usec;
02533 #endif
02534 }
02535
02544 dbus_bool_t
02545 _dbus_create_directory (const DBusString *filename,
02546 DBusError *error)
02547 {
02548 const char *filename_c;
02549
02550 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02551
02552 filename_c = _dbus_string_get_const_data (filename);
02553
02554 if (mkdir (filename_c, 0700) < 0)
02555 {
02556 if (errno == EEXIST)
02557 return TRUE;
02558
02559 dbus_set_error (error, DBUS_ERROR_FAILED,
02560 "Failed to create directory %s: %s\n",
02561 filename_c, _dbus_strerror (errno));
02562 return FALSE;
02563 }
02564 else
02565 return TRUE;
02566 }
02567
02578 dbus_bool_t
02579 _dbus_concat_dir_and_file (DBusString *dir,
02580 const DBusString *next_component)
02581 {
02582 dbus_bool_t dir_ends_in_slash;
02583 dbus_bool_t file_starts_with_slash;
02584
02585 if (_dbus_string_get_length (dir) == 0 ||
02586 _dbus_string_get_length (next_component) == 0)
02587 return TRUE;
02588
02589 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02590 _dbus_string_get_length (dir) - 1);
02591
02592 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02593
02594 if (dir_ends_in_slash && file_starts_with_slash)
02595 {
02596 _dbus_string_shorten (dir, 1);
02597 }
02598 else if (!(dir_ends_in_slash || file_starts_with_slash))
02599 {
02600 if (!_dbus_string_append_byte (dir, '/'))
02601 return FALSE;
02602 }
02603
02604 return _dbus_string_copy (next_component, 0, dir,
02605 _dbus_string_get_length (dir));
02606 }
02607
02609 #define NANOSECONDS_PER_SECOND 1000000000
02610
02611 #define MICROSECONDS_PER_SECOND 1000000
02612
02613 #define MILLISECONDS_PER_SECOND 1000
02614
02615 #define NANOSECONDS_PER_MILLISECOND 1000000
02616
02617 #define MICROSECONDS_PER_MILLISECOND 1000
02618
02623 void
02624 _dbus_sleep_milliseconds (int milliseconds)
02625 {
02626 #ifdef HAVE_NANOSLEEP
02627 struct timespec req;
02628 struct timespec rem;
02629
02630 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02631 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02632 rem.tv_sec = 0;
02633 rem.tv_nsec = 0;
02634
02635 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02636 req = rem;
02637 #elif defined (HAVE_USLEEP)
02638 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02639 #else
02640 sleep (MAX (milliseconds / 1000, 1));
02641 #endif
02642 }
02643
02644 static dbus_bool_t
02645 _dbus_generate_pseudorandom_bytes (DBusString *str,
02646 int n_bytes)
02647 {
02648 int old_len;
02649 char *p;
02650
02651 old_len = _dbus_string_get_length (str);
02652
02653 if (!_dbus_string_lengthen (str, n_bytes))
02654 return FALSE;
02655
02656 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02657
02658 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02659
02660 return TRUE;
02661 }
02662
02671 dbus_bool_t
02672 _dbus_generate_random_bytes (DBusString *str,
02673 int n_bytes)
02674 {
02675 int old_len;
02676 int fd;
02677
02678
02679
02680
02681
02682
02683
02684 old_len = _dbus_string_get_length (str);
02685 fd = -1;
02686
02687
02688 fd = open ("/dev/urandom", O_RDONLY);
02689 if (fd < 0)
02690 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02691
02692 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02693
02694 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02695 {
02696 _dbus_close (fd, NULL);
02697 _dbus_string_set_length (str, old_len);
02698 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02699 }
02700
02701 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02702 n_bytes);
02703
02704 _dbus_close (fd, NULL);
02705
02706 return TRUE;
02707 }
02708
02714 void
02715 _dbus_exit (int code)
02716 {
02717 _exit (code);
02718 }
02719
02728 const char*
02729 _dbus_strerror (int error_number)
02730 {
02731 const char *msg;
02732
02733 msg = strerror (error_number);
02734 if (msg == NULL)
02735 msg = "unknown";
02736
02737 return msg;
02738 }
02739
02743 void
02744 _dbus_disable_sigpipe (void)
02745 {
02746 signal (SIGPIPE, SIG_IGN);
02747 }
02748
02756 void
02757 _dbus_fd_set_close_on_exec (intptr_t fd)
02758 {
02759 int val;
02760
02761 val = fcntl (fd, F_GETFD, 0);
02762
02763 if (val < 0)
02764 return;
02765
02766 val |= FD_CLOEXEC;
02767
02768 fcntl (fd, F_SETFD, val);
02769 }
02770
02778 dbus_bool_t
02779 _dbus_close (int fd,
02780 DBusError *error)
02781 {
02782 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02783
02784 again:
02785 if (close (fd) < 0)
02786 {
02787 if (errno == EINTR)
02788 goto again;
02789
02790 dbus_set_error (error, _dbus_error_from_errno (errno),
02791 "Could not close fd %d", fd);
02792 return FALSE;
02793 }
02794
02795 return TRUE;
02796 }
02797
02805 int
02806 _dbus_dup(int fd,
02807 DBusError *error)
02808 {
02809 int new_fd;
02810
02811 #ifdef F_DUPFD_CLOEXEC
02812 dbus_bool_t cloexec_done;
02813
02814 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02815 cloexec_done = new_fd >= 0;
02816
02817 if (new_fd < 0 && errno == EINVAL)
02818 #endif
02819 {
02820 new_fd = fcntl(fd, F_DUPFD, 3);
02821 }
02822
02823 if (new_fd < 0) {
02824
02825 dbus_set_error (error, _dbus_error_from_errno (errno),
02826 "Could not duplicate fd %d", fd);
02827 return -1;
02828 }
02829
02830 #ifdef F_DUPFD_CLOEXEC
02831 if (!cloexec_done)
02832 #endif
02833 {
02834 _dbus_fd_set_close_on_exec(new_fd);
02835 }
02836
02837 return new_fd;
02838 }
02839
02847 dbus_bool_t
02848 _dbus_set_fd_nonblocking (int fd,
02849 DBusError *error)
02850 {
02851 int val;
02852
02853 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02854
02855 val = fcntl (fd, F_GETFL, 0);
02856 if (val < 0)
02857 {
02858 dbus_set_error (error, _dbus_error_from_errno (errno),
02859 "Failed to get flags from file descriptor %d: %s",
02860 fd, _dbus_strerror (errno));
02861 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02862 _dbus_strerror (errno));
02863 return FALSE;
02864 }
02865
02866 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02867 {
02868 dbus_set_error (error, _dbus_error_from_errno (errno),
02869 "Failed to set nonblocking flag of file descriptor %d: %s",
02870 fd, _dbus_strerror (errno));
02871 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02872 fd, _dbus_strerror (errno));
02873
02874 return FALSE;
02875 }
02876
02877 return TRUE;
02878 }
02879
02885 void
02886 _dbus_print_backtrace (void)
02887 {
02888 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02889 void *bt[500];
02890 int bt_size;
02891 int i;
02892 char **syms;
02893
02894 bt_size = backtrace (bt, 500);
02895
02896 syms = backtrace_symbols (bt, bt_size);
02897
02898 i = 0;
02899 while (i < bt_size)
02900 {
02901
02902 fprintf (stderr, " %s\n", syms[i]);
02903 ++i;
02904 }
02905 fflush (stderr);
02906
02907 free (syms);
02908 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02909 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02910 #else
02911 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02912 #endif
02913 }
02914
02932 dbus_bool_t
02933 _dbus_full_duplex_pipe (int *fd1,
02934 int *fd2,
02935 dbus_bool_t blocking,
02936 DBusError *error)
02937 {
02938 #ifdef HAVE_SOCKETPAIR
02939 int fds[2];
02940 int retval;
02941
02942 #ifdef SOCK_CLOEXEC
02943 dbus_bool_t cloexec_done;
02944
02945 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02946 cloexec_done = retval >= 0;
02947
02948 if (retval < 0 && errno == EINVAL)
02949 #endif
02950 {
02951 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02952 }
02953
02954 if (retval < 0)
02955 {
02956 dbus_set_error (error, _dbus_error_from_errno (errno),
02957 "Could not create full-duplex pipe");
02958 return FALSE;
02959 }
02960
02961 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02962
02963 #ifdef SOCK_CLOEXEC
02964 if (!cloexec_done)
02965 #endif
02966 {
02967 _dbus_fd_set_close_on_exec (fds[0]);
02968 _dbus_fd_set_close_on_exec (fds[1]);
02969 }
02970
02971 if (!blocking &&
02972 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02973 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02974 {
02975 dbus_set_error (error, _dbus_error_from_errno (errno),
02976 "Could not set full-duplex pipe nonblocking");
02977
02978 _dbus_close (fds[0], NULL);
02979 _dbus_close (fds[1], NULL);
02980
02981 return FALSE;
02982 }
02983
02984 *fd1 = fds[0];
02985 *fd2 = fds[1];
02986
02987 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02988 *fd1, *fd2);
02989
02990 return TRUE;
02991 #else
02992 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02993 dbus_set_error (error, DBUS_ERROR_FAILED,
02994 "_dbus_full_duplex_pipe() not implemented on this OS");
02995 return FALSE;
02996 #endif
02997 }
02998
03007 int
03008 _dbus_printf_string_upper_bound (const char *format,
03009 va_list args)
03010 {
03011 char c;
03012 return vsnprintf (&c, 1, format, args);
03013 }
03014
03021 const char*
03022 _dbus_get_tmpdir(void)
03023 {
03024 static const char* tmpdir = NULL;
03025
03026 if (tmpdir == NULL)
03027 {
03028
03029
03030
03031
03032 if (tmpdir == NULL)
03033 tmpdir = getenv("TMPDIR");
03034
03035
03036
03037
03038 if (tmpdir == NULL)
03039 tmpdir = getenv("TMP");
03040 if (tmpdir == NULL)
03041 tmpdir = getenv("TEMP");
03042
03043
03044 if (tmpdir == NULL)
03045 tmpdir = "/tmp";
03046 }
03047
03048 _dbus_assert(tmpdir != NULL);
03049
03050 return tmpdir;
03051 }
03052
03072 static dbus_bool_t
03073 _read_subprocess_line_argv (const char *progpath,
03074 dbus_bool_t path_fallback,
03075 char * const *argv,
03076 DBusString *result,
03077 DBusError *error)
03078 {
03079 int result_pipe[2] = { -1, -1 };
03080 int errors_pipe[2] = { -1, -1 };
03081 pid_t pid;
03082 int ret;
03083 int status;
03084 int orig_len;
03085 int i;
03086
03087 dbus_bool_t retval;
03088 sigset_t new_set, old_set;
03089
03090 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03091 retval = FALSE;
03092
03093
03094
03095
03096
03097 sigemptyset (&new_set);
03098 sigaddset (&new_set, SIGCHLD);
03099 sigprocmask (SIG_BLOCK, &new_set, &old_set);
03100
03101 orig_len = _dbus_string_get_length (result);
03102
03103 #define READ_END 0
03104 #define WRITE_END 1
03105 if (pipe (result_pipe) < 0)
03106 {
03107 dbus_set_error (error, _dbus_error_from_errno (errno),
03108 "Failed to create a pipe to call %s: %s",
03109 progpath, _dbus_strerror (errno));
03110 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03111 progpath, _dbus_strerror (errno));
03112 goto out;
03113 }
03114 if (pipe (errors_pipe) < 0)
03115 {
03116 dbus_set_error (error, _dbus_error_from_errno (errno),
03117 "Failed to create a pipe to call %s: %s",
03118 progpath, _dbus_strerror (errno));
03119 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03120 progpath, _dbus_strerror (errno));
03121 goto out;
03122 }
03123
03124 pid = fork ();
03125 if (pid < 0)
03126 {
03127 dbus_set_error (error, _dbus_error_from_errno (errno),
03128 "Failed to fork() to call %s: %s",
03129 progpath, _dbus_strerror (errno));
03130 _dbus_verbose ("Failed to fork() to call %s: %s\n",
03131 progpath, _dbus_strerror (errno));
03132 goto out;
03133 }
03134
03135 if (pid == 0)
03136 {
03137
03138 int maxfds;
03139 int fd;
03140
03141 fd = open ("/dev/null", O_RDWR);
03142 if (fd == -1)
03143
03144 _exit (1);
03145
03146 _dbus_verbose ("/dev/null fd %d opened\n", fd);
03147
03148
03149 close (result_pipe[READ_END]);
03150 close (errors_pipe[READ_END]);
03151 close (0);
03152 close (1);
03153 close (2);
03154
03155 if (dup2 (fd, 0) == -1)
03156 _exit (1);
03157 if (dup2 (result_pipe[WRITE_END], 1) == -1)
03158 _exit (1);
03159 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03160 _exit (1);
03161
03162 maxfds = sysconf (_SC_OPEN_MAX);
03163
03164
03165
03166 if (maxfds < 0)
03167 maxfds = 1024;
03168
03169 for (i = 3; i < maxfds; i++)
03170 close (i);
03171
03172 sigprocmask (SIG_SETMASK, &old_set, NULL);
03173
03174
03175 if (progpath[0] == '/')
03176 {
03177 execv (progpath, argv);
03178
03179
03180
03181
03182
03183
03184 if (path_fallback)
03185
03186 execvp (strrchr (progpath, '/')+1, argv);
03187 }
03188 else
03189 execvp (progpath, argv);
03190
03191
03192 _exit (1);
03193 }
03194
03195
03196 close (result_pipe[WRITE_END]);
03197 close (errors_pipe[WRITE_END]);
03198 result_pipe[WRITE_END] = -1;
03199 errors_pipe[WRITE_END] = -1;
03200
03201 ret = 0;
03202 do
03203 {
03204 ret = _dbus_read (result_pipe[READ_END], result, 1024);
03205 }
03206 while (ret > 0);
03207
03208
03209 do
03210 {
03211 ret = waitpid (pid, &status, 0);
03212 }
03213 while (ret == -1 && errno == EINTR);
03214
03215
03216
03217 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03218 {
03219
03220 DBusString error_message;
03221 if (!_dbus_string_init (&error_message))
03222 {
03223 _DBUS_SET_OOM (error);
03224 goto out;
03225 }
03226
03227 ret = 0;
03228 do
03229 {
03230 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03231 }
03232 while (ret > 0);
03233
03234 _dbus_string_set_length (result, orig_len);
03235 if (_dbus_string_get_length (&error_message) > 0)
03236 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03237 "%s terminated abnormally with the following error: %s",
03238 progpath, _dbus_string_get_data (&error_message));
03239 else
03240 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03241 "%s terminated abnormally without any error message",
03242 progpath);
03243 goto out;
03244 }
03245
03246 retval = TRUE;
03247
03248 out:
03249 sigprocmask (SIG_SETMASK, &old_set, NULL);
03250
03251 if (retval)
03252 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03253 else
03254 _DBUS_ASSERT_ERROR_IS_SET (error);
03255
03256 if (result_pipe[0] != -1)
03257 close (result_pipe[0]);
03258 if (result_pipe[1] != -1)
03259 close (result_pipe[1]);
03260 if (errors_pipe[0] != -1)
03261 close (errors_pipe[0]);
03262 if (errors_pipe[1] != -1)
03263 close (errors_pipe[1]);
03264
03265 return retval;
03266 }
03267
03279 dbus_bool_t
03280 _dbus_get_autolaunch_address (const char *scope,
03281 DBusString *address,
03282 DBusError *error)
03283 {
03284 #ifdef DBUS_BUILD_X11
03285
03286
03287
03288 const char *display;
03289 static char *argv[6];
03290 int i;
03291 DBusString uuid;
03292 dbus_bool_t retval;
03293
03294 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03295 retval = FALSE;
03296
03297
03298
03299
03300 display = _dbus_getenv ("DISPLAY");
03301
03302 if (display == NULL || display[0] == '\0')
03303 {
03304 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03305 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03306 return FALSE;
03307 }
03308
03309 if (!_dbus_string_init (&uuid))
03310 {
03311 _DBUS_SET_OOM (error);
03312 return FALSE;
03313 }
03314
03315 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03316 {
03317 _DBUS_SET_OOM (error);
03318 goto out;
03319 }
03320
03321 i = 0;
03322 argv[i] = "dbus-launch";
03323 ++i;
03324 argv[i] = "--autolaunch";
03325 ++i;
03326 argv[i] = _dbus_string_get_data (&uuid);
03327 ++i;
03328 argv[i] = "--binary-syntax";
03329 ++i;
03330 argv[i] = "--close-stderr";
03331 ++i;
03332 argv[i] = NULL;
03333 ++i;
03334
03335 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03336
03337 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03338 TRUE,
03339 argv, address, error);
03340
03341 out:
03342 _dbus_string_free (&uuid);
03343 return retval;
03344 #else
03345 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03346 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03347 "set your DBUS_SESSION_BUS_ADDRESS instead");
03348 return FALSE;
03349 #endif
03350 }
03351
03370 dbus_bool_t
03371 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
03372 dbus_bool_t create_if_not_found,
03373 DBusError *error)
03374 {
03375 DBusString filename;
03376 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03377 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03378 }
03379
03380 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03381 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03382
03389 dbus_bool_t
03390 _dbus_lookup_launchd_socket (DBusString *socket_path,
03391 const char *launchd_env_var,
03392 DBusError *error)
03393 {
03394 #ifdef DBUS_ENABLE_LAUNCHD
03395 char *argv[4];
03396 int i;
03397
03398 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03399
03400 i = 0;
03401 argv[i] = "launchctl";
03402 ++i;
03403 argv[i] = "getenv";
03404 ++i;
03405 argv[i] = (char*)launchd_env_var;
03406 ++i;
03407 argv[i] = NULL;
03408 ++i;
03409
03410 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03411
03412 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03413 {
03414 return FALSE;
03415 }
03416
03417
03418 if (_dbus_string_get_length(socket_path) == 0)
03419 {
03420 return FALSE;
03421 }
03422
03423
03424 _dbus_string_shorten(socket_path, 1);
03425 return TRUE;
03426 #else
03427 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03428 "can't lookup socket from launchd; launchd support not compiled in");
03429 return FALSE;
03430 #endif
03431 }
03432
03433 static dbus_bool_t
03434 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
03435 {
03436 #ifdef DBUS_ENABLE_LAUNCHD
03437 dbus_bool_t valid_socket;
03438 DBusString socket_path;
03439
03440 if (!_dbus_string_init (&socket_path))
03441 {
03442 _DBUS_SET_OOM (error);
03443 return FALSE;
03444 }
03445
03446 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03447
03448 if (dbus_error_is_set(error))
03449 {
03450 _dbus_string_free(&socket_path);
03451 return FALSE;
03452 }
03453
03454 if (!valid_socket)
03455 {
03456 dbus_set_error(error, "no socket path",
03457 "launchd did not provide a socket path, "
03458 "verify that org.freedesktop.dbus-session.plist is loaded!");
03459 _dbus_string_free(&socket_path);
03460 return FALSE;
03461 }
03462 if (!_dbus_string_append (address, "unix:path="))
03463 {
03464 _DBUS_SET_OOM (error);
03465 _dbus_string_free(&socket_path);
03466 return FALSE;
03467 }
03468 if (!_dbus_string_copy (&socket_path, 0, address,
03469 _dbus_string_get_length (address)))
03470 {
03471 _DBUS_SET_OOM (error);
03472 _dbus_string_free(&socket_path);
03473 return FALSE;
03474 }
03475
03476 _dbus_string_free(&socket_path);
03477 return TRUE;
03478 #else
03479 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03480 "can't lookup session address from launchd; launchd support not compiled in");
03481 return FALSE;
03482 #endif
03483 }
03484
03504 dbus_bool_t
03505 _dbus_lookup_session_address (dbus_bool_t *supported,
03506 DBusString *address,
03507 DBusError *error)
03508 {
03509 #ifdef DBUS_ENABLE_LAUNCHD
03510 *supported = TRUE;
03511 return _dbus_lookup_session_address_launchd (address, error);
03512 #else
03513
03514
03515
03516
03517 *supported = FALSE;
03518 return TRUE;
03519 #endif
03520 }
03521
03539 dbus_bool_t
03540 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03541 {
03542 const char *xdg_data_home;
03543 const char *xdg_data_dirs;
03544 DBusString servicedir_path;
03545
03546 if (!_dbus_string_init (&servicedir_path))
03547 return FALSE;
03548
03549 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03550 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03551
03552 if (xdg_data_dirs != NULL)
03553 {
03554 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03555 goto oom;
03556
03557 if (!_dbus_string_append (&servicedir_path, ":"))
03558 goto oom;
03559 }
03560 else
03561 {
03562 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03563 goto oom;
03564 }
03565
03566
03567
03568
03569
03570
03571
03572 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03573 goto oom;
03574
03575 if (xdg_data_home != NULL)
03576 {
03577 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03578 goto oom;
03579 }
03580 else
03581 {
03582 const DBusString *homedir;
03583 DBusString local_share;
03584
03585 if (!_dbus_homedir_from_current_process (&homedir))
03586 goto oom;
03587
03588 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03589 goto oom;
03590
03591 _dbus_string_init_const (&local_share, "/.local/share");
03592 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03593 goto oom;
03594 }
03595
03596 if (!_dbus_split_paths_and_append (&servicedir_path,
03597 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03598 dirs))
03599 goto oom;
03600
03601 _dbus_string_free (&servicedir_path);
03602 return TRUE;
03603
03604 oom:
03605 _dbus_string_free (&servicedir_path);
03606 return FALSE;
03607 }
03608
03609
03628 dbus_bool_t
03629 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03630 {
03631 const char *xdg_data_dirs;
03632 DBusString servicedir_path;
03633
03634 if (!_dbus_string_init (&servicedir_path))
03635 return FALSE;
03636
03637 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03638
03639 if (xdg_data_dirs != NULL)
03640 {
03641 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03642 goto oom;
03643
03644 if (!_dbus_string_append (&servicedir_path, ":"))
03645 goto oom;
03646 }
03647 else
03648 {
03649 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03650 goto oom;
03651 }
03652
03653
03654
03655
03656
03657
03658
03659 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03660 goto oom;
03661
03662 if (!_dbus_split_paths_and_append (&servicedir_path,
03663 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03664 dirs))
03665 goto oom;
03666
03667 _dbus_string_free (&servicedir_path);
03668 return TRUE;
03669
03670 oom:
03671 _dbus_string_free (&servicedir_path);
03672 return FALSE;
03673 }
03674
03683 dbus_bool_t
03684 _dbus_append_system_config_file (DBusString *str)
03685 {
03686 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03687 }
03688
03695 dbus_bool_t
03696 _dbus_append_session_config_file (DBusString *str)
03697 {
03698 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03699 }
03700
03708 void
03709 _dbus_flush_caches (void)
03710 {
03711 _dbus_user_database_flush_system ();
03712 }
03713
03727 dbus_bool_t
03728 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03729 DBusCredentials *credentials)
03730 {
03731 DBusString homedir;
03732 DBusString dotdir;
03733 dbus_uid_t uid;
03734
03735 _dbus_assert (credentials != NULL);
03736 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03737
03738 if (!_dbus_string_init (&homedir))
03739 return FALSE;
03740
03741 uid = _dbus_credentials_get_unix_uid (credentials);
03742 _dbus_assert (uid != DBUS_UID_UNSET);
03743
03744 if (!_dbus_homedir_from_uid (uid, &homedir))
03745 goto failed;
03746
03747 #ifdef DBUS_BUILD_TESTS
03748 {
03749 const char *override;
03750
03751 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03752 if (override != NULL && *override != '\0')
03753 {
03754 _dbus_string_set_length (&homedir, 0);
03755 if (!_dbus_string_append (&homedir, override))
03756 goto failed;
03757
03758 _dbus_verbose ("Using fake homedir for testing: %s\n",
03759 _dbus_string_get_const_data (&homedir));
03760 }
03761 else
03762 {
03763 static dbus_bool_t already_warned = FALSE;
03764 if (!already_warned)
03765 {
03766 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03767 already_warned = TRUE;
03768 }
03769 }
03770 }
03771 #endif
03772
03773 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03774 if (!_dbus_concat_dir_and_file (&homedir,
03775 &dotdir))
03776 goto failed;
03777
03778 if (!_dbus_string_copy (&homedir, 0,
03779 directory, _dbus_string_get_length (directory))) {
03780 goto failed;
03781 }
03782
03783 _dbus_string_free (&homedir);
03784 return TRUE;
03785
03786 failed:
03787 _dbus_string_free (&homedir);
03788 return FALSE;
03789 }
03790
03791
03792 dbus_bool_t
03793 _dbus_daemon_publish_session_bus_address (const char* addr,
03794 const char *scope)
03795 {
03796 return TRUE;
03797 }
03798
03799
03800 void
03801 _dbus_daemon_unpublish_session_bus_address (void)
03802 {
03803
03804 }
03805
03812 dbus_bool_t
03813 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03814 {
03815 return errno == EAGAIN || errno == EWOULDBLOCK;
03816 }
03817
03825 dbus_bool_t
03826 _dbus_delete_directory (const DBusString *filename,
03827 DBusError *error)
03828 {
03829 const char *filename_c;
03830
03831 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03832
03833 filename_c = _dbus_string_get_const_data (filename);
03834
03835 if (rmdir (filename_c) != 0)
03836 {
03837 dbus_set_error (error, DBUS_ERROR_FAILED,
03838 "Failed to remove directory %s: %s\n",
03839 filename_c, _dbus_strerror (errno));
03840 return FALSE;
03841 }
03842
03843 return TRUE;
03844 }
03845
03853 dbus_bool_t
03854 _dbus_socket_can_pass_unix_fd(int fd) {
03855
03856 #ifdef SCM_RIGHTS
03857 union {
03858 struct sockaddr sa;
03859 struct sockaddr_storage storage;
03860 struct sockaddr_un un;
03861 } sa_buf;
03862
03863 socklen_t sa_len = sizeof(sa_buf);
03864
03865 _DBUS_ZERO(sa_buf);
03866
03867 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03868 return FALSE;
03869
03870 return sa_buf.sa.sa_family == AF_UNIX;
03871
03872 #else
03873 return FALSE;
03874
03875 #endif
03876 }
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886 const char *
03887 _dbus_replace_install_prefix (const char *configure_time_path)
03888 {
03889 return configure_time_path;
03890 }
03891
03892