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 #ifdef _AIX
00028 #include <alloca.h>
00029 #endif
00030
00031 #include "dbus-internals.h"
00032 #include "dbus-sysdeps.h"
00033 #include "dbus-sysdeps-unix.h"
00034 #include "dbus-threads.h"
00035 #include "dbus-protocol.h"
00036 #include "dbus-transport.h"
00037 #include "dbus-string.h"
00038 #include "dbus-userdb.h"
00039 #include "dbus-list.h"
00040 #include "dbus-credentials.h"
00041 #include "dbus-nonce.h"
00042
00043 #include <sys/types.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <signal.h>
00047 #include <unistd.h>
00048 #include <stdio.h>
00049 #include <fcntl.h>
00050 #include <sys/socket.h>
00051 #include <dirent.h>
00052 #include <sys/un.h>
00053 #include <pwd.h>
00054 #include <time.h>
00055 #include <locale.h>
00056 #include <sys/time.h>
00057 #include <sys/stat.h>
00058 #include <sys/wait.h>
00059 #include <netinet/in.h>
00060 #include <netdb.h>
00061 #include <grp.h>
00062
00063 #ifdef HAVE_ERRNO_H
00064 #include <errno.h>
00065 #endif
00066 #ifdef HAVE_WRITEV
00067 #include <sys/uio.h>
00068 #endif
00069 #ifdef HAVE_POLL
00070 #include <sys/poll.h>
00071 #endif
00072 #ifdef HAVE_BACKTRACE
00073 #include <execinfo.h>
00074 #endif
00075 #ifdef HAVE_GETPEERUCRED
00076 #include <ucred.h>
00077 #endif
00078
00079 #ifdef HAVE_ADT
00080 #include <bsm/adt.h>
00081 #endif
00082
00083 #include "sd-daemon.h"
00084
00085 #ifndef O_BINARY
00086 #define O_BINARY 0
00087 #endif
00088
00089 #ifndef AI_ADDRCONFIG
00090 #define AI_ADDRCONFIG 0
00091 #endif
00092
00093 #ifndef HAVE_SOCKLEN_T
00094 #define socklen_t int
00095 #endif
00096
00097 #if defined (__sun) || defined (__sun__) || (defined(_AIX) && !defined(_LINUX_SOURCE_COMPAT))
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 # ifndef CMSG_ALIGN
00109 # ifdef __sun__
00110 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00111 # else
00112
00113 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00114 ~(sizeof (long) - 1))
00115 # endif
00116 # endif
00117
00118 # ifndef CMSG_SPACE
00119 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00120 CMSG_ALIGN (len))
00121 # endif
00122
00123 # ifndef CMSG_LEN
00124 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00125 # endif
00126
00127 #endif
00128
00129 static dbus_bool_t
00130 _dbus_open_socket (int *fd_p,
00131 int domain,
00132 int type,
00133 int protocol,
00134 DBusError *error)
00135 {
00136 #ifdef SOCK_CLOEXEC
00137 dbus_bool_t cloexec_done;
00138
00139 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00140 cloexec_done = *fd_p >= 0;
00141
00142
00143 if (*fd_p < 0 && errno == EINVAL)
00144 #endif
00145 {
00146 *fd_p = socket (domain, type, protocol);
00147 }
00148
00149 if (*fd_p >= 0)
00150 {
00151 #ifdef SOCK_CLOEXEC
00152 if (!cloexec_done)
00153 #endif
00154 {
00155 _dbus_fd_set_close_on_exec(*fd_p);
00156 }
00157
00158 _dbus_verbose ("socket fd %d opened\n", *fd_p);
00159 return TRUE;
00160 }
00161 else
00162 {
00163 dbus_set_error(error,
00164 _dbus_error_from_errno (errno),
00165 "Failed to open socket: %s",
00166 _dbus_strerror (errno));
00167 return FALSE;
00168 }
00169 }
00170
00181 static dbus_bool_t
00182 _dbus_open_unix_socket (int *fd,
00183 DBusError *error)
00184 {
00185 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00186 }
00187
00196 dbus_bool_t
00197 _dbus_close_socket (int fd,
00198 DBusError *error)
00199 {
00200 return _dbus_close (fd, error);
00201 }
00202
00212 int
00213 _dbus_read_socket (int fd,
00214 DBusString *buffer,
00215 int count)
00216 {
00217 return _dbus_read (fd, buffer, count);
00218 }
00219
00230 int
00231 _dbus_write_socket (int fd,
00232 const DBusString *buffer,
00233 int start,
00234 int len)
00235 {
00236 #if HAVE_DECL_MSG_NOSIGNAL
00237 const char *data;
00238 int bytes_written;
00239
00240 data = _dbus_string_get_const_data_len (buffer, start, len);
00241
00242 again:
00243
00244 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00245
00246 if (bytes_written < 0 && errno == EINTR)
00247 goto again;
00248
00249 return bytes_written;
00250
00251 #else
00252 return _dbus_write (fd, buffer, start, len);
00253 #endif
00254 }
00255
00268 int
00269 _dbus_read_socket_with_unix_fds (int fd,
00270 DBusString *buffer,
00271 int count,
00272 int *fds,
00273 int *n_fds) {
00274 #ifndef HAVE_UNIX_FD_PASSING
00275 int r;
00276
00277 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00278 return r;
00279
00280 *n_fds = 0;
00281 return r;
00282
00283 #else
00284 int bytes_read;
00285 int start;
00286 struct msghdr m;
00287 struct iovec iov;
00288
00289 _dbus_assert (count >= 0);
00290 _dbus_assert (*n_fds >= 0);
00291
00292 start = _dbus_string_get_length (buffer);
00293
00294 if (!_dbus_string_lengthen (buffer, count))
00295 {
00296 errno = ENOMEM;
00297 return -1;
00298 }
00299
00300 _DBUS_ZERO(iov);
00301 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00302 iov.iov_len = count;
00303
00304 _DBUS_ZERO(m);
00305 m.msg_iov = &iov;
00306 m.msg_iovlen = 1;
00307
00308
00309
00310
00311
00312 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00313
00314
00315
00316 m.msg_control = alloca(m.msg_controllen);
00317 memset(m.msg_control, 0, m.msg_controllen);
00318
00319 again:
00320
00321 bytes_read = recvmsg(fd, &m, 0
00322 #ifdef MSG_CMSG_CLOEXEC
00323 |MSG_CMSG_CLOEXEC
00324 #endif
00325 );
00326
00327 if (bytes_read < 0)
00328 {
00329 if (errno == EINTR)
00330 goto again;
00331 else
00332 {
00333
00334 _dbus_string_set_length (buffer, start);
00335 return -1;
00336 }
00337 }
00338 else
00339 {
00340 struct cmsghdr *cm;
00341 dbus_bool_t found = FALSE;
00342
00343 if (m.msg_flags & MSG_CTRUNC)
00344 {
00345
00346
00347
00348
00349
00350 errno = ENOSPC;
00351 _dbus_string_set_length (buffer, start);
00352 return -1;
00353 }
00354
00355 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00356 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00357 {
00358 unsigned i;
00359
00360 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
00361 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
00362
00363 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
00364 found = TRUE;
00365
00366
00367
00368
00369 for (i = 0; i < *n_fds; i++)
00370 _dbus_fd_set_close_on_exec(fds[i]);
00371
00372 break;
00373 }
00374
00375 if (!found)
00376 *n_fds = 0;
00377
00378
00379 _dbus_string_set_length (buffer, start + bytes_read);
00380
00381 #if 0
00382 if (bytes_read > 0)
00383 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00384 #endif
00385
00386 return bytes_read;
00387 }
00388 #endif
00389 }
00390
00391 int
00392 _dbus_write_socket_with_unix_fds(int fd,
00393 const DBusString *buffer,
00394 int start,
00395 int len,
00396 const int *fds,
00397 int n_fds) {
00398
00399 #ifndef HAVE_UNIX_FD_PASSING
00400
00401 if (n_fds > 0) {
00402 errno = ENOTSUP;
00403 return -1;
00404 }
00405
00406 return _dbus_write_socket(fd, buffer, start, len);
00407 #else
00408 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00409 #endif
00410 }
00411
00412 int
00413 _dbus_write_socket_with_unix_fds_two(int fd,
00414 const DBusString *buffer1,
00415 int start1,
00416 int len1,
00417 const DBusString *buffer2,
00418 int start2,
00419 int len2,
00420 const int *fds,
00421 int n_fds) {
00422
00423 #ifndef HAVE_UNIX_FD_PASSING
00424
00425 if (n_fds > 0) {
00426 errno = ENOTSUP;
00427 return -1;
00428 }
00429
00430 return _dbus_write_socket_two(fd,
00431 buffer1, start1, len1,
00432 buffer2, start2, len2);
00433 #else
00434
00435 struct msghdr m;
00436 struct cmsghdr *cm;
00437 struct iovec iov[2];
00438 int bytes_written;
00439
00440 _dbus_assert (len1 >= 0);
00441 _dbus_assert (len2 >= 0);
00442 _dbus_assert (n_fds >= 0);
00443
00444 _DBUS_ZERO(iov);
00445 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00446 iov[0].iov_len = len1;
00447
00448 if (buffer2)
00449 {
00450 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00451 iov[1].iov_len = len2;
00452 }
00453
00454 _DBUS_ZERO(m);
00455 m.msg_iov = iov;
00456 m.msg_iovlen = buffer2 ? 2 : 1;
00457
00458 if (n_fds > 0)
00459 {
00460 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00461 m.msg_control = alloca(m.msg_controllen);
00462 memset(m.msg_control, 0, m.msg_controllen);
00463
00464 cm = CMSG_FIRSTHDR(&m);
00465 cm->cmsg_level = SOL_SOCKET;
00466 cm->cmsg_type = SCM_RIGHTS;
00467 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00468 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00469 }
00470
00471 again:
00472
00473 bytes_written = sendmsg (fd, &m, 0
00474 #if HAVE_DECL_MSG_NOSIGNAL
00475 |MSG_NOSIGNAL
00476 #endif
00477 );
00478
00479 if (bytes_written < 0 && errno == EINTR)
00480 goto again;
00481
00482 #if 0
00483 if (bytes_written > 0)
00484 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00485 #endif
00486
00487 return bytes_written;
00488 #endif
00489 }
00490
00504 int
00505 _dbus_write_socket_two (int fd,
00506 const DBusString *buffer1,
00507 int start1,
00508 int len1,
00509 const DBusString *buffer2,
00510 int start2,
00511 int len2)
00512 {
00513 #if HAVE_DECL_MSG_NOSIGNAL
00514 struct iovec vectors[2];
00515 const char *data1;
00516 const char *data2;
00517 int bytes_written;
00518 struct msghdr m;
00519
00520 _dbus_assert (buffer1 != NULL);
00521 _dbus_assert (start1 >= 0);
00522 _dbus_assert (start2 >= 0);
00523 _dbus_assert (len1 >= 0);
00524 _dbus_assert (len2 >= 0);
00525
00526 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00527
00528 if (buffer2 != NULL)
00529 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00530 else
00531 {
00532 data2 = NULL;
00533 start2 = 0;
00534 len2 = 0;
00535 }
00536
00537 vectors[0].iov_base = (char*) data1;
00538 vectors[0].iov_len = len1;
00539 vectors[1].iov_base = (char*) data2;
00540 vectors[1].iov_len = len2;
00541
00542 _DBUS_ZERO(m);
00543 m.msg_iov = vectors;
00544 m.msg_iovlen = data2 ? 2 : 1;
00545
00546 again:
00547
00548 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00549
00550 if (bytes_written < 0 && errno == EINTR)
00551 goto again;
00552
00553 return bytes_written;
00554
00555 #else
00556 return _dbus_write_two (fd, buffer1, start1, len1,
00557 buffer2, start2, len2);
00558 #endif
00559 }
00560
00561 dbus_bool_t
00562 _dbus_socket_is_invalid (int fd)
00563 {
00564 return fd < 0 ? TRUE : FALSE;
00565 }
00566
00583 int
00584 _dbus_read (int fd,
00585 DBusString *buffer,
00586 int count)
00587 {
00588 int bytes_read;
00589 int start;
00590 char *data;
00591
00592 _dbus_assert (count >= 0);
00593
00594 start = _dbus_string_get_length (buffer);
00595
00596 if (!_dbus_string_lengthen (buffer, count))
00597 {
00598 errno = ENOMEM;
00599 return -1;
00600 }
00601
00602 data = _dbus_string_get_data_len (buffer, start, count);
00603
00604 again:
00605
00606 bytes_read = read (fd, data, count);
00607
00608 if (bytes_read < 0)
00609 {
00610 if (errno == EINTR)
00611 goto again;
00612 else
00613 {
00614
00615 _dbus_string_set_length (buffer, start);
00616 return -1;
00617 }
00618 }
00619 else
00620 {
00621
00622 _dbus_string_set_length (buffer, start + bytes_read);
00623
00624 #if 0
00625 if (bytes_read > 0)
00626 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00627 #endif
00628
00629 return bytes_read;
00630 }
00631 }
00632
00643 int
00644 _dbus_write (int fd,
00645 const DBusString *buffer,
00646 int start,
00647 int len)
00648 {
00649 const char *data;
00650 int bytes_written;
00651
00652 data = _dbus_string_get_const_data_len (buffer, start, len);
00653
00654 again:
00655
00656 bytes_written = write (fd, data, len);
00657
00658 if (bytes_written < 0 && errno == EINTR)
00659 goto again;
00660
00661 #if 0
00662 if (bytes_written > 0)
00663 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00664 #endif
00665
00666 return bytes_written;
00667 }
00668
00689 int
00690 _dbus_write_two (int fd,
00691 const DBusString *buffer1,
00692 int start1,
00693 int len1,
00694 const DBusString *buffer2,
00695 int start2,
00696 int len2)
00697 {
00698 _dbus_assert (buffer1 != NULL);
00699 _dbus_assert (start1 >= 0);
00700 _dbus_assert (start2 >= 0);
00701 _dbus_assert (len1 >= 0);
00702 _dbus_assert (len2 >= 0);
00703
00704 #ifdef HAVE_WRITEV
00705 {
00706 struct iovec vectors[2];
00707 const char *data1;
00708 const char *data2;
00709 int bytes_written;
00710
00711 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00712
00713 if (buffer2 != NULL)
00714 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00715 else
00716 {
00717 data2 = NULL;
00718 start2 = 0;
00719 len2 = 0;
00720 }
00721
00722 vectors[0].iov_base = (char*) data1;
00723 vectors[0].iov_len = len1;
00724 vectors[1].iov_base = (char*) data2;
00725 vectors[1].iov_len = len2;
00726
00727 again:
00728
00729 bytes_written = writev (fd,
00730 vectors,
00731 data2 ? 2 : 1);
00732
00733 if (bytes_written < 0 && errno == EINTR)
00734 goto again;
00735
00736 return bytes_written;
00737 }
00738 #else
00739 {
00740 int ret1;
00741
00742 ret1 = _dbus_write (fd, buffer1, start1, len1);
00743 if (ret1 == len1 && buffer2 != NULL)
00744 {
00745 ret2 = _dbus_write (fd, buffer2, start2, len2);
00746 if (ret2 < 0)
00747 ret2 = 0;
00748
00749 return ret1 + ret2;
00750 }
00751 else
00752 return ret1;
00753 }
00754 #endif
00755 }
00756
00757 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00758
00788 int
00789 _dbus_connect_unix_socket (const char *path,
00790 dbus_bool_t abstract,
00791 DBusError *error)
00792 {
00793 int fd;
00794 size_t path_len;
00795 struct sockaddr_un addr;
00796
00797 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00798
00799 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00800 path, abstract);
00801
00802
00803 if (!_dbus_open_unix_socket (&fd, error))
00804 {
00805 _DBUS_ASSERT_ERROR_IS_SET(error);
00806 return -1;
00807 }
00808 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00809
00810 _DBUS_ZERO (addr);
00811 addr.sun_family = AF_UNIX;
00812 path_len = strlen (path);
00813
00814 if (abstract)
00815 {
00816 #ifdef HAVE_ABSTRACT_SOCKETS
00817 addr.sun_path[0] = '\0';
00818 path_len++;
00819
00820 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00821 {
00822 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00823 "Abstract socket name too long\n");
00824 _dbus_close (fd, NULL);
00825 return -1;
00826 }
00827
00828 strncpy (&addr.sun_path[1], path, path_len);
00829
00830 #else
00831 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00832 "Operating system does not support abstract socket namespace\n");
00833 _dbus_close (fd, NULL);
00834 return -1;
00835 #endif
00836 }
00837 else
00838 {
00839 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00840 {
00841 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00842 "Socket name too long\n");
00843 _dbus_close (fd, NULL);
00844 return -1;
00845 }
00846
00847 strncpy (addr.sun_path, path, path_len);
00848 }
00849
00850 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00851 {
00852 dbus_set_error (error,
00853 _dbus_error_from_errno (errno),
00854 "Failed to connect to socket %s: %s",
00855 path, _dbus_strerror (errno));
00856
00857 _dbus_close (fd, NULL);
00858 return -1;
00859 }
00860
00861 if (!_dbus_set_fd_nonblocking (fd, error))
00862 {
00863 _DBUS_ASSERT_ERROR_IS_SET (error);
00864
00865 _dbus_close (fd, NULL);
00866 return -1;
00867 }
00868
00869 return fd;
00870 }
00871
00884 int
00885 _dbus_connect_exec (const char *path,
00886 char *const argv[],
00887 DBusError *error)
00888 {
00889 int fds[2];
00890 pid_t pid;
00891
00892 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00893
00894 _dbus_verbose ("connecting to process %s\n", path);
00895
00896 if (socketpair (AF_UNIX, SOCK_STREAM
00897 #ifdef SOCK_CLOEXEC
00898 |SOCK_CLOEXEC
00899 #endif
00900 , 0, fds) < 0)
00901 {
00902 dbus_set_error (error,
00903 _dbus_error_from_errno (errno),
00904 "Failed to create socket pair: %s",
00905 _dbus_strerror (errno));
00906 return -1;
00907 }
00908
00909 _dbus_fd_set_close_on_exec (fds[0]);
00910 _dbus_fd_set_close_on_exec (fds[1]);
00911
00912 pid = fork ();
00913 if (pid < 0)
00914 {
00915 dbus_set_error (error,
00916 _dbus_error_from_errno (errno),
00917 "Failed to fork() to call %s: %s",
00918 path, _dbus_strerror (errno));
00919 close (fds[0]);
00920 close (fds[1]);
00921 return -1;
00922 }
00923
00924 if (pid == 0)
00925 {
00926
00927 close (fds[0]);
00928
00929 dup2 (fds[1], STDIN_FILENO);
00930 dup2 (fds[1], STDOUT_FILENO);
00931
00932 if (fds[1] != STDIN_FILENO &&
00933 fds[1] != STDOUT_FILENO)
00934 close (fds[1]);
00935
00936
00937
00938
00939 _dbus_close_all ();
00940
00941 execvp (path, argv);
00942
00943 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
00944
00945 _exit(1);
00946 }
00947
00948
00949 close (fds[1]);
00950
00951 if (!_dbus_set_fd_nonblocking (fds[0], error))
00952 {
00953 _DBUS_ASSERT_ERROR_IS_SET (error);
00954
00955 close (fds[0]);
00956 return -1;
00957 }
00958
00959 return fds[0];
00960 }
00961
00971 static dbus_bool_t
00972 _dbus_set_local_creds (int fd, dbus_bool_t on)
00973 {
00974 dbus_bool_t retval = TRUE;
00975
00976 #if defined(HAVE_CMSGCRED)
00977
00978
00979
00980 #elif defined(LOCAL_CREDS)
00981 int val = on ? 1 : 0;
00982 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00983 {
00984 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00985 retval = FALSE;
00986 }
00987 else
00988 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00989 on ? "enabled" : "disabled", fd);
00990 #endif
00991
00992 return retval;
00993 }
00994
01012 int
01013 _dbus_listen_unix_socket (const char *path,
01014 dbus_bool_t abstract,
01015 DBusError *error)
01016 {
01017 int listen_fd;
01018 struct sockaddr_un addr;
01019 size_t path_len;
01020 unsigned int reuseaddr;
01021
01022 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01023
01024 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
01025 path, abstract);
01026
01027 if (!_dbus_open_unix_socket (&listen_fd, error))
01028 {
01029 _DBUS_ASSERT_ERROR_IS_SET(error);
01030 return -1;
01031 }
01032 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01033
01034 _DBUS_ZERO (addr);
01035 addr.sun_family = AF_UNIX;
01036 path_len = strlen (path);
01037
01038 if (abstract)
01039 {
01040 #ifdef HAVE_ABSTRACT_SOCKETS
01041
01042
01043
01044 addr.sun_path[0] = '\0';
01045 path_len++;
01046
01047 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01048 {
01049 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01050 "Abstract socket name too long\n");
01051 _dbus_close (listen_fd, NULL);
01052 return -1;
01053 }
01054
01055 strncpy (&addr.sun_path[1], path, path_len);
01056
01057 #else
01058 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
01059 "Operating system does not support abstract socket namespace\n");
01060 _dbus_close (listen_fd, NULL);
01061 return -1;
01062 #endif
01063 }
01064 else
01065 {
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 {
01077 struct stat sb;
01078
01079 if (stat (path, &sb) == 0 &&
01080 S_ISSOCK (sb.st_mode))
01081 unlink (path);
01082 }
01083
01084 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01085 {
01086 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01087 "Abstract socket name too long\n");
01088 _dbus_close (listen_fd, NULL);
01089 return -1;
01090 }
01091
01092 strncpy (addr.sun_path, path, path_len);
01093 }
01094
01095 reuseaddr = 1;
01096 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01097 {
01098 _dbus_warn ("Failed to set socket option\"%s\": %s",
01099 path, _dbus_strerror (errno));
01100 }
01101
01102 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01103 {
01104 dbus_set_error (error, _dbus_error_from_errno (errno),
01105 "Failed to bind socket \"%s\": %s",
01106 path, _dbus_strerror (errno));
01107 _dbus_close (listen_fd, NULL);
01108 return -1;
01109 }
01110
01111 if (listen (listen_fd, 30 ) < 0)
01112 {
01113 dbus_set_error (error, _dbus_error_from_errno (errno),
01114 "Failed to listen on socket \"%s\": %s",
01115 path, _dbus_strerror (errno));
01116 _dbus_close (listen_fd, NULL);
01117 return -1;
01118 }
01119
01120 if (!_dbus_set_local_creds (listen_fd, TRUE))
01121 {
01122 dbus_set_error (error, _dbus_error_from_errno (errno),
01123 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01124 path, _dbus_strerror (errno));
01125 close (listen_fd);
01126 return -1;
01127 }
01128
01129 if (!_dbus_set_fd_nonblocking (listen_fd, error))
01130 {
01131 _DBUS_ASSERT_ERROR_IS_SET (error);
01132 _dbus_close (listen_fd, NULL);
01133 return -1;
01134 }
01135
01136
01137
01138
01139 if (!abstract && chmod (path, 0777) < 0)
01140 _dbus_warn ("Could not set mode 0777 on socket %s\n",
01141 path);
01142
01143 return listen_fd;
01144 }
01145
01156 int
01157 _dbus_listen_systemd_sockets (int **fds,
01158 DBusError *error)
01159 {
01160 int r, n;
01161 unsigned fd;
01162 int *new_fds;
01163
01164 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01165
01166 n = sd_listen_fds (TRUE);
01167 if (n < 0)
01168 {
01169 dbus_set_error (error, _dbus_error_from_errno (-n),
01170 "Failed to acquire systemd socket: %s",
01171 _dbus_strerror (-n));
01172 return -1;
01173 }
01174
01175 if (n <= 0)
01176 {
01177 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01178 "No socket received.");
01179 return -1;
01180 }
01181
01182 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01183 {
01184 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01185 if (r < 0)
01186 {
01187 dbus_set_error (error, _dbus_error_from_errno (-r),
01188 "Failed to verify systemd socket type: %s",
01189 _dbus_strerror (-r));
01190 return -1;
01191 }
01192
01193 if (!r)
01194 {
01195 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01196 "Passed socket has wrong type.");
01197 return -1;
01198 }
01199 }
01200
01201
01202
01203
01204 new_fds = dbus_new (int, n);
01205 if (!new_fds)
01206 {
01207 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01208 "Failed to allocate file handle array.");
01209 goto fail;
01210 }
01211
01212 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01213 {
01214 if (!_dbus_set_local_creds (fd, TRUE))
01215 {
01216 dbus_set_error (error, _dbus_error_from_errno (errno),
01217 "Failed to enable LOCAL_CREDS on systemd socket: %s",
01218 _dbus_strerror (errno));
01219 goto fail;
01220 }
01221
01222 if (!_dbus_set_fd_nonblocking (fd, error))
01223 {
01224 _DBUS_ASSERT_ERROR_IS_SET (error);
01225 goto fail;
01226 }
01227
01228 new_fds[fd - SD_LISTEN_FDS_START] = fd;
01229 }
01230
01231 *fds = new_fds;
01232 return n;
01233
01234 fail:
01235
01236 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01237 {
01238 _dbus_close (fd, NULL);
01239 }
01240
01241 dbus_free (new_fds);
01242 return -1;
01243 }
01244
01258 int
01259 _dbus_connect_tcp_socket (const char *host,
01260 const char *port,
01261 const char *family,
01262 DBusError *error)
01263 {
01264 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01265 }
01266
01267 int
01268 _dbus_connect_tcp_socket_with_nonce (const char *host,
01269 const char *port,
01270 const char *family,
01271 const char *noncefile,
01272 DBusError *error)
01273 {
01274 int saved_errno = 0;
01275 int fd = -1, res;
01276 struct addrinfo hints;
01277 struct addrinfo *ai, *tmp;
01278
01279 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01280
01281 _DBUS_ZERO (hints);
01282
01283 if (!family)
01284 hints.ai_family = AF_UNSPEC;
01285 else if (!strcmp(family, "ipv4"))
01286 hints.ai_family = AF_INET;
01287 else if (!strcmp(family, "ipv6"))
01288 hints.ai_family = AF_INET6;
01289 else
01290 {
01291 dbus_set_error (error,
01292 DBUS_ERROR_BAD_ADDRESS,
01293 "Unknown address family %s", family);
01294 return -1;
01295 }
01296 hints.ai_protocol = IPPROTO_TCP;
01297 hints.ai_socktype = SOCK_STREAM;
01298 hints.ai_flags = AI_ADDRCONFIG;
01299
01300 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01301 {
01302 dbus_set_error (error,
01303 _dbus_error_from_errno (errno),
01304 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01305 host, port, gai_strerror(res), res);
01306 return -1;
01307 }
01308
01309 tmp = ai;
01310 while (tmp)
01311 {
01312 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01313 {
01314 freeaddrinfo(ai);
01315 _DBUS_ASSERT_ERROR_IS_SET(error);
01316 return -1;
01317 }
01318 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01319
01320 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01321 {
01322 saved_errno = errno;
01323 _dbus_close(fd, NULL);
01324 fd = -1;
01325 tmp = tmp->ai_next;
01326 continue;
01327 }
01328
01329 break;
01330 }
01331 freeaddrinfo(ai);
01332
01333 if (fd == -1)
01334 {
01335 dbus_set_error (error,
01336 _dbus_error_from_errno (saved_errno),
01337 "Failed to connect to socket \"%s:%s\" %s",
01338 host, port, _dbus_strerror(saved_errno));
01339 return -1;
01340 }
01341
01342 if (noncefile != NULL)
01343 {
01344 DBusString noncefileStr;
01345 dbus_bool_t ret;
01346 _dbus_string_init_const (&noncefileStr, noncefile);
01347 ret = _dbus_send_nonce (fd, &noncefileStr, error);
01348 _dbus_string_free (&noncefileStr);
01349
01350 if (!ret)
01351 {
01352 _dbus_close (fd, NULL);
01353 return -1;
01354 }
01355 }
01356
01357 if (!_dbus_set_fd_nonblocking (fd, error))
01358 {
01359 _dbus_close (fd, NULL);
01360 return -1;
01361 }
01362
01363 return fd;
01364 }
01365
01382 int
01383 _dbus_listen_tcp_socket (const char *host,
01384 const char *port,
01385 const char *family,
01386 DBusString *retport,
01387 int **fds_p,
01388 DBusError *error)
01389 {
01390 int saved_errno;
01391 int nlisten_fd = 0, *listen_fd = NULL, res, i;
01392 struct addrinfo hints;
01393 struct addrinfo *ai, *tmp;
01394 unsigned int reuseaddr;
01395
01396 *fds_p = NULL;
01397 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01398
01399 _DBUS_ZERO (hints);
01400
01401 if (!family)
01402 hints.ai_family = AF_UNSPEC;
01403 else if (!strcmp(family, "ipv4"))
01404 hints.ai_family = AF_INET;
01405 else if (!strcmp(family, "ipv6"))
01406 hints.ai_family = AF_INET6;
01407 else
01408 {
01409 dbus_set_error (error,
01410 DBUS_ERROR_BAD_ADDRESS,
01411 "Unknown address family %s", family);
01412 return -1;
01413 }
01414
01415 hints.ai_protocol = IPPROTO_TCP;
01416 hints.ai_socktype = SOCK_STREAM;
01417 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01418
01419 redo_lookup_with_port:
01420 ai = NULL;
01421 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01422 {
01423 dbus_set_error (error,
01424 _dbus_error_from_errno (errno),
01425 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01426 host ? host : "*", port, gai_strerror(res), res);
01427 goto failed;
01428 }
01429
01430 tmp = ai;
01431 while (tmp)
01432 {
01433 int fd = -1, *newlisten_fd;
01434 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01435 {
01436 _DBUS_ASSERT_ERROR_IS_SET(error);
01437 goto failed;
01438 }
01439 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01440
01441 reuseaddr = 1;
01442 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01443 {
01444 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01445 host ? host : "*", port, _dbus_strerror (errno));
01446 }
01447
01448 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01449 {
01450 saved_errno = errno;
01451 _dbus_close(fd, NULL);
01452 if (saved_errno == EADDRINUSE)
01453 {
01454
01455
01456
01457 tmp = tmp->ai_next;
01458 continue;
01459 }
01460 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01461 "Failed to bind socket \"%s:%s\": %s",
01462 host ? host : "*", port, _dbus_strerror (saved_errno));
01463 goto failed;
01464 }
01465
01466 if (listen (fd, 30 ) < 0)
01467 {
01468 saved_errno = errno;
01469 _dbus_close (fd, NULL);
01470 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01471 "Failed to listen on socket \"%s:%s\": %s",
01472 host ? host : "*", port, _dbus_strerror (saved_errno));
01473 goto failed;
01474 }
01475
01476 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01477 if (!newlisten_fd)
01478 {
01479 saved_errno = errno;
01480 _dbus_close (fd, NULL);
01481 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01482 "Failed to allocate file handle array: %s",
01483 _dbus_strerror (saved_errno));
01484 goto failed;
01485 }
01486 listen_fd = newlisten_fd;
01487 listen_fd[nlisten_fd] = fd;
01488 nlisten_fd++;
01489
01490 if (!_dbus_string_get_length(retport))
01491 {
01492
01493
01494
01495
01496 if (!port || !strcmp(port, "0"))
01497 {
01498 int result;
01499 struct sockaddr_storage addr;
01500 socklen_t addrlen;
01501 char portbuf[50];
01502
01503 addrlen = sizeof(addr);
01504 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01505
01506 if (result == -1 ||
01507 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01508 portbuf, sizeof(portbuf),
01509 NI_NUMERICHOST)) != 0)
01510 {
01511 dbus_set_error (error, _dbus_error_from_errno (errno),
01512 "Failed to resolve port \"%s:%s\": %s (%s)",
01513 host ? host : "*", port, gai_strerror(res), res);
01514 goto failed;
01515 }
01516 if (!_dbus_string_append(retport, portbuf))
01517 {
01518 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01519 goto failed;
01520 }
01521
01522
01523 port = _dbus_string_get_const_data(retport);
01524 freeaddrinfo(ai);
01525 goto redo_lookup_with_port;
01526 }
01527 else
01528 {
01529 if (!_dbus_string_append(retport, port))
01530 {
01531 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01532 goto failed;
01533 }
01534 }
01535 }
01536
01537 tmp = tmp->ai_next;
01538 }
01539 freeaddrinfo(ai);
01540 ai = NULL;
01541
01542 if (!nlisten_fd)
01543 {
01544 errno = EADDRINUSE;
01545 dbus_set_error (error, _dbus_error_from_errno (errno),
01546 "Failed to bind socket \"%s:%s\": %s",
01547 host ? host : "*", port, _dbus_strerror (errno));
01548 goto failed;
01549 }
01550
01551 for (i = 0 ; i < nlisten_fd ; i++)
01552 {
01553 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01554 {
01555 goto failed;
01556 }
01557 }
01558
01559 *fds_p = listen_fd;
01560
01561 return nlisten_fd;
01562
01563 failed:
01564 if (ai)
01565 freeaddrinfo(ai);
01566 for (i = 0 ; i < nlisten_fd ; i++)
01567 _dbus_close(listen_fd[i], NULL);
01568 dbus_free(listen_fd);
01569 return -1;
01570 }
01571
01572 static dbus_bool_t
01573 write_credentials_byte (int server_fd,
01574 DBusError *error)
01575 {
01576 int bytes_written;
01577 char buf[1] = { '\0' };
01578 #if defined(HAVE_CMSGCRED)
01579 union {
01580 struct cmsghdr hdr;
01581 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01582 } cmsg;
01583 struct iovec iov;
01584 struct msghdr msg;
01585 iov.iov_base = buf;
01586 iov.iov_len = 1;
01587
01588 _DBUS_ZERO(msg);
01589 msg.msg_iov = &iov;
01590 msg.msg_iovlen = 1;
01591
01592 msg.msg_control = (caddr_t) &cmsg;
01593 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01594 _DBUS_ZERO(cmsg);
01595 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01596 cmsg.hdr.cmsg_level = SOL_SOCKET;
01597 cmsg.hdr.cmsg_type = SCM_CREDS;
01598 #endif
01599
01600 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01601
01602 again:
01603
01604 #if defined(HAVE_CMSGCRED)
01605 bytes_written = sendmsg (server_fd, &msg, 0
01606 #if HAVE_DECL_MSG_NOSIGNAL
01607 |MSG_NOSIGNAL
01608 #endif
01609 );
01610 #else
01611 bytes_written = send (server_fd, buf, 1, 0
01612 #if HAVE_DECL_MSG_NOSIGNAL
01613 |MSG_NOSIGNAL
01614 #endif
01615 );
01616 #endif
01617
01618 if (bytes_written < 0 && errno == EINTR)
01619 goto again;
01620
01621 if (bytes_written < 0)
01622 {
01623 dbus_set_error (error, _dbus_error_from_errno (errno),
01624 "Failed to write credentials byte: %s",
01625 _dbus_strerror (errno));
01626 return FALSE;
01627 }
01628 else if (bytes_written == 0)
01629 {
01630 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01631 "wrote zero bytes writing credentials byte");
01632 return FALSE;
01633 }
01634 else
01635 {
01636 _dbus_assert (bytes_written == 1);
01637 _dbus_verbose ("wrote credentials byte\n");
01638 return TRUE;
01639 }
01640 }
01641
01663 dbus_bool_t
01664 _dbus_read_credentials_socket (int client_fd,
01665 DBusCredentials *credentials,
01666 DBusError *error)
01667 {
01668 struct msghdr msg;
01669 struct iovec iov;
01670 char buf;
01671 dbus_uid_t uid_read;
01672 dbus_pid_t pid_read;
01673 int bytes_read;
01674
01675 #ifdef HAVE_CMSGCRED
01676 union {
01677 struct cmsghdr hdr;
01678 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01679 } cmsg;
01680
01681 #elif defined(LOCAL_CREDS)
01682 struct {
01683 struct cmsghdr hdr;
01684 struct sockcred cred;
01685 } cmsg;
01686 #endif
01687
01688 uid_read = DBUS_UID_UNSET;
01689 pid_read = DBUS_PID_UNSET;
01690
01691 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01692
01693
01694
01695
01696
01697 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01698 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01699 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01700
01701 _dbus_credentials_clear (credentials);
01702
01703
01704
01705
01706
01707
01708
01709 iov.iov_base = &buf;
01710 iov.iov_len = 1;
01711
01712 _DBUS_ZERO(msg);
01713 msg.msg_iov = &iov;
01714 msg.msg_iovlen = 1;
01715
01716 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01717 _DBUS_ZERO(cmsg);
01718 msg.msg_control = (caddr_t) &cmsg;
01719 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01720 #endif
01721
01722 again:
01723 bytes_read = recvmsg (client_fd, &msg, 0);
01724
01725 if (bytes_read < 0)
01726 {
01727 if (errno == EINTR)
01728 goto again;
01729
01730
01731
01732
01733
01734
01735 dbus_set_error (error, _dbus_error_from_errno (errno),
01736 "Failed to read credentials byte: %s",
01737 _dbus_strerror (errno));
01738 return FALSE;
01739 }
01740 else if (bytes_read == 0)
01741 {
01742
01743
01744
01745 dbus_set_error (error, DBUS_ERROR_FAILED,
01746 "Failed to read credentials byte (zero-length read)");
01747 return FALSE;
01748 }
01749 else if (buf != '\0')
01750 {
01751 dbus_set_error (error, DBUS_ERROR_FAILED,
01752 "Credentials byte was not nul");
01753 return FALSE;
01754 }
01755
01756 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01757 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01758 || cmsg.hdr.cmsg_type != SCM_CREDS)
01759 {
01760 dbus_set_error (error, DBUS_ERROR_FAILED,
01761 "Message from recvmsg() was not SCM_CREDS");
01762 return FALSE;
01763 }
01764 #endif
01765
01766 _dbus_verbose ("read credentials byte\n");
01767
01768 {
01769 #ifdef SO_PEERCRED
01770 #ifdef __OpenBSD__
01771 struct sockpeercred cr;
01772 #else
01773 struct ucred cr;
01774 #endif
01775 int cr_len = sizeof (cr);
01776
01777 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01778 cr_len == sizeof (cr))
01779 {
01780 pid_read = cr.pid;
01781 uid_read = cr.uid;
01782 }
01783 else
01784 {
01785 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01786 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01787 }
01788 #elif defined(HAVE_CMSGCRED)
01789 struct cmsgcred *cred;
01790
01791 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01792 pid_read = cred->cmcred_pid;
01793 uid_read = cred->cmcred_euid;
01794 #elif defined(LOCAL_CREDS)
01795 pid_read = DBUS_PID_UNSET;
01796 uid_read = cmsg.cred.sc_uid;
01797
01798
01799 _dbus_set_local_creds (client_fd, FALSE);
01800 #elif defined(HAVE_GETPEEREID)
01801 uid_t euid;
01802 gid_t egid;
01803 if (getpeereid (client_fd, &euid, &egid) == 0)
01804 {
01805 uid_read = euid;
01806 }
01807 else
01808 {
01809 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01810 }
01811 #elif defined(HAVE_GETPEERUCRED)
01812 ucred_t * ucred = NULL;
01813 if (getpeerucred (client_fd, &ucred) == 0)
01814 {
01815 pid_read = ucred_getpid (ucred);
01816 uid_read = ucred_geteuid (ucred);
01817 #ifdef HAVE_ADT
01818
01819 adt_session_data_t *adth = NULL;
01820 adt_export_data_t *data = NULL;
01821 size_t size = 0;
01822 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01823 {
01824 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01825 }
01826 else
01827 {
01828 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01829 {
01830 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01831 }
01832 else
01833 {
01834 size = adt_export_session_data (adth, &data);
01835 if (size <= 0)
01836 {
01837 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01838 }
01839 else
01840 {
01841 _dbus_credentials_add_adt_audit_data (credentials, data, size);
01842 free (data);
01843 }
01844 }
01845 (void) adt_end_session (adth);
01846 }
01847 #endif
01848 }
01849 else
01850 {
01851 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01852 }
01853 if (ucred != NULL)
01854 ucred_free (ucred);
01855 #else
01856 _dbus_verbose ("Socket credentials not supported on this OS\n");
01857 #endif
01858 }
01859
01860 _dbus_verbose ("Credentials:"
01861 " pid "DBUS_PID_FORMAT
01862 " uid "DBUS_UID_FORMAT
01863 "\n",
01864 pid_read,
01865 uid_read);
01866
01867 if (pid_read != DBUS_PID_UNSET)
01868 {
01869 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01870 {
01871 _DBUS_SET_OOM (error);
01872 return FALSE;
01873 }
01874 }
01875
01876 if (uid_read != DBUS_UID_UNSET)
01877 {
01878 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01879 {
01880 _DBUS_SET_OOM (error);
01881 return FALSE;
01882 }
01883 }
01884
01885 return TRUE;
01886 }
01887
01905 dbus_bool_t
01906 _dbus_send_credentials_socket (int server_fd,
01907 DBusError *error)
01908 {
01909 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01910
01911 if (write_credentials_byte (server_fd, error))
01912 return TRUE;
01913 else
01914 return FALSE;
01915 }
01916
01926 int
01927 _dbus_accept (int listen_fd)
01928 {
01929 int client_fd;
01930 struct sockaddr addr;
01931 socklen_t addrlen;
01932 #ifdef HAVE_ACCEPT4
01933 dbus_bool_t cloexec_done;
01934 #endif
01935
01936 addrlen = sizeof (addr);
01937
01938 retry:
01939
01940 #ifdef HAVE_ACCEPT4
01941
01942 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01943 cloexec_done = client_fd >= 0;
01944
01945 if (client_fd < 0 && errno == ENOSYS)
01946 #endif
01947 {
01948 client_fd = accept (listen_fd, &addr, &addrlen);
01949 }
01950
01951 if (client_fd < 0)
01952 {
01953 if (errno == EINTR)
01954 goto retry;
01955 }
01956
01957 _dbus_verbose ("client fd %d accepted\n", client_fd);
01958
01959 #ifdef HAVE_ACCEPT4
01960 if (!cloexec_done)
01961 #endif
01962 {
01963 _dbus_fd_set_close_on_exec(client_fd);
01964 }
01965
01966 return client_fd;
01967 }
01968
01977 dbus_bool_t
01978 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01979 {
01980 const char *directory;
01981 struct stat sb;
01982
01983 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01984
01985 directory = _dbus_string_get_const_data (dir);
01986
01987 if (stat (directory, &sb) < 0)
01988 {
01989 dbus_set_error (error, _dbus_error_from_errno (errno),
01990 "%s", _dbus_strerror (errno));
01991
01992 return FALSE;
01993 }
01994
01995 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01996 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01997 {
01998 dbus_set_error (error, DBUS_ERROR_FAILED,
01999 "%s directory is not private to the user", directory);
02000 return FALSE;
02001 }
02002
02003 return TRUE;
02004 }
02005
02006 static dbus_bool_t
02007 fill_user_info_from_passwd (struct passwd *p,
02008 DBusUserInfo *info,
02009 DBusError *error)
02010 {
02011 _dbus_assert (p->pw_name != NULL);
02012 _dbus_assert (p->pw_dir != NULL);
02013
02014 info->uid = p->pw_uid;
02015 info->primary_gid = p->pw_gid;
02016 info->username = _dbus_strdup (p->pw_name);
02017 info->homedir = _dbus_strdup (p->pw_dir);
02018
02019 if (info->username == NULL ||
02020 info->homedir == NULL)
02021 {
02022 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02023 return FALSE;
02024 }
02025
02026 return TRUE;
02027 }
02028
02029 static dbus_bool_t
02030 fill_user_info (DBusUserInfo *info,
02031 dbus_uid_t uid,
02032 const DBusString *username,
02033 DBusError *error)
02034 {
02035 const char *username_c;
02036
02037
02038 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
02039 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
02040
02041 info->uid = DBUS_UID_UNSET;
02042 info->primary_gid = DBUS_GID_UNSET;
02043 info->group_ids = NULL;
02044 info->n_group_ids = 0;
02045 info->username = NULL;
02046 info->homedir = NULL;
02047
02048 if (username != NULL)
02049 username_c = _dbus_string_get_const_data (username);
02050 else
02051 username_c = NULL;
02052
02053
02054
02055
02056
02057
02058 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
02059 {
02060 struct passwd *p;
02061 int result;
02062 size_t buflen;
02063 char *buf;
02064 struct passwd p_str;
02065
02066
02067 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
02068
02069
02070
02071
02072
02073 if ((long) buflen <= 0)
02074 buflen = 1024;
02075
02076 result = -1;
02077 while (1)
02078 {
02079 buf = dbus_malloc (buflen);
02080 if (buf == NULL)
02081 {
02082 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02083 return FALSE;
02084 }
02085
02086 p = NULL;
02087 #ifdef HAVE_POSIX_GETPWNAM_R
02088 if (uid != DBUS_UID_UNSET)
02089 result = getpwuid_r (uid, &p_str, buf, buflen,
02090 &p);
02091 else
02092 result = getpwnam_r (username_c, &p_str, buf, buflen,
02093 &p);
02094 #else
02095 if (uid != DBUS_UID_UNSET)
02096 p = getpwuid_r (uid, &p_str, buf, buflen);
02097 else
02098 p = getpwnam_r (username_c, &p_str, buf, buflen);
02099 result = 0;
02100 #endif
02101
02102 if (result == ERANGE && buflen < 512 * 1024)
02103 {
02104 dbus_free (buf);
02105 buflen *= 2;
02106 }
02107 else
02108 {
02109 break;
02110 }
02111 }
02112 if (result == 0 && p == &p_str)
02113 {
02114 if (!fill_user_info_from_passwd (p, info, error))
02115 {
02116 dbus_free (buf);
02117 return FALSE;
02118 }
02119 dbus_free (buf);
02120 }
02121 else
02122 {
02123 dbus_set_error (error, _dbus_error_from_errno (errno),
02124 "User \"%s\" unknown or no memory to allocate password entry\n",
02125 username_c ? username_c : "???");
02126 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02127 dbus_free (buf);
02128 return FALSE;
02129 }
02130 }
02131 #else
02132 {
02133
02134 struct passwd *p;
02135
02136 if (uid != DBUS_UID_UNSET)
02137 p = getpwuid (uid);
02138 else
02139 p = getpwnam (username_c);
02140
02141 if (p != NULL)
02142 {
02143 if (!fill_user_info_from_passwd (p, info, error))
02144 {
02145 return FALSE;
02146 }
02147 }
02148 else
02149 {
02150 dbus_set_error (error, _dbus_error_from_errno (errno),
02151 "User \"%s\" unknown or no memory to allocate password entry\n",
02152 username_c ? username_c : "???");
02153 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02154 return FALSE;
02155 }
02156 }
02157 #endif
02158
02159
02160 username_c = info->username;
02161
02162 #ifdef HAVE_GETGROUPLIST
02163 {
02164 gid_t *buf;
02165 int buf_count;
02166 int i;
02167 int initial_buf_count;
02168
02169 initial_buf_count = 17;
02170 buf_count = initial_buf_count;
02171 buf = dbus_new (gid_t, buf_count);
02172 if (buf == NULL)
02173 {
02174 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02175 goto failed;
02176 }
02177
02178 if (getgrouplist (username_c,
02179 info->primary_gid,
02180 buf, &buf_count) < 0)
02181 {
02182 gid_t *new;
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196 if (buf_count == initial_buf_count)
02197 {
02198 buf_count *= 16;
02199 }
02200 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02201 if (new == NULL)
02202 {
02203 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02204 dbus_free (buf);
02205 goto failed;
02206 }
02207
02208 buf = new;
02209
02210 errno = 0;
02211 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02212 {
02213 if (errno == 0)
02214 {
02215 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02216 username_c, buf_count, buf_count);
02217 }
02218 else
02219 {
02220 dbus_set_error (error,
02221 _dbus_error_from_errno (errno),
02222 "Failed to get groups for username \"%s\" primary GID "
02223 DBUS_GID_FORMAT ": %s\n",
02224 username_c, info->primary_gid,
02225 _dbus_strerror (errno));
02226 dbus_free (buf);
02227 goto failed;
02228 }
02229 }
02230 }
02231
02232 info->group_ids = dbus_new (dbus_gid_t, buf_count);
02233 if (info->group_ids == NULL)
02234 {
02235 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02236 dbus_free (buf);
02237 goto failed;
02238 }
02239
02240 for (i = 0; i < buf_count; ++i)
02241 info->group_ids[i] = buf[i];
02242
02243 info->n_group_ids = buf_count;
02244
02245 dbus_free (buf);
02246 }
02247 #else
02248 {
02249
02250 info->group_ids = dbus_new (dbus_gid_t, 1);
02251 if (info->group_ids == NULL)
02252 {
02253 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02254 goto failed;
02255 }
02256
02257 info->n_group_ids = 1;
02258
02259 (info->group_ids)[0] = info->primary_gid;
02260 }
02261 #endif
02262
02263 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02264
02265 return TRUE;
02266
02267 failed:
02268 _DBUS_ASSERT_ERROR_IS_SET (error);
02269 return FALSE;
02270 }
02271
02280 dbus_bool_t
02281 _dbus_user_info_fill (DBusUserInfo *info,
02282 const DBusString *username,
02283 DBusError *error)
02284 {
02285 return fill_user_info (info, DBUS_UID_UNSET,
02286 username, error);
02287 }
02288
02297 dbus_bool_t
02298 _dbus_user_info_fill_uid (DBusUserInfo *info,
02299 dbus_uid_t uid,
02300 DBusError *error)
02301 {
02302 return fill_user_info (info, uid,
02303 NULL, error);
02304 }
02305
02313 dbus_bool_t
02314 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02315 {
02316
02317
02318
02319
02320 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02321 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02322 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02323
02324 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02325 return FALSE;
02326 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02327 return FALSE;
02328
02329 return TRUE;
02330 }
02331
02343 dbus_bool_t
02344 _dbus_append_user_from_current_process (DBusString *str)
02345 {
02346 return _dbus_string_append_uint (str,
02347 _dbus_geteuid ());
02348 }
02349
02354 dbus_pid_t
02355 _dbus_getpid (void)
02356 {
02357 return getpid ();
02358 }
02359
02363 dbus_uid_t
02364 _dbus_getuid (void)
02365 {
02366 return getuid ();
02367 }
02368
02372 dbus_uid_t
02373 _dbus_geteuid (void)
02374 {
02375 return geteuid ();
02376 }
02377
02384 unsigned long
02385 _dbus_pid_for_log (void)
02386 {
02387 return getpid ();
02388 }
02389
02397 dbus_bool_t
02398 _dbus_parse_uid (const DBusString *uid_str,
02399 dbus_uid_t *uid)
02400 {
02401 int end;
02402 long val;
02403
02404 if (_dbus_string_get_length (uid_str) == 0)
02405 {
02406 _dbus_verbose ("UID string was zero length\n");
02407 return FALSE;
02408 }
02409
02410 val = -1;
02411 end = 0;
02412 if (!_dbus_string_parse_int (uid_str, 0, &val,
02413 &end))
02414 {
02415 _dbus_verbose ("could not parse string as a UID\n");
02416 return FALSE;
02417 }
02418
02419 if (end != _dbus_string_get_length (uid_str))
02420 {
02421 _dbus_verbose ("string contained trailing stuff after UID\n");
02422 return FALSE;
02423 }
02424
02425 *uid = val;
02426
02427 return TRUE;
02428 }
02429
02430 #if !DBUS_USE_SYNC
02431 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02432 #endif
02433
02440 dbus_int32_t
02441 _dbus_atomic_inc (DBusAtomic *atomic)
02442 {
02443 #if DBUS_USE_SYNC
02444 return __sync_add_and_fetch(&atomic->value, 1)-1;
02445 #else
02446 dbus_int32_t res;
02447 _DBUS_LOCK (atomic);
02448 res = atomic->value;
02449 atomic->value += 1;
02450 _DBUS_UNLOCK (atomic);
02451 return res;
02452 #endif
02453 }
02454
02461 dbus_int32_t
02462 _dbus_atomic_dec (DBusAtomic *atomic)
02463 {
02464 #if DBUS_USE_SYNC
02465 return __sync_sub_and_fetch(&atomic->value, 1)+1;
02466 #else
02467 dbus_int32_t res;
02468
02469 _DBUS_LOCK (atomic);
02470 res = atomic->value;
02471 atomic->value -= 1;
02472 _DBUS_UNLOCK (atomic);
02473 return res;
02474 #endif
02475 }
02476
02484 dbus_int32_t
02485 _dbus_atomic_get (DBusAtomic *atomic)
02486 {
02487 #if DBUS_USE_SYNC
02488 __sync_synchronize ();
02489 return atomic->value;
02490 #else
02491 dbus_int32_t res;
02492
02493 _DBUS_LOCK (atomic);
02494 res = atomic->value;
02495 _DBUS_UNLOCK (atomic);
02496 return res;
02497 #endif
02498 }
02499
02508 int
02509 _dbus_poll (DBusPollFD *fds,
02510 int n_fds,
02511 int timeout_milliseconds)
02512 {
02513 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02514
02515
02516
02517
02518 if (_DBUS_POLLIN == POLLIN &&
02519 _DBUS_POLLPRI == POLLPRI &&
02520 _DBUS_POLLOUT == POLLOUT &&
02521 _DBUS_POLLERR == POLLERR &&
02522 _DBUS_POLLHUP == POLLHUP &&
02523 _DBUS_POLLNVAL == POLLNVAL &&
02524 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02525 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02526 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02527 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02528 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02529 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02530 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02531 {
02532 return poll ((struct pollfd*) fds,
02533 n_fds,
02534 timeout_milliseconds);
02535 }
02536 else
02537 {
02538
02539
02540
02541 _dbus_warn ("didn't implement poll() properly for this system yet\n");
02542 return -1;
02543 }
02544 #else
02545
02546 fd_set read_set, write_set, err_set;
02547 int max_fd = 0;
02548 int i;
02549 struct timeval tv;
02550 int ready;
02551
02552 FD_ZERO (&read_set);
02553 FD_ZERO (&write_set);
02554 FD_ZERO (&err_set);
02555
02556 for (i = 0; i < n_fds; i++)
02557 {
02558 DBusPollFD *fdp = &fds[i];
02559
02560 if (fdp->events & _DBUS_POLLIN)
02561 FD_SET (fdp->fd, &read_set);
02562
02563 if (fdp->events & _DBUS_POLLOUT)
02564 FD_SET (fdp->fd, &write_set);
02565
02566 FD_SET (fdp->fd, &err_set);
02567
02568 max_fd = MAX (max_fd, fdp->fd);
02569 }
02570
02571 tv.tv_sec = timeout_milliseconds / 1000;
02572 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02573
02574 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02575 timeout_milliseconds < 0 ? NULL : &tv);
02576
02577 if (ready > 0)
02578 {
02579 for (i = 0; i < n_fds; i++)
02580 {
02581 DBusPollFD *fdp = &fds[i];
02582
02583 fdp->revents = 0;
02584
02585 if (FD_ISSET (fdp->fd, &read_set))
02586 fdp->revents |= _DBUS_POLLIN;
02587
02588 if (FD_ISSET (fdp->fd, &write_set))
02589 fdp->revents |= _DBUS_POLLOUT;
02590
02591 if (FD_ISSET (fdp->fd, &err_set))
02592 fdp->revents |= _DBUS_POLLERR;
02593 }
02594 }
02595
02596 return ready;
02597 #endif
02598 }
02599
02607 void
02608 _dbus_get_monotonic_time (long *tv_sec,
02609 long *tv_usec)
02610 {
02611 #ifdef HAVE_MONOTONIC_CLOCK
02612 struct timespec ts;
02613 clock_gettime (CLOCK_MONOTONIC, &ts);
02614
02615 if (tv_sec)
02616 *tv_sec = ts.tv_sec;
02617 if (tv_usec)
02618 *tv_usec = ts.tv_nsec / 1000;
02619 #else
02620 struct timeval t;
02621
02622 gettimeofday (&t, NULL);
02623
02624 if (tv_sec)
02625 *tv_sec = t.tv_sec;
02626 if (tv_usec)
02627 *tv_usec = t.tv_usec;
02628 #endif
02629 }
02630
02638 void
02639 _dbus_get_real_time (long *tv_sec,
02640 long *tv_usec)
02641 {
02642 struct timeval t;
02643
02644 gettimeofday (&t, NULL);
02645
02646 if (tv_sec)
02647 *tv_sec = t.tv_sec;
02648 if (tv_usec)
02649 *tv_usec = t.tv_usec;
02650 }
02651
02660 dbus_bool_t
02661 _dbus_create_directory (const DBusString *filename,
02662 DBusError *error)
02663 {
02664 const char *filename_c;
02665
02666 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02667
02668 filename_c = _dbus_string_get_const_data (filename);
02669
02670 if (mkdir (filename_c, 0700) < 0)
02671 {
02672 if (errno == EEXIST)
02673 return TRUE;
02674
02675 dbus_set_error (error, DBUS_ERROR_FAILED,
02676 "Failed to create directory %s: %s\n",
02677 filename_c, _dbus_strerror (errno));
02678 return FALSE;
02679 }
02680 else
02681 return TRUE;
02682 }
02683
02694 dbus_bool_t
02695 _dbus_concat_dir_and_file (DBusString *dir,
02696 const DBusString *next_component)
02697 {
02698 dbus_bool_t dir_ends_in_slash;
02699 dbus_bool_t file_starts_with_slash;
02700
02701 if (_dbus_string_get_length (dir) == 0 ||
02702 _dbus_string_get_length (next_component) == 0)
02703 return TRUE;
02704
02705 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02706 _dbus_string_get_length (dir) - 1);
02707
02708 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02709
02710 if (dir_ends_in_slash && file_starts_with_slash)
02711 {
02712 _dbus_string_shorten (dir, 1);
02713 }
02714 else if (!(dir_ends_in_slash || file_starts_with_slash))
02715 {
02716 if (!_dbus_string_append_byte (dir, '/'))
02717 return FALSE;
02718 }
02719
02720 return _dbus_string_copy (next_component, 0, dir,
02721 _dbus_string_get_length (dir));
02722 }
02723
02725 #define NANOSECONDS_PER_SECOND 1000000000
02726
02727 #define MICROSECONDS_PER_SECOND 1000000
02728
02729 #define MILLISECONDS_PER_SECOND 1000
02730
02731 #define NANOSECONDS_PER_MILLISECOND 1000000
02732
02733 #define MICROSECONDS_PER_MILLISECOND 1000
02734
02739 void
02740 _dbus_sleep_milliseconds (int milliseconds)
02741 {
02742 #ifdef HAVE_NANOSLEEP
02743 struct timespec req;
02744 struct timespec rem;
02745
02746 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02747 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02748 rem.tv_sec = 0;
02749 rem.tv_nsec = 0;
02750
02751 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02752 req = rem;
02753 #elif defined (HAVE_USLEEP)
02754 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02755 #else
02756 sleep (MAX (milliseconds / 1000, 1));
02757 #endif
02758 }
02759
02760 static dbus_bool_t
02761 _dbus_generate_pseudorandom_bytes (DBusString *str,
02762 int n_bytes)
02763 {
02764 int old_len;
02765 char *p;
02766
02767 old_len = _dbus_string_get_length (str);
02768
02769 if (!_dbus_string_lengthen (str, n_bytes))
02770 return FALSE;
02771
02772 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02773
02774 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02775
02776 return TRUE;
02777 }
02778
02787 dbus_bool_t
02788 _dbus_generate_random_bytes (DBusString *str,
02789 int n_bytes)
02790 {
02791 int old_len;
02792 int fd;
02793
02794
02795
02796
02797
02798
02799
02800 old_len = _dbus_string_get_length (str);
02801 fd = -1;
02802
02803
02804 fd = open ("/dev/urandom", O_RDONLY);
02805 if (fd < 0)
02806 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02807
02808 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02809
02810 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02811 {
02812 _dbus_close (fd, NULL);
02813 _dbus_string_set_length (str, old_len);
02814 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02815 }
02816
02817 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02818 n_bytes);
02819
02820 _dbus_close (fd, NULL);
02821
02822 return TRUE;
02823 }
02824
02830 void
02831 _dbus_exit (int code)
02832 {
02833 _exit (code);
02834 }
02835
02844 const char*
02845 _dbus_strerror (int error_number)
02846 {
02847 const char *msg;
02848
02849 msg = strerror (error_number);
02850 if (msg == NULL)
02851 msg = "unknown";
02852
02853 return msg;
02854 }
02855
02859 void
02860 _dbus_disable_sigpipe (void)
02861 {
02862 signal (SIGPIPE, SIG_IGN);
02863 }
02864
02872 void
02873 _dbus_fd_set_close_on_exec (intptr_t fd)
02874 {
02875 int val;
02876
02877 val = fcntl (fd, F_GETFD, 0);
02878
02879 if (val < 0)
02880 return;
02881
02882 val |= FD_CLOEXEC;
02883
02884 fcntl (fd, F_SETFD, val);
02885 }
02886
02894 dbus_bool_t
02895 _dbus_close (int fd,
02896 DBusError *error)
02897 {
02898 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02899
02900 again:
02901 if (close (fd) < 0)
02902 {
02903 if (errno == EINTR)
02904 goto again;
02905
02906 dbus_set_error (error, _dbus_error_from_errno (errno),
02907 "Could not close fd %d", fd);
02908 return FALSE;
02909 }
02910
02911 return TRUE;
02912 }
02913
02921 int
02922 _dbus_dup(int fd,
02923 DBusError *error)
02924 {
02925 int new_fd;
02926
02927 #ifdef F_DUPFD_CLOEXEC
02928 dbus_bool_t cloexec_done;
02929
02930 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02931 cloexec_done = new_fd >= 0;
02932
02933 if (new_fd < 0 && errno == EINVAL)
02934 #endif
02935 {
02936 new_fd = fcntl(fd, F_DUPFD, 3);
02937 }
02938
02939 if (new_fd < 0) {
02940
02941 dbus_set_error (error, _dbus_error_from_errno (errno),
02942 "Could not duplicate fd %d", fd);
02943 return -1;
02944 }
02945
02946 #ifdef F_DUPFD_CLOEXEC
02947 if (!cloexec_done)
02948 #endif
02949 {
02950 _dbus_fd_set_close_on_exec(new_fd);
02951 }
02952
02953 return new_fd;
02954 }
02955
02963 dbus_bool_t
02964 _dbus_set_fd_nonblocking (int fd,
02965 DBusError *error)
02966 {
02967 int val;
02968
02969 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02970
02971 val = fcntl (fd, F_GETFL, 0);
02972 if (val < 0)
02973 {
02974 dbus_set_error (error, _dbus_error_from_errno (errno),
02975 "Failed to get flags from file descriptor %d: %s",
02976 fd, _dbus_strerror (errno));
02977 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02978 _dbus_strerror (errno));
02979 return FALSE;
02980 }
02981
02982 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02983 {
02984 dbus_set_error (error, _dbus_error_from_errno (errno),
02985 "Failed to set nonblocking flag of file descriptor %d: %s",
02986 fd, _dbus_strerror (errno));
02987 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02988 fd, _dbus_strerror (errno));
02989
02990 return FALSE;
02991 }
02992
02993 return TRUE;
02994 }
02995
03001 void
03002 _dbus_print_backtrace (void)
03003 {
03004 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
03005 void *bt[500];
03006 int bt_size;
03007 int i;
03008 char **syms;
03009
03010 bt_size = backtrace (bt, 500);
03011
03012 syms = backtrace_symbols (bt, bt_size);
03013
03014 i = 0;
03015 while (i < bt_size)
03016 {
03017
03018 fprintf (stderr, " %s\n", syms[i]);
03019 ++i;
03020 }
03021 fflush (stderr);
03022
03023 free (syms);
03024 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
03025 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
03026 #else
03027 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
03028 #endif
03029 }
03030
03043 dbus_bool_t
03044 _dbus_full_duplex_pipe (int *fd1,
03045 int *fd2,
03046 dbus_bool_t blocking,
03047 DBusError *error)
03048 {
03049 #ifdef HAVE_SOCKETPAIR
03050 int fds[2];
03051 int retval;
03052
03053 #ifdef SOCK_CLOEXEC
03054 dbus_bool_t cloexec_done;
03055
03056 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
03057 cloexec_done = retval >= 0;
03058
03059 if (retval < 0 && errno == EINVAL)
03060 #endif
03061 {
03062 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
03063 }
03064
03065 if (retval < 0)
03066 {
03067 dbus_set_error (error, _dbus_error_from_errno (errno),
03068 "Could not create full-duplex pipe");
03069 return FALSE;
03070 }
03071
03072 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03073
03074 #ifdef SOCK_CLOEXEC
03075 if (!cloexec_done)
03076 #endif
03077 {
03078 _dbus_fd_set_close_on_exec (fds[0]);
03079 _dbus_fd_set_close_on_exec (fds[1]);
03080 }
03081
03082 if (!blocking &&
03083 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03084 !_dbus_set_fd_nonblocking (fds[1], NULL)))
03085 {
03086 dbus_set_error (error, _dbus_error_from_errno (errno),
03087 "Could not set full-duplex pipe nonblocking");
03088
03089 _dbus_close (fds[0], NULL);
03090 _dbus_close (fds[1], NULL);
03091
03092 return FALSE;
03093 }
03094
03095 *fd1 = fds[0];
03096 *fd2 = fds[1];
03097
03098 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03099 *fd1, *fd2);
03100
03101 return TRUE;
03102 #else
03103 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03104 dbus_set_error (error, DBUS_ERROR_FAILED,
03105 "_dbus_full_duplex_pipe() not implemented on this OS");
03106 return FALSE;
03107 #endif
03108 }
03109
03118 int
03119 _dbus_printf_string_upper_bound (const char *format,
03120 va_list args)
03121 {
03122 char static_buf[1024];
03123 int bufsize = sizeof (static_buf);
03124 int len;
03125
03126 len = vsnprintf (static_buf, bufsize, format, args);
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136 if (len == bufsize)
03137 {
03138
03139
03140
03141
03142 if (vsnprintf (static_buf, 1, format, args) == 1)
03143 len = -1;
03144 }
03145
03146
03147
03148 while (len < 0)
03149 {
03150 char *buf;
03151
03152 bufsize *= 2;
03153
03154 buf = dbus_malloc (bufsize);
03155
03156 if (buf == NULL)
03157 return -1;
03158
03159 len = vsnprintf (buf, bufsize, format, args);
03160 dbus_free (buf);
03161
03162
03163
03164
03165 if (len == bufsize)
03166 len = -1;
03167 }
03168
03169 return len;
03170 }
03171
03178 const char*
03179 _dbus_get_tmpdir(void)
03180 {
03181 static const char* tmpdir = NULL;
03182
03183 if (tmpdir == NULL)
03184 {
03185
03186
03187
03188
03189 if (tmpdir == NULL)
03190 tmpdir = getenv("TMPDIR");
03191
03192
03193
03194
03195 if (tmpdir == NULL)
03196 tmpdir = getenv("TMP");
03197 if (tmpdir == NULL)
03198 tmpdir = getenv("TEMP");
03199
03200
03201 if (tmpdir == NULL)
03202 tmpdir = "/tmp";
03203 }
03204
03205 _dbus_assert(tmpdir != NULL);
03206
03207 return tmpdir;
03208 }
03209
03229 static dbus_bool_t
03230 _read_subprocess_line_argv (const char *progpath,
03231 dbus_bool_t path_fallback,
03232 char * const *argv,
03233 DBusString *result,
03234 DBusError *error)
03235 {
03236 int result_pipe[2] = { -1, -1 };
03237 int errors_pipe[2] = { -1, -1 };
03238 pid_t pid;
03239 int ret;
03240 int status;
03241 int orig_len;
03242
03243 dbus_bool_t retval;
03244 sigset_t new_set, old_set;
03245
03246 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03247 retval = FALSE;
03248
03249
03250
03251
03252
03253 sigemptyset (&new_set);
03254 sigaddset (&new_set, SIGCHLD);
03255 sigprocmask (SIG_BLOCK, &new_set, &old_set);
03256
03257 orig_len = _dbus_string_get_length (result);
03258
03259 #define READ_END 0
03260 #define WRITE_END 1
03261 if (pipe (result_pipe) < 0)
03262 {
03263 dbus_set_error (error, _dbus_error_from_errno (errno),
03264 "Failed to create a pipe to call %s: %s",
03265 progpath, _dbus_strerror (errno));
03266 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03267 progpath, _dbus_strerror (errno));
03268 goto out;
03269 }
03270 if (pipe (errors_pipe) < 0)
03271 {
03272 dbus_set_error (error, _dbus_error_from_errno (errno),
03273 "Failed to create a pipe to call %s: %s",
03274 progpath, _dbus_strerror (errno));
03275 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03276 progpath, _dbus_strerror (errno));
03277 goto out;
03278 }
03279
03280 pid = fork ();
03281 if (pid < 0)
03282 {
03283 dbus_set_error (error, _dbus_error_from_errno (errno),
03284 "Failed to fork() to call %s: %s",
03285 progpath, _dbus_strerror (errno));
03286 _dbus_verbose ("Failed to fork() to call %s: %s\n",
03287 progpath, _dbus_strerror (errno));
03288 goto out;
03289 }
03290
03291 if (pid == 0)
03292 {
03293
03294 int fd;
03295
03296 fd = open ("/dev/null", O_RDWR);
03297 if (fd == -1)
03298
03299 _exit (1);
03300
03301 _dbus_verbose ("/dev/null fd %d opened\n", fd);
03302
03303
03304 close (result_pipe[READ_END]);
03305 close (errors_pipe[READ_END]);
03306 close (0);
03307 close (1);
03308 close (2);
03309
03310 if (dup2 (fd, 0) == -1)
03311 _exit (1);
03312 if (dup2 (result_pipe[WRITE_END], 1) == -1)
03313 _exit (1);
03314 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03315 _exit (1);
03316
03317 _dbus_close_all ();
03318
03319 sigprocmask (SIG_SETMASK, &old_set, NULL);
03320
03321
03322 if (progpath[0] == '/')
03323 {
03324 execv (progpath, argv);
03325
03326
03327
03328
03329
03330
03331 if (path_fallback)
03332
03333 execvp (strrchr (progpath, '/')+1, argv);
03334 }
03335 else
03336 execvp (progpath, argv);
03337
03338
03339 _exit (1);
03340 }
03341
03342
03343 close (result_pipe[WRITE_END]);
03344 close (errors_pipe[WRITE_END]);
03345 result_pipe[WRITE_END] = -1;
03346 errors_pipe[WRITE_END] = -1;
03347
03348 ret = 0;
03349 do
03350 {
03351 ret = _dbus_read (result_pipe[READ_END], result, 1024);
03352 }
03353 while (ret > 0);
03354
03355
03356 do
03357 {
03358 ret = waitpid (pid, &status, 0);
03359 }
03360 while (ret == -1 && errno == EINTR);
03361
03362
03363
03364 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03365 {
03366
03367 DBusString error_message;
03368 if (!_dbus_string_init (&error_message))
03369 {
03370 _DBUS_SET_OOM (error);
03371 goto out;
03372 }
03373
03374 ret = 0;
03375 do
03376 {
03377 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03378 }
03379 while (ret > 0);
03380
03381 _dbus_string_set_length (result, orig_len);
03382 if (_dbus_string_get_length (&error_message) > 0)
03383 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03384 "%s terminated abnormally with the following error: %s",
03385 progpath, _dbus_string_get_data (&error_message));
03386 else
03387 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03388 "%s terminated abnormally without any error message",
03389 progpath);
03390 goto out;
03391 }
03392
03393 retval = TRUE;
03394
03395 out:
03396 sigprocmask (SIG_SETMASK, &old_set, NULL);
03397
03398 if (retval)
03399 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03400 else
03401 _DBUS_ASSERT_ERROR_IS_SET (error);
03402
03403 if (result_pipe[0] != -1)
03404 close (result_pipe[0]);
03405 if (result_pipe[1] != -1)
03406 close (result_pipe[1]);
03407 if (errors_pipe[0] != -1)
03408 close (errors_pipe[0]);
03409 if (errors_pipe[1] != -1)
03410 close (errors_pipe[1]);
03411
03412 return retval;
03413 }
03414
03426 dbus_bool_t
03427 _dbus_get_autolaunch_address (const char *scope,
03428 DBusString *address,
03429 DBusError *error)
03430 {
03431 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03432
03433
03434
03435 const char *display;
03436 static char *argv[6];
03437 int i;
03438 DBusString uuid;
03439 dbus_bool_t retval;
03440
03441 if (_dbus_check_setuid ())
03442 {
03443 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03444 "Unable to autolaunch when setuid");
03445 return FALSE;
03446 }
03447
03448 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03449 retval = FALSE;
03450
03451
03452
03453
03454 display = _dbus_getenv ("DISPLAY");
03455
03456 if (display == NULL || display[0] == '\0')
03457 {
03458 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03459 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03460 return FALSE;
03461 }
03462
03463 if (!_dbus_string_init (&uuid))
03464 {
03465 _DBUS_SET_OOM (error);
03466 return FALSE;
03467 }
03468
03469 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03470 {
03471 _DBUS_SET_OOM (error);
03472 goto out;
03473 }
03474
03475 i = 0;
03476 argv[i] = "dbus-launch";
03477 ++i;
03478 argv[i] = "--autolaunch";
03479 ++i;
03480 argv[i] = _dbus_string_get_data (&uuid);
03481 ++i;
03482 argv[i] = "--binary-syntax";
03483 ++i;
03484 argv[i] = "--close-stderr";
03485 ++i;
03486 argv[i] = NULL;
03487 ++i;
03488
03489 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03490
03491 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03492 TRUE,
03493 argv, address, error);
03494
03495 out:
03496 _dbus_string_free (&uuid);
03497 return retval;
03498 #else
03499 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03500 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03501 "set your DBUS_SESSION_BUS_ADDRESS instead");
03502 return FALSE;
03503 #endif
03504 }
03505
03524 dbus_bool_t
03525 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
03526 dbus_bool_t create_if_not_found,
03527 DBusError *error)
03528 {
03529 DBusString filename;
03530 dbus_bool_t b;
03531
03532 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03533
03534 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03535 if (b)
03536 return TRUE;
03537
03538 dbus_error_free (error);
03539
03540
03541 _dbus_string_init_const (&filename, "/etc/machine-id");
03542 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03543 }
03544
03545 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03546 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03547
03554 dbus_bool_t
03555 _dbus_lookup_launchd_socket (DBusString *socket_path,
03556 const char *launchd_env_var,
03557 DBusError *error)
03558 {
03559 #ifdef DBUS_ENABLE_LAUNCHD
03560 char *argv[4];
03561 int i;
03562
03563 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03564
03565 if (_dbus_check_setuid ())
03566 {
03567 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03568 "Unable to find launchd socket when setuid");
03569 return FALSE;
03570 }
03571
03572 i = 0;
03573 argv[i] = "launchctl";
03574 ++i;
03575 argv[i] = "getenv";
03576 ++i;
03577 argv[i] = (char*)launchd_env_var;
03578 ++i;
03579 argv[i] = NULL;
03580 ++i;
03581
03582 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03583
03584 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03585 {
03586 return FALSE;
03587 }
03588
03589
03590 if (_dbus_string_get_length(socket_path) == 0)
03591 {
03592 return FALSE;
03593 }
03594
03595
03596 _dbus_string_shorten(socket_path, 1);
03597 return TRUE;
03598 #else
03599 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03600 "can't lookup socket from launchd; launchd support not compiled in");
03601 return FALSE;
03602 #endif
03603 }
03604
03605 #ifdef DBUS_ENABLE_LAUNCHD
03606 static dbus_bool_t
03607 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
03608 {
03609 dbus_bool_t valid_socket;
03610 DBusString socket_path;
03611
03612 if (_dbus_check_setuid ())
03613 {
03614 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03615 "Unable to find launchd socket when setuid");
03616 return FALSE;
03617 }
03618
03619 if (!_dbus_string_init (&socket_path))
03620 {
03621 _DBUS_SET_OOM (error);
03622 return FALSE;
03623 }
03624
03625 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03626
03627 if (dbus_error_is_set(error))
03628 {
03629 _dbus_string_free(&socket_path);
03630 return FALSE;
03631 }
03632
03633 if (!valid_socket)
03634 {
03635 dbus_set_error(error, "no socket path",
03636 "launchd did not provide a socket path, "
03637 "verify that org.freedesktop.dbus-session.plist is loaded!");
03638 _dbus_string_free(&socket_path);
03639 return FALSE;
03640 }
03641 if (!_dbus_string_append (address, "unix:path="))
03642 {
03643 _DBUS_SET_OOM (error);
03644 _dbus_string_free(&socket_path);
03645 return FALSE;
03646 }
03647 if (!_dbus_string_copy (&socket_path, 0, address,
03648 _dbus_string_get_length (address)))
03649 {
03650 _DBUS_SET_OOM (error);
03651 _dbus_string_free(&socket_path);
03652 return FALSE;
03653 }
03654
03655 _dbus_string_free(&socket_path);
03656 return TRUE;
03657 }
03658 #endif
03659
03679 dbus_bool_t
03680 _dbus_lookup_session_address (dbus_bool_t *supported,
03681 DBusString *address,
03682 DBusError *error)
03683 {
03684 #ifdef DBUS_ENABLE_LAUNCHD
03685 *supported = TRUE;
03686 return _dbus_lookup_session_address_launchd (address, error);
03687 #else
03688
03689
03690
03691
03692 *supported = FALSE;
03693 return TRUE;
03694 #endif
03695 }
03696
03714 dbus_bool_t
03715 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03716 {
03717 const char *xdg_data_home;
03718 const char *xdg_data_dirs;
03719 DBusString servicedir_path;
03720
03721 if (!_dbus_string_init (&servicedir_path))
03722 return FALSE;
03723
03724 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03725 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03726
03727 if (xdg_data_home != NULL)
03728 {
03729 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03730 goto oom;
03731 }
03732 else
03733 {
03734 const DBusString *homedir;
03735 DBusString local_share;
03736
03737 if (!_dbus_homedir_from_current_process (&homedir))
03738 goto oom;
03739
03740 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03741 goto oom;
03742
03743 _dbus_string_init_const (&local_share, "/.local/share");
03744 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03745 goto oom;
03746 }
03747
03748 if (!_dbus_string_append (&servicedir_path, ":"))
03749 goto oom;
03750
03751 if (xdg_data_dirs != NULL)
03752 {
03753 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03754 goto oom;
03755
03756 if (!_dbus_string_append (&servicedir_path, ":"))
03757 goto oom;
03758 }
03759 else
03760 {
03761 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03762 goto oom;
03763 }
03764
03765
03766
03767
03768
03769
03770
03771 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03772 goto oom;
03773
03774 if (!_dbus_split_paths_and_append (&servicedir_path,
03775 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03776 dirs))
03777 goto oom;
03778
03779 _dbus_string_free (&servicedir_path);
03780 return TRUE;
03781
03782 oom:
03783 _dbus_string_free (&servicedir_path);
03784 return FALSE;
03785 }
03786
03787
03806 dbus_bool_t
03807 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03808 {
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818 static const char standard_search_path[] =
03819 "/usr/local/share:"
03820 "/usr/share:"
03821 DBUS_DATADIR ":"
03822 "/lib";
03823 DBusString servicedir_path;
03824
03825 _dbus_string_init_const (&servicedir_path, standard_search_path);
03826
03827 return _dbus_split_paths_and_append (&servicedir_path,
03828 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03829 dirs);
03830 }
03831
03840 dbus_bool_t
03841 _dbus_append_system_config_file (DBusString *str)
03842 {
03843 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03844 }
03845
03852 dbus_bool_t
03853 _dbus_append_session_config_file (DBusString *str)
03854 {
03855 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03856 }
03857
03865 void
03866 _dbus_flush_caches (void)
03867 {
03868 _dbus_user_database_flush_system ();
03869 }
03870
03884 dbus_bool_t
03885 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
03886 DBusCredentials *credentials)
03887 {
03888 DBusString homedir;
03889 DBusString dotdir;
03890 dbus_uid_t uid;
03891
03892 _dbus_assert (credentials != NULL);
03893 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03894
03895 if (!_dbus_string_init (&homedir))
03896 return FALSE;
03897
03898 uid = _dbus_credentials_get_unix_uid (credentials);
03899 _dbus_assert (uid != DBUS_UID_UNSET);
03900
03901 if (!_dbus_homedir_from_uid (uid, &homedir))
03902 goto failed;
03903
03904 #ifdef DBUS_BUILD_TESTS
03905 {
03906 const char *override;
03907
03908 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03909 if (override != NULL && *override != '\0')
03910 {
03911 _dbus_string_set_length (&homedir, 0);
03912 if (!_dbus_string_append (&homedir, override))
03913 goto failed;
03914
03915 _dbus_verbose ("Using fake homedir for testing: %s\n",
03916 _dbus_string_get_const_data (&homedir));
03917 }
03918 else
03919 {
03920 static dbus_bool_t already_warned = FALSE;
03921 if (!already_warned)
03922 {
03923 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03924 already_warned = TRUE;
03925 }
03926 }
03927 }
03928 #endif
03929
03930 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03931 if (!_dbus_concat_dir_and_file (&homedir,
03932 &dotdir))
03933 goto failed;
03934
03935 if (!_dbus_string_copy (&homedir, 0,
03936 directory, _dbus_string_get_length (directory))) {
03937 goto failed;
03938 }
03939
03940 _dbus_string_free (&homedir);
03941 return TRUE;
03942
03943 failed:
03944 _dbus_string_free (&homedir);
03945 return FALSE;
03946 }
03947
03948
03949 dbus_bool_t
03950 _dbus_daemon_publish_session_bus_address (const char* addr,
03951 const char *scope)
03952 {
03953 return TRUE;
03954 }
03955
03956
03957 void
03958 _dbus_daemon_unpublish_session_bus_address (void)
03959 {
03960
03961 }
03962
03969 dbus_bool_t
03970 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03971 {
03972 return errno == EAGAIN || errno == EWOULDBLOCK;
03973 }
03974
03982 dbus_bool_t
03983 _dbus_delete_directory (const DBusString *filename,
03984 DBusError *error)
03985 {
03986 const char *filename_c;
03987
03988 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03989
03990 filename_c = _dbus_string_get_const_data (filename);
03991
03992 if (rmdir (filename_c) != 0)
03993 {
03994 dbus_set_error (error, DBUS_ERROR_FAILED,
03995 "Failed to remove directory %s: %s\n",
03996 filename_c, _dbus_strerror (errno));
03997 return FALSE;
03998 }
03999
04000 return TRUE;
04001 }
04002
04010 dbus_bool_t
04011 _dbus_socket_can_pass_unix_fd(int fd) {
04012
04013 #ifdef SCM_RIGHTS
04014 union {
04015 struct sockaddr sa;
04016 struct sockaddr_storage storage;
04017 struct sockaddr_un un;
04018 } sa_buf;
04019
04020 socklen_t sa_len = sizeof(sa_buf);
04021
04022 _DBUS_ZERO(sa_buf);
04023
04024 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
04025 return FALSE;
04026
04027 return sa_buf.sa.sa_family == AF_UNIX;
04028
04029 #else
04030 return FALSE;
04031
04032 #endif
04033 }
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043 const char *
04044 _dbus_replace_install_prefix (const char *configure_time_path)
04045 {
04046 return configure_time_path;
04047 }
04048
04053 void
04054 _dbus_close_all (void)
04055 {
04056 int maxfds, i;
04057
04058 #ifdef __linux__
04059 DIR *d;
04060
04061
04062
04063
04064 d = opendir ("/proc/self/fd");
04065 if (d)
04066 {
04067 for (;;)
04068 {
04069 struct dirent buf, *de;
04070 int k, fd;
04071 long l;
04072 char *e = NULL;
04073
04074 k = readdir_r (d, &buf, &de);
04075 if (k != 0 || !de)
04076 break;
04077
04078 if (de->d_name[0] == '.')
04079 continue;
04080
04081 errno = 0;
04082 l = strtol (de->d_name, &e, 10);
04083 if (errno != 0 || e == NULL || *e != '\0')
04084 continue;
04085
04086 fd = (int) l;
04087 if (fd < 3)
04088 continue;
04089
04090 if (fd == dirfd (d))
04091 continue;
04092
04093 close (fd);
04094 }
04095
04096 closedir (d);
04097 return;
04098 }
04099 #endif
04100
04101 maxfds = sysconf (_SC_OPEN_MAX);
04102
04103
04104
04105
04106 if (maxfds < 0)
04107 maxfds = 1024;
04108
04109
04110 for (i = 3; i < maxfds; i++)
04111 close (i);
04112 }
04113
04123 dbus_bool_t
04124 _dbus_check_setuid (void)
04125 {
04126
04127
04128
04129 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
04130 {
04131
04132 extern int __libc_enable_secure;
04133 return __libc_enable_secure;
04134 }
04135 #elif defined(HAVE_ISSETUGID)
04136
04137 return issetugid ();
04138 #else
04139 uid_t ruid, euid, suid;
04140 gid_t rgid, egid, sgid;
04141
04142 static dbus_bool_t check_setuid_initialised;
04143 static dbus_bool_t is_setuid;
04144
04145 if (_DBUS_UNLIKELY (!check_setuid_initialised))
04146 {
04147 #ifdef HAVE_GETRESUID
04148 if (getresuid (&ruid, &euid, &suid) != 0 ||
04149 getresgid (&rgid, &egid, &sgid) != 0)
04150 #endif
04151 {
04152 suid = ruid = getuid ();
04153 sgid = rgid = getgid ();
04154 euid = geteuid ();
04155 egid = getegid ();
04156 }
04157
04158 check_setuid_initialised = TRUE;
04159 is_setuid = (ruid != euid || ruid != suid ||
04160 rgid != egid || rgid != sgid);
04161
04162 }
04163 return is_setuid;
04164 #endif
04165 }
04166
04167