00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037 #include "dbus-nonce.h"
00038
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 #include <stdio.h>
00045 #include <fcntl.h>
00046 #include <sys/socket.h>
00047 #include <dirent.h>
00048 #include <sys/un.h>
00049 #include <pwd.h>
00050 #include <time.h>
00051 #include <locale.h>
00052 #include <sys/time.h>
00053 #include <sys/stat.h>
00054 #include <sys/wait.h>
00055 #include <netinet/in.h>
00056 #include <netdb.h>
00057 #include <grp.h>
00058
00059 #ifdef HAVE_ERRNO_H
00060 #include <errno.h>
00061 #endif
00062 #ifdef HAVE_WRITEV
00063 #include <sys/uio.h>
00064 #endif
00065 #ifdef HAVE_POLL
00066 #include <sys/poll.h>
00067 #endif
00068 #ifdef HAVE_BACKTRACE
00069 #include <execinfo.h>
00070 #endif
00071 #ifdef HAVE_GETPEERUCRED
00072 #include <ucred.h>
00073 #endif
00074
00075 #ifdef HAVE_ADT
00076 #include <bsm/adt.h>
00077 #endif
00078
00079 #include "sd-daemon.h"
00080
00081 #ifndef O_BINARY
00082 #define O_BINARY 0
00083 #endif
00084
00085 #ifndef AI_ADDRCONFIG
00086 #define AI_ADDRCONFIG 0
00087 #endif
00088
00089 #ifndef HAVE_SOCKLEN_T
00090 #define socklen_t int
00091 #endif
00092
00093 static dbus_bool_t
00094 _dbus_open_socket (int *fd_p,
00095 int domain,
00096 int type,
00097 int protocol,
00098 DBusError *error)
00099 {
00100 #ifdef SOCK_CLOEXEC
00101 dbus_bool_t cloexec_done;
00102
00103 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00104 cloexec_done = *fd_p >= 0;
00105
00106
00107 if (*fd_p < 0 && errno == EINVAL)
00108 #endif
00109 {
00110 *fd_p = socket (domain, type, protocol);
00111 }
00112
00113 if (*fd_p >= 0)
00114 {
00115 #ifdef SOCK_CLOEXEC
00116 if (!cloexec_done)
00117 #endif
00118 {
00119 _dbus_fd_set_close_on_exec(*fd_p);
00120 }
00121
00122 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00123 return TRUE;
00124 }
00125 else
00126 {
00127 dbus_set_error(error,
00128 _dbus_error_from_errno (errno),
00129 "Failed to open socket: %s",
00130 _dbus_strerror (errno));
00131 return FALSE;
00132 }
00133 }
00134
00135 dbus_bool_t
00136 _dbus_open_tcp_socket (int *fd,
00137 DBusError *error)
00138 {
00139 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00140 }
00141
00152 dbus_bool_t
00153 _dbus_open_unix_socket (int *fd,
00154 DBusError *error)
00155 {
00156 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00157 }
00158
00167 dbus_bool_t
00168 _dbus_close_socket (int fd,
00169 DBusError *error)
00170 {
00171 return _dbus_close (fd, error);
00172 }
00173
00183 int
00184 _dbus_read_socket (int fd,
00185 DBusString *buffer,
00186 int count)
00187 {
00188 return _dbus_read (fd, buffer, count);
00189 }
00190
00201 int
00202 _dbus_write_socket (int fd,
00203 const DBusString *buffer,
00204 int start,
00205 int len)
00206 {
00207 #ifdef HAVE_DECL_MSG_NOSIGNAL
00208 const char *data;
00209 int bytes_written;
00210
00211 data = _dbus_string_get_const_data_len (buffer, start, len);
00212
00213 again:
00214
00215 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00216
00217 if (bytes_written < 0 && errno == EINTR)
00218 goto again;
00219
00220 return bytes_written;
00221
00222 #else
00223 return _dbus_write (fd, buffer, start, len);
00224 #endif
00225 }
00226
00239 int
00240 _dbus_read_socket_with_unix_fds (int fd,
00241 DBusString *buffer,
00242 int count,
00243 int *fds,
00244 int *n_fds) {
00245 #ifndef HAVE_UNIX_FD_PASSING
00246 int r;
00247
00248 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00249 return r;
00250
00251 *n_fds = 0;
00252 return r;
00253
00254 #else
00255 int bytes_read;
00256 int start;
00257 struct msghdr m;
00258 struct iovec iov;
00259
00260 _dbus_assert (count >= 0);
00261 _dbus_assert (*n_fds >= 0);
00262
00263 start = _dbus_string_get_length (buffer);
00264
00265 if (!_dbus_string_lengthen (buffer, count))
00266 {
00267 errno = ENOMEM;
00268 return -1;
00269 }
00270
00271 _DBUS_ZERO(iov);
00272 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00273 iov.iov_len = count;
00274
00275 _DBUS_ZERO(m);
00276 m.msg_iov = &iov;
00277 m.msg_iovlen = 1;
00278
00279
00280
00281
00282
00283 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00284
00285
00286
00287 m.msg_control = alloca(m.msg_controllen);
00288 memset(m.msg_control, 0, m.msg_controllen);
00289
00290
00291
00292
00293
00294 m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
00295
00296 again:
00297
00298 bytes_read = recvmsg(fd, &m, 0
00299 #ifdef MSG_CMSG_CLOEXEC
00300 |MSG_CMSG_CLOEXEC
00301 #endif
00302 );
00303
00304 if (bytes_read < 0)
00305 {
00306 if (errno == EINTR)
00307 goto again;
00308 else
00309 {
00310
00311 _dbus_string_set_length (buffer, start);
00312 return -1;
00313 }
00314 }
00315 else
00316 {
00317 struct cmsghdr *cm;
00318 dbus_bool_t found = FALSE;
00319
00320 if (m.msg_flags & MSG_CTRUNC)
00321 {
00322
00323
00324
00325
00326
00327 errno = ENOSPC;
00328 _dbus_string_set_length (buffer, start);
00329 return -1;
00330 }
00331
00332 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00333 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00334 {
00335 size_t i;
00336 int *payload = (int *) CMSG_DATA (cm);
00337 size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
00338 size_t payload_len_fds = payload_len_bytes / sizeof (int);
00339 size_t fds_to_use;
00340
00341
00342
00343
00344 _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
00345
00346 if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
00347 {
00348
00349 fds_to_use = payload_len_fds;
00350 }
00351 else
00352 {
00353
00354
00355
00356
00357 fds_to_use = (size_t) *n_fds;
00358
00359
00360
00361
00362 for (i = fds_to_use; i < payload_len_fds; i++)
00363 {
00364 close (payload[i]);
00365 }
00366 }
00367
00368 memcpy (fds, payload, fds_to_use * sizeof (int));
00369 found = TRUE;
00370
00371
00372 *n_fds = (int) fds_to_use;
00373
00374
00375
00376
00377 for (i = 0; i < fds_to_use; i++)
00378 _dbus_fd_set_close_on_exec(fds[i]);
00379
00380 break;
00381 }
00382
00383 if (!found)
00384 *n_fds = 0;
00385
00386
00387 _dbus_string_set_length (buffer, start + bytes_read);
00388
00389 #if 0
00390 if (bytes_read > 0)
00391 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00392 #endif
00393
00394 return bytes_read;
00395 }
00396 #endif
00397 }
00398
00399 int
00400 _dbus_write_socket_with_unix_fds(int fd,
00401 const DBusString *buffer,
00402 int start,
00403 int len,
00404 const int *fds,
00405 int n_fds) {
00406
00407 #ifndef HAVE_UNIX_FD_PASSING
00408
00409 if (n_fds > 0) {
00410 errno = ENOTSUP;
00411 return -1;
00412 }
00413
00414 return _dbus_write_socket(fd, buffer, start, len);
00415 #else
00416 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00417 #endif
00418 }
00419
00420 int
00421 _dbus_write_socket_with_unix_fds_two(int fd,
00422 const DBusString *buffer1,
00423 int start1,
00424 int len1,
00425 const DBusString *buffer2,
00426 int start2,
00427 int len2,
00428 const int *fds,
00429 int n_fds) {
00430
00431 #ifndef HAVE_UNIX_FD_PASSING
00432
00433 if (n_fds > 0) {
00434 errno = ENOTSUP;
00435 return -1;
00436 }
00437
00438 return _dbus_write_socket_two(fd,
00439 buffer1, start1, len1,
00440 buffer2, start2, len2);
00441 #else
00442
00443 struct msghdr m;
00444 struct cmsghdr *cm;
00445 struct iovec iov[2];
00446 int bytes_written;
00447
00448 _dbus_assert (len1 >= 0);
00449 _dbus_assert (len2 >= 0);
00450 _dbus_assert (n_fds >= 0);
00451
00452 _DBUS_ZERO(iov);
00453 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00454 iov[0].iov_len = len1;
00455
00456 if (buffer2)
00457 {
00458 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00459 iov[1].iov_len = len2;
00460 }
00461
00462 _DBUS_ZERO(m);
00463 m.msg_iov = iov;
00464 m.msg_iovlen = buffer2 ? 2 : 1;
00465
00466 if (n_fds > 0)
00467 {
00468 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00469 m.msg_control = alloca(m.msg_controllen);
00470 memset(m.msg_control, 0, m.msg_controllen);
00471
00472 cm = CMSG_FIRSTHDR(&m);
00473 cm->cmsg_level = SOL_SOCKET;
00474 cm->cmsg_type = SCM_RIGHTS;
00475 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00476 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00477 }
00478
00479 again:
00480
00481 bytes_written = sendmsg (fd, &m, 0
00482 #ifdef HAVE_DECL_MSG_NOSIGNAL
00483 |MSG_NOSIGNAL
00484 #endif
00485 );
00486
00487 if (bytes_written < 0 && errno == EINTR)
00488 goto again;
00489
00490 #if 0
00491 if (bytes_written > 0)
00492 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00493 #endif
00494
00495 return bytes_written;
00496 #endif
00497 }
00498
00512 int
00513 _dbus_write_socket_two (int fd,
00514 const DBusString *buffer1,
00515 int start1,
00516 int len1,
00517 const DBusString *buffer2,
00518 int start2,
00519 int len2)
00520 {
00521 #ifdef HAVE_DECL_MSG_NOSIGNAL
00522 struct iovec vectors[2];
00523 const char *data1;
00524 const char *data2;
00525 int bytes_written;
00526 struct msghdr m;
00527
00528 _dbus_assert (buffer1 != NULL);
00529 _dbus_assert (start1 >= 0);
00530 _dbus_assert (start2 >= 0);
00531 _dbus_assert (len1 >= 0);
00532 _dbus_assert (len2 >= 0);
00533
00534 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00535
00536 if (buffer2 != NULL)
00537 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00538 else
00539 {
00540 data2 = NULL;
00541 start2 = 0;
00542 len2 = 0;
00543 }
00544
00545 vectors[0].iov_base = (char*) data1;
00546 vectors[0].iov_len = len1;
00547 vectors[1].iov_base = (char*) data2;
00548 vectors[1].iov_len = len2;
00549
00550 _DBUS_ZERO(m);
00551 m.msg_iov = vectors;
00552 m.msg_iovlen = data2 ? 2 : 1;
00553
00554 again:
00555
00556 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00557
00558 if (bytes_written < 0 && errno == EINTR)
00559 goto again;
00560
00561 return bytes_written;
00562
00563 #else
00564 return _dbus_write_two (fd, buffer1, start1, len1,
00565 buffer2, start2, len2);
00566 #endif
00567 }
00568
00569 dbus_bool_t
00570 _dbus_socket_is_invalid (int fd)
00571 {
00572 return fd < 0 ? TRUE : FALSE;
00573 }
00574
00591 int
00592 _dbus_read (int fd,
00593 DBusString *buffer,
00594 int count)
00595 {
00596 int bytes_read;
00597 int start;
00598 char *data;
00599
00600 _dbus_assert (count >= 0);
00601
00602 start = _dbus_string_get_length (buffer);
00603
00604 if (!_dbus_string_lengthen (buffer, count))
00605 {
00606 errno = ENOMEM;
00607 return -1;
00608 }
00609
00610 data = _dbus_string_get_data_len (buffer, start, count);
00611
00612 again:
00613
00614 bytes_read = read (fd, data, count);
00615
00616 if (bytes_read < 0)
00617 {
00618 if (errno == EINTR)
00619 goto again;
00620 else
00621 {
00622
00623 _dbus_string_set_length (buffer, start);
00624 return -1;
00625 }
00626 }
00627 else
00628 {
00629
00630 _dbus_string_set_length (buffer, start + bytes_read);
00631
00632 #if 0
00633 if (bytes_read > 0)
00634 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00635 #endif
00636
00637 return bytes_read;
00638 }
00639 }
00640
00651 int
00652 _dbus_write (int fd,
00653 const DBusString *buffer,
00654 int start,
00655 int len)
00656 {
00657 const char *data;
00658 int bytes_written;
00659
00660 data = _dbus_string_get_const_data_len (buffer, start, len);
00661
00662 again:
00663
00664 bytes_written = write (fd, data, len);
00665
00666 if (bytes_written < 0 && errno == EINTR)
00667 goto again;
00668
00669 #if 0
00670 if (bytes_written > 0)
00671 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00672 #endif
00673
00674 return bytes_written;
00675 }
00676
00697 int
00698 _dbus_write_two (int fd,
00699 const DBusString *buffer1,
00700 int start1,
00701 int len1,
00702 const DBusString *buffer2,
00703 int start2,
00704 int len2)
00705 {
00706 _dbus_assert (buffer1 != NULL);
00707 _dbus_assert (start1 >= 0);
00708 _dbus_assert (start2 >= 0);
00709 _dbus_assert (len1 >= 0);
00710 _dbus_assert (len2 >= 0);
00711
00712 #ifdef HAVE_WRITEV
00713 {
00714 struct iovec vectors[2];
00715 const char *data1;
00716 const char *data2;
00717 int bytes_written;
00718
00719 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00720
00721 if (buffer2 != NULL)
00722 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00723 else
00724 {
00725 data2 = NULL;
00726 start2 = 0;
00727 len2 = 0;
00728 }
00729
00730 vectors[0].iov_base = (char*) data1;
00731 vectors[0].iov_len = len1;
00732 vectors[1].iov_base = (char*) data2;
00733 vectors[1].iov_len = len2;
00734
00735 again:
00736
00737 bytes_written = writev (fd,
00738 vectors,
00739 data2 ? 2 : 1);
00740
00741 if (bytes_written < 0 && errno == EINTR)
00742 goto again;
00743
00744 return bytes_written;
00745 }
00746 #else
00747 {
00748 int ret1;
00749
00750 ret1 = _dbus_write (fd, buffer1, start1, len1);
00751 if (ret1 == len1 && buffer2 != NULL)
00752 {
00753 ret2 = _dbus_write (fd, buffer2, start2, len2);
00754 if (ret2 < 0)
00755 ret2 = 0;
00756
00757 return ret1 + ret2;
00758 }
00759 else
00760 return ret1;
00761 }
00762 #endif
00763 }
00764
00765 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00766
00796 int
00797 _dbus_connect_unix_socket (const char *path,
00798 dbus_bool_t abstract,
00799 DBusError *error)
00800 {
00801 int fd;
00802 size_t path_len;
00803 struct sockaddr_un addr;
00804
00805 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00806
00807 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00808 path, abstract);
00809
00810
00811 if (!_dbus_open_unix_socket (&fd, error))
00812 {
00813 _DBUS_ASSERT_ERROR_IS_SET(error);
00814 return -1;
00815 }
00816 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00817
00818 _DBUS_ZERO (addr);
00819 addr.sun_family = AF_UNIX;
00820 path_len = strlen (path);
00821
00822 if (abstract)
00823 {
00824 #ifdef HAVE_ABSTRACT_SOCKETS
00825 addr.sun_path[0] = '\0';
00826 path_len++;
00827
00828 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00829 {
00830 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00831 "Abstract socket name too long\n");
00832 _dbus_close (fd, NULL);
00833 return -1;
00834 }
00835
00836 strncpy (&addr.sun_path[1], path, path_len);
00837
00838 #else
00839 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00840 "Operating system does not support abstract socket namespace\n");
00841 _dbus_close (fd, NULL);
00842 return -1;
00843 #endif
00844 }
00845 else
00846 {
00847 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00848 {
00849 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00850 "Socket name too long\n");
00851 _dbus_close (fd, NULL);
00852 return -1;
00853 }
00854
00855 strncpy (addr.sun_path, path, path_len);
00856 }
00857
00858 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00859 {
00860 dbus_set_error (error,
00861 _dbus_error_from_errno (errno),
00862 "Failed to connect to socket %s: %s",
00863 path, _dbus_strerror (errno));
00864
00865 _dbus_close (fd, NULL);
00866 fd = -1;
00867
00868 return -1;
00869 }
00870
00871 if (!_dbus_set_fd_nonblocking (fd, error))
00872 {
00873 _DBUS_ASSERT_ERROR_IS_SET (error);
00874
00875 _dbus_close (fd, NULL);
00876 fd = -1;
00877
00878 return -1;
00879 }
00880
00881 return fd;
00882 }
00883
00893 static dbus_bool_t
00894 _dbus_set_local_creds (int fd, dbus_bool_t on)
00895 {
00896 dbus_bool_t retval = TRUE;
00897
00898 #if defined(HAVE_CMSGCRED)
00899
00900
00901
00902 #elif defined(LOCAL_CREDS)
00903 int val = on ? 1 : 0;
00904 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00905 {
00906 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00907 retval = FALSE;
00908 }
00909 else
00910 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00911 on ? "enabled" : "disabled", fd);
00912 #endif
00913
00914 return retval;
00915 }
00916
00934 int
00935 _dbus_listen_unix_socket (const char *path,
00936 dbus_bool_t abstract,
00937 DBusError *error)
00938 {
00939 int listen_fd;
00940 struct sockaddr_un addr;
00941 size_t path_len;
00942 unsigned int reuseaddr;
00943
00944 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00945
00946 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00947 path, abstract);
00948
00949 if (!_dbus_open_unix_socket (&listen_fd, error))
00950 {
00951 _DBUS_ASSERT_ERROR_IS_SET(error);
00952 return -1;
00953 }
00954 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00955
00956 _DBUS_ZERO (addr);
00957 addr.sun_family = AF_UNIX;
00958 path_len = strlen (path);
00959
00960 if (abstract)
00961 {
00962 #ifdef HAVE_ABSTRACT_SOCKETS
00963
00964
00965
00966 addr.sun_path[0] = '\0';
00967 path_len++;
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[1], path, path_len);
00978
00979 #else
00980 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00981 "Operating system does not support abstract socket namespace\n");
00982 _dbus_close (listen_fd, NULL);
00983 return -1;
00984 #endif
00985 }
00986 else
00987 {
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 {
00999 struct stat sb;
01000
01001 if (stat (path, &sb) == 0 &&
01002 S_ISSOCK (sb.st_mode))
01003 unlink (path);
01004 }
01005
01006 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01007 {
01008 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01009 "Abstract socket name too long\n");
01010 _dbus_close (listen_fd, NULL);
01011 return -1;
01012 }
01013
01014 strncpy (addr.sun_path, path, path_len);
01015 }
01016
01017 reuseaddr = 1;
01018 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01019 {
01020 _dbus_warn ("Failed to set socket option\"%s\": %s",
01021 path, _dbus_strerror (errno));
01022 }
01023
01024 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01025 {
01026 dbus_set_error (error, _dbus_error_from_errno (errno),
01027 "Failed to bind socket \"%s\": %s",
01028 path, _dbus_strerror (errno));
01029 _dbus_close (listen_fd, NULL);
01030 return -1;
01031 }
01032
01033 if (listen (listen_fd, 30 ) < 0)
01034 {
01035 dbus_set_error (error, _dbus_error_from_errno (errno),
01036 "Failed to listen on socket \"%s\": %s",
01037 path, _dbus_strerror (errno));
01038 _dbus_close (listen_fd, NULL);
01039 return -1;
01040 }
01041
01042 if (!_dbus_set_local_creds (listen_fd, TRUE))
01043 {
01044 dbus_set_error (error, _dbus_error_from_errno (errno),
01045 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01046 path, _dbus_strerror (errno));
01047 close (listen_fd);
01048 return -1;
01049 }
01050
01051 if (!_dbus_set_fd_nonblocking (listen_fd, error))
01052 {
01053 _DBUS_ASSERT_ERROR_IS_SET (error);
01054 _dbus_close (listen_fd, NULL);
01055 return -1;
01056 }
01057
01058
01059
01060
01061 if (!abstract && chmod (path, 0777) < 0)
01062 _dbus_warn ("Could not set mode 0777 on socket %s\n",
01063 path);
01064
01065 return listen_fd;
01066 }
01067
01078 int
01079 _dbus_listen_systemd_sockets (int **fds,
01080 DBusError *error)
01081 {
01082 int r, n;
01083 unsigned fd;
01084 int *new_fds;
01085
01086 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01087
01088 n = sd_listen_fds (TRUE);
01089 if (n < 0)
01090 {
01091 dbus_set_error (error, _dbus_error_from_errno (-n),
01092 "Failed to acquire systemd socket: %s",
01093 _dbus_strerror (-n));
01094 return -1;
01095 }
01096
01097 if (n <= 0)
01098 {
01099 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01100 "No socket received.");
01101 return -1;
01102 }
01103
01104 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01105 {
01106 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01107 if (r < 0)
01108 {
01109 dbus_set_error (error, _dbus_error_from_errno (-r),
01110 "Failed to verify systemd socket type: %s",
01111 _dbus_strerror (-r));
01112 return -1;
01113 }
01114
01115 if (!r)
01116 {
01117 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01118 "Passed socket has wrong type.");
01119 return -1;
01120 }
01121 }
01122
01123
01124
01125
01126 new_fds = dbus_new (int, n);
01127 if (!new_fds)
01128 {
01129 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01130 "Failed to allocate file handle array.");
01131 goto fail;
01132 }
01133
01134 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01135 {
01136 if (!_dbus_set_local_creds (fd, TRUE))
01137 {
01138 dbus_set_error (error, _dbus_error_from_errno (errno),
01139 "Failed to enable LOCAL_CREDS on systemd socket: %s",
01140 _dbus_strerror (errno));
01141 goto fail;
01142 }
01143
01144 if (!_dbus_set_fd_nonblocking (fd, error))
01145 {
01146 _DBUS_ASSERT_ERROR_IS_SET (error);
01147 goto fail;
01148 }
01149
01150 new_fds[fd - SD_LISTEN_FDS_START] = fd;
01151 }
01152
01153 *fds = new_fds;
01154 return n;
01155
01156 fail:
01157
01158 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01159 {
01160 _dbus_close (fd, NULL);
01161 }
01162
01163 dbus_free (new_fds);
01164 return -1;
01165 }
01166
01180 int
01181 _dbus_connect_tcp_socket (const char *host,
01182 const char *port,
01183 const char *family,
01184 DBusError *error)
01185 {
01186 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01187 }
01188
01189 int
01190 _dbus_connect_tcp_socket_with_nonce (const char *host,
01191 const char *port,
01192 const char *family,
01193 const char *noncefile,
01194 DBusError *error)
01195 {
01196 int saved_errno = 0;
01197 int fd = -1, res;
01198 struct addrinfo hints;
01199 struct addrinfo *ai, *tmp;
01200
01201 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01202
01203 if (!_dbus_open_tcp_socket (&fd, error))
01204 {
01205 _DBUS_ASSERT_ERROR_IS_SET(error);
01206 return -1;
01207 }
01208
01209 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01210
01211 _DBUS_ZERO (hints);
01212
01213 if (!family)
01214 hints.ai_family = AF_UNSPEC;
01215 else if (!strcmp(family, "ipv4"))
01216 hints.ai_family = AF_INET;
01217 else if (!strcmp(family, "ipv6"))
01218 hints.ai_family = AF_INET6;
01219 else
01220 {
01221 dbus_set_error (error,
01222 DBUS_ERROR_BAD_ADDRESS,
01223 "Unknown address family %s", family);
01224 return -1;
01225 }
01226 hints.ai_protocol = IPPROTO_TCP;
01227 hints.ai_socktype = SOCK_STREAM;
01228 hints.ai_flags = AI_ADDRCONFIG;
01229
01230 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01231 {
01232 dbus_set_error (error,
01233 _dbus_error_from_errno (errno),
01234 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01235 host, port, gai_strerror(res), res);
01236 _dbus_close (fd, NULL);
01237 return -1;
01238 }
01239
01240 tmp = ai;
01241 while (tmp)
01242 {
01243 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01244 {
01245 freeaddrinfo(ai);
01246 _DBUS_ASSERT_ERROR_IS_SET(error);
01247 return -1;
01248 }
01249 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01250
01251 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01252 {
01253 saved_errno = errno;
01254 _dbus_close(fd, NULL);
01255 fd = -1;
01256 tmp = tmp->ai_next;
01257 continue;
01258 }
01259
01260 break;
01261 }
01262 freeaddrinfo(ai);
01263
01264 if (fd == -1)
01265 {
01266 dbus_set_error (error,
01267 _dbus_error_from_errno (saved_errno),
01268 "Failed to connect to socket \"%s:%s\" %s",
01269 host, port, _dbus_strerror(saved_errno));
01270 return -1;
01271 }
01272
01273 if (noncefile != NULL)
01274 {
01275 DBusString noncefileStr;
01276 dbus_bool_t ret;
01277 _dbus_string_init_const (&noncefileStr, noncefile);
01278 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01279 _dbus_string_free (&noncefileStr);
01280
01281 if (!ret)
01282 {
01283 _dbus_close (fd, NULL);
01284 return -1;
01285 }
01286 }
01287
01288 if (!_dbus_set_fd_nonblocking (fd, error))
01289 {
01290 _dbus_close (fd, NULL);
01291 return -1;
01292 }
01293
01294 return fd;
01295 }
01296
01313 int
01314 _dbus_listen_tcp_socket (const char *host,
01315 const char *port,
01316 const char *family,
01317 DBusString *retport,
01318 int **fds_p,
01319 DBusError *error)
01320 {
01321 int saved_errno;
01322 int nlisten_fd = 0, *listen_fd = NULL, res, i;
01323 struct addrinfo hints;
01324 struct addrinfo *ai, *tmp;
01325 unsigned int reuseaddr;
01326
01327 *fds_p = NULL;
01328 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01329
01330 _DBUS_ZERO (hints);
01331
01332 if (!family)
01333 hints.ai_family = AF_UNSPEC;
01334 else if (!strcmp(family, "ipv4"))
01335 hints.ai_family = AF_INET;
01336 else if (!strcmp(family, "ipv6"))
01337 hints.ai_family = AF_INET6;
01338 else
01339 {
01340 dbus_set_error (error,
01341 DBUS_ERROR_BAD_ADDRESS,
01342 "Unknown address family %s", family);
01343 return -1;
01344 }
01345
01346 hints.ai_protocol = IPPROTO_TCP;
01347 hints.ai_socktype = SOCK_STREAM;
01348 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01349
01350 redo_lookup_with_port:
01351 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01352 {
01353 dbus_set_error (error,
01354 _dbus_error_from_errno (errno),
01355 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01356 host ? host : "*", port, gai_strerror(res), res);
01357 return -1;
01358 }
01359
01360 tmp = ai;
01361 while (tmp)
01362 {
01363 int fd = -1, *newlisten_fd;
01364 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01365 {
01366 _DBUS_ASSERT_ERROR_IS_SET(error);
01367 goto failed;
01368 }
01369 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01370
01371 reuseaddr = 1;
01372 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01373 {
01374 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01375 host ? host : "*", port, _dbus_strerror (errno));
01376 }
01377
01378 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01379 {
01380 saved_errno = errno;
01381 _dbus_close(fd, NULL);
01382 if (saved_errno == EADDRINUSE)
01383 {
01384
01385
01386
01387 tmp = tmp->ai_next;
01388 continue;
01389 }
01390 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01391 "Failed to bind socket \"%s:%s\": %s",
01392 host ? host : "*", port, _dbus_strerror (saved_errno));
01393 goto failed;
01394 }
01395
01396 if (listen (fd, 30 ) < 0)
01397 {
01398 saved_errno = errno;
01399 _dbus_close (fd, NULL);
01400 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01401 "Failed to listen on socket \"%s:%s\": %s",
01402 host ? host : "*", port, _dbus_strerror (saved_errno));
01403 goto failed;
01404 }
01405
01406 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01407 if (!newlisten_fd)
01408 {
01409 saved_errno = errno;
01410 _dbus_close (fd, NULL);
01411 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01412 "Failed to allocate file handle array: %s",
01413 _dbus_strerror (saved_errno));
01414 goto failed;
01415 }
01416 listen_fd = newlisten_fd;
01417 listen_fd[nlisten_fd] = fd;
01418 nlisten_fd++;
01419
01420 if (!_dbus_string_get_length(retport))
01421 {
01422
01423
01424
01425
01426 if (!port || !strcmp(port, "0"))
01427 {
01428 struct sockaddr_storage addr;
01429 socklen_t addrlen;
01430 char portbuf[50];
01431
01432 addrlen = sizeof(addr);
01433 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01434
01435 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
01436 portbuf, sizeof(portbuf),
01437 NI_NUMERICHOST)) != 0)
01438 {
01439 dbus_set_error (error, _dbus_error_from_errno (errno),
01440 "Failed to resolve port \"%s:%s\": %s (%s)",
01441 host ? host : "*", port, gai_strerror(res), res);
01442 goto failed;
01443 }
01444 if (!_dbus_string_append(retport, portbuf))
01445 {
01446 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01447 goto failed;
01448 }
01449
01450
01451 port = _dbus_string_get_const_data(retport);
01452 freeaddrinfo(ai);
01453 goto redo_lookup_with_port;
01454 }
01455 else
01456 {
01457 if (!_dbus_string_append(retport, port))
01458 {
01459 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01460 goto failed;
01461 }
01462 }
01463 }
01464
01465 tmp = tmp->ai_next;
01466 }
01467 freeaddrinfo(ai);
01468 ai = NULL;
01469
01470 if (!nlisten_fd)
01471 {
01472 errno = EADDRINUSE;
01473 dbus_set_error (error, _dbus_error_from_errno (errno),
01474 "Failed to bind socket \"%s:%s\": %s",
01475 host ? host : "*", port, _dbus_strerror (errno));
01476 return -1;
01477 }
01478
01479 for (i = 0 ; i < nlisten_fd ; i++)
01480 {
01481 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01482 {
01483 goto failed;
01484 }
01485 }
01486
01487 *fds_p = listen_fd;
01488
01489 return nlisten_fd;
01490
01491 failed:
01492 if (ai)
01493 freeaddrinfo(ai);
01494 for (i = 0 ; i < nlisten_fd ; i++)
01495 _dbus_close(listen_fd[i], NULL);
01496 dbus_free(listen_fd);
01497 return -1;
01498 }
01499
01500 static dbus_bool_t
01501 write_credentials_byte (int server_fd,
01502 DBusError *error)
01503 {
01504 int bytes_written;
01505 char buf[1] = { '\0' };
01506 #if defined(HAVE_CMSGCRED)
01507 union {
01508 struct cmsghdr hdr;
01509 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01510 } cmsg;
01511 struct iovec iov;
01512 struct msghdr msg;
01513 iov.iov_base = buf;
01514 iov.iov_len = 1;
01515
01516 _DBUS_ZERO(msg);
01517 msg.msg_iov = &iov;
01518 msg.msg_iovlen = 1;
01519
01520 msg.msg_control = (caddr_t) &cmsg;
01521 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01522 _DBUS_ZERO(cmsg);
01523 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01524 cmsg.hdr.cmsg_level = SOL_SOCKET;
01525 cmsg.hdr.cmsg_type = SCM_CREDS;
01526 #endif
01527
01528 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01529
01530 again:
01531
01532 #if defined(HAVE_CMSGCRED)
01533 bytes_written = sendmsg (server_fd, &msg, 0
01534 #ifdef HAVE_DECL_MSG_NOSIGNAL
01535 |MSG_NOSIGNAL
01536 #endif
01537 );
01538 #else
01539 bytes_written = send (server_fd, buf, 1, 0
01540 #ifdef HAVE_DECL_MSG_NOSIGNAL
01541 |MSG_NOSIGNAL
01542 #endif
01543 );
01544 #endif
01545
01546 if (bytes_written < 0 && errno == EINTR)
01547 goto again;
01548
01549 if (bytes_written < 0)
01550 {
01551 dbus_set_error (error, _dbus_error_from_errno (errno),
01552 "Failed to write credentials byte: %s",
01553 _dbus_strerror (errno));
01554 return FALSE;
01555 }
01556 else if (bytes_written == 0)
01557 {
01558 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01559 "wrote zero bytes writing credentials byte");
01560 return FALSE;
01561 }
01562 else
01563 {
01564 _dbus_assert (bytes_written == 1);
01565 _dbus_verbose ("wrote credentials byte\n");
01566 return TRUE;
01567 }
01568 }
01569
01591 dbus_bool_t
01592 _dbus_read_credentials_socket (int client_fd,
01593 DBusCredentials *credentials,
01594 DBusError *error)
01595 {
01596 struct msghdr msg;
01597 struct iovec iov;
01598 char buf;
01599 dbus_uid_t uid_read;
01600 dbus_pid_t pid_read;
01601 int bytes_read;
01602
01603 #ifdef HAVE_CMSGCRED
01604 union {
01605 struct cmsghdr hdr;
01606 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01607 } cmsg;
01608
01609 #elif defined(LOCAL_CREDS)
01610 struct {
01611 struct cmsghdr hdr;
01612 struct sockcred cred;
01613 } cmsg;
01614 #endif
01615
01616 uid_read = DBUS_UID_UNSET;
01617 pid_read = DBUS_PID_UNSET;
01618
01619 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01620
01621
01622
01623
01624
01625 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01626 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01627 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01628
01629 _dbus_credentials_clear (credentials);
01630
01631
01632
01633
01634
01635
01636
01637 iov.iov_base = &buf;
01638 iov.iov_len = 1;
01639
01640 _DBUS_ZERO(msg);
01641 msg.msg_iov = &iov;
01642 msg.msg_iovlen = 1;
01643
01644 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01645 _DBUS_ZERO(cmsg);
01646 msg.msg_control = (caddr_t) &cmsg;
01647 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01648 #endif
01649
01650 again:
01651 bytes_read = recvmsg (client_fd, &msg, 0);
01652
01653 if (bytes_read < 0)
01654 {
01655 if (errno == EINTR)
01656 goto again;
01657
01658
01659
01660
01661
01662
01663 dbus_set_error (error, _dbus_error_from_errno (errno),
01664 "Failed to read credentials byte: %s",
01665 _dbus_strerror (errno));
01666 return FALSE;
01667 }
01668 else if (bytes_read == 0)
01669 {
01670
01671
01672
01673 dbus_set_error (error, DBUS_ERROR_FAILED,
01674 "Failed to read credentials byte (zero-length read)");
01675 return FALSE;
01676 }
01677 else if (buf != '\0')
01678 {
01679 dbus_set_error (error, DBUS_ERROR_FAILED,
01680 "Credentials byte was not nul");
01681 return FALSE;
01682 }
01683
01684 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01685 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01686 || cmsg.hdr.cmsg_type != SCM_CREDS)
01687 {
01688 dbus_set_error (error, DBUS_ERROR_FAILED,
01689 "Message from recvmsg() was not SCM_CREDS");
01690 return FALSE;
01691 }
01692 #endif
01693
01694 _dbus_verbose ("read credentials byte\n");
01695
01696 {
01697 #ifdef SO_PEERCRED
01698 struct ucred cr;
01699 int cr_len = sizeof (cr);
01700
01701 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01702 cr_len == sizeof (cr))
01703 {
01704 pid_read = cr.pid;
01705 uid_read = cr.uid;
01706 }
01707 else
01708 {
01709 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01710 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01711 }
01712 #elif defined(HAVE_CMSGCRED)
01713 struct cmsgcred *cred;
01714
01715 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01716 pid_read = cred->cmcred_pid;
01717 uid_read = cred->cmcred_euid;
01718 #elif defined(LOCAL_CREDS)
01719 pid_read = DBUS_PID_UNSET;
01720 uid_read = cmsg.cred.sc_uid;
01721
01722
01723 _dbus_set_local_creds (client_fd, FALSE);
01724 #elif defined(HAVE_GETPEEREID)
01725 uid_t euid;
01726 gid_t egid;
01727 if (getpeereid (client_fd, &euid, &egid) == 0)
01728 {
01729 uid_read = euid;
01730 }
01731 else
01732 {
01733 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01734 }
01735 #elif defined(HAVE_GETPEERUCRED)
01736 ucred_t * ucred = NULL;
01737 if (getpeerucred (client_fd, &ucred) == 0)
01738 {
01739 pid_read = ucred_getpid (ucred);
01740 uid_read = ucred_geteuid (ucred);
01741 #ifdef HAVE_ADT
01742
01743 adt_session_data_t *adth = NULL;
01744 adt_export_data_t *data = NULL;
01745 size_t size = 0;
01746 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01747 {
01748 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01749 }
01750 else
01751 {
01752 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01753 {
01754 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01755 }
01756 else
01757 {
01758 size = adt_export_session_data (adth, &data);
01759 if (size <= 0)
01760 {
01761 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01762 }
01763 else
01764 {
01765 _dbus_credentials_add_adt_audit_data (credentials, data, size);
01766 free (data);
01767 }
01768 }
01769 (void) adt_end_session (adth);
01770 }
01771 #endif
01772 }
01773 else
01774 {
01775 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01776 }
01777 if (ucred != NULL)
01778 ucred_free (ucred);
01779 #else
01780 _dbus_verbose ("Socket credentials not supported on this OS\n");
01781 #endif
01782 }
01783
01784 _dbus_verbose ("Credentials:"
01785 " pid "DBUS_PID_FORMAT
01786 " uid "DBUS_UID_FORMAT
01787 "\n",
01788 pid_read,
01789 uid_read);
01790
01791 if (pid_read != DBUS_PID_UNSET)
01792 {
01793 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01794 {
01795 _DBUS_SET_OOM (error);
01796 return FALSE;
01797 }
01798 }
01799
01800 if (uid_read != DBUS_UID_UNSET)
01801 {
01802 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01803 {
01804 _DBUS_SET_OOM (error);
01805 return FALSE;
01806 }
01807 }
01808
01809 return TRUE;
01810 }
01811
01829 dbus_bool_t
01830 _dbus_send_credentials_socket (int server_fd,
01831 DBusError *error)
01832 {
01833 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01834
01835 if (write_credentials_byte (server_fd, error))
01836 return TRUE;
01837 else
01838 return FALSE;
01839 }
01840
01850 int
01851 _dbus_accept (int listen_fd)
01852 {
01853 int client_fd;
01854 struct sockaddr addr;
01855 socklen_t addrlen;
01856 #ifdef HAVE_ACCEPT4
01857 dbus_bool_t cloexec_done;
01858 #endif
01859
01860 addrlen = sizeof (addr);
01861
01862 retry:
01863
01864 #ifdef HAVE_ACCEPT4
01865
01866 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01867 cloexec_done = client_fd >= 0;
01868
01869 if (client_fd < 0 && errno == ENOSYS)
01870 #endif
01871 {
01872 client_fd = accept (listen_fd, &addr, &addrlen);
01873 }
01874
01875 if (client_fd < 0)
01876 {
01877 if (errno == EINTR)
01878 goto retry;
01879 }
01880
01881 _dbus_verbose ("client fd %d accepted\n", client_fd);
01882
01883 #ifdef HAVE_ACCEPT4
01884 if (!cloexec_done)
01885 #endif
01886 {
01887 _dbus_fd_set_close_on_exec(client_fd);
01888 }
01889
01890 return client_fd;
01891 }
01892
01901 dbus_bool_t
01902 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01903 {
01904 const char *directory;
01905 struct stat sb;
01906
01907 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01908
01909 directory = _dbus_string_get_const_data (dir);
01910
01911 if (stat (directory, &sb) < 0)
01912 {
01913 dbus_set_error (error, _dbus_error_from_errno (errno),
01914 "%s", _dbus_strerror (errno));
01915
01916 return FALSE;
01917 }
01918
01919 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01920 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01921 {
01922 dbus_set_error (error, DBUS_ERROR_FAILED,
01923 "%s directory is not private to the user", directory);
01924 return FALSE;
01925 }
01926
01927 return TRUE;
01928 }
01929
01930 static dbus_bool_t
01931 fill_user_info_from_passwd (struct passwd *p,
01932 DBusUserInfo *info,
01933 DBusError *error)
01934 {
01935 _dbus_assert (p->pw_name != NULL);
01936 _dbus_assert (p->pw_dir != NULL);
01937
01938 info->uid = p->pw_uid;
01939 info->primary_gid = p->pw_gid;
01940 info->username = _dbus_strdup (p->pw_name);
01941 info->homedir = _dbus_strdup (p->pw_dir);
01942
01943 if (info->username == NULL ||
01944 info->homedir == NULL)
01945 {
01946 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01947 return FALSE;
01948 }
01949
01950 return TRUE;
01951 }
01952
01953 static dbus_bool_t
01954 fill_user_info (DBusUserInfo *info,
01955 dbus_uid_t uid,
01956 const DBusString *username,
01957 DBusError *error)
01958 {
01959 const char *username_c;
01960
01961
01962 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01963 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01964
01965 info->uid = DBUS_UID_UNSET;
01966 info->primary_gid = DBUS_GID_UNSET;
01967 info->group_ids = NULL;
01968 info->n_group_ids = 0;
01969 info->username = NULL;
01970 info->homedir = NULL;
01971
01972 if (username != NULL)
01973 username_c = _dbus_string_get_const_data (username);
01974 else
01975 username_c = NULL;
01976
01977
01978
01979
01980
01981
01982 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01983 {
01984 struct passwd *p;
01985 int result;
01986 size_t buflen;
01987 char *buf;
01988 struct passwd p_str;
01989
01990
01991 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01992
01993
01994
01995
01996
01997 if ((long) buflen <= 0)
01998 buflen = 1024;
01999
02000 result = -1;
02001 while (1)
02002 {
02003 buf = dbus_malloc (buflen);
02004 if (buf == NULL)
02005 {
02006 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02007 return FALSE;
02008 }
02009
02010 p = NULL;
02011 #ifdef HAVE_POSIX_GETPWNAM_R
02012 if (uid != DBUS_UID_UNSET)
02013 result = getpwuid_r (uid, &p_str, buf, buflen,
02014 &p);
02015 else
02016 result = getpwnam_r (username_c, &p_str, buf, buflen,
02017 &p);
02018 #else
02019 if (uid != DBUS_UID_UNSET)
02020 p = getpwuid_r (uid, &p_str, buf, buflen);
02021 else
02022 p = getpwnam_r (username_c, &p_str, buf, buflen);
02023 result = 0;
02024 #endif
02025
02026 if (result == ERANGE && buflen < 512 * 1024)
02027 {
02028 dbus_free (buf);
02029 buflen *= 2;
02030 }
02031 else
02032 {
02033 break;
02034 }
02035 }
02036 if (result == 0 && p == &p_str)
02037 {
02038 if (!fill_user_info_from_passwd (p, info, error))
02039 {
02040 dbus_free (buf);
02041 return FALSE;
02042 }
02043 dbus_free (buf);
02044 }
02045 else
02046 {
02047 dbus_set_error (error, _dbus_error_from_errno (errno),
02048 "User \"%s\" unknown or no memory to allocate password entry\n",
02049 username_c ? username_c : "???");
02050 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02051 dbus_free (buf);
02052 return FALSE;
02053 }
02054 }
02055 #else
02056 {
02057
02058 struct passwd *p;
02059
02060 if (uid != DBUS_UID_UNSET)
02061 p = getpwuid (uid);
02062 else
02063 p = getpwnam (username_c);
02064
02065 if (p != NULL)
02066 {
02067 if (!fill_user_info_from_passwd (p, info, error))
02068 {
02069 return FALSE;
02070 }
02071 }
02072 else
02073 {
02074 dbus_set_error (error, _dbus_error_from_errno (errno),
02075 "User \"%s\" unknown or no memory to allocate password entry\n",
02076 username_c ? username_c : "???");
02077 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02078 return FALSE;
02079 }
02080 }
02081 #endif
02082
02083
02084 username_c = info->username;
02085
02086 #ifdef HAVE_GETGROUPLIST
02087 {
02088 gid_t *buf;
02089 int buf_count;
02090 int i;
02091 int initial_buf_count;
02092
02093 initial_buf_count = 17;
02094 buf_count = initial_buf_count;
02095 buf = dbus_new (gid_t, buf_count);
02096 if (buf == NULL)
02097 {
02098 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02099 goto failed;
02100 }
02101
02102 if (getgrouplist (username_c,
02103 info->primary_gid,
02104 buf, &buf_count) < 0)
02105 {
02106 gid_t *new;
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120 if (buf_count == initial_buf_count)
02121 {
02122 buf_count *= 16;
02123 }
02124 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02125 if (new == NULL)
02126 {
02127 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02128 dbus_free (buf);
02129 goto failed;
02130 }
02131
02132 buf = new;
02133
02134 errno = 0;
02135 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02136 {
02137 if (errno == 0)
02138 {
02139 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02140 username_c, buf_count, buf_count);
02141 }
02142 else
02143 {
02144 dbus_set_error (error,
02145 _dbus_error_from_errno (errno),
02146 "Failed to get groups for username \"%s\" primary GID "
02147 DBUS_GID_FORMAT ": %s\n",
02148 username_c, info->primary_gid,
02149 _dbus_strerror (errno));
02150 dbus_free (buf);
02151 goto failed;
02152 }
02153 }
02154 }
02155
02156 info->group_ids = dbus_new (dbus_gid_t, buf_count);
02157 if (info->group_ids == NULL)
02158 {
02159 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02160 dbus_free (buf);
02161 goto failed;
02162 }
02163
02164 for (i = 0; i < buf_count; ++i)
02165 info->group_ids[i] = buf[i];
02166
02167 info->n_group_ids = buf_count;
02168
02169 dbus_free (buf);
02170 }
02171 #else
02172 {
02173
02174 info->group_ids = dbus_new (dbus_gid_t, 1);
02175 if (info->group_ids == NULL)
02176 {
02177 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02178 goto failed;
02179 }
02180
02181 info->n_group_ids = 1;
02182
02183 (info->group_ids)[0] = info->primary_gid;
02184 }
02185 #endif
02186
02187 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02188
02189 return TRUE;
02190
02191 failed:
02192 _DBUS_ASSERT_ERROR_IS_SET (error);
02193 return FALSE;
02194 }
02195
02204 dbus_bool_t
02205 _dbus_user_info_fill (DBusUserInfo *info,
02206 const DBusString *username,
02207 DBusError *error)
02208 {
02209 return fill_user_info (info, DBUS_UID_UNSET,
02210 username, error);
02211 }
02212
02221 dbus_bool_t
02222 _dbus_user_info_fill_uid (DBusUserInfo *info,
02223 dbus_uid_t uid,
02224 DBusError *error)
02225 {
02226 return fill_user_info (info, uid,
02227 NULL, error);
02228 }
02229
02237 dbus_bool_t
02238 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02239 {
02240
02241
02242
02243
02244 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02245 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02246 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02247
02248 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02249 return FALSE;
02250 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02251 return FALSE;
02252
02253 return TRUE;
02254 }
02255
02267 dbus_bool_t
02268 _dbus_append_user_from_current_process (DBusString *str)
02269 {
02270 return _dbus_string_append_uint (str,
02271 _dbus_geteuid ());
02272 }
02273
02278 dbus_pid_t
02279 _dbus_getpid (void)
02280 {
02281 return getpid ();
02282 }
02283
02287 dbus_uid_t
02288 _dbus_getuid (void)
02289 {
02290 return getuid ();
02291 }
02292
02296 dbus_uid_t
02297 _dbus_geteuid (void)
02298 {
02299 return geteuid ();
02300 }
02301
02308 unsigned long
02309 _dbus_pid_for_log (void)
02310 {
02311 return getpid ();
02312 }
02313
02321 dbus_bool_t
02322 _dbus_parse_uid (const DBusString *uid_str,
02323 dbus_uid_t *uid)
02324 {
02325 int end;
02326 long val;
02327
02328 if (_dbus_string_get_length (uid_str) == 0)
02329 {
02330 _dbus_verbose ("UID string was zero length\n");
02331 return FALSE;
02332 }
02333
02334 val = -1;
02335 end = 0;
02336 if (!_dbus_string_parse_int (uid_str, 0, &val,
02337 &end))
02338 {
02339 _dbus_verbose ("could not parse string as a UID\n");
02340 return FALSE;
02341 }
02342
02343 if (end != _dbus_string_get_length (uid_str))
02344 {
02345 _dbus_verbose ("string contained trailing stuff after UID\n");
02346 return FALSE;
02347 }
02348
02349 *uid = val;
02350
02351 return TRUE;
02352 }
02353
02354 #if !DBUS_USE_SYNC
02355 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02356 #endif
02357
02364 dbus_int32_t
02365 _dbus_atomic_inc (DBusAtomic *atomic)
02366 {
02367 #if DBUS_USE_SYNC
02368 return __sync_add_and_fetch(&atomic->value, 1)-1;
02369 #else
02370 dbus_int32_t res;
02371 _DBUS_LOCK (atomic);
02372 res = atomic->value;
02373 atomic->value += 1;
02374 _DBUS_UNLOCK (atomic);
02375 return res;
02376 #endif
02377 }
02378
02385 dbus_int32_t
02386 _dbus_atomic_dec (DBusAtomic *atomic)
02387 {
02388 #if DBUS_USE_SYNC
02389 return __sync_sub_and_fetch(&atomic->value, 1)+1;
02390 #else
02391 dbus_int32_t res;
02392
02393 _DBUS_LOCK (atomic);
02394 res = atomic->value;
02395 atomic->value -= 1;
02396 _DBUS_UNLOCK (atomic);
02397 return res;
02398 #endif
02399 }
02400
02401 #ifdef DBUS_BUILD_TESTS
02402
02405 dbus_gid_t
02406 _dbus_getgid (void)
02407 {
02408 return getgid ();
02409 }
02410 #endif
02411
02420 int
02421 _dbus_poll (DBusPollFD *fds,
02422 int n_fds,
02423 int timeout_milliseconds)
02424 {
02425 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02426
02427
02428
02429
02430 if (_DBUS_POLLIN == POLLIN &&
02431 _DBUS_POLLPRI == POLLPRI &&
02432 _DBUS_POLLOUT == POLLOUT &&
02433 _DBUS_POLLERR == POLLERR &&
02434 _DBUS_POLLHUP == POLLHUP &&
02435 _DBUS_POLLNVAL == POLLNVAL &&
02436 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02437 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02438 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02439 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02440 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02441 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02442 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02443 {
02444 return poll ((struct pollfd*) fds,
02445 n_fds,
02446 timeout_milliseconds);
02447 }
02448 else
02449 {
02450
02451
02452
02453 _dbus_warn ("didn't implement poll() properly for this system yet\n");
02454 return -1;
02455 }
02456 #else
02457
02458 fd_set read_set, write_set, err_set;
02459 int max_fd = 0;
02460 int i;
02461 struct timeval tv;
02462 int ready;
02463
02464 FD_ZERO (&read_set);
02465 FD_ZERO (&write_set);
02466 FD_ZERO (&err_set);
02467
02468 for (i = 0; i < n_fds; i++)
02469 {
02470 DBusPollFD *fdp = &fds[i];
02471
02472 if (fdp->events & _DBUS_POLLIN)
02473 FD_SET (fdp->fd, &read_set);
02474
02475 if (fdp->events & _DBUS_POLLOUT)
02476 FD_SET (fdp->fd, &write_set);
02477
02478 FD_SET (fdp->fd, &err_set);
02479
02480 max_fd = MAX (max_fd, fdp->fd);
02481 }
02482
02483 tv.tv_sec = timeout_milliseconds / 1000;
02484 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02485
02486 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02487 timeout_milliseconds < 0 ? NULL : &tv);
02488
02489 if (ready > 0)
02490 {
02491 for (i = 0; i < n_fds; i++)
02492 {
02493 DBusPollFD *fdp = &fds[i];
02494
02495 fdp->revents = 0;
02496
02497 if (FD_ISSET (fdp->fd, &read_set))
02498 fdp->revents |= _DBUS_POLLIN;
02499
02500 if (FD_ISSET (fdp->fd, &write_set))
02501 fdp->revents |= _DBUS_POLLOUT;
02502
02503 if (FD_ISSET (fdp->fd, &err_set))
02504 fdp->revents |= _DBUS_POLLERR;
02505 }
02506 }
02507
02508 return ready;
02509 #endif
02510 }
02511
02519 void
02520 _dbus_get_current_time (long *tv_sec,
02521 long *tv_usec)
02522 {
02523 struct timeval t;
02524
02525 #ifdef HAVE_MONOTONIC_CLOCK
02526 struct timespec ts;
02527 clock_gettime (CLOCK_MONOTONIC, &ts);
02528
02529 if (tv_sec)
02530 *tv_sec = ts.tv_sec;
02531 if (tv_usec)
02532 *tv_usec = ts.tv_nsec / 1000;
02533 #else
02534 gettimeofday (&t, NULL);
02535
02536 if (tv_sec)
02537 *tv_sec = t.tv_sec;
02538 if (tv_usec)
02539 *tv_usec = t.tv_usec;
02540 #endif
02541 }
02542
02551 dbus_bool_t
02552 _dbus_create_directory (const DBusString *filename,
02553 DBusError *error)
02554 {
02555 const char *filename_c;
02556
02557 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02558
02559 filename_c = _dbus_string_get_const_data (filename);
02560
02561 if (mkdir (filename_c, 0700) < 0)
02562 {
02563 if (errno == EEXIST)
02564 return TRUE;
02565
02566 dbus_set_error (error, DBUS_ERROR_FAILED,
02567 "Failed to create directory %s: %s\n",
02568 filename_c, _dbus_strerror (errno));
02569 return FALSE;
02570 }
02571 else
02572 return TRUE;
02573 }
02574
02585 dbus_bool_t
02586 _dbus_concat_dir_and_file (DBusString *dir,
02587 const DBusString *next_component)
02588 {
02589 dbus_bool_t dir_ends_in_slash;
02590 dbus_bool_t file_starts_with_slash;
02591
02592 if (_dbus_string_get_length (dir) == 0 ||
02593 _dbus_string_get_length (next_component) == 0)
02594 return TRUE;
02595
02596 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02597 _dbus_string_get_length (dir) - 1);
02598
02599 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02600
02601 if (dir_ends_in_slash && file_starts_with_slash)
02602 {
02603 _dbus_string_shorten (dir, 1);
02604 }
02605 else if (!(dir_ends_in_slash || file_starts_with_slash))
02606 {
02607 if (!_dbus_string_append_byte (dir, '/'))
02608 return FALSE;
02609 }
02610
02611 return _dbus_string_copy (next_component, 0, dir,
02612 _dbus_string_get_length (dir));
02613 }
02614
02616 #define NANOSECONDS_PER_SECOND 1000000000
02617
02618 #define MICROSECONDS_PER_SECOND 1000000
02619
02620 #define MILLISECONDS_PER_SECOND 1000
02621
02622 #define NANOSECONDS_PER_MILLISECOND 1000000
02623
02624 #define MICROSECONDS_PER_MILLISECOND 1000
02625
02630 void
02631 _dbus_sleep_milliseconds (int milliseconds)
02632 {
02633 #ifdef HAVE_NANOSLEEP
02634 struct timespec req;
02635 struct timespec rem;
02636
02637 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02638 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02639 rem.tv_sec = 0;
02640 rem.tv_nsec = 0;
02641
02642 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02643 req = rem;
02644 #elif defined (HAVE_USLEEP)
02645 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02646 #else
02647 sleep (MAX (milliseconds / 1000, 1));
02648 #endif
02649 }
02650
02651 static dbus_bool_t
02652 _dbus_generate_pseudorandom_bytes (DBusString *str,
02653 int n_bytes)
02654 {
02655 int old_len;
02656 char *p;
02657
02658 old_len = _dbus_string_get_length (str);
02659
02660 if (!_dbus_string_lengthen (str, n_bytes))
02661 return FALSE;
02662
02663 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02664
02665 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02666
02667 return TRUE;
02668 }
02669
02678 dbus_bool_t
02679 _dbus_generate_random_bytes (DBusString *str,
02680 int n_bytes)
02681 {
02682 int old_len;
02683 int fd;
02684
02685
02686
02687
02688
02689
02690
02691 old_len = _dbus_string_get_length (str);
02692 fd = -1;
02693
02694
02695 fd = open ("/dev/urandom", O_RDONLY);
02696 if (fd < 0)
02697 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02698
02699 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02700
02701 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02702 {
02703 _dbus_close (fd, NULL);
02704 _dbus_string_set_length (str, old_len);
02705 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02706 }
02707
02708 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02709 n_bytes);
02710
02711 _dbus_close (fd, NULL);
02712
02713 return TRUE;
02714 }
02715
02721 void
02722 _dbus_exit (int code)
02723 {
02724 _exit (code);
02725 }
02726
02735 const char*
02736 _dbus_strerror (int error_number)
02737 {
02738 const char *msg;
02739
02740 msg = strerror (error_number);
02741 if (msg == NULL)
02742 msg = "unknown";
02743
02744 return msg;
02745 }
02746
02750 void
02751 _dbus_disable_sigpipe (void)
02752 {
02753 signal (SIGPIPE, SIG_IGN);
02754 }
02755
02763 void
02764 _dbus_fd_set_close_on_exec (intptr_t fd)
02765 {
02766 int val;
02767
02768 val = fcntl (fd, F_GETFD, 0);
02769
02770 if (val < 0)
02771 return;
02772
02773 val |= FD_CLOEXEC;
02774
02775 fcntl (fd, F_SETFD, val);
02776 }
02777
02785 dbus_bool_t
02786 _dbus_close (int fd,
02787 DBusError *error)
02788 {
02789 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02790
02791 again:
02792 if (close (fd) < 0)
02793 {
02794 if (errno == EINTR)
02795 goto again;
02796
02797 dbus_set_error (error, _dbus_error_from_errno (errno),
02798 "Could not close fd %d", fd);
02799 return FALSE;
02800 }
02801
02802 return TRUE;
02803 }
02804
02812 int
02813 _dbus_dup(int fd,
02814 DBusError *error)
02815 {
02816 int new_fd;
02817
02818 #ifdef F_DUPFD_CLOEXEC
02819 dbus_bool_t cloexec_done;
02820
02821 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02822 cloexec_done = new_fd >= 0;
02823
02824 if (new_fd < 0 && errno == EINVAL)
02825 #endif
02826 {
02827 new_fd = fcntl(fd, F_DUPFD, 3);
02828 }
02829
02830 if (new_fd < 0) {
02831
02832 dbus_set_error (error, _dbus_error_from_errno (errno),
02833 "Could not duplicate fd %d", fd);
02834 return -1;
02835 }
02836
02837 #ifdef F_DUPFD_CLOEXEC
02838 if (!cloexec_done)
02839 #endif
02840 {
02841 _dbus_fd_set_close_on_exec(new_fd);
02842 }
02843
02844 return new_fd;
02845 }
02846
02854 dbus_bool_t
02855 _dbus_set_fd_nonblocking (int fd,
02856 DBusError *error)
02857 {
02858 int val;
02859
02860 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02861
02862 val = fcntl (fd, F_GETFL, 0);
02863 if (val < 0)
02864 {
02865 dbus_set_error (error, _dbus_error_from_errno (errno),
02866 "Failed to get flags from file descriptor %d: %s",
02867 fd, _dbus_strerror (errno));
02868 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02869 _dbus_strerror (errno));
02870 return FALSE;
02871 }
02872
02873 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02874 {
02875 dbus_set_error (error, _dbus_error_from_errno (errno),
02876 "Failed to set nonblocking flag of file descriptor %d: %s",
02877 fd, _dbus_strerror (errno));
02878 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02879 fd, _dbus_strerror (errno));
02880
02881 return FALSE;
02882 }
02883
02884 return TRUE;
02885 }
02886
02892 void
02893 _dbus_print_backtrace (void)
02894 {
02895 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02896 void *bt[500];
02897 int bt_size;
02898 int i;
02899 char **syms;
02900
02901 bt_size = backtrace (bt, 500);
02902
02903 syms = backtrace_symbols (bt, bt_size);
02904
02905 i = 0;
02906 while (i < bt_size)
02907 {
02908
02909 fprintf (stderr, " %s\n", syms[i]);
02910 ++i;
02911 }
02912 fflush (stderr);
02913
02914 free (syms);
02915 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02916 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02917 #else
02918 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02919 #endif
02920 }
02921
02939 dbus_bool_t
02940 _dbus_full_duplex_pipe (int *fd1,
02941 int *fd2,
02942 dbus_bool_t blocking,
02943 DBusError *error)
02944 {
02945 #ifdef HAVE_SOCKETPAIR
02946 int fds[2];
02947 int retval;
02948
02949 #ifdef SOCK_CLOEXEC
02950 dbus_bool_t cloexec_done;
02951
02952 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02953 cloexec_done = retval >= 0;
02954
02955 if (retval < 0 && errno == EINVAL)
02956 #endif
02957 {
02958 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02959 }
02960
02961 if (retval < 0)
02962 {
02963 dbus_set_error (error, _dbus_error_from_errno (errno),
02964 "Could not create full-duplex pipe");
02965 return FALSE;
02966 }
02967
02968 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02969
02970 #ifdef SOCK_CLOEXEC
02971 if (!cloexec_done)
02972 #endif
02973 {
02974 _dbus_fd_set_close_on_exec (fds[0]);
02975 _dbus_fd_set_close_on_exec (fds[1]);
02976 }
02977
02978 if (!blocking &&
02979 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02980 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02981 {
02982 dbus_set_error (error, _dbus_error_from_errno (errno),
02983 "Could not set full-duplex pipe nonblocking");
02984
02985 _dbus_close (fds[0], NULL);
02986 _dbus_close (fds[1], NULL);
02987
02988 return FALSE;
02989 }
02990
02991 *fd1 = fds[0];
02992 *fd2 = fds[1];
02993
02994 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02995 *fd1, *fd2);
02996
02997 return TRUE;
02998 #else
02999 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03000 dbus_set_error (error, DBUS_ERROR_FAILED,
03001 "_dbus_full_duplex_pipe() not implemented on this OS");
03002 return FALSE;
03003 #endif
03004 }
03005
03014 int
03015 _dbus_printf_string_upper_bound (const char *format,
03016 va_list args)
03017 {
03018 char static_buf[1024];
03019 int bufsize = sizeof (static_buf);
03020 int len;
03021 va_list args_copy;
03022
03023 DBUS_VA_COPY (args_copy, args);
03024 len = vsnprintf (static_buf, bufsize, format, args_copy);
03025 va_end (args_copy);
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035 if (len == bufsize)
03036 {
03037
03038
03039
03040
03041 DBUS_VA_COPY (args_copy, args);
03042
03043 if (vsnprintf (static_buf, 1, format, args_copy) == 1)
03044 len = -1;
03045
03046 va_end (args_copy);
03047 }
03048
03049
03050
03051 while (len < 0)
03052 {
03053 char *buf;
03054
03055 bufsize *= 2;
03056
03057 buf = dbus_malloc (bufsize);
03058
03059 if (buf == NULL)
03060 return -1;
03061
03062 DBUS_VA_COPY (args_copy, args);
03063 len = vsnprintf (buf, bufsize, format, args_copy);
03064 va_end (args_copy);
03065
03066 dbus_free (buf);
03067
03068
03069
03070
03071 if (len == bufsize)
03072 len = -1;
03073 }
03074
03075 return len;
03076
03077 }
03078
03085 const char*
03086 _dbus_get_tmpdir(void)
03087 {
03088 static const char* tmpdir = NULL;
03089
03090 if (tmpdir == NULL)
03091 {
03092
03093
03094
03095
03096 if (tmpdir == NULL)
03097 tmpdir = getenv("TMPDIR");
03098
03099
03100
03101
03102 if (tmpdir == NULL)
03103 tmpdir = getenv("TMP");
03104 if (tmpdir == NULL)
03105 tmpdir = getenv("TEMP");
03106
03107
03108 if (tmpdir == NULL)
03109 tmpdir = "/tmp";
03110 }
03111
03112 _dbus_assert(tmpdir != NULL);
03113
03114 return tmpdir;
03115 }
03116
03136 static dbus_bool_t
03137 _read_subprocess_line_argv (const char *progpath,
03138 dbus_bool_t path_fallback,
03139 char * const *argv,
03140 DBusString *result,
03141 DBusError *error)
03142 {
03143 int result_pipe[2] = { -1, -1 };
03144 int errors_pipe[2] = { -1, -1 };
03145 pid_t pid;
03146 int ret;
03147 int status;
03148 int orig_len;
03149 int i;
03150
03151 dbus_bool_t retval;
03152 sigset_t new_set, old_set;
03153
03154 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03155 retval = FALSE;
03156
03157
03158
03159
03160
03161 sigemptyset (&new_set);
03162 sigaddset (&new_set, SIGCHLD);
03163 sigprocmask (SIG_BLOCK, &new_set, &old_set);
03164
03165 orig_len = _dbus_string_get_length (result);
03166
03167 #define READ_END 0
03168 #define WRITE_END 1
03169 if (pipe (result_pipe) < 0)
03170 {
03171 dbus_set_error (error, _dbus_error_from_errno (errno),
03172 "Failed to create a pipe to call %s: %s",
03173 progpath, _dbus_strerror (errno));
03174 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03175 progpath, _dbus_strerror (errno));
03176 goto out;
03177 }
03178 if (pipe (errors_pipe) < 0)
03179 {
03180 dbus_set_error (error, _dbus_error_from_errno (errno),
03181 "Failed to create a pipe to call %s: %s",
03182 progpath, _dbus_strerror (errno));
03183 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03184 progpath, _dbus_strerror (errno));
03185 goto out;
03186 }
03187
03188 pid = fork ();
03189 if (pid < 0)
03190 {
03191 dbus_set_error (error, _dbus_error_from_errno (errno),
03192 "Failed to fork() to call %s: %s",
03193 progpath, _dbus_strerror (errno));
03194 _dbus_verbose ("Failed to fork() to call %s: %s\n",
03195 progpath, _dbus_strerror (errno));
03196 goto out;
03197 }
03198
03199 if (pid == 0)
03200 {
03201
03202 int maxfds;
03203 int fd;
03204
03205 fd = open ("/dev/null", O_RDWR);
03206 if (fd == -1)
03207
03208 _exit (1);
03209
03210 _dbus_verbose ("/dev/null fd %d opened\n", fd);
03211
03212
03213 close (result_pipe[READ_END]);
03214 close (errors_pipe[READ_END]);
03215 close (0);
03216 close (1);
03217 close (2);
03218
03219 if (dup2 (fd, 0) == -1)
03220 _exit (1);
03221 if (dup2 (result_pipe[WRITE_END], 1) == -1)
03222 _exit (1);
03223 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03224 _exit (1);
03225
03226 maxfds = sysconf (_SC_OPEN_MAX);
03227
03228
03229
03230 if (maxfds < 0)
03231 maxfds = 1024;
03232
03233 for (i = 3; i < maxfds; i++)
03234 close (i);
03235
03236 sigprocmask (SIG_SETMASK, &old_set, NULL);
03237
03238
03239 if (progpath[0] == '/')
03240 {
03241 execv (progpath, argv);
03242
03243
03244
03245
03246
03247
03248 if (path_fallback)
03249
03250 execvp (strrchr (progpath, '/')+1, argv);
03251 }
03252 else
03253 execvp (progpath, argv);
03254
03255
03256 _exit (1);
03257 }
03258
03259
03260 close (result_pipe[WRITE_END]);
03261 close (errors_pipe[WRITE_END]);
03262 result_pipe[WRITE_END] = -1;
03263 errors_pipe[WRITE_END] = -1;
03264
03265 ret = 0;
03266 do
03267 {
03268 ret = _dbus_read (result_pipe[READ_END], result, 1024);
03269 }
03270 while (ret > 0);
03271
03272
03273 do
03274 {
03275 ret = waitpid (pid, &status, 0);
03276 }
03277 while (ret == -1 && errno == EINTR);
03278
03279
03280
03281 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03282 {
03283
03284 DBusString error_message;
03285 _dbus_string_init (&error_message);
03286 ret = 0;
03287 do
03288 {
03289 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03290 }
03291 while (ret > 0);
03292
03293 _dbus_string_set_length (result, orig_len);
03294 if (_dbus_string_get_length (&error_message) > 0)
03295 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03296 "%s terminated abnormally with the following error: %s",
03297 progpath, _dbus_string_get_data (&error_message));
03298 else
03299 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03300 "%s terminated abnormally without any error message",
03301 progpath);
03302 goto out;
03303 }
03304
03305 retval = TRUE;
03306
03307 out:
03308 sigprocmask (SIG_SETMASK, &old_set, NULL);
03309
03310 if (retval)
03311 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03312 else
03313 _DBUS_ASSERT_ERROR_IS_SET (error);
03314
03315 if (result_pipe[0] != -1)
03316 close (result_pipe[0]);
03317 if (result_pipe[1] != -1)
03318 close (result_pipe[1]);
03319 if (errors_pipe[0] != -1)
03320 close (errors_pipe[0]);
03321 if (errors_pipe[1] != -1)
03322 close (errors_pipe[1]);
03323
03324 return retval;
03325 }
03326
03338 dbus_bool_t
03339 _dbus_get_autolaunch_address (const char *scope,
03340 DBusString *address,
03341 DBusError *error)
03342 {
03343 static char *argv[6];
03344 int i;
03345 DBusString uuid;
03346 dbus_bool_t retval;
03347
03348 if (_dbus_check_setuid ())
03349 {
03350 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03351 "Unable to autolaunch when setuid");
03352 return FALSE;
03353 }
03354
03355 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03356 retval = FALSE;
03357
03358 if (!_dbus_string_init (&uuid))
03359 {
03360 _DBUS_SET_OOM (error);
03361 return FALSE;
03362 }
03363
03364 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03365 {
03366 _DBUS_SET_OOM (error);
03367 goto out;
03368 }
03369
03370 i = 0;
03371 argv[i] = "dbus-launch";
03372 ++i;
03373 argv[i] = "--autolaunch";
03374 ++i;
03375 argv[i] = _dbus_string_get_data (&uuid);
03376 ++i;
03377 argv[i] = "--binary-syntax";
03378 ++i;
03379 argv[i] = "--close-stderr";
03380 ++i;
03381 argv[i] = NULL;
03382 ++i;
03383
03384 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03385
03386 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03387 TRUE,
03388 argv, address, error);
03389
03390 out:
03391 _dbus_string_free (&uuid);
03392 return retval;
03393 }
03394
03413 dbus_bool_t
03414 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
03415 dbus_bool_t create_if_not_found,
03416 DBusError *error)
03417 {
03418 DBusString filename;
03419 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03420 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03421 }
03422
03423 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03424 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03425
03432 dbus_bool_t
03433 _dbus_lookup_launchd_socket (DBusString *socket_path,
03434 const char *launchd_env_var,
03435 DBusError *error)
03436 {
03437 #ifdef DBUS_ENABLE_LAUNCHD
03438 char *argv[4];
03439 int i;
03440
03441 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03442
03443 if (_dbus_check_setuid ())
03444 {
03445 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03446 "Unable to find launchd socket when setuid");
03447 return FALSE;
03448 }
03449
03450 i = 0;
03451 argv[i] = "launchctl";
03452 ++i;
03453 argv[i] = "getenv";
03454 ++i;
03455 argv[i] = (char*)launchd_env_var;
03456 ++i;
03457 argv[i] = NULL;
03458 ++i;
03459
03460 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03461
03462 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03463 {
03464 return FALSE;
03465 }
03466
03467
03468 if (_dbus_string_get_length(socket_path) == 0)
03469 {
03470 return FALSE;
03471 }
03472
03473
03474 _dbus_string_shorten(socket_path, 1);
03475 return TRUE;
03476 #else
03477 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03478 "can't lookup socket from launchd; launchd support not compiled in");
03479 return FALSE;
03480 #endif
03481 }
03482
03483 static dbus_bool_t
03484 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
03485 {
03486 #ifdef DBUS_ENABLE_LAUNCHD
03487 dbus_bool_t valid_socket;
03488 DBusString socket_path;
03489
03490 if (_dbus_check_setuid ())
03491 {
03492 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03493 "Unable to find launchd socket when setuid");
03494 return FALSE;
03495 }
03496
03497 if (!_dbus_string_init (&socket_path))
03498 {
03499 _DBUS_SET_OOM (error);
03500 return FALSE;
03501 }
03502
03503 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03504
03505 if (dbus_error_is_set(error))
03506 {
03507 _dbus_string_free(&socket_path);
03508 return FALSE;
03509 }
03510
03511 if (!valid_socket)
03512 {
03513 dbus_set_error(error, "no socket path",
03514 "launchd did not provide a socket path, "
03515 "verify that org.freedesktop.dbus-session.plist is loaded!");
03516 _dbus_string_free(&socket_path);
03517 return FALSE;
03518 }
03519 if (!_dbus_string_append (address, "unix:path="))
03520 {
03521 _DBUS_SET_OOM (error);
03522 _dbus_string_free(&socket_path);
03523 return FALSE;
03524 }
03525 if (!_dbus_string_copy (&socket_path, 0, address,
03526 _dbus_string_get_length (address)))
03527 {
03528 _DBUS_SET_OOM (error);
03529 _dbus_string_free(&socket_path);
03530 return FALSE;
03531 }
03532
03533 _dbus_string_free(&socket_path);
03534 return TRUE;
03535 #else
03536 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03537 "can't lookup session address from launchd; launchd support not compiled in");
03538 return FALSE;
03539 #endif
03540 }
03541
03561 dbus_bool_t
03562 _dbus_lookup_session_address (dbus_bool_t *supported,
03563 DBusString *address,
03564 DBusError *error)
03565 {
03566 #ifdef DBUS_ENABLE_LAUNCHD
03567 *supported = TRUE;
03568 return _dbus_lookup_session_address_launchd (address, error);
03569 #else
03570
03571
03572
03573
03574 *supported = FALSE;
03575 return TRUE;
03576 #endif
03577 }
03578
03596 dbus_bool_t
03597 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03598 {
03599 const char *xdg_data_home;
03600 const char *xdg_data_dirs;
03601 DBusString servicedir_path;
03602
03603 if (!_dbus_string_init (&servicedir_path))
03604 return FALSE;
03605
03606 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03607 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03608
03609 if (xdg_data_dirs != NULL)
03610 {
03611 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03612 goto oom;
03613
03614 if (!_dbus_string_append (&servicedir_path, ":"))
03615 goto oom;
03616 }
03617 else
03618 {
03619 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03620 goto oom;
03621 }
03622
03623
03624
03625
03626
03627
03628
03629 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03630 goto oom;
03631
03632 if (xdg_data_home != NULL)
03633 {
03634 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03635 goto oom;
03636 }
03637 else
03638 {
03639 const DBusString *homedir;
03640 DBusString local_share;
03641
03642 if (!_dbus_homedir_from_current_process (&homedir))
03643 goto oom;
03644
03645 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03646 goto oom;
03647
03648 _dbus_string_init_const (&local_share, "/.local/share");
03649 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03650 goto oom;
03651 }
03652
03653 if (!_dbus_split_paths_and_append (&servicedir_path,
03654 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03655 dirs))
03656 goto oom;
03657
03658 _dbus_string_free (&servicedir_path);
03659 return TRUE;
03660
03661 oom:
03662 _dbus_string_free (&servicedir_path);
03663 return FALSE;
03664 }
03665
03666
03685 dbus_bool_t
03686 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03687 {
03688 const char *xdg_data_dirs;
03689 DBusString servicedir_path;
03690
03691 if (!_dbus_string_init (&servicedir_path))
03692 return FALSE;
03693
03694 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03695
03696 if (xdg_data_dirs != NULL)
03697 {
03698 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03699 goto oom;
03700
03701 if (!_dbus_string_append (&servicedir_path, ":"))
03702 goto oom;
03703 }
03704 else
03705 {
03706 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03707 goto oom;
03708 }
03709
03710
03711
03712
03713
03714
03715
03716 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03717 goto oom;
03718
03719 if (!_dbus_split_paths_and_append (&servicedir_path,
03720 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03721 dirs))
03722 goto oom;
03723
03724 _dbus_string_free (&servicedir_path);
03725 return TRUE;
03726
03727 oom:
03728 _dbus_string_free (&servicedir_path);
03729 return FALSE;
03730 }
03731
03740 dbus_bool_t
03741 _dbus_append_system_config_file (DBusString *str)
03742 {
03743 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03744 }
03745
03752 dbus_bool_t
03753 _dbus_append_session_config_file (DBusString *str)
03754 {
03755 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03756 }
03757
03765 void
03766 _dbus_flush_caches (void)
03767 {
03768 _dbus_user_database_flush_system ();
03769 }
03770
03784 dbus_bool_t
03785 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03786 DBusCredentials *credentials)
03787 {
03788 DBusString homedir;
03789 DBusString dotdir;
03790 dbus_uid_t uid;
03791
03792 _dbus_assert (credentials != NULL);
03793 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03794
03795 if (!_dbus_string_init (&homedir))
03796 return FALSE;
03797
03798 uid = _dbus_credentials_get_unix_uid (credentials);
03799 _dbus_assert (uid != DBUS_UID_UNSET);
03800
03801 if (!_dbus_homedir_from_uid (uid, &homedir))
03802 goto failed;
03803
03804 #ifdef DBUS_BUILD_TESTS
03805 {
03806 const char *override;
03807
03808 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03809 if (override != NULL && *override != '\0')
03810 {
03811 _dbus_string_set_length (&homedir, 0);
03812 if (!_dbus_string_append (&homedir, override))
03813 goto failed;
03814
03815 _dbus_verbose ("Using fake homedir for testing: %s\n",
03816 _dbus_string_get_const_data (&homedir));
03817 }
03818 else
03819 {
03820 static dbus_bool_t already_warned = FALSE;
03821 if (!already_warned)
03822 {
03823 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03824 already_warned = TRUE;
03825 }
03826 }
03827 }
03828 #endif
03829
03830 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03831 if (!_dbus_concat_dir_and_file (&homedir,
03832 &dotdir))
03833 goto failed;
03834
03835 if (!_dbus_string_copy (&homedir, 0,
03836 directory, _dbus_string_get_length (directory))) {
03837 goto failed;
03838 }
03839
03840 _dbus_string_free (&homedir);
03841 return TRUE;
03842
03843 failed:
03844 _dbus_string_free (&homedir);
03845 return FALSE;
03846 }
03847
03848
03849 dbus_bool_t
03850 _dbus_daemon_publish_session_bus_address (const char* addr,
03851 const char *scope)
03852 {
03853 return TRUE;
03854 }
03855
03856
03857 void
03858 _dbus_daemon_unpublish_session_bus_address (void)
03859 {
03860
03861 }
03862
03869 dbus_bool_t
03870 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03871 {
03872 return errno == EAGAIN || errno == EWOULDBLOCK;
03873 }
03874
03882 dbus_bool_t
03883 _dbus_delete_directory (const DBusString *filename,
03884 DBusError *error)
03885 {
03886 const char *filename_c;
03887
03888 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03889
03890 filename_c = _dbus_string_get_const_data (filename);
03891
03892 if (rmdir (filename_c) != 0)
03893 {
03894 dbus_set_error (error, DBUS_ERROR_FAILED,
03895 "Failed to remove directory %s: %s\n",
03896 filename_c, _dbus_strerror (errno));
03897 return FALSE;
03898 }
03899
03900 return TRUE;
03901 }
03902
03910 dbus_bool_t
03911 _dbus_socket_can_pass_unix_fd(int fd) {
03912
03913 #ifdef SCM_RIGHTS
03914 union {
03915 struct sockaddr sa;
03916 struct sockaddr_storage storage;
03917 struct sockaddr_un un;
03918 } sa_buf;
03919
03920 socklen_t sa_len = sizeof(sa_buf);
03921
03922 _DBUS_ZERO(sa_buf);
03923
03924 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03925 return FALSE;
03926
03927 return sa_buf.sa.sa_family == AF_UNIX;
03928
03929 #else
03930 return FALSE;
03931
03932 #endif
03933 }
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943 const char *
03944 _dbus_replace_install_prefix (const char *configure_time_path)
03945 {
03946 return configure_time_path;
03947 }
03948
03958 dbus_bool_t
03959 _dbus_check_setuid (void)
03960 {
03961
03962
03963
03964 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
03965 {
03966
03967 extern int __libc_enable_secure;
03968 return __libc_enable_secure;
03969 }
03970 #elif defined(HAVE_ISSETUGID)
03971
03972 return issetugid ();
03973 #else
03974 uid_t ruid, euid, suid;
03975 gid_t rgid, egid, sgid;
03976
03977 static dbus_bool_t check_setuid_initialised;
03978 static dbus_bool_t is_setuid;
03979
03980 if (_DBUS_UNLIKELY (!check_setuid_initialised))
03981 {
03982 #ifdef HAVE_GETRESUID
03983 if (getresuid (&ruid, &euid, &suid) != 0 ||
03984 getresgid (&rgid, &egid, &sgid) != 0)
03985 #endif
03986 {
03987 suid = ruid = getuid ();
03988 sgid = rgid = getgid ();
03989 euid = geteuid ();
03990 egid = getegid ();
03991 }
03992
03993 check_setuid_initialised = TRUE;
03994 is_setuid = (ruid != euid || ruid != suid ||
03995 rgid != egid || rgid != sgid);
03996
03997 }
03998 return is_setuid;
03999 #endif
04000 }
04001
04002