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