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 #if defined (__sun) || defined (__sun__)
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 # ifndef CMSG_ALIGN
00105 # ifdef __sun__
00106 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00107 # else
00108
00109 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00110 ~(sizeof (long) - 1))
00111 # endif
00112 # endif
00113
00114 # ifndef CMSG_SPACE
00115 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00116 CMSG_ALIGN (len))
00117 # endif
00118
00119 # ifndef CMSG_LEN
00120 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00121 # endif
00122
00123 #endif
00124
00125 static dbus_bool_t
00126 _dbus_open_socket (int *fd_p,
00127 int domain,
00128 int type,
00129 int protocol,
00130 DBusError *error)
00131 {
00132 #ifdef SOCK_CLOEXEC
00133 dbus_bool_t cloexec_done;
00134
00135 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00136 cloexec_done = *fd_p >= 0;
00137
00138
00139 if (*fd_p < 0 && errno == EINVAL)
00140 #endif
00141 {
00142 *fd_p = socket (domain, type, protocol);
00143 }
00144
00145 if (*fd_p >= 0)
00146 {
00147 #ifdef SOCK_CLOEXEC
00148 if (!cloexec_done)
00149 #endif
00150 {
00151 _dbus_fd_set_close_on_exec(*fd_p);
00152 }
00153
00154 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00155 return TRUE;
00156 }
00157 else
00158 {
00159 dbus_set_error(error,
00160 _dbus_error_from_errno (errno),
00161 "Failed to open socket: %s",
00162 _dbus_strerror (errno));
00163 return FALSE;
00164 }
00165 }
00166
00167 dbus_bool_t
00168 _dbus_open_tcp_socket (int *fd,
00169 DBusError *error)
00170 {
00171 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00172 }
00173
00184 dbus_bool_t
00185 _dbus_open_unix_socket (int *fd,
00186 DBusError *error)
00187 {
00188 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00189 }
00190
00199 dbus_bool_t
00200 _dbus_close_socket (int fd,
00201 DBusError *error)
00202 {
00203 return _dbus_close (fd, error);
00204 }
00205
00215 int
00216 _dbus_read_socket (int fd,
00217 DBusString *buffer,
00218 int count)
00219 {
00220 return _dbus_read (fd, buffer, count);
00221 }
00222
00233 int
00234 _dbus_write_socket (int fd,
00235 const DBusString *buffer,
00236 int start,
00237 int len)
00238 {
00239 #if HAVE_DECL_MSG_NOSIGNAL
00240 const char *data;
00241 int bytes_written;
00242
00243 data = _dbus_string_get_const_data_len (buffer, start, len);
00244
00245 again:
00246
00247 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00248
00249 if (bytes_written < 0 && errno == EINTR)
00250 goto again;
00251
00252 return bytes_written;
00253
00254 #else
00255 return _dbus_write (fd, buffer, start, len);
00256 #endif
00257 }
00258
00271 int
00272 _dbus_read_socket_with_unix_fds (int fd,
00273 DBusString *buffer,
00274 int count,
00275 int *fds,
00276 int *n_fds) {
00277 #ifndef HAVE_UNIX_FD_PASSING
00278 int r;
00279
00280 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00281 return r;
00282
00283 *n_fds = 0;
00284 return r;
00285
00286 #else
00287 int bytes_read;
00288 int start;
00289 struct msghdr m;
00290 struct iovec iov;
00291
00292 _dbus_assert (count >= 0);
00293 _dbus_assert (*n_fds >= 0);
00294
00295 start = _dbus_string_get_length (buffer);
00296
00297 if (!_dbus_string_lengthen (buffer, count))
00298 {
00299 errno = ENOMEM;
00300 return -1;
00301 }
00302
00303 _DBUS_ZERO(iov);
00304 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00305 iov.iov_len = count;
00306
00307 _DBUS_ZERO(m);
00308 m.msg_iov = &iov;
00309 m.msg_iovlen = 1;
00310
00311
00312
00313
00314
00315 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00316
00317
00318
00319 m.msg_control = alloca(m.msg_controllen);
00320 memset(m.msg_control, 0, m.msg_controllen);
00321
00322 again:
00323
00324 bytes_read = recvmsg(fd, &m, 0
00325 #ifdef MSG_CMSG_CLOEXEC
00326 |MSG_CMSG_CLOEXEC
00327 #endif
00328 );
00329
00330 if (bytes_read < 0)
00331 {
00332 if (errno == EINTR)
00333 goto again;
00334 else
00335 {
00336
00337 _dbus_string_set_length (buffer, start);
00338 return -1;
00339 }
00340 }
00341 else
00342 {
00343 struct cmsghdr *cm;
00344 dbus_bool_t found = FALSE;
00345
00346 if (m.msg_flags & MSG_CTRUNC)
00347 {
00348
00349
00350
00351
00352
00353 errno = ENOSPC;
00354 _dbus_string_set_length (buffer, start);
00355 return -1;
00356 }
00357
00358 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00359 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00360 {
00361 unsigned i;
00362
00363 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
00364 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
00365
00366 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
00367 found = TRUE;
00368
00369
00370
00371
00372 for (i = 0; i < *n_fds; i++)
00373 _dbus_fd_set_close_on_exec(fds[i]);
00374
00375 break;
00376 }
00377
00378 if (!found)
00379 *n_fds = 0;
00380
00381
00382 _dbus_string_set_length (buffer, start + bytes_read);
00383
00384 #if 0
00385 if (bytes_read > 0)
00386 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00387 #endif
00388
00389 return bytes_read;
00390 }
00391 #endif
00392 }
00393
00394 int
00395 _dbus_write_socket_with_unix_fds(int fd,
00396 const DBusString *buffer,
00397 int start,
00398 int len,
00399 const int *fds,
00400 int n_fds) {
00401
00402 #ifndef HAVE_UNIX_FD_PASSING
00403
00404 if (n_fds > 0) {
00405 errno = ENOTSUP;
00406 return -1;
00407 }
00408
00409 return _dbus_write_socket(fd, buffer, start, len);
00410 #else
00411 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00412 #endif
00413 }
00414
00415 int
00416 _dbus_write_socket_with_unix_fds_two(int fd,
00417 const DBusString *buffer1,
00418 int start1,
00419 int len1,
00420 const DBusString *buffer2,
00421 int start2,
00422 int len2,
00423 const int *fds,
00424 int n_fds) {
00425
00426 #ifndef HAVE_UNIX_FD_PASSING
00427
00428 if (n_fds > 0) {
00429 errno = ENOTSUP;
00430 return -1;
00431 }
00432
00433 return _dbus_write_socket_two(fd,
00434 buffer1, start1, len1,
00435 buffer2, start2, len2);
00436 #else
00437
00438 struct msghdr m;
00439 struct cmsghdr *cm;
00440 struct iovec iov[2];
00441 int bytes_written;
00442
00443 _dbus_assert (len1 >= 0);
00444 _dbus_assert (len2 >= 0);
00445 _dbus_assert (n_fds >= 0);
00446
00447 _DBUS_ZERO(iov);
00448 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00449 iov[0].iov_len = len1;
00450
00451 if (buffer2)
00452 {
00453 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00454 iov[1].iov_len = len2;
00455 }
00456
00457 _DBUS_ZERO(m);
00458 m.msg_iov = iov;
00459 m.msg_iovlen = buffer2 ? 2 : 1;
00460
00461 if (n_fds > 0)
00462 {
00463 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00464 m.msg_control = alloca(m.msg_controllen);
00465 memset(m.msg_control, 0, m.msg_controllen);
00466
00467 cm = CMSG_FIRSTHDR(&m);
00468 cm->cmsg_level = SOL_SOCKET;
00469 cm->cmsg_type = SCM_RIGHTS;
00470 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00471 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00472 }
00473
00474 again:
00475
00476 bytes_written = sendmsg (fd, &m, 0
00477 #if HAVE_DECL_MSG_NOSIGNAL
00478 |MSG_NOSIGNAL
00479 #endif
00480 );
00481
00482 if (bytes_written < 0 && errno == EINTR)
00483 goto again;
00484
00485 #if 0
00486 if (bytes_written > 0)
00487 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00488 #endif
00489
00490 return bytes_written;
00491 #endif
00492 }
00493
00507 int
00508 _dbus_write_socket_two (int fd,
00509 const DBusString *buffer1,
00510 int start1,
00511 int len1,
00512 const DBusString *buffer2,
00513 int start2,
00514 int len2)
00515 {
00516 #if HAVE_DECL_MSG_NOSIGNAL
00517 struct iovec vectors[2];
00518 const char *data1;
00519 const char *data2;
00520 int bytes_written;
00521 struct msghdr m;
00522
00523 _dbus_assert (buffer1 != NULL);
00524 _dbus_assert (start1 >= 0);
00525 _dbus_assert (start2 >= 0);
00526 _dbus_assert (len1 >= 0);
00527 _dbus_assert (len2 >= 0);
00528
00529 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00530
00531 if (buffer2 != NULL)
00532 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00533 else
00534 {
00535 data2 = NULL;
00536 start2 = 0;
00537 len2 = 0;
00538 }
00539
00540 vectors[0].iov_base = (char*) data1;
00541 vectors[0].iov_len = len1;
00542 vectors[1].iov_base = (char*) data2;
00543 vectors[1].iov_len = len2;
00544
00545 _DBUS_ZERO(m);
00546 m.msg_iov = vectors;
00547 m.msg_iovlen = data2 ? 2 : 1;
00548
00549 again:
00550
00551 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00552
00553 if (bytes_written < 0 && errno == EINTR)
00554 goto again;
00555
00556 return bytes_written;
00557
00558 #else
00559 return _dbus_write_two (fd, buffer1, start1, len1,
00560 buffer2, start2, len2);
00561 #endif
00562 }
00563
00564 dbus_bool_t
00565 _dbus_socket_is_invalid (int fd)
00566 {
00567 return fd < 0 ? TRUE : FALSE;
00568 }
00569
00586 int
00587 _dbus_read (int fd,
00588 DBusString *buffer,
00589 int count)
00590 {
00591 int bytes_read;
00592 int start;
00593 char *data;
00594
00595 _dbus_assert (count >= 0);
00596
00597 start = _dbus_string_get_length (buffer);
00598
00599 if (!_dbus_string_lengthen (buffer, count))
00600 {
00601 errno = ENOMEM;
00602 return -1;
00603 }
00604
00605 data = _dbus_string_get_data_len (buffer, start, count);
00606
00607 again:
00608
00609 bytes_read = read (fd, data, count);
00610
00611 if (bytes_read < 0)
00612 {
00613 if (errno == EINTR)
00614 goto again;
00615 else
00616 {
00617
00618 _dbus_string_set_length (buffer, start);
00619 return -1;
00620 }
00621 }
00622 else
00623 {
00624
00625 _dbus_string_set_length (buffer, start + bytes_read);
00626
00627 #if 0
00628 if (bytes_read > 0)
00629 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00630 #endif
00631
00632 return bytes_read;
00633 }
00634 }
00635
00646 int
00647 _dbus_write (int fd,
00648 const DBusString *buffer,
00649 int start,
00650 int len)
00651 {
00652 const char *data;
00653 int bytes_written;
00654
00655 data = _dbus_string_get_const_data_len (buffer, start, len);
00656
00657 again:
00658
00659 bytes_written = write (fd, data, len);
00660
00661 if (bytes_written < 0 && errno == EINTR)
00662 goto again;
00663
00664 #if 0
00665 if (bytes_written > 0)
00666 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00667 #endif
00668
00669 return bytes_written;
00670 }
00671
00692 int
00693 _dbus_write_two (int fd,
00694 const DBusString *buffer1,
00695 int start1,
00696 int len1,
00697 const DBusString *buffer2,
00698 int start2,
00699 int len2)
00700 {
00701 _dbus_assert (buffer1 != NULL);
00702 _dbus_assert (start1 >= 0);
00703 _dbus_assert (start2 >= 0);
00704 _dbus_assert (len1 >= 0);
00705 _dbus_assert (len2 >= 0);
00706
00707 #ifdef HAVE_WRITEV
00708 {
00709 struct iovec vectors[2];
00710 const char *data1;
00711 const char *data2;
00712 int bytes_written;
00713
00714 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00715
00716 if (buffer2 != NULL)
00717 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00718 else
00719 {
00720 data2 = NULL;
00721 start2 = 0;
00722 len2 = 0;
00723 }
00724
00725 vectors[0].iov_base = (char*) data1;
00726 vectors[0].iov_len = len1;
00727 vectors[1].iov_base = (char*) data2;
00728 vectors[1].iov_len = len2;
00729
00730 again:
00731
00732 bytes_written = writev (fd,
00733 vectors,
00734 data2 ? 2 : 1);
00735
00736 if (bytes_written < 0 && errno == EINTR)
00737 goto again;
00738
00739 return bytes_written;
00740 }
00741 #else
00742 {
00743 int ret1;
00744
00745 ret1 = _dbus_write (fd, buffer1, start1, len1);
00746 if (ret1 == len1 && buffer2 != NULL)
00747 {
00748 ret2 = _dbus_write (fd, buffer2, start2, len2);
00749 if (ret2 < 0)
00750 ret2 = 0;
00751
00752 return ret1 + ret2;
00753 }
00754 else
00755 return ret1;
00756 }
00757 #endif
00758 }
00759
00760 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00761
00791 int
00792 _dbus_connect_unix_socket (const char *path,
00793 dbus_bool_t abstract,
00794 DBusError *error)
00795 {
00796 int fd;
00797 size_t path_len;
00798 struct sockaddr_un addr;
00799
00800 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00801
00802 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00803 path, abstract);
00804
00805
00806 if (!_dbus_open_unix_socket (&fd, error))
00807 {
00808 _DBUS_ASSERT_ERROR_IS_SET(error);
00809 return -1;
00810 }
00811 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00812
00813 _DBUS_ZERO (addr);
00814 addr.sun_family = AF_UNIX;
00815 path_len = strlen (path);
00816
00817 if (abstract)
00818 {
00819 #ifdef HAVE_ABSTRACT_SOCKETS
00820 addr.sun_path[0] = '\0';
00821 path_len++;
00822
00823 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00824 {
00825 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00826 "Abstract socket name too long\n");
00827 _dbus_close (fd, NULL);
00828 return -1;
00829 }
00830
00831 strncpy (&addr.sun_path[1], path, path_len);
00832
00833 #else
00834 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00835 "Operating system does not support abstract socket namespace\n");
00836 _dbus_close (fd, NULL);
00837 return -1;
00838 #endif
00839 }
00840 else
00841 {
00842 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00843 {
00844 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00845 "Socket name too long\n");
00846 _dbus_close (fd, NULL);
00847 return -1;
00848 }
00849
00850 strncpy (addr.sun_path, path, path_len);
00851 }
00852
00853 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00854 {
00855 dbus_set_error (error,
00856 _dbus_error_from_errno (errno),
00857 "Failed to connect to socket %s: %s",
00858 path, _dbus_strerror (errno));
00859
00860 _dbus_close (fd, NULL);
00861 return -1;
00862 }
00863
00864 if (!_dbus_set_fd_nonblocking (fd, error))
00865 {
00866 _DBUS_ASSERT_ERROR_IS_SET (error);
00867
00868 _dbus_close (fd, NULL);
00869 return -1;
00870 }
00871
00872 return fd;
00873 }
00874
00884 static dbus_bool_t
00885 _dbus_set_local_creds (int fd, dbus_bool_t on)
00886 {
00887 dbus_bool_t retval = TRUE;
00888
00889 #if defined(HAVE_CMSGCRED)
00890
00891
00892
00893 #elif defined(LOCAL_CREDS)
00894 int val = on ? 1 : 0;
00895 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00896 {
00897 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00898 retval = FALSE;
00899 }
00900 else
00901 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00902 on ? "enabled" : "disabled", fd);
00903 #endif
00904
00905 return retval;
00906 }
00907
00925 int
00926 _dbus_listen_unix_socket (const char *path,
00927 dbus_bool_t abstract,
00928 DBusError *error)
00929 {
00930 int listen_fd;
00931 struct sockaddr_un addr;
00932 size_t path_len;
00933 unsigned int reuseaddr;
00934
00935 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00936
00937 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00938 path, abstract);
00939
00940 if (!_dbus_open_unix_socket (&listen_fd, error))
00941 {
00942 _DBUS_ASSERT_ERROR_IS_SET(error);
00943 return -1;
00944 }
00945 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00946
00947 _DBUS_ZERO (addr);
00948 addr.sun_family = AF_UNIX;
00949 path_len = strlen (path);
00950
00951 if (abstract)
00952 {
00953 #ifdef HAVE_ABSTRACT_SOCKETS
00954
00955
00956
00957 addr.sun_path[0] = '\0';
00958 path_len++;
00959
00960 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00961 {
00962 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00963 "Abstract socket name too long\n");
00964 _dbus_close (listen_fd, NULL);
00965 return -1;
00966 }
00967
00968 strncpy (&addr.sun_path[1], path, path_len);
00969
00970 #else
00971 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00972 "Operating system does not support abstract socket namespace\n");
00973 _dbus_close (listen_fd, NULL);
00974 return -1;
00975 #endif
00976 }
00977 else
00978 {
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 {
00990 struct stat sb;
00991
00992 if (stat (path, &sb) == 0 &&
00993 S_ISSOCK (sb.st_mode))
00994 unlink (path);
00995 }
00996
00997 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00998 {
00999 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01000 "Abstract socket name too long\n");
01001 _dbus_close (listen_fd, NULL);
01002 return -1;
01003 }
01004
01005 strncpy (addr.sun_path, path, path_len);
01006 }
01007
01008 reuseaddr = 1;
01009 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01010 {
01011 _dbus_warn ("Failed to set socket option\"%s\": %s",
01012 path, _dbus_strerror (errno));
01013 }
01014
01015 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01016 {
01017 dbus_set_error (error, _dbus_error_from_errno (errno),
01018 "Failed to bind socket \"%s\": %s",
01019 path, _dbus_strerror (errno));
01020 _dbus_close (listen_fd, NULL);
01021 return -1;
01022 }
01023
01024 if (listen (listen_fd, 30 ) < 0)
01025 {
01026 dbus_set_error (error, _dbus_error_from_errno (errno),
01027 "Failed to listen on socket \"%s\": %s",
01028 path, _dbus_strerror (errno));
01029 _dbus_close (listen_fd, NULL);
01030 return -1;
01031 }
01032
01033 if (!_dbus_set_local_creds (listen_fd, TRUE))
01034 {
01035 dbus_set_error (error, _dbus_error_from_errno (errno),
01036 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01037 path, _dbus_strerror (errno));
01038 close (listen_fd);
01039 return -1;
01040 }
01041
01042 if (!_dbus_set_fd_nonblocking (listen_fd, error))
01043 {
01044 _DBUS_ASSERT_ERROR_IS_SET (error);
01045 _dbus_close (listen_fd, NULL);
01046 return -1;
01047 }
01048
01049
01050
01051
01052 if (!abstract && chmod (path, 0777) < 0)
01053 _dbus_warn ("Could not set mode 0777 on socket %s\n",
01054 path);
01055
01056 return listen_fd;
01057 }
01058
01069 int
01070 _dbus_listen_systemd_sockets (int **fds,
01071 DBusError *error)
01072 {
01073 int r, n;
01074 unsigned fd;
01075 int *new_fds;
01076
01077 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01078
01079 n = sd_listen_fds (TRUE);
01080 if (n < 0)
01081 {
01082 dbus_set_error (error, _dbus_error_from_errno (-n),
01083 "Failed to acquire systemd socket: %s",
01084 _dbus_strerror (-n));
01085 return -1;
01086 }
01087
01088 if (n <= 0)
01089 {
01090 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01091 "No socket received.");
01092 return -1;
01093 }
01094
01095 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01096 {
01097 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01098 if (r < 0)
01099 {
01100 dbus_set_error (error, _dbus_error_from_errno (-r),
01101 "Failed to verify systemd socket type: %s",
01102 _dbus_strerror (-r));
01103 return -1;
01104 }
01105
01106 if (!r)
01107 {
01108 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01109 "Passed socket has wrong type.");
01110 return -1;
01111 }
01112 }
01113
01114
01115
01116
01117 new_fds = dbus_new (int, n);
01118 if (!new_fds)
01119 {
01120 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01121 "Failed to allocate file handle array.");
01122 goto fail;
01123 }
01124
01125 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01126 {
01127 if (!_dbus_set_local_creds (fd, TRUE))
01128 {
01129 dbus_set_error (error, _dbus_error_from_errno (errno),
01130 "Failed to enable LOCAL_CREDS on systemd socket: %s",
01131 _dbus_strerror (errno));
01132 goto fail;
01133 }
01134
01135 if (!_dbus_set_fd_nonblocking (fd, error))
01136 {
01137 _DBUS_ASSERT_ERROR_IS_SET (error);
01138 goto fail;
01139 }
01140
01141 new_fds[fd - SD_LISTEN_FDS_START] = fd;
01142 }
01143
01144 *fds = new_fds;
01145 return n;
01146
01147 fail:
01148
01149 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01150 {
01151 _dbus_close (fd, NULL);
01152 }
01153
01154 dbus_free (new_fds);
01155 return -1;
01156 }
01157
01171 int
01172 _dbus_connect_tcp_socket (const char *host,
01173 const char *port,
01174 const char *family,
01175 DBusError *error)
01176 {
01177 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01178 }
01179
01180 int
01181 _dbus_connect_tcp_socket_with_nonce (const char *host,
01182 const char *port,
01183 const char *family,
01184 const char *noncefile,
01185 DBusError *error)
01186 {
01187 int saved_errno = 0;
01188 int fd = -1, res;
01189 struct addrinfo hints;
01190 struct addrinfo *ai, *tmp;
01191
01192 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01193
01194 _DBUS_ZERO (hints);
01195
01196 if (!family)
01197 hints.ai_family = AF_UNSPEC;
01198 else if (!strcmp(family, "ipv4"))
01199 hints.ai_family = AF_INET;
01200 else if (!strcmp(family, "ipv6"))
01201 hints.ai_family = AF_INET6;
01202 else
01203 {
01204 dbus_set_error (error,
01205 DBUS_ERROR_BAD_ADDRESS,
01206 "Unknown address family %s", family);
01207 return -1;
01208 }
01209 hints.ai_protocol = IPPROTO_TCP;
01210 hints.ai_socktype = SOCK_STREAM;
01211 hints.ai_flags = AI_ADDRCONFIG;
01212
01213 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01214 {
01215 dbus_set_error (error,
01216 _dbus_error_from_errno (errno),
01217 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01218 host, port, gai_strerror(res), res);
01219 _dbus_close (fd, NULL);
01220 return -1;
01221 }
01222
01223 tmp = ai;
01224 while (tmp)
01225 {
01226 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01227 {
01228 freeaddrinfo(ai);
01229 _DBUS_ASSERT_ERROR_IS_SET(error);
01230 return -1;
01231 }
01232 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01233
01234 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01235 {
01236 saved_errno = errno;
01237 _dbus_close(fd, NULL);
01238 fd = -1;
01239 tmp = tmp->ai_next;
01240 continue;
01241 }
01242
01243 break;
01244 }
01245 freeaddrinfo(ai);
01246
01247 if (fd == -1)
01248 {
01249 dbus_set_error (error,
01250 _dbus_error_from_errno (saved_errno),
01251 "Failed to connect to socket \"%s:%s\" %s",
01252 host, port, _dbus_strerror(saved_errno));
01253 return -1;
01254 }
01255
01256 if (noncefile != NULL)
01257 {
01258 DBusString noncefileStr;
01259 dbus_bool_t ret;
01260 _dbus_string_init_const (&noncefileStr, noncefile);
01261 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01262 _dbus_string_free (&noncefileStr);
01263
01264 if (!ret)
01265 {
01266 _dbus_close (fd, NULL);
01267 return -1;
01268 }
01269 }
01270
01271 if (!_dbus_set_fd_nonblocking (fd, error))
01272 {
01273 _dbus_close (fd, NULL);
01274 return -1;
01275 }
01276
01277 return fd;
01278 }
01279
01296 int
01297 _dbus_listen_tcp_socket (const char *host,
01298 const char *port,
01299 const char *family,
01300 DBusString *retport,
01301 int **fds_p,
01302 DBusError *error)
01303 {
01304 int saved_errno;
01305 int nlisten_fd = 0, *listen_fd = NULL, res, i;
01306 struct addrinfo hints;
01307 struct addrinfo *ai, *tmp;
01308 unsigned int reuseaddr;
01309
01310 *fds_p = NULL;
01311 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01312
01313 _DBUS_ZERO (hints);
01314
01315 if (!family)
01316 hints.ai_family = AF_UNSPEC;
01317 else if (!strcmp(family, "ipv4"))
01318 hints.ai_family = AF_INET;
01319 else if (!strcmp(family, "ipv6"))
01320 hints.ai_family = AF_INET6;
01321 else
01322 {
01323 dbus_set_error (error,
01324 DBUS_ERROR_BAD_ADDRESS,
01325 "Unknown address family %s", family);
01326 return -1;
01327 }
01328
01329 hints.ai_protocol = IPPROTO_TCP;
01330 hints.ai_socktype = SOCK_STREAM;
01331 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01332
01333 redo_lookup_with_port:
01334 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01335 {
01336 dbus_set_error (error,
01337 _dbus_error_from_errno (errno),
01338 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01339 host ? host : "*", port, gai_strerror(res), res);
01340 return -1;
01341 }
01342
01343 tmp = ai;
01344 while (tmp)
01345 {
01346 int fd = -1, *newlisten_fd;
01347 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01348 {
01349 _DBUS_ASSERT_ERROR_IS_SET(error);
01350 goto failed;
01351 }
01352 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01353
01354 reuseaddr = 1;
01355 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01356 {
01357 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01358 host ? host : "*", port, _dbus_strerror (errno));
01359 }
01360
01361 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01362 {
01363 saved_errno = errno;
01364 _dbus_close(fd, NULL);
01365 if (saved_errno == EADDRINUSE)
01366 {
01367
01368
01369
01370 tmp = tmp->ai_next;
01371 continue;
01372 }
01373 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01374 "Failed to bind socket \"%s:%s\": %s",
01375 host ? host : "*", port, _dbus_strerror (saved_errno));
01376 goto failed;
01377 }
01378
01379 if (listen (fd, 30 ) < 0)
01380 {
01381 saved_errno = errno;
01382 _dbus_close (fd, NULL);
01383 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01384 "Failed to listen on socket \"%s:%s\": %s",
01385 host ? host : "*", port, _dbus_strerror (saved_errno));
01386 goto failed;
01387 }
01388
01389 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01390 if (!newlisten_fd)
01391 {
01392 saved_errno = errno;
01393 _dbus_close (fd, NULL);
01394 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01395 "Failed to allocate file handle array: %s",
01396 _dbus_strerror (saved_errno));
01397 goto failed;
01398 }
01399 listen_fd = newlisten_fd;
01400 listen_fd[nlisten_fd] = fd;
01401 nlisten_fd++;
01402
01403 if (!_dbus_string_get_length(retport))
01404 {
01405
01406
01407
01408
01409 if (!port || !strcmp(port, "0"))
01410 {
01411 int result;
01412 struct sockaddr_storage addr;
01413 socklen_t addrlen;
01414 char portbuf[50];
01415
01416 addrlen = sizeof(addr);
01417 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01418
01419 if (result == -1 ||
01420 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01421 portbuf, sizeof(portbuf),
01422 NI_NUMERICHOST)) != 0)
01423 {
01424 dbus_set_error (error, _dbus_error_from_errno (errno),
01425 "Failed to resolve port \"%s:%s\": %s (%s)",
01426 host ? host : "*", port, gai_strerror(res), res);
01427 goto failed;
01428 }
01429 if (!_dbus_string_append(retport, portbuf))
01430 {
01431 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01432 goto failed;
01433 }
01434
01435
01436 port = _dbus_string_get_const_data(retport);
01437 freeaddrinfo(ai);
01438 goto redo_lookup_with_port;
01439 }
01440 else
01441 {
01442 if (!_dbus_string_append(retport, port))
01443 {
01444 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01445 goto failed;
01446 }
01447 }
01448 }
01449
01450 tmp = tmp->ai_next;
01451 }
01452 freeaddrinfo(ai);
01453 ai = NULL;
01454
01455 if (!nlisten_fd)
01456 {
01457 errno = EADDRINUSE;
01458 dbus_set_error (error, _dbus_error_from_errno (errno),
01459 "Failed to bind socket \"%s:%s\": %s",
01460 host ? host : "*", port, _dbus_strerror (errno));
01461 goto failed;
01462 }
01463
01464 for (i = 0 ; i < nlisten_fd ; i++)
01465 {
01466 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01467 {
01468 goto failed;
01469 }
01470 }
01471
01472 *fds_p = listen_fd;
01473
01474 return nlisten_fd;
01475
01476 failed:
01477 if (ai)
01478 freeaddrinfo(ai);
01479 for (i = 0 ; i < nlisten_fd ; i++)
01480 _dbus_close(listen_fd[i], NULL);
01481 dbus_free(listen_fd);
01482 return -1;
01483 }
01484
01485 static dbus_bool_t
01486 write_credentials_byte (int server_fd,
01487 DBusError *error)
01488 {
01489 int bytes_written;
01490 char buf[1] = { '\0' };
01491 #if defined(HAVE_CMSGCRED)
01492 union {
01493 struct cmsghdr hdr;
01494 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01495 } cmsg;
01496 struct iovec iov;
01497 struct msghdr msg;
01498 iov.iov_base = buf;
01499 iov.iov_len = 1;
01500
01501 _DBUS_ZERO(msg);
01502 msg.msg_iov = &iov;
01503 msg.msg_iovlen = 1;
01504
01505 msg.msg_control = (caddr_t) &cmsg;
01506 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01507 _DBUS_ZERO(cmsg);
01508 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01509 cmsg.hdr.cmsg_level = SOL_SOCKET;
01510 cmsg.hdr.cmsg_type = SCM_CREDS;
01511 #endif
01512
01513 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01514
01515 again:
01516
01517 #if defined(HAVE_CMSGCRED)
01518 bytes_written = sendmsg (server_fd, &msg, 0
01519 #if HAVE_DECL_MSG_NOSIGNAL
01520 |MSG_NOSIGNAL
01521 #endif
01522 );
01523 #else
01524 bytes_written = send (server_fd, buf, 1, 0
01525 #if HAVE_DECL_MSG_NOSIGNAL
01526 |MSG_NOSIGNAL
01527 #endif
01528 );
01529 #endif
01530
01531 if (bytes_written < 0 && errno == EINTR)
01532 goto again;
01533
01534 if (bytes_written < 0)
01535 {
01536 dbus_set_error (error, _dbus_error_from_errno (errno),
01537 "Failed to write credentials byte: %s",
01538 _dbus_strerror (errno));
01539 return FALSE;
01540 }
01541 else if (bytes_written == 0)
01542 {
01543 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01544 "wrote zero bytes writing credentials byte");
01545 return FALSE;
01546 }
01547 else
01548 {
01549 _dbus_assert (bytes_written == 1);
01550 _dbus_verbose ("wrote credentials byte\n");
01551 return TRUE;
01552 }
01553 }
01554
01576 dbus_bool_t
01577 _dbus_read_credentials_socket (int client_fd,
01578 DBusCredentials *credentials,
01579 DBusError *error)
01580 {
01581 struct msghdr msg;
01582 struct iovec iov;
01583 char buf;
01584 dbus_uid_t uid_read;
01585 dbus_pid_t pid_read;
01586 int bytes_read;
01587
01588 #ifdef HAVE_CMSGCRED
01589 union {
01590 struct cmsghdr hdr;
01591 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01592 } cmsg;
01593
01594 #elif defined(LOCAL_CREDS)
01595 struct {
01596 struct cmsghdr hdr;
01597 struct sockcred cred;
01598 } cmsg;
01599 #endif
01600
01601 uid_read = DBUS_UID_UNSET;
01602 pid_read = DBUS_PID_UNSET;
01603
01604 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01605
01606
01607
01608
01609
01610 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01611 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01612 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01613
01614 _dbus_credentials_clear (credentials);
01615
01616
01617
01618
01619
01620
01621
01622 iov.iov_base = &buf;
01623 iov.iov_len = 1;
01624
01625 _DBUS_ZERO(msg);
01626 msg.msg_iov = &iov;
01627 msg.msg_iovlen = 1;
01628
01629 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01630 _DBUS_ZERO(cmsg);
01631 msg.msg_control = (caddr_t) &cmsg;
01632 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01633 #endif
01634
01635 again:
01636 bytes_read = recvmsg (client_fd, &msg, 0);
01637
01638 if (bytes_read < 0)
01639 {
01640 if (errno == EINTR)
01641 goto again;
01642
01643
01644
01645
01646
01647
01648 dbus_set_error (error, _dbus_error_from_errno (errno),
01649 "Failed to read credentials byte: %s",
01650 _dbus_strerror (errno));
01651 return FALSE;
01652 }
01653 else if (bytes_read == 0)
01654 {
01655
01656
01657
01658 dbus_set_error (error, DBUS_ERROR_FAILED,
01659 "Failed to read credentials byte (zero-length read)");
01660 return FALSE;
01661 }
01662 else if (buf != '\0')
01663 {
01664 dbus_set_error (error, DBUS_ERROR_FAILED,
01665 "Credentials byte was not nul");
01666 return FALSE;
01667 }
01668
01669 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01670 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01671 || cmsg.hdr.cmsg_type != SCM_CREDS)
01672 {
01673 dbus_set_error (error, DBUS_ERROR_FAILED,
01674 "Message from recvmsg() was not SCM_CREDS");
01675 return FALSE;
01676 }
01677 #endif
01678
01679 _dbus_verbose ("read credentials byte\n");
01680
01681 {
01682 #ifdef SO_PEERCRED
01683 #ifdef __OpenBSD__
01684 struct sockpeercred cr;
01685 #else
01686 struct ucred cr;
01687 #endif
01688 int cr_len = sizeof (cr);
01689
01690 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01691 cr_len == sizeof (cr))
01692 {
01693 pid_read = cr.pid;
01694 uid_read = cr.uid;
01695 }
01696 else
01697 {
01698 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01699 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01700 }
01701 #elif defined(HAVE_CMSGCRED)
01702 struct cmsgcred *cred;
01703
01704 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01705 pid_read = cred->cmcred_pid;
01706 uid_read = cred->cmcred_euid;
01707 #elif defined(LOCAL_CREDS)
01708 pid_read = DBUS_PID_UNSET;
01709 uid_read = cmsg.cred.sc_uid;
01710
01711
01712 _dbus_set_local_creds (client_fd, FALSE);
01713 #elif defined(HAVE_GETPEEREID)
01714 uid_t euid;
01715 gid_t egid;
01716 if (getpeereid (client_fd, &euid, &egid) == 0)
01717 {
01718 uid_read = euid;
01719 }
01720 else
01721 {
01722 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01723 }
01724 #elif defined(HAVE_GETPEERUCRED)
01725 ucred_t * ucred = NULL;
01726 if (getpeerucred (client_fd, &ucred) == 0)
01727 {
01728 pid_read = ucred_getpid (ucred);
01729 uid_read = ucred_geteuid (ucred);
01730 #ifdef HAVE_ADT
01731
01732 adt_session_data_t *adth = NULL;
01733 adt_export_data_t *data = NULL;
01734 size_t size = 0;
01735 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01736 {
01737 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01738 }
01739 else
01740 {
01741 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01742 {
01743 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01744 }
01745 else
01746 {
01747 size = adt_export_session_data (adth, &data);
01748 if (size <= 0)
01749 {
01750 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01751 }
01752 else
01753 {
01754 _dbus_credentials_add_adt_audit_data (credentials, data, size);
01755 free (data);
01756 }
01757 }
01758 (void) adt_end_session (adth);
01759 }
01760 #endif
01761 }
01762 else
01763 {
01764 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01765 }
01766 if (ucred != NULL)
01767 ucred_free (ucred);
01768 #else
01769 _dbus_verbose ("Socket credentials not supported on this OS\n");
01770 #endif
01771 }
01772
01773 _dbus_verbose ("Credentials:"
01774 " pid "DBUS_PID_FORMAT
01775 " uid "DBUS_UID_FORMAT
01776 "\n",
01777 pid_read,
01778 uid_read);
01779
01780 if (pid_read != DBUS_PID_UNSET)
01781 {
01782 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01783 {
01784 _DBUS_SET_OOM (error);
01785 return FALSE;
01786 }
01787 }
01788
01789 if (uid_read != DBUS_UID_UNSET)
01790 {
01791 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01792 {
01793 _DBUS_SET_OOM (error);
01794 return FALSE;
01795 }
01796 }
01797
01798 return TRUE;
01799 }
01800
01818 dbus_bool_t
01819 _dbus_send_credentials_socket (int server_fd,
01820 DBusError *error)
01821 {
01822 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01823
01824 if (write_credentials_byte (server_fd, error))
01825 return TRUE;
01826 else
01827 return FALSE;
01828 }
01829
01839 int
01840 _dbus_accept (int listen_fd)
01841 {
01842 int client_fd;
01843 struct sockaddr addr;
01844 socklen_t addrlen;
01845 #ifdef HAVE_ACCEPT4
01846 dbus_bool_t cloexec_done;
01847 #endif
01848
01849 addrlen = sizeof (addr);
01850
01851 retry:
01852
01853 #ifdef HAVE_ACCEPT4
01854
01855 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01856 cloexec_done = client_fd >= 0;
01857
01858 if (client_fd < 0 && errno == ENOSYS)
01859 #endif
01860 {
01861 client_fd = accept (listen_fd, &addr, &addrlen);
01862 }
01863
01864 if (client_fd < 0)
01865 {
01866 if (errno == EINTR)
01867 goto retry;
01868 }
01869
01870 _dbus_verbose ("client fd %d accepted\n", client_fd);
01871
01872 #ifdef HAVE_ACCEPT4
01873 if (!cloexec_done)
01874 #endif
01875 {
01876 _dbus_fd_set_close_on_exec(client_fd);
01877 }
01878
01879 return client_fd;
01880 }
01881
01890 dbus_bool_t
01891 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01892 {
01893 const char *directory;
01894 struct stat sb;
01895
01896 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01897
01898 directory = _dbus_string_get_const_data (dir);
01899
01900 if (stat (directory, &sb) < 0)
01901 {
01902 dbus_set_error (error, _dbus_error_from_errno (errno),
01903 "%s", _dbus_strerror (errno));
01904
01905 return FALSE;
01906 }
01907
01908 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01909 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01910 {
01911 dbus_set_error (error, DBUS_ERROR_FAILED,
01912 "%s directory is not private to the user", directory);
01913 return FALSE;
01914 }
01915
01916 return TRUE;
01917 }
01918
01919 static dbus_bool_t
01920 fill_user_info_from_passwd (struct passwd *p,
01921 DBusUserInfo *info,
01922 DBusError *error)
01923 {
01924 _dbus_assert (p->pw_name != NULL);
01925 _dbus_assert (p->pw_dir != NULL);
01926
01927 info->uid = p->pw_uid;
01928 info->primary_gid = p->pw_gid;
01929 info->username = _dbus_strdup (p->pw_name);
01930 info->homedir = _dbus_strdup (p->pw_dir);
01931
01932 if (info->username == NULL ||
01933 info->homedir == NULL)
01934 {
01935 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01936 return FALSE;
01937 }
01938
01939 return TRUE;
01940 }
01941
01942 static dbus_bool_t
01943 fill_user_info (DBusUserInfo *info,
01944 dbus_uid_t uid,
01945 const DBusString *username,
01946 DBusError *error)
01947 {
01948 const char *username_c;
01949
01950
01951 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01952 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01953
01954 info->uid = DBUS_UID_UNSET;
01955 info->primary_gid = DBUS_GID_UNSET;
01956 info->group_ids = NULL;
01957 info->n_group_ids = 0;
01958 info->username = NULL;
01959 info->homedir = NULL;
01960
01961 if (username != NULL)
01962 username_c = _dbus_string_get_const_data (username);
01963 else
01964 username_c = NULL;
01965
01966
01967
01968
01969
01970
01971 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01972 {
01973 struct passwd *p;
01974 int result;
01975 size_t buflen;
01976 char *buf;
01977 struct passwd p_str;
01978
01979
01980 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01981
01982
01983
01984
01985
01986 if ((long) buflen <= 0)
01987 buflen = 1024;
01988
01989 result = -1;
01990 while (1)
01991 {
01992 buf = dbus_malloc (buflen);
01993 if (buf == NULL)
01994 {
01995 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01996 return FALSE;
01997 }
01998
01999 p = NULL;
02000 #ifdef HAVE_POSIX_GETPWNAM_R
02001 if (uid != DBUS_UID_UNSET)
02002 result = getpwuid_r (uid, &p_str, buf, buflen,
02003 &p);
02004 else
02005 result = getpwnam_r (username_c, &p_str, buf, buflen,
02006 &p);
02007 #else
02008 if (uid != DBUS_UID_UNSET)
02009 p = getpwuid_r (uid, &p_str, buf, buflen);
02010 else
02011 p = getpwnam_r (username_c, &p_str, buf, buflen);
02012 result = 0;
02013 #endif
02014
02015 if (result == ERANGE && buflen < 512 * 1024)
02016 {
02017 dbus_free (buf);
02018 buflen *= 2;
02019 }
02020 else
02021 {
02022 break;
02023 }
02024 }
02025 if (result == 0 && p == &p_str)
02026 {
02027 if (!fill_user_info_from_passwd (p, info, error))
02028 {
02029 dbus_free (buf);
02030 return FALSE;
02031 }
02032 dbus_free (buf);
02033 }
02034 else
02035 {
02036 dbus_set_error (error, _dbus_error_from_errno (errno),
02037 "User \"%s\" unknown or no memory to allocate password entry\n",
02038 username_c ? username_c : "???");
02039 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02040 dbus_free (buf);
02041 return FALSE;
02042 }
02043 }
02044 #else
02045 {
02046
02047 struct passwd *p;
02048
02049 if (uid != DBUS_UID_UNSET)
02050 p = getpwuid (uid);
02051 else
02052 p = getpwnam (username_c);
02053
02054 if (p != NULL)
02055 {
02056 if (!fill_user_info_from_passwd (p, info, error))
02057 {
02058 return FALSE;
02059 }
02060 }
02061 else
02062 {
02063 dbus_set_error (error, _dbus_error_from_errno (errno),
02064 "User \"%s\" unknown or no memory to allocate password entry\n",
02065 username_c ? username_c : "???");
02066 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02067 return FALSE;
02068 }
02069 }
02070 #endif
02071
02072
02073 username_c = info->username;
02074
02075 #ifdef HAVE_GETGROUPLIST
02076 {
02077 gid_t *buf;
02078 int buf_count;
02079 int i;
02080 int initial_buf_count;
02081
02082 initial_buf_count = 17;
02083 buf_count = initial_buf_count;
02084 buf = dbus_new (gid_t, buf_count);
02085 if (buf == NULL)
02086 {
02087 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02088 goto failed;
02089 }
02090
02091 if (getgrouplist (username_c,
02092 info->primary_gid,
02093 buf, &buf_count) < 0)
02094 {
02095 gid_t *new;
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109 if (buf_count == initial_buf_count)
02110 {
02111 buf_count *= 16;
02112 }
02113 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02114 if (new == NULL)
02115 {
02116 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02117 dbus_free (buf);
02118 goto failed;
02119 }
02120
02121 buf = new;
02122
02123 errno = 0;
02124 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02125 {
02126 if (errno == 0)
02127 {
02128 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02129 username_c, buf_count, buf_count);
02130 }
02131 else
02132 {
02133 dbus_set_error (error,
02134 _dbus_error_from_errno (errno),
02135 "Failed to get groups for username \"%s\" primary GID "
02136 DBUS_GID_FORMAT ": %s\n",
02137 username_c, info->primary_gid,
02138 _dbus_strerror (errno));
02139 dbus_free (buf);
02140 goto failed;
02141 }
02142 }
02143 }
02144
02145 info->group_ids = dbus_new (dbus_gid_t, buf_count);
02146 if (info->group_ids == NULL)
02147 {
02148 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02149 dbus_free (buf);
02150 goto failed;
02151 }
02152
02153 for (i = 0; i < buf_count; ++i)
02154 info->group_ids[i] = buf[i];
02155
02156 info->n_group_ids = buf_count;
02157
02158 dbus_free (buf);
02159 }
02160 #else
02161 {
02162
02163 info->group_ids = dbus_new (dbus_gid_t, 1);
02164 if (info->group_ids == NULL)
02165 {
02166 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02167 goto failed;
02168 }
02169
02170 info->n_group_ids = 1;
02171
02172 (info->group_ids)[0] = info->primary_gid;
02173 }
02174 #endif
02175
02176 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02177
02178 return TRUE;
02179
02180 failed:
02181 _DBUS_ASSERT_ERROR_IS_SET (error);
02182 return FALSE;
02183 }
02184
02193 dbus_bool_t
02194 _dbus_user_info_fill (DBusUserInfo *info,
02195 const DBusString *username,
02196 DBusError *error)
02197 {
02198 return fill_user_info (info, DBUS_UID_UNSET,
02199 username, error);
02200 }
02201
02210 dbus_bool_t
02211 _dbus_user_info_fill_uid (DBusUserInfo *info,
02212 dbus_uid_t uid,
02213 DBusError *error)
02214 {
02215 return fill_user_info (info, uid,
02216 NULL, error);
02217 }
02218
02226 dbus_bool_t
02227 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02228 {
02229
02230
02231
02232
02233 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02234 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02235 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02236
02237 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02238 return FALSE;
02239 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02240 return FALSE;
02241
02242 return TRUE;
02243 }
02244
02256 dbus_bool_t
02257 _dbus_append_user_from_current_process (DBusString *str)
02258 {
02259 return _dbus_string_append_uint (str,
02260 _dbus_geteuid ());
02261 }
02262
02267 dbus_pid_t
02268 _dbus_getpid (void)
02269 {
02270 return getpid ();
02271 }
02272
02276 dbus_uid_t
02277 _dbus_getuid (void)
02278 {
02279 return getuid ();
02280 }
02281
02285 dbus_uid_t
02286 _dbus_geteuid (void)
02287 {
02288 return geteuid ();
02289 }
02290
02297 unsigned long
02298 _dbus_pid_for_log (void)
02299 {
02300 return getpid ();
02301 }
02302
02310 dbus_bool_t
02311 _dbus_parse_uid (const DBusString *uid_str,
02312 dbus_uid_t *uid)
02313 {
02314 int end;
02315 long val;
02316
02317 if (_dbus_string_get_length (uid_str) == 0)
02318 {
02319 _dbus_verbose ("UID string was zero length\n");
02320 return FALSE;
02321 }
02322
02323 val = -1;
02324 end = 0;
02325 if (!_dbus_string_parse_int (uid_str, 0, &val,
02326 &end))
02327 {
02328 _dbus_verbose ("could not parse string as a UID\n");
02329 return FALSE;
02330 }
02331
02332 if (end != _dbus_string_get_length (uid_str))
02333 {
02334 _dbus_verbose ("string contained trailing stuff after UID\n");
02335 return FALSE;
02336 }
02337
02338 *uid = val;
02339
02340 return TRUE;
02341 }
02342
02343 #if !DBUS_USE_SYNC
02344 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02345 #endif
02346
02353 dbus_int32_t
02354 _dbus_atomic_inc (DBusAtomic *atomic)
02355 {
02356 #if DBUS_USE_SYNC
02357 return __sync_add_and_fetch(&atomic->value, 1)-1;
02358 #else
02359 dbus_int32_t res;
02360 _DBUS_LOCK (atomic);
02361 res = atomic->value;
02362 atomic->value += 1;
02363 _DBUS_UNLOCK (atomic);
02364 return res;
02365 #endif
02366 }
02367
02374 dbus_int32_t
02375 _dbus_atomic_dec (DBusAtomic *atomic)
02376 {
02377 #if DBUS_USE_SYNC
02378 return __sync_sub_and_fetch(&atomic->value, 1)+1;
02379 #else
02380 dbus_int32_t res;
02381
02382 _DBUS_LOCK (atomic);
02383 res = atomic->value;
02384 atomic->value -= 1;
02385 _DBUS_UNLOCK (atomic);
02386 return res;
02387 #endif
02388 }
02389
02397 dbus_int32_t
02398 _dbus_atomic_get (DBusAtomic *atomic)
02399 {
02400 #if DBUS_USE_SYNC
02401 __sync_synchronize ();
02402 return atomic->value;
02403 #else
02404 dbus_int32_t res;
02405
02406 _DBUS_LOCK (atomic);
02407 res = atomic->value;
02408 _DBUS_UNLOCK (atomic);
02409 return res;
02410 #endif
02411 }
02412
02413 #ifdef DBUS_BUILD_TESTS
02414
02417 dbus_gid_t
02418 _dbus_getgid (void)
02419 {
02420 return getgid ();
02421 }
02422 #endif
02423
02432 int
02433 _dbus_poll (DBusPollFD *fds,
02434 int n_fds,
02435 int timeout_milliseconds)
02436 {
02437 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02438
02439
02440
02441
02442 if (_DBUS_POLLIN == POLLIN &&
02443 _DBUS_POLLPRI == POLLPRI &&
02444 _DBUS_POLLOUT == POLLOUT &&
02445 _DBUS_POLLERR == POLLERR &&
02446 _DBUS_POLLHUP == POLLHUP &&
02447 _DBUS_POLLNVAL == POLLNVAL &&
02448 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02449 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02450 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02451 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02452 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02453 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02454 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02455 {
02456 return poll ((struct pollfd*) fds,
02457 n_fds,
02458 timeout_milliseconds);
02459 }
02460 else
02461 {
02462
02463
02464
02465 _dbus_warn ("didn't implement poll() properly for this system yet\n");
02466 return -1;
02467 }
02468 #else
02469
02470 fd_set read_set, write_set, err_set;
02471 int max_fd = 0;
02472 int i;
02473 struct timeval tv;
02474 int ready;
02475
02476 FD_ZERO (&read_set);
02477 FD_ZERO (&write_set);
02478 FD_ZERO (&err_set);
02479
02480 for (i = 0; i < n_fds; i++)
02481 {
02482 DBusPollFD *fdp = &fds[i];
02483
02484 if (fdp->events & _DBUS_POLLIN)
02485 FD_SET (fdp->fd, &read_set);
02486
02487 if (fdp->events & _DBUS_POLLOUT)
02488 FD_SET (fdp->fd, &write_set);
02489
02490 FD_SET (fdp->fd, &err_set);
02491
02492 max_fd = MAX (max_fd, fdp->fd);
02493 }
02494
02495 tv.tv_sec = timeout_milliseconds / 1000;
02496 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02497
02498 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02499 timeout_milliseconds < 0 ? NULL : &tv);
02500
02501 if (ready > 0)
02502 {
02503 for (i = 0; i < n_fds; i++)
02504 {
02505 DBusPollFD *fdp = &fds[i];
02506
02507 fdp->revents = 0;
02508
02509 if (FD_ISSET (fdp->fd, &read_set))
02510 fdp->revents |= _DBUS_POLLIN;
02511
02512 if (FD_ISSET (fdp->fd, &write_set))
02513 fdp->revents |= _DBUS_POLLOUT;
02514
02515 if (FD_ISSET (fdp->fd, &err_set))
02516 fdp->revents |= _DBUS_POLLERR;
02517 }
02518 }
02519
02520 return ready;
02521 #endif
02522 }
02523
02531 void
02532 _dbus_get_current_time (long *tv_sec,
02533 long *tv_usec)
02534 {
02535 struct timeval t;
02536
02537 #ifdef HAVE_MONOTONIC_CLOCK
02538 struct timespec ts;
02539 clock_gettime (CLOCK_MONOTONIC, &ts);
02540
02541 if (tv_sec)
02542 *tv_sec = ts.tv_sec;
02543 if (tv_usec)
02544 *tv_usec = ts.tv_nsec / 1000;
02545 #else
02546 gettimeofday (&t, NULL);
02547
02548 if (tv_sec)
02549 *tv_sec = t.tv_sec;
02550 if (tv_usec)
02551 *tv_usec = t.tv_usec;
02552 #endif
02553 }
02554
02563 dbus_bool_t
02564 _dbus_create_directory (const DBusString *filename,
02565 DBusError *error)
02566 {
02567 const char *filename_c;
02568
02569 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02570
02571 filename_c = _dbus_string_get_const_data (filename);
02572
02573 if (mkdir (filename_c, 0700) < 0)
02574 {
02575 if (errno == EEXIST)
02576 return TRUE;
02577
02578 dbus_set_error (error, DBUS_ERROR_FAILED,
02579 "Failed to create directory %s: %s\n",
02580 filename_c, _dbus_strerror (errno));
02581 return FALSE;
02582 }
02583 else
02584 return TRUE;
02585 }
02586
02597 dbus_bool_t
02598 _dbus_concat_dir_and_file (DBusString *dir,
02599 const DBusString *next_component)
02600 {
02601 dbus_bool_t dir_ends_in_slash;
02602 dbus_bool_t file_starts_with_slash;
02603
02604 if (_dbus_string_get_length (dir) == 0 ||
02605 _dbus_string_get_length (next_component) == 0)
02606 return TRUE;
02607
02608 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02609 _dbus_string_get_length (dir) - 1);
02610
02611 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02612
02613 if (dir_ends_in_slash && file_starts_with_slash)
02614 {
02615 _dbus_string_shorten (dir, 1);
02616 }
02617 else if (!(dir_ends_in_slash || file_starts_with_slash))
02618 {
02619 if (!_dbus_string_append_byte (dir, '/'))
02620 return FALSE;
02621 }
02622
02623 return _dbus_string_copy (next_component, 0, dir,
02624 _dbus_string_get_length (dir));
02625 }
02626
02628 #define NANOSECONDS_PER_SECOND 1000000000
02629
02630 #define MICROSECONDS_PER_SECOND 1000000
02631
02632 #define MILLISECONDS_PER_SECOND 1000
02633
02634 #define NANOSECONDS_PER_MILLISECOND 1000000
02635
02636 #define MICROSECONDS_PER_MILLISECOND 1000
02637
02642 void
02643 _dbus_sleep_milliseconds (int milliseconds)
02644 {
02645 #ifdef HAVE_NANOSLEEP
02646 struct timespec req;
02647 struct timespec rem;
02648
02649 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02650 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02651 rem.tv_sec = 0;
02652 rem.tv_nsec = 0;
02653
02654 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02655 req = rem;
02656 #elif defined (HAVE_USLEEP)
02657 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02658 #else
02659 sleep (MAX (milliseconds / 1000, 1));
02660 #endif
02661 }
02662
02663 static dbus_bool_t
02664 _dbus_generate_pseudorandom_bytes (DBusString *str,
02665 int n_bytes)
02666 {
02667 int old_len;
02668 char *p;
02669
02670 old_len = _dbus_string_get_length (str);
02671
02672 if (!_dbus_string_lengthen (str, n_bytes))
02673 return FALSE;
02674
02675 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02676
02677 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02678
02679 return TRUE;
02680 }
02681
02690 dbus_bool_t
02691 _dbus_generate_random_bytes (DBusString *str,
02692 int n_bytes)
02693 {
02694 int old_len;
02695 int fd;
02696
02697
02698
02699
02700
02701
02702
02703 old_len = _dbus_string_get_length (str);
02704 fd = -1;
02705
02706
02707 fd = open ("/dev/urandom", O_RDONLY);
02708 if (fd < 0)
02709 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02710
02711 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02712
02713 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02714 {
02715 _dbus_close (fd, NULL);
02716 _dbus_string_set_length (str, old_len);
02717 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02718 }
02719
02720 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02721 n_bytes);
02722
02723 _dbus_close (fd, NULL);
02724
02725 return TRUE;
02726 }
02727
02733 void
02734 _dbus_exit (int code)
02735 {
02736 _exit (code);
02737 }
02738
02747 const char*
02748 _dbus_strerror (int error_number)
02749 {
02750 const char *msg;
02751
02752 msg = strerror (error_number);
02753 if (msg == NULL)
02754 msg = "unknown";
02755
02756 return msg;
02757 }
02758
02762 void
02763 _dbus_disable_sigpipe (void)
02764 {
02765 signal (SIGPIPE, SIG_IGN);
02766 }
02767
02775 void
02776 _dbus_fd_set_close_on_exec (intptr_t fd)
02777 {
02778 int val;
02779
02780 val = fcntl (fd, F_GETFD, 0);
02781
02782 if (val < 0)
02783 return;
02784
02785 val |= FD_CLOEXEC;
02786
02787 fcntl (fd, F_SETFD, val);
02788 }
02789
02797 dbus_bool_t
02798 _dbus_close (int fd,
02799 DBusError *error)
02800 {
02801 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02802
02803 again:
02804 if (close (fd) < 0)
02805 {
02806 if (errno == EINTR)
02807 goto again;
02808
02809 dbus_set_error (error, _dbus_error_from_errno (errno),
02810 "Could not close fd %d", fd);
02811 return FALSE;
02812 }
02813
02814 return TRUE;
02815 }
02816
02824 int
02825 _dbus_dup(int fd,
02826 DBusError *error)
02827 {
02828 int new_fd;
02829
02830 #ifdef F_DUPFD_CLOEXEC
02831 dbus_bool_t cloexec_done;
02832
02833 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02834 cloexec_done = new_fd >= 0;
02835
02836 if (new_fd < 0 && errno == EINVAL)
02837 #endif
02838 {
02839 new_fd = fcntl(fd, F_DUPFD, 3);
02840 }
02841
02842 if (new_fd < 0) {
02843
02844 dbus_set_error (error, _dbus_error_from_errno (errno),
02845 "Could not duplicate fd %d", fd);
02846 return -1;
02847 }
02848
02849 #ifdef F_DUPFD_CLOEXEC
02850 if (!cloexec_done)
02851 #endif
02852 {
02853 _dbus_fd_set_close_on_exec(new_fd);
02854 }
02855
02856 return new_fd;
02857 }
02858
02866 dbus_bool_t
02867 _dbus_set_fd_nonblocking (int fd,
02868 DBusError *error)
02869 {
02870 int val;
02871
02872 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02873
02874 val = fcntl (fd, F_GETFL, 0);
02875 if (val < 0)
02876 {
02877 dbus_set_error (error, _dbus_error_from_errno (errno),
02878 "Failed to get flags from file descriptor %d: %s",
02879 fd, _dbus_strerror (errno));
02880 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02881 _dbus_strerror (errno));
02882 return FALSE;
02883 }
02884
02885 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02886 {
02887 dbus_set_error (error, _dbus_error_from_errno (errno),
02888 "Failed to set nonblocking flag of file descriptor %d: %s",
02889 fd, _dbus_strerror (errno));
02890 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02891 fd, _dbus_strerror (errno));
02892
02893 return FALSE;
02894 }
02895
02896 return TRUE;
02897 }
02898
02904 void
02905 _dbus_print_backtrace (void)
02906 {
02907 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02908 void *bt[500];
02909 int bt_size;
02910 int i;
02911 char **syms;
02912
02913 bt_size = backtrace (bt, 500);
02914
02915 syms = backtrace_symbols (bt, bt_size);
02916
02917 i = 0;
02918 while (i < bt_size)
02919 {
02920
02921 fprintf (stderr, " %s\n", syms[i]);
02922 ++i;
02923 }
02924 fflush (stderr);
02925
02926 free (syms);
02927 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02928 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02929 #else
02930 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02931 #endif
02932 }
02933
02951 dbus_bool_t
02952 _dbus_full_duplex_pipe (int *fd1,
02953 int *fd2,
02954 dbus_bool_t blocking,
02955 DBusError *error)
02956 {
02957 #ifdef HAVE_SOCKETPAIR
02958 int fds[2];
02959 int retval;
02960
02961 #ifdef SOCK_CLOEXEC
02962 dbus_bool_t cloexec_done;
02963
02964 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02965 cloexec_done = retval >= 0;
02966
02967 if (retval < 0 && errno == EINVAL)
02968 #endif
02969 {
02970 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02971 }
02972
02973 if (retval < 0)
02974 {
02975 dbus_set_error (error, _dbus_error_from_errno (errno),
02976 "Could not create full-duplex pipe");
02977 return FALSE;
02978 }
02979
02980 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02981
02982 #ifdef SOCK_CLOEXEC
02983 if (!cloexec_done)
02984 #endif
02985 {
02986 _dbus_fd_set_close_on_exec (fds[0]);
02987 _dbus_fd_set_close_on_exec (fds[1]);
02988 }
02989
02990 if (!blocking &&
02991 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02992 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02993 {
02994 dbus_set_error (error, _dbus_error_from_errno (errno),
02995 "Could not set full-duplex pipe nonblocking");
02996
02997 _dbus_close (fds[0], NULL);
02998 _dbus_close (fds[1], NULL);
02999
03000 return FALSE;
03001 }
03002
03003 *fd1 = fds[0];
03004 *fd2 = fds[1];
03005
03006 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03007 *fd1, *fd2);
03008
03009 return TRUE;
03010 #else
03011 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03012 dbus_set_error (error, DBUS_ERROR_FAILED,
03013 "_dbus_full_duplex_pipe() not implemented on this OS");
03014 return FALSE;
03015 #endif
03016 }
03017
03026 int
03027 _dbus_printf_string_upper_bound (const char *format,
03028 va_list args)
03029 {
03030 char static_buf[1024];
03031 int bufsize = sizeof (static_buf);
03032 int len;
03033
03034 len = vsnprintf (static_buf, bufsize, format, args);
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044 if (len == bufsize)
03045 {
03046
03047
03048
03049
03050 if (vsnprintf (static_buf, 1, format, args) == 1)
03051 len = -1;
03052 }
03053
03054
03055
03056 while (len < 0)
03057 {
03058 char *buf;
03059
03060 bufsize *= 2;
03061
03062 buf = dbus_malloc (bufsize);
03063
03064 if (buf == NULL)
03065 return -1;
03066
03067 len = vsnprintf (buf, bufsize, format, args);
03068 dbus_free (buf);
03069
03070
03071
03072
03073 if (len == bufsize)
03074 len = -1;
03075 }
03076
03077 return len;
03078 }
03079
03086 const char*
03087 _dbus_get_tmpdir(void)
03088 {
03089 static const char* tmpdir = NULL;
03090
03091 if (tmpdir == NULL)
03092 {
03093
03094
03095
03096
03097 if (tmpdir == NULL)
03098 tmpdir = getenv("TMPDIR");
03099
03100
03101
03102
03103 if (tmpdir == NULL)
03104 tmpdir = getenv("TMP");
03105 if (tmpdir == NULL)
03106 tmpdir = getenv("TEMP");
03107
03108
03109 if (tmpdir == NULL)
03110 tmpdir = "/tmp";
03111 }
03112
03113 _dbus_assert(tmpdir != NULL);
03114
03115 return tmpdir;
03116 }
03117
03137 static dbus_bool_t
03138 _read_subprocess_line_argv (const char *progpath,
03139 dbus_bool_t path_fallback,
03140 char * const *argv,
03141 DBusString *result,
03142 DBusError *error)
03143 {
03144 int result_pipe[2] = { -1, -1 };
03145 int errors_pipe[2] = { -1, -1 };
03146 pid_t pid;
03147 int ret;
03148 int status;
03149 int orig_len;
03150 int i;
03151
03152 dbus_bool_t retval;
03153 sigset_t new_set, old_set;
03154
03155 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03156 retval = FALSE;
03157
03158
03159
03160
03161
03162 sigemptyset (&new_set);
03163 sigaddset (&new_set, SIGCHLD);
03164 sigprocmask (SIG_BLOCK, &new_set, &old_set);
03165
03166 orig_len = _dbus_string_get_length (result);
03167
03168 #define READ_END 0
03169 #define WRITE_END 1
03170 if (pipe (result_pipe) < 0)
03171 {
03172 dbus_set_error (error, _dbus_error_from_errno (errno),
03173 "Failed to create a pipe to call %s: %s",
03174 progpath, _dbus_strerror (errno));
03175 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03176 progpath, _dbus_strerror (errno));
03177 goto out;
03178 }
03179 if (pipe (errors_pipe) < 0)
03180 {
03181 dbus_set_error (error, _dbus_error_from_errno (errno),
03182 "Failed to create a pipe to call %s: %s",
03183 progpath, _dbus_strerror (errno));
03184 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03185 progpath, _dbus_strerror (errno));
03186 goto out;
03187 }
03188
03189 pid = fork ();
03190 if (pid < 0)
03191 {
03192 dbus_set_error (error, _dbus_error_from_errno (errno),
03193 "Failed to fork() to call %s: %s",
03194 progpath, _dbus_strerror (errno));
03195 _dbus_verbose ("Failed to fork() to call %s: %s\n",
03196 progpath, _dbus_strerror (errno));
03197 goto out;
03198 }
03199
03200 if (pid == 0)
03201 {
03202
03203 int maxfds;
03204 int fd;
03205
03206 fd = open ("/dev/null", O_RDWR);
03207 if (fd == -1)
03208
03209 _exit (1);
03210
03211 _dbus_verbose ("/dev/null fd %d opened\n", fd);
03212
03213
03214 close (result_pipe[READ_END]);
03215 close (errors_pipe[READ_END]);
03216 close (0);
03217 close (1);
03218 close (2);
03219
03220 if (dup2 (fd, 0) == -1)
03221 _exit (1);
03222 if (dup2 (result_pipe[WRITE_END], 1) == -1)
03223 _exit (1);
03224 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03225 _exit (1);
03226
03227 maxfds = sysconf (_SC_OPEN_MAX);
03228
03229
03230
03231 if (maxfds < 0)
03232 maxfds = 1024;
03233
03234 for (i = 3; i < maxfds; i++)
03235 close (i);
03236
03237 sigprocmask (SIG_SETMASK, &old_set, NULL);
03238
03239
03240 if (progpath[0] == '/')
03241 {
03242 execv (progpath, argv);
03243
03244
03245
03246
03247
03248
03249 if (path_fallback)
03250
03251 execvp (strrchr (progpath, '/')+1, argv);
03252 }
03253 else
03254 execvp (progpath, argv);
03255
03256
03257 _exit (1);
03258 }
03259
03260
03261 close (result_pipe[WRITE_END]);
03262 close (errors_pipe[WRITE_END]);
03263 result_pipe[WRITE_END] = -1;
03264 errors_pipe[WRITE_END] = -1;
03265
03266 ret = 0;
03267 do
03268 {
03269 ret = _dbus_read (result_pipe[READ_END], result, 1024);
03270 }
03271 while (ret > 0);
03272
03273
03274 do
03275 {
03276 ret = waitpid (pid, &status, 0);
03277 }
03278 while (ret == -1 && errno == EINTR);
03279
03280
03281
03282 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03283 {
03284
03285 DBusString error_message;
03286 if (!_dbus_string_init (&error_message))
03287 {
03288 _DBUS_SET_OOM (error);
03289 goto out;
03290 }
03291
03292 ret = 0;
03293 do
03294 {
03295 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03296 }
03297 while (ret > 0);
03298
03299 _dbus_string_set_length (result, orig_len);
03300 if (_dbus_string_get_length (&error_message) > 0)
03301 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03302 "%s terminated abnormally with the following error: %s",
03303 progpath, _dbus_string_get_data (&error_message));
03304 else
03305 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03306 "%s terminated abnormally without any error message",
03307 progpath);
03308 goto out;
03309 }
03310
03311 retval = TRUE;
03312
03313 out:
03314 sigprocmask (SIG_SETMASK, &old_set, NULL);
03315
03316 if (retval)
03317 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03318 else
03319 _DBUS_ASSERT_ERROR_IS_SET (error);
03320
03321 if (result_pipe[0] != -1)
03322 close (result_pipe[0]);
03323 if (result_pipe[1] != -1)
03324 close (result_pipe[1]);
03325 if (errors_pipe[0] != -1)
03326 close (errors_pipe[0]);
03327 if (errors_pipe[1] != -1)
03328 close (errors_pipe[1]);
03329
03330 return retval;
03331 }
03332
03344 dbus_bool_t
03345 _dbus_get_autolaunch_address (const char *scope,
03346 DBusString *address,
03347 DBusError *error)
03348 {
03349 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03350
03351
03352
03353 const char *display;
03354 static char *argv[6];
03355 int i;
03356 DBusString uuid;
03357 dbus_bool_t retval;
03358
03359 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03360 retval = FALSE;
03361
03362
03363
03364
03365 display = _dbus_getenv ("DISPLAY");
03366
03367 if (display == NULL || display[0] == '\0')
03368 {
03369 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03370 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03371 return FALSE;
03372 }
03373
03374 if (!_dbus_string_init (&uuid))
03375 {
03376 _DBUS_SET_OOM (error);
03377 return FALSE;
03378 }
03379
03380 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03381 {
03382 _DBUS_SET_OOM (error);
03383 goto out;
03384 }
03385
03386 i = 0;
03387 argv[i] = "dbus-launch";
03388 ++i;
03389 argv[i] = "--autolaunch";
03390 ++i;
03391 argv[i] = _dbus_string_get_data (&uuid);
03392 ++i;
03393 argv[i] = "--binary-syntax";
03394 ++i;
03395 argv[i] = "--close-stderr";
03396 ++i;
03397 argv[i] = NULL;
03398 ++i;
03399
03400 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03401
03402 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03403 TRUE,
03404 argv, address, error);
03405
03406 out:
03407 _dbus_string_free (&uuid);
03408 return retval;
03409 #else
03410 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03411 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03412 "set your DBUS_SESSION_BUS_ADDRESS instead");
03413 return FALSE;
03414 #endif
03415 }
03416
03435 dbus_bool_t
03436 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
03437 dbus_bool_t create_if_not_found,
03438 DBusError *error)
03439 {
03440 DBusString filename;
03441 dbus_bool_t b;
03442
03443 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03444
03445 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03446 if (b)
03447 return TRUE;
03448
03449 dbus_error_free (error);
03450
03451
03452 _dbus_string_init_const (&filename, "/etc/machine-id");
03453 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03454 }
03455
03456 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03457 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03458
03465 dbus_bool_t
03466 _dbus_lookup_launchd_socket (DBusString *socket_path,
03467 const char *launchd_env_var,
03468 DBusError *error)
03469 {
03470 #ifdef DBUS_ENABLE_LAUNCHD
03471 char *argv[4];
03472 int i;
03473
03474 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03475
03476 i = 0;
03477 argv[i] = "launchctl";
03478 ++i;
03479 argv[i] = "getenv";
03480 ++i;
03481 argv[i] = (char*)launchd_env_var;
03482 ++i;
03483 argv[i] = NULL;
03484 ++i;
03485
03486 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03487
03488 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03489 {
03490 return FALSE;
03491 }
03492
03493
03494 if (_dbus_string_get_length(socket_path) == 0)
03495 {
03496 return FALSE;
03497 }
03498
03499
03500 _dbus_string_shorten(socket_path, 1);
03501 return TRUE;
03502 #else
03503 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03504 "can't lookup socket from launchd; launchd support not compiled in");
03505 return FALSE;
03506 #endif
03507 }
03508
03509 static dbus_bool_t
03510 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
03511 {
03512 #ifdef DBUS_ENABLE_LAUNCHD
03513 dbus_bool_t valid_socket;
03514 DBusString socket_path;
03515
03516 if (!_dbus_string_init (&socket_path))
03517 {
03518 _DBUS_SET_OOM (error);
03519 return FALSE;
03520 }
03521
03522 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03523
03524 if (dbus_error_is_set(error))
03525 {
03526 _dbus_string_free(&socket_path);
03527 return FALSE;
03528 }
03529
03530 if (!valid_socket)
03531 {
03532 dbus_set_error(error, "no socket path",
03533 "launchd did not provide a socket path, "
03534 "verify that org.freedesktop.dbus-session.plist is loaded!");
03535 _dbus_string_free(&socket_path);
03536 return FALSE;
03537 }
03538 if (!_dbus_string_append (address, "unix:path="))
03539 {
03540 _DBUS_SET_OOM (error);
03541 _dbus_string_free(&socket_path);
03542 return FALSE;
03543 }
03544 if (!_dbus_string_copy (&socket_path, 0, address,
03545 _dbus_string_get_length (address)))
03546 {
03547 _DBUS_SET_OOM (error);
03548 _dbus_string_free(&socket_path);
03549 return FALSE;
03550 }
03551
03552 _dbus_string_free(&socket_path);
03553 return TRUE;
03554 #else
03555 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03556 "can't lookup session address from launchd; launchd support not compiled in");
03557 return FALSE;
03558 #endif
03559 }
03560
03580 dbus_bool_t
03581 _dbus_lookup_session_address (dbus_bool_t *supported,
03582 DBusString *address,
03583 DBusError *error)
03584 {
03585 #ifdef DBUS_ENABLE_LAUNCHD
03586 *supported = TRUE;
03587 return _dbus_lookup_session_address_launchd (address, error);
03588 #else
03589
03590
03591
03592
03593 *supported = FALSE;
03594 return TRUE;
03595 #endif
03596 }
03597
03615 dbus_bool_t
03616 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03617 {
03618 const char *xdg_data_home;
03619 const char *xdg_data_dirs;
03620 DBusString servicedir_path;
03621
03622 if (!_dbus_string_init (&servicedir_path))
03623 return FALSE;
03624
03625 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03626 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03627
03628 if (xdg_data_home != NULL)
03629 {
03630 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03631 goto oom;
03632 }
03633 else
03634 {
03635 const DBusString *homedir;
03636 DBusString local_share;
03637
03638 if (!_dbus_homedir_from_current_process (&homedir))
03639 goto oom;
03640
03641 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03642 goto oom;
03643
03644 _dbus_string_init_const (&local_share, "/.local/share");
03645 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03646 goto oom;
03647 }
03648
03649 if (!_dbus_string_append (&servicedir_path, ":"))
03650 goto oom;
03651
03652 if (xdg_data_dirs != NULL)
03653 {
03654 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03655 goto oom;
03656
03657 if (!_dbus_string_append (&servicedir_path, ":"))
03658 goto oom;
03659 }
03660 else
03661 {
03662 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03663 goto oom;
03664 }
03665
03666
03667
03668
03669
03670
03671
03672 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03673 goto oom;
03674
03675 if (!_dbus_split_paths_and_append (&servicedir_path,
03676 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03677 dirs))
03678 goto oom;
03679
03680 _dbus_string_free (&servicedir_path);
03681 return TRUE;
03682
03683 oom:
03684 _dbus_string_free (&servicedir_path);
03685 return FALSE;
03686 }
03687
03688
03707 dbus_bool_t
03708 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03709 {
03710 const char *xdg_data_dirs;
03711 DBusString servicedir_path;
03712
03713 if (!_dbus_string_init (&servicedir_path))
03714 return FALSE;
03715
03716 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03717
03718 if (xdg_data_dirs != NULL)
03719 {
03720 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03721 goto oom;
03722
03723 if (!_dbus_string_append (&servicedir_path, ":"))
03724 goto oom;
03725 }
03726 else
03727 {
03728 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03729 goto oom;
03730 }
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742 if (!_dbus_string_append (&servicedir_path,
03743 DBUS_DATADIR":"
03744 "/lib:"))
03745 goto oom;
03746
03747 if (!_dbus_split_paths_and_append (&servicedir_path,
03748 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03749 dirs))
03750 goto oom;
03751
03752 _dbus_string_free (&servicedir_path);
03753 return TRUE;
03754
03755 oom:
03756 _dbus_string_free (&servicedir_path);
03757 return FALSE;
03758 }
03759
03768 dbus_bool_t
03769 _dbus_append_system_config_file (DBusString *str)
03770 {
03771 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03772 }
03773
03780 dbus_bool_t
03781 _dbus_append_session_config_file (DBusString *str)
03782 {
03783 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03784 }
03785
03793 void
03794 _dbus_flush_caches (void)
03795 {
03796 _dbus_user_database_flush_system ();
03797 }
03798
03812 dbus_bool_t
03813 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03814 DBusCredentials *credentials)
03815 {
03816 DBusString homedir;
03817 DBusString dotdir;
03818 dbus_uid_t uid;
03819
03820 _dbus_assert (credentials != NULL);
03821 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03822
03823 if (!_dbus_string_init (&homedir))
03824 return FALSE;
03825
03826 uid = _dbus_credentials_get_unix_uid (credentials);
03827 _dbus_assert (uid != DBUS_UID_UNSET);
03828
03829 if (!_dbus_homedir_from_uid (uid, &homedir))
03830 goto failed;
03831
03832 #ifdef DBUS_BUILD_TESTS
03833 {
03834 const char *override;
03835
03836 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03837 if (override != NULL && *override != '\0')
03838 {
03839 _dbus_string_set_length (&homedir, 0);
03840 if (!_dbus_string_append (&homedir, override))
03841 goto failed;
03842
03843 _dbus_verbose ("Using fake homedir for testing: %s\n",
03844 _dbus_string_get_const_data (&homedir));
03845 }
03846 else
03847 {
03848 static dbus_bool_t already_warned = FALSE;
03849 if (!already_warned)
03850 {
03851 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03852 already_warned = TRUE;
03853 }
03854 }
03855 }
03856 #endif
03857
03858 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03859 if (!_dbus_concat_dir_and_file (&homedir,
03860 &dotdir))
03861 goto failed;
03862
03863 if (!_dbus_string_copy (&homedir, 0,
03864 directory, _dbus_string_get_length (directory))) {
03865 goto failed;
03866 }
03867
03868 _dbus_string_free (&homedir);
03869 return TRUE;
03870
03871 failed:
03872 _dbus_string_free (&homedir);
03873 return FALSE;
03874 }
03875
03876
03877 dbus_bool_t
03878 _dbus_daemon_publish_session_bus_address (const char* addr,
03879 const char *scope)
03880 {
03881 return TRUE;
03882 }
03883
03884
03885 void
03886 _dbus_daemon_unpublish_session_bus_address (void)
03887 {
03888
03889 }
03890
03897 dbus_bool_t
03898 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03899 {
03900 return errno == EAGAIN || errno == EWOULDBLOCK;
03901 }
03902
03910 dbus_bool_t
03911 _dbus_delete_directory (const DBusString *filename,
03912 DBusError *error)
03913 {
03914 const char *filename_c;
03915
03916 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03917
03918 filename_c = _dbus_string_get_const_data (filename);
03919
03920 if (rmdir (filename_c) != 0)
03921 {
03922 dbus_set_error (error, DBUS_ERROR_FAILED,
03923 "Failed to remove directory %s: %s\n",
03924 filename_c, _dbus_strerror (errno));
03925 return FALSE;
03926 }
03927
03928 return TRUE;
03929 }
03930
03938 dbus_bool_t
03939 _dbus_socket_can_pass_unix_fd(int fd) {
03940
03941 #ifdef SCM_RIGHTS
03942 union {
03943 struct sockaddr sa;
03944 struct sockaddr_storage storage;
03945 struct sockaddr_un un;
03946 } sa_buf;
03947
03948 socklen_t sa_len = sizeof(sa_buf);
03949
03950 _DBUS_ZERO(sa_buf);
03951
03952 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03953 return FALSE;
03954
03955 return sa_buf.sa.sa_family == AF_UNIX;
03956
03957 #else
03958 return FALSE;
03959
03960 #endif
03961 }
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971 const char *
03972 _dbus_replace_install_prefix (const char *configure_time_path)
03973 {
03974 return configure_time_path;
03975 }
03976
03977