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 "dbus-internals.h"
00026 #include "dbus-sysdeps.h"
00027 #include "dbus-sysdeps-unix.h"
00028 #include "dbus-threads.h"
00029 #include "dbus-protocol.h"
00030 #include "dbus-transport.h"
00031 #include "dbus-string.h"
00032 #include "dbus-userdb.h"
00033 #include "dbus-list.h"
00034 #include <sys/types.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <signal.h>
00038 #include <unistd.h>
00039 #include <stdio.h>
00040 #include <fcntl.h>
00041 #include <sys/socket.h>
00042 #include <dirent.h>
00043 #include <sys/un.h>
00044 #include <pwd.h>
00045 #include <time.h>
00046 #include <locale.h>
00047 #include <sys/time.h>
00048 #include <sys/stat.h>
00049 #include <sys/wait.h>
00050 #include <netinet/in.h>
00051 #include <netdb.h>
00052 #include <grp.h>
00053
00054 #ifdef HAVE_ERRNO_H
00055 #include <errno.h>
00056 #endif
00057 #ifdef HAVE_WRITEV
00058 #include <sys/uio.h>
00059 #endif
00060 #ifdef HAVE_POLL
00061 #include <sys/poll.h>
00062 #endif
00063 #ifdef HAVE_BACKTRACE
00064 #include <execinfo.h>
00065 #endif
00066 #ifdef HAVE_GETPEERUCRED
00067 #include <ucred.h>
00068 #endif
00069
00070 #ifndef O_BINARY
00071 #define O_BINARY 0
00072 #endif
00073
00074 #ifndef HAVE_SOCKLEN_T
00075 #define socklen_t int
00076 #endif
00077
00078 static dbus_bool_t
00079 _dbus_open_socket (int *fd_p,
00080 int domain,
00081 int type,
00082 int protocol,
00083 DBusError *error)
00084 {
00085 *fd_p = socket (domain, type, protocol);
00086 if (*fd_p >= 0)
00087 {
00088 return TRUE;
00089 }
00090 else
00091 {
00092 dbus_set_error(error,
00093 _dbus_error_from_errno (errno),
00094 "Failed to open socket: %s",
00095 _dbus_strerror (errno));
00096 return FALSE;
00097 }
00098 }
00099
00100 dbus_bool_t
00101 _dbus_open_tcp_socket (int *fd,
00102 DBusError *error)
00103 {
00104 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00105 }
00106
00114 dbus_bool_t
00115 _dbus_open_unix_socket (int *fd,
00116 DBusError *error)
00117 {
00118 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00119 }
00120
00129 dbus_bool_t
00130 _dbus_close_socket (int fd,
00131 DBusError *error)
00132 {
00133 return _dbus_close (fd, error);
00134 }
00135
00145 int
00146 _dbus_read_socket (int fd,
00147 DBusString *buffer,
00148 int count)
00149 {
00150 return _dbus_read (fd, buffer, count);
00151 }
00152
00163 int
00164 _dbus_write_socket (int fd,
00165 const DBusString *buffer,
00166 int start,
00167 int len)
00168 {
00169 return _dbus_write (fd, buffer, start, len);
00170 }
00171
00185 int
00186 _dbus_write_socket_two (int fd,
00187 const DBusString *buffer1,
00188 int start1,
00189 int len1,
00190 const DBusString *buffer2,
00191 int start2,
00192 int len2)
00193 {
00194 return _dbus_write_two (fd, buffer1, start1, len1,
00195 buffer2, start2, len2);
00196 }
00197
00198
00215 int
00216 _dbus_read (int fd,
00217 DBusString *buffer,
00218 int count)
00219 {
00220 int bytes_read;
00221 int start;
00222 char *data;
00223
00224 _dbus_assert (count >= 0);
00225
00226 start = _dbus_string_get_length (buffer);
00227
00228 if (!_dbus_string_lengthen (buffer, count))
00229 {
00230 errno = ENOMEM;
00231 return -1;
00232 }
00233
00234 data = _dbus_string_get_data_len (buffer, start, count);
00235
00236 again:
00237
00238 bytes_read = read (fd, data, count);
00239
00240 if (bytes_read < 0)
00241 {
00242 if (errno == EINTR)
00243 goto again;
00244 else
00245 {
00246
00247 _dbus_string_set_length (buffer, start);
00248 return -1;
00249 }
00250 }
00251 else
00252 {
00253
00254 _dbus_string_set_length (buffer, start + bytes_read);
00255
00256 #if 0
00257 if (bytes_read > 0)
00258 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00259 #endif
00260
00261 return bytes_read;
00262 }
00263 }
00264
00275 int
00276 _dbus_write (int fd,
00277 const DBusString *buffer,
00278 int start,
00279 int len)
00280 {
00281 const char *data;
00282 int bytes_written;
00283
00284 data = _dbus_string_get_const_data_len (buffer, start, len);
00285
00286 again:
00287
00288 bytes_written = write (fd, data, len);
00289
00290 if (bytes_written < 0 && errno == EINTR)
00291 goto again;
00292
00293 #if 0
00294 if (bytes_written > 0)
00295 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00296 #endif
00297
00298 return bytes_written;
00299 }
00300
00321 int
00322 _dbus_write_two (int fd,
00323 const DBusString *buffer1,
00324 int start1,
00325 int len1,
00326 const DBusString *buffer2,
00327 int start2,
00328 int len2)
00329 {
00330 _dbus_assert (buffer1 != NULL);
00331 _dbus_assert (start1 >= 0);
00332 _dbus_assert (start2 >= 0);
00333 _dbus_assert (len1 >= 0);
00334 _dbus_assert (len2 >= 0);
00335
00336 #ifdef HAVE_WRITEV
00337 {
00338 struct iovec vectors[2];
00339 const char *data1;
00340 const char *data2;
00341 int bytes_written;
00342
00343 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00344
00345 if (buffer2 != NULL)
00346 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00347 else
00348 {
00349 data2 = NULL;
00350 start2 = 0;
00351 len2 = 0;
00352 }
00353
00354 vectors[0].iov_base = (char*) data1;
00355 vectors[0].iov_len = len1;
00356 vectors[1].iov_base = (char*) data2;
00357 vectors[1].iov_len = len2;
00358
00359 again:
00360
00361 bytes_written = writev (fd,
00362 vectors,
00363 data2 ? 2 : 1);
00364
00365 if (bytes_written < 0 && errno == EINTR)
00366 goto again;
00367
00368 return bytes_written;
00369 }
00370 #else
00371 {
00372 int ret1;
00373
00374 ret1 = _dbus_write (fd, buffer1, start1, len1);
00375 if (ret1 == len1 && buffer2 != NULL)
00376 {
00377 ret2 = _dbus_write (fd, buffer2, start2, len2);
00378 if (ret2 < 0)
00379 ret2 = 0;
00380
00381 return ret1 + ret2;
00382 }
00383 else
00384 return ret1;
00385 }
00386 #endif
00387 }
00388
00389 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00390
00418 int
00419 _dbus_connect_unix_socket (const char *path,
00420 dbus_bool_t abstract,
00421 DBusError *error)
00422 {
00423 int fd;
00424 size_t path_len;
00425 struct sockaddr_un addr;
00426
00427 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00428
00429 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00430 path, abstract);
00431
00432
00433 if (!_dbus_open_unix_socket (&fd, error))
00434 {
00435 _DBUS_ASSERT_ERROR_IS_SET(error);
00436 return -1;
00437 }
00438 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00439
00440 _DBUS_ZERO (addr);
00441 addr.sun_family = AF_UNIX;
00442 path_len = strlen (path);
00443
00444 if (abstract)
00445 {
00446 #ifdef HAVE_ABSTRACT_SOCKETS
00447 addr.sun_path[0] = '\0';
00448 path_len++;
00449
00450 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00451 {
00452 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00453 "Abstract socket name too long\n");
00454 _dbus_close (fd, NULL);
00455 return -1;
00456 }
00457
00458 strncpy (&addr.sun_path[1], path, path_len);
00459
00460 #else
00461 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00462 "Operating system does not support abstract socket namespace\n");
00463 _dbus_close (fd, NULL);
00464 return -1;
00465 #endif
00466 }
00467 else
00468 {
00469 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00470 {
00471 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00472 "Socket name too long\n");
00473 _dbus_close (fd, NULL);
00474 return -1;
00475 }
00476
00477 strncpy (addr.sun_path, path, path_len);
00478 }
00479
00480 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00481 {
00482 dbus_set_error (error,
00483 _dbus_error_from_errno (errno),
00484 "Failed to connect to socket %s: %s",
00485 path, _dbus_strerror (errno));
00486
00487 _dbus_close (fd, NULL);
00488 fd = -1;
00489
00490 return -1;
00491 }
00492
00493 if (!_dbus_set_fd_nonblocking (fd, error))
00494 {
00495 _DBUS_ASSERT_ERROR_IS_SET (error);
00496
00497 _dbus_close (fd, NULL);
00498 fd = -1;
00499
00500 return -1;
00501 }
00502
00503 return fd;
00504 }
00505
00515 static dbus_bool_t
00516 _dbus_set_local_creds (int fd, dbus_bool_t on)
00517 {
00518 dbus_bool_t retval = TRUE;
00519
00520 #if defined(HAVE_CMSGCRED)
00521
00522
00523
00524 #elif defined(LOCAL_CREDS)
00525 int val = on ? 1 : 0;
00526 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00527 {
00528 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00529 retval = FALSE;
00530 }
00531 else
00532 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00533 on ? "enabled" : "disabled", fd);
00534 #endif
00535
00536 return retval;
00537 }
00538
00554 int
00555 _dbus_listen_unix_socket (const char *path,
00556 dbus_bool_t abstract,
00557 DBusError *error)
00558 {
00559 int listen_fd;
00560 struct sockaddr_un addr;
00561 size_t path_len;
00562
00563 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00564
00565 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00566 path, abstract);
00567
00568 if (!_dbus_open_unix_socket (&listen_fd, error))
00569 {
00570 _DBUS_ASSERT_ERROR_IS_SET(error);
00571 return -1;
00572 }
00573 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00574
00575 _DBUS_ZERO (addr);
00576 addr.sun_family = AF_UNIX;
00577 path_len = strlen (path);
00578
00579 if (abstract)
00580 {
00581 #ifdef HAVE_ABSTRACT_SOCKETS
00582
00583
00584
00585 addr.sun_path[0] = '\0';
00586 path_len++;
00587
00588 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00589 {
00590 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00591 "Abstract socket name too long\n");
00592 _dbus_close (listen_fd, NULL);
00593 return -1;
00594 }
00595
00596 strncpy (&addr.sun_path[1], path, path_len);
00597
00598 #else
00599 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00600 "Operating system does not support abstract socket namespace\n");
00601 _dbus_close (listen_fd, NULL);
00602 return -1;
00603 #endif
00604 }
00605 else
00606 {
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 {
00618 struct stat sb;
00619
00620 if (stat (path, &sb) == 0 &&
00621 S_ISSOCK (sb.st_mode))
00622 unlink (path);
00623 }
00624
00625 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00626 {
00627 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00628 "Abstract socket name too long\n");
00629 _dbus_close (listen_fd, NULL);
00630 return -1;
00631 }
00632
00633 strncpy (addr.sun_path, path, path_len);
00634 }
00635
00636 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00637 {
00638 dbus_set_error (error, _dbus_error_from_errno (errno),
00639 "Failed to bind socket \"%s\": %s",
00640 path, _dbus_strerror (errno));
00641 _dbus_close (listen_fd, NULL);
00642 return -1;
00643 }
00644
00645 if (listen (listen_fd, 30 ) < 0)
00646 {
00647 dbus_set_error (error, _dbus_error_from_errno (errno),
00648 "Failed to listen on socket \"%s\": %s",
00649 path, _dbus_strerror (errno));
00650 _dbus_close (listen_fd, NULL);
00651 return -1;
00652 }
00653
00654 if (!_dbus_set_local_creds (listen_fd, TRUE))
00655 {
00656 dbus_set_error (error, _dbus_error_from_errno (errno),
00657 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
00658 path, _dbus_strerror (errno));
00659 close (listen_fd);
00660 return -1;
00661 }
00662
00663 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00664 {
00665 _DBUS_ASSERT_ERROR_IS_SET (error);
00666 _dbus_close (listen_fd, NULL);
00667 return -1;
00668 }
00669
00670
00671
00672
00673 if (!abstract && chmod (path, 0777) < 0)
00674 _dbus_warn ("Could not set mode 0777 on socket %s\n",
00675 path);
00676
00677 return listen_fd;
00678 }
00679
00690 int
00691 _dbus_connect_tcp_socket (const char *host,
00692 dbus_uint32_t port,
00693 DBusError *error)
00694 {
00695 int fd;
00696 struct sockaddr_in addr;
00697 struct hostent *he;
00698 struct in_addr *haddr;
00699
00700 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00701
00702
00703 if (!_dbus_open_tcp_socket (&fd, error))
00704 {
00705 _DBUS_ASSERT_ERROR_IS_SET(error);
00706
00707 return -1;
00708 }
00709 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00710
00711 if (host == NULL)
00712 host = "localhost";
00713
00714 he = gethostbyname (host);
00715 if (he == NULL)
00716 {
00717 dbus_set_error (error,
00718 _dbus_error_from_errno (errno),
00719 "Failed to lookup hostname: %s",
00720 host);
00721 _dbus_close (fd, NULL);
00722 return -1;
00723 }
00724
00725 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
00726
00727 _DBUS_ZERO (addr);
00728 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
00729 addr.sin_family = AF_INET;
00730 addr.sin_port = htons (port);
00731
00732 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
00733 {
00734 dbus_set_error (error,
00735 _dbus_error_from_errno (errno),
00736 "Failed to connect to socket %s:%d %s",
00737 host, port, _dbus_strerror (errno));
00738
00739 _dbus_close (fd, NULL);
00740 fd = -1;
00741
00742 return -1;
00743 }
00744
00745 if (!_dbus_set_fd_nonblocking (fd, error))
00746 {
00747 _dbus_close (fd, NULL);
00748 fd = -1;
00749
00750 return -1;
00751 }
00752
00753 return fd;
00754 }
00755
00766 int
00767 _dbus_listen_tcp_socket (const char *host,
00768 dbus_uint32_t port,
00769 DBusError *error)
00770 {
00771 int listen_fd;
00772 struct sockaddr_in addr;
00773 struct hostent *he;
00774 struct in_addr *haddr;
00775
00776 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00777
00778
00779 if (!_dbus_open_tcp_socket (&listen_fd, error))
00780 {
00781 _DBUS_ASSERT_ERROR_IS_SET(error);
00782 return -1;
00783 }
00784 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00785
00786 he = gethostbyname (host);
00787 if (he == NULL)
00788 {
00789 dbus_set_error (error,
00790 _dbus_error_from_errno (errno),
00791 "Failed to lookup hostname: %s",
00792 host);
00793 _dbus_close (listen_fd, NULL);
00794 return -1;
00795 }
00796
00797 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
00798
00799 _DBUS_ZERO (addr);
00800 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
00801 addr.sin_family = AF_INET;
00802 addr.sin_port = htons (port);
00803
00804 if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
00805 {
00806 dbus_set_error (error, _dbus_error_from_errno (errno),
00807 "Failed to bind socket \"%s:%d\": %s",
00808 host, port, _dbus_strerror (errno));
00809 _dbus_close (listen_fd, NULL);
00810 return -1;
00811 }
00812
00813 if (listen (listen_fd, 30 ) < 0)
00814 {
00815 dbus_set_error (error, _dbus_error_from_errno (errno),
00816 "Failed to listen on socket \"%s:%d\": %s",
00817 host, port, _dbus_strerror (errno));
00818 _dbus_close (listen_fd, NULL);
00819 return -1;
00820 }
00821
00822 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00823 {
00824 _dbus_close (listen_fd, NULL);
00825 return -1;
00826 }
00827
00828 return listen_fd;
00829 }
00830
00831 static dbus_bool_t
00832 write_credentials_byte (int server_fd,
00833 DBusError *error)
00834 {
00835 int bytes_written;
00836 char buf[1] = { '\0' };
00837 #if defined(HAVE_CMSGCRED)
00838 struct {
00839 struct cmsghdr hdr;
00840 struct cmsgcred cred;
00841 } cmsg;
00842 struct iovec iov;
00843 struct msghdr msg;
00844 iov.iov_base = buf;
00845 iov.iov_len = 1;
00846
00847 memset (&msg, 0, sizeof (msg));
00848 msg.msg_iov = &iov;
00849 msg.msg_iovlen = 1;
00850
00851 msg.msg_control = &cmsg;
00852 msg.msg_controllen = sizeof (cmsg);
00853 memset (&cmsg, 0, sizeof (cmsg));
00854 cmsg.hdr.cmsg_len = sizeof (cmsg);
00855 cmsg.hdr.cmsg_level = SOL_SOCKET;
00856 cmsg.hdr.cmsg_type = SCM_CREDS;
00857 #endif
00858
00859 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00860
00861 again:
00862
00863 #if defined(HAVE_CMSGCRED)
00864 bytes_written = sendmsg (server_fd, &msg, 0);
00865 #else
00866 bytes_written = write (server_fd, buf, 1);
00867 #endif
00868
00869 if (bytes_written < 0 && errno == EINTR)
00870 goto again;
00871
00872 if (bytes_written < 0)
00873 {
00874 dbus_set_error (error, _dbus_error_from_errno (errno),
00875 "Failed to write credentials byte: %s",
00876 _dbus_strerror (errno));
00877 return FALSE;
00878 }
00879 else if (bytes_written == 0)
00880 {
00881 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
00882 "wrote zero bytes writing credentials byte");
00883 return FALSE;
00884 }
00885 else
00886 {
00887 _dbus_assert (bytes_written == 1);
00888 _dbus_verbose ("wrote credentials byte\n");
00889 return TRUE;
00890 }
00891 }
00892
00911 dbus_bool_t
00912 _dbus_read_credentials_unix_socket (int client_fd,
00913 DBusCredentials *credentials,
00914 DBusError *error)
00915 {
00916 struct msghdr msg;
00917 struct iovec iov;
00918 char buf;
00919
00920 #ifdef HAVE_CMSGCRED
00921 struct {
00922 struct cmsghdr hdr;
00923 struct cmsgcred cred;
00924 } cmsg;
00925
00926 #elif defined(LOCAL_CREDS)
00927 struct {
00928 struct cmsghdr hdr;
00929 struct sockcred cred;
00930 } cmsg;
00931 #endif
00932
00933 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00934
00935
00936
00937
00938
00939 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
00940 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
00941 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
00942
00943 _dbus_credentials_clear (credentials);
00944
00945
00946
00947
00948
00949
00950
00951 iov.iov_base = &buf;
00952 iov.iov_len = 1;
00953
00954 memset (&msg, 0, sizeof (msg));
00955 msg.msg_iov = &iov;
00956 msg.msg_iovlen = 1;
00957
00958 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
00959 memset (&cmsg, 0, sizeof (cmsg));
00960 msg.msg_control = &cmsg;
00961 msg.msg_controllen = sizeof (cmsg);
00962 #endif
00963
00964 again:
00965 if (recvmsg (client_fd, &msg, 0) < 0)
00966 {
00967 if (errno == EINTR)
00968 goto again;
00969
00970 dbus_set_error (error, _dbus_error_from_errno (errno),
00971 "Failed to read credentials byte: %s",
00972 _dbus_strerror (errno));
00973 return FALSE;
00974 }
00975
00976 if (buf != '\0')
00977 {
00978 dbus_set_error (error, DBUS_ERROR_FAILED,
00979 "Credentials byte was not nul");
00980 return FALSE;
00981 }
00982
00983 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
00984 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
00985 {
00986 dbus_set_error (error, DBUS_ERROR_FAILED,
00987 "Message from recvmsg() was not SCM_CREDS");
00988 return FALSE;
00989 }
00990 #endif
00991
00992 _dbus_verbose ("read credentials byte\n");
00993
00994 {
00995 #ifdef SO_PEERCRED
00996 struct ucred cr;
00997 int cr_len = sizeof (cr);
00998
00999 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01000 cr_len == sizeof (cr))
01001 {
01002 credentials->pid = cr.pid;
01003 credentials->uid = cr.uid;
01004 credentials->gid = cr.gid;
01005 }
01006 else
01007 {
01008 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01009 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01010 }
01011 #elif defined(HAVE_CMSGCRED)
01012 credentials->pid = cmsg.cred.cmcred_pid;
01013 credentials->uid = cmsg.cred.cmcred_euid;
01014 credentials->gid = cmsg.cred.cmcred_groups[0];
01015 #elif defined(LOCAL_CREDS)
01016 credentials->pid = DBUS_PID_UNSET;
01017 credentials->uid = cmsg.cred.sc_uid;
01018 credentials->gid = cmsg.cred.sc_gid;
01019
01020
01021 _dbus_set_local_creds (client_fd, FALSE);
01022 #elif defined(HAVE_GETPEEREID)
01023 uid_t euid;
01024 gid_t egid;
01025 if (getpeereid (client_fd, &euid, &egid) == 0)
01026 {
01027 credentials->uid = euid;
01028 credentials->gid = egid;
01029 }
01030 else
01031 {
01032 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01033 }
01034 #elif defined(HAVE_GETPEERUCRED)
01035 ucred_t * ucred = NULL;
01036 if (getpeerucred (client_fd, &ucred) == 0)
01037 {
01038 credentials->pid = ucred_getpid (ucred);
01039 credentials->uid = ucred_geteuid (ucred);
01040 credentials->gid = ucred_getegid (ucred);
01041 }
01042 else
01043 {
01044 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01045 }
01046 if (ucred != NULL)
01047 ucred_free (ucred);
01048 #else
01049 _dbus_verbose ("Socket credentials not supported on this OS\n");
01050 #endif
01051 }
01052
01053 _dbus_verbose ("Credentials:"
01054 " pid "DBUS_PID_FORMAT
01055 " uid "DBUS_UID_FORMAT
01056 " gid "DBUS_GID_FORMAT"\n",
01057 credentials->pid,
01058 credentials->uid,
01059 credentials->gid);
01060
01061 return TRUE;
01062 }
01063
01081 dbus_bool_t
01082 _dbus_send_credentials_unix_socket (int server_fd,
01083 DBusError *error)
01084 {
01085 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01086
01087 if (write_credentials_byte (server_fd, error))
01088 return TRUE;
01089 else
01090 return FALSE;
01091 }
01092
01100 int
01101 _dbus_accept (int listen_fd)
01102 {
01103 int client_fd;
01104 struct sockaddr addr;
01105 socklen_t addrlen;
01106
01107 addrlen = sizeof (addr);
01108
01109 retry:
01110 client_fd = accept (listen_fd, &addr, &addrlen);
01111
01112 if (client_fd < 0)
01113 {
01114 if (errno == EINTR)
01115 goto retry;
01116 }
01117
01118 return client_fd;
01119 }
01120
01129 dbus_bool_t
01130 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01131 {
01132 const char *directory;
01133 struct stat sb;
01134
01135 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01136
01137 directory = _dbus_string_get_const_data (dir);
01138
01139 if (stat (directory, &sb) < 0)
01140 {
01141 dbus_set_error (error, _dbus_error_from_errno (errno),
01142 "%s", _dbus_strerror (errno));
01143
01144 return FALSE;
01145 }
01146
01147 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01148 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01149 {
01150 dbus_set_error (error, DBUS_ERROR_FAILED,
01151 "%s directory is not private to the user", directory);
01152 return FALSE;
01153 }
01154
01155 return TRUE;
01156 }
01157
01158 static dbus_bool_t
01159 fill_user_info_from_passwd (struct passwd *p,
01160 DBusUserInfo *info,
01161 DBusError *error)
01162 {
01163 _dbus_assert (p->pw_name != NULL);
01164 _dbus_assert (p->pw_dir != NULL);
01165
01166 info->uid = p->pw_uid;
01167 info->primary_gid = p->pw_gid;
01168 info->username = _dbus_strdup (p->pw_name);
01169 info->homedir = _dbus_strdup (p->pw_dir);
01170
01171 if (info->username == NULL ||
01172 info->homedir == NULL)
01173 {
01174 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01175 return FALSE;
01176 }
01177
01178 return TRUE;
01179 }
01180
01181 static dbus_bool_t
01182 fill_user_info (DBusUserInfo *info,
01183 dbus_uid_t uid,
01184 const DBusString *username,
01185 DBusError *error)
01186 {
01187 const char *username_c;
01188
01189
01190 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01191 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01192
01193 info->uid = DBUS_UID_UNSET;
01194 info->primary_gid = DBUS_GID_UNSET;
01195 info->group_ids = NULL;
01196 info->n_group_ids = 0;
01197 info->username = NULL;
01198 info->homedir = NULL;
01199
01200 if (username != NULL)
01201 username_c = _dbus_string_get_const_data (username);
01202 else
01203 username_c = NULL;
01204
01205
01206
01207
01208
01209
01210 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01211 {
01212 struct passwd *p;
01213 int result;
01214 char buf[1024];
01215 struct passwd p_str;
01216
01217 p = NULL;
01218 #ifdef HAVE_POSIX_GETPWNAM_R
01219 if (uid != DBUS_UID_UNSET)
01220 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
01221 &p);
01222 else
01223 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
01224 &p);
01225 #else
01226 if (uid != DBUS_UID_UNSET)
01227 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
01228 else
01229 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
01230 result = 0;
01231 #endif
01232 if (result == 0 && p == &p_str)
01233 {
01234 if (!fill_user_info_from_passwd (p, info, error))
01235 return FALSE;
01236 }
01237 else
01238 {
01239 dbus_set_error (error, _dbus_error_from_errno (errno),
01240 "User \"%s\" unknown or no memory to allocate password entry\n",
01241 username_c ? username_c : "???");
01242 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01243 return FALSE;
01244 }
01245 }
01246 #else
01247 {
01248
01249 struct passwd *p;
01250
01251 if (uid != DBUS_UID_UNSET)
01252 p = getpwuid (uid);
01253 else
01254 p = getpwnam (username_c);
01255
01256 if (p != NULL)
01257 {
01258 if (!fill_user_info_from_passwd (p, info, error))
01259 return FALSE;
01260 }
01261 else
01262 {
01263 dbus_set_error (error, _dbus_error_from_errno (errno),
01264 "User \"%s\" unknown or no memory to allocate password entry\n",
01265 username_c ? username_c : "???");
01266 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01267 return FALSE;
01268 }
01269 }
01270 #endif
01271
01272
01273 username_c = info->username;
01274
01275 #ifdef HAVE_GETGROUPLIST
01276 {
01277 gid_t *buf;
01278 int buf_count;
01279 int i;
01280
01281 buf_count = 17;
01282 buf = dbus_new (gid_t, buf_count);
01283 if (buf == NULL)
01284 {
01285 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01286 goto failed;
01287 }
01288
01289 if (getgrouplist (username_c,
01290 info->primary_gid,
01291 buf, &buf_count) < 0)
01292 {
01293 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
01294 if (new == NULL)
01295 {
01296 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01297 dbus_free (buf);
01298 goto failed;
01299 }
01300
01301 buf = new;
01302
01303 errno = 0;
01304 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
01305 {
01306 dbus_set_error (error,
01307 _dbus_error_from_errno (errno),
01308 "Failed to get groups for username \"%s\" primary GID "
01309 DBUS_GID_FORMAT ": %s\n",
01310 username_c, info->primary_gid,
01311 _dbus_strerror (errno));
01312 dbus_free (buf);
01313 goto failed;
01314 }
01315 }
01316
01317 info->group_ids = dbus_new (dbus_gid_t, buf_count);
01318 if (info->group_ids == NULL)
01319 {
01320 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01321 dbus_free (buf);
01322 goto failed;
01323 }
01324
01325 for (i = 0; i < buf_count; ++i)
01326 info->group_ids[i] = buf[i];
01327
01328 info->n_group_ids = buf_count;
01329
01330 dbus_free (buf);
01331 }
01332 #else
01333 {
01334
01335 info->group_ids = dbus_new (dbus_gid_t, 1);
01336 if (info->group_ids == NULL)
01337 {
01338 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01339 goto failed;
01340 }
01341
01342 info->n_group_ids = 1;
01343
01344 (info->group_ids)[0] = info->primary_gid;
01345 }
01346 #endif
01347
01348 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01349
01350 return TRUE;
01351
01352 failed:
01353 _DBUS_ASSERT_ERROR_IS_SET (error);
01354 return FALSE;
01355 }
01356
01365 dbus_bool_t
01366 _dbus_user_info_fill (DBusUserInfo *info,
01367 const DBusString *username,
01368 DBusError *error)
01369 {
01370 return fill_user_info (info, DBUS_UID_UNSET,
01371 username, error);
01372 }
01373
01382 dbus_bool_t
01383 _dbus_user_info_fill_uid (DBusUserInfo *info,
01384 dbus_uid_t uid,
01385 DBusError *error)
01386 {
01387 return fill_user_info (info, uid,
01388 NULL, error);
01389 }
01390
01396 void
01397 _dbus_credentials_from_current_process (DBusCredentials *credentials)
01398 {
01399
01400
01401
01402
01403 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
01404 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
01405 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
01406
01407 credentials->pid = getpid ();
01408 credentials->uid = getuid ();
01409 credentials->gid = getgid ();
01410 }
01411
01416 unsigned long
01417 _dbus_getpid (void)
01418 {
01419 return getpid ();
01420 }
01421
01425 dbus_uid_t
01426 _dbus_getuid (void)
01427 {
01428 return getuid ();
01429 }
01430
01431 #ifdef DBUS_BUILD_TESTS
01432
01435 dbus_gid_t
01436 _dbus_getgid (void)
01437 {
01438 return getgid ();
01439 }
01440 #endif
01441
01450 int
01451 _dbus_poll (DBusPollFD *fds,
01452 int n_fds,
01453 int timeout_milliseconds)
01454 {
01455 #ifdef HAVE_POLL
01456
01457
01458
01459
01460 if (_DBUS_POLLIN == POLLIN &&
01461 _DBUS_POLLPRI == POLLPRI &&
01462 _DBUS_POLLOUT == POLLOUT &&
01463 _DBUS_POLLERR == POLLERR &&
01464 _DBUS_POLLHUP == POLLHUP &&
01465 _DBUS_POLLNVAL == POLLNVAL &&
01466 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
01467 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
01468 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
01469 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
01470 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
01471 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
01472 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
01473 {
01474 return poll ((struct pollfd*) fds,
01475 n_fds,
01476 timeout_milliseconds);
01477 }
01478 else
01479 {
01480
01481
01482
01483 _dbus_warn ("didn't implement poll() properly for this system yet\n");
01484 return -1;
01485 }
01486 #else
01487
01488 fd_set read_set, write_set, err_set;
01489 int max_fd = 0;
01490 int i;
01491 struct timeval tv;
01492 int ready;
01493
01494 FD_ZERO (&read_set);
01495 FD_ZERO (&write_set);
01496 FD_ZERO (&err_set);
01497
01498 for (i = 0; i < n_fds; i++)
01499 {
01500 DBusPollFD *fdp = &fds[i];
01501
01502 if (fdp->events & _DBUS_POLLIN)
01503 FD_SET (fdp->fd, &read_set);
01504
01505 if (fdp->events & _DBUS_POLLOUT)
01506 FD_SET (fdp->fd, &write_set);
01507
01508 FD_SET (fdp->fd, &err_set);
01509
01510 max_fd = MAX (max_fd, fdp->fd);
01511 }
01512
01513 tv.tv_sec = timeout_milliseconds / 1000;
01514 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01515
01516 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01517 timeout_milliseconds < 0 ? NULL : &tv);
01518
01519 if (ready > 0)
01520 {
01521 for (i = 0; i < n_fds; i++)
01522 {
01523 DBusPollFD *fdp = &fds[i];
01524
01525 fdp->revents = 0;
01526
01527 if (FD_ISSET (fdp->fd, &read_set))
01528 fdp->revents |= _DBUS_POLLIN;
01529
01530 if (FD_ISSET (fdp->fd, &write_set))
01531 fdp->revents |= _DBUS_POLLOUT;
01532
01533 if (FD_ISSET (fdp->fd, &err_set))
01534 fdp->revents |= _DBUS_POLLERR;
01535 }
01536 }
01537
01538 return ready;
01539 #endif
01540 }
01541
01548 void
01549 _dbus_get_current_time (long *tv_sec,
01550 long *tv_usec)
01551 {
01552 struct timeval t;
01553
01554 gettimeofday (&t, NULL);
01555
01556 if (tv_sec)
01557 *tv_sec = t.tv_sec;
01558 if (tv_usec)
01559 *tv_usec = t.tv_usec;
01560 }
01561
01572 dbus_bool_t
01573 _dbus_file_get_contents (DBusString *str,
01574 const DBusString *filename,
01575 DBusError *error)
01576 {
01577 int fd;
01578 struct stat sb;
01579 int orig_len;
01580 int total;
01581 const char *filename_c;
01582
01583 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01584
01585 filename_c = _dbus_string_get_const_data (filename);
01586
01587
01588 fd = open (filename_c, O_RDONLY | O_BINARY);
01589 if (fd < 0)
01590 {
01591 dbus_set_error (error, _dbus_error_from_errno (errno),
01592 "Failed to open \"%s\": %s",
01593 filename_c,
01594 _dbus_strerror (errno));
01595 return FALSE;
01596 }
01597
01598 if (fstat (fd, &sb) < 0)
01599 {
01600 dbus_set_error (error, _dbus_error_from_errno (errno),
01601 "Failed to stat \"%s\": %s",
01602 filename_c,
01603 _dbus_strerror (errno));
01604
01605 _dbus_verbose ("fstat() failed: %s",
01606 _dbus_strerror (errno));
01607
01608 _dbus_close (fd, NULL);
01609
01610 return FALSE;
01611 }
01612
01613 if (sb.st_size > _DBUS_ONE_MEGABYTE)
01614 {
01615 dbus_set_error (error, DBUS_ERROR_FAILED,
01616 "File size %lu of \"%s\" is too large.",
01617 (unsigned long) sb.st_size, filename_c);
01618 _dbus_close (fd, NULL);
01619 return FALSE;
01620 }
01621
01622 total = 0;
01623 orig_len = _dbus_string_get_length (str);
01624 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
01625 {
01626 int bytes_read;
01627
01628 while (total < (int) sb.st_size)
01629 {
01630 bytes_read = _dbus_read (fd, str,
01631 sb.st_size - total);
01632 if (bytes_read <= 0)
01633 {
01634 dbus_set_error (error, _dbus_error_from_errno (errno),
01635 "Error reading \"%s\": %s",
01636 filename_c,
01637 _dbus_strerror (errno));
01638
01639 _dbus_verbose ("read() failed: %s",
01640 _dbus_strerror (errno));
01641
01642 _dbus_close (fd, NULL);
01643 _dbus_string_set_length (str, orig_len);
01644 return FALSE;
01645 }
01646 else
01647 total += bytes_read;
01648 }
01649
01650 _dbus_close (fd, NULL);
01651 return TRUE;
01652 }
01653 else if (sb.st_size != 0)
01654 {
01655 _dbus_verbose ("Can only open regular files at the moment.\n");
01656 dbus_set_error (error, DBUS_ERROR_FAILED,
01657 "\"%s\" is not a regular file",
01658 filename_c);
01659 _dbus_close (fd, NULL);
01660 return FALSE;
01661 }
01662 else
01663 {
01664 _dbus_close (fd, NULL);
01665 return TRUE;
01666 }
01667 }
01668
01678 dbus_bool_t
01679 _dbus_string_save_to_file (const DBusString *str,
01680 const DBusString *filename,
01681 DBusError *error)
01682 {
01683 int fd;
01684 int bytes_to_write;
01685 const char *filename_c;
01686 DBusString tmp_filename;
01687 const char *tmp_filename_c;
01688 int total;
01689 dbus_bool_t need_unlink;
01690 dbus_bool_t retval;
01691
01692 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01693
01694 fd = -1;
01695 retval = FALSE;
01696 need_unlink = FALSE;
01697
01698 if (!_dbus_string_init (&tmp_filename))
01699 {
01700 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01701 return FALSE;
01702 }
01703
01704 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
01705 {
01706 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01707 _dbus_string_free (&tmp_filename);
01708 return FALSE;
01709 }
01710
01711 if (!_dbus_string_append (&tmp_filename, "."))
01712 {
01713 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01714 _dbus_string_free (&tmp_filename);
01715 return FALSE;
01716 }
01717
01718 #define N_TMP_FILENAME_RANDOM_BYTES 8
01719 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
01720 {
01721 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01722 _dbus_string_free (&tmp_filename);
01723 return FALSE;
01724 }
01725
01726 filename_c = _dbus_string_get_const_data (filename);
01727 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
01728
01729 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
01730 0600);
01731 if (fd < 0)
01732 {
01733 dbus_set_error (error, _dbus_error_from_errno (errno),
01734 "Could not create %s: %s", tmp_filename_c,
01735 _dbus_strerror (errno));
01736 goto out;
01737 }
01738
01739 need_unlink = TRUE;
01740
01741 total = 0;
01742 bytes_to_write = _dbus_string_get_length (str);
01743
01744 while (total < bytes_to_write)
01745 {
01746 int bytes_written;
01747
01748 bytes_written = _dbus_write (fd, str, total,
01749 bytes_to_write - total);
01750
01751 if (bytes_written <= 0)
01752 {
01753 dbus_set_error (error, _dbus_error_from_errno (errno),
01754 "Could not write to %s: %s", tmp_filename_c,
01755 _dbus_strerror (errno));
01756
01757 goto out;
01758 }
01759
01760 total += bytes_written;
01761 }
01762
01763 if (!_dbus_close (fd, NULL))
01764 {
01765 dbus_set_error (error, _dbus_error_from_errno (errno),
01766 "Could not close file %s: %s",
01767 tmp_filename_c, _dbus_strerror (errno));
01768
01769 goto out;
01770 }
01771
01772 fd = -1;
01773
01774 if (rename (tmp_filename_c, filename_c) < 0)
01775 {
01776 dbus_set_error (error, _dbus_error_from_errno (errno),
01777 "Could not rename %s to %s: %s",
01778 tmp_filename_c, filename_c,
01779 _dbus_strerror (errno));
01780
01781 goto out;
01782 }
01783
01784 need_unlink = FALSE;
01785
01786 retval = TRUE;
01787
01788 out:
01789
01790
01791
01792
01793 if (fd >= 0)
01794 _dbus_close (fd, NULL);
01795
01796 if (need_unlink && unlink (tmp_filename_c) < 0)
01797 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
01798 tmp_filename_c, _dbus_strerror (errno));
01799
01800 _dbus_string_free (&tmp_filename);
01801
01802 if (!retval)
01803 _DBUS_ASSERT_ERROR_IS_SET (error);
01804
01805 return retval;
01806 }
01807
01814 dbus_bool_t
01815 _dbus_make_file_world_readable(const DBusString *filename,
01816 DBusError *error)
01817 {
01818 const char *filename_c;
01819
01820 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01821
01822 filename_c = _dbus_string_get_const_data (filename);
01823 if (chmod (filename_c, 0644) == -1)
01824 {
01825 dbus_set_error (error,
01826 DBUS_ERROR_FAILED,
01827 "Could not change permissions of file %s: %s\n",
01828 filename_c,
01829 _dbus_strerror (errno));
01830 return FALSE;
01831 }
01832 return TRUE;
01833 }
01834
01841 dbus_bool_t
01842 _dbus_create_file_exclusively (const DBusString *filename,
01843 DBusError *error)
01844 {
01845 int fd;
01846 const char *filename_c;
01847
01848 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01849
01850 filename_c = _dbus_string_get_const_data (filename);
01851
01852 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
01853 0600);
01854 if (fd < 0)
01855 {
01856 dbus_set_error (error,
01857 DBUS_ERROR_FAILED,
01858 "Could not create file %s: %s\n",
01859 filename_c,
01860 _dbus_strerror (errno));
01861 return FALSE;
01862 }
01863
01864 if (!_dbus_close (fd, NULL))
01865 {
01866 dbus_set_error (error,
01867 DBUS_ERROR_FAILED,
01868 "Could not close file %s: %s\n",
01869 filename_c,
01870 _dbus_strerror (errno));
01871 return FALSE;
01872 }
01873
01874 return TRUE;
01875 }
01876
01885 dbus_bool_t
01886 _dbus_delete_file (const DBusString *filename,
01887 DBusError *error)
01888 {
01889 const char *filename_c;
01890
01891 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01892
01893 filename_c = _dbus_string_get_const_data (filename);
01894
01895 if (unlink (filename_c) < 0)
01896 {
01897 dbus_set_error (error, DBUS_ERROR_FAILED,
01898 "Failed to delete file %s: %s\n",
01899 filename_c, _dbus_strerror (errno));
01900 return FALSE;
01901 }
01902 else
01903 return TRUE;
01904 }
01905
01914 dbus_bool_t
01915 _dbus_create_directory (const DBusString *filename,
01916 DBusError *error)
01917 {
01918 const char *filename_c;
01919
01920 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01921
01922 filename_c = _dbus_string_get_const_data (filename);
01923
01924 if (mkdir (filename_c, 0700) < 0)
01925 {
01926 if (errno == EEXIST)
01927 return TRUE;
01928
01929 dbus_set_error (error, DBUS_ERROR_FAILED,
01930 "Failed to create directory %s: %s\n",
01931 filename_c, _dbus_strerror (errno));
01932 return FALSE;
01933 }
01934 else
01935 return TRUE;
01936 }
01937
01948 dbus_bool_t
01949 _dbus_concat_dir_and_file (DBusString *dir,
01950 const DBusString *next_component)
01951 {
01952 dbus_bool_t dir_ends_in_slash;
01953 dbus_bool_t file_starts_with_slash;
01954
01955 if (_dbus_string_get_length (dir) == 0 ||
01956 _dbus_string_get_length (next_component) == 0)
01957 return TRUE;
01958
01959 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
01960 _dbus_string_get_length (dir) - 1);
01961
01962 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
01963
01964 if (dir_ends_in_slash && file_starts_with_slash)
01965 {
01966 _dbus_string_shorten (dir, 1);
01967 }
01968 else if (!(dir_ends_in_slash || file_starts_with_slash))
01969 {
01970 if (!_dbus_string_append_byte (dir, '/'))
01971 return FALSE;
01972 }
01973
01974 return _dbus_string_copy (next_component, 0, dir,
01975 _dbus_string_get_length (dir));
01976 }
01977
01979 #define NANOSECONDS_PER_SECOND 1000000000
01980
01981 #define MICROSECONDS_PER_SECOND 1000000
01982
01983 #define MILLISECONDS_PER_SECOND 1000
01984
01985 #define NANOSECONDS_PER_MILLISECOND 1000000
01986
01987 #define MICROSECONDS_PER_MILLISECOND 1000
01988
01993 void
01994 _dbus_sleep_milliseconds (int milliseconds)
01995 {
01996 #ifdef HAVE_NANOSLEEP
01997 struct timespec req;
01998 struct timespec rem;
01999
02000 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02001 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02002 rem.tv_sec = 0;
02003 rem.tv_nsec = 0;
02004
02005 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02006 req = rem;
02007 #elif defined (HAVE_USLEEP)
02008 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02009 #else
02010 sleep (MAX (milliseconds / 1000, 1));
02011 #endif
02012 }
02013
02014 static dbus_bool_t
02015 _dbus_generate_pseudorandom_bytes (DBusString *str,
02016 int n_bytes)
02017 {
02018 int old_len;
02019 char *p;
02020
02021 old_len = _dbus_string_get_length (str);
02022
02023 if (!_dbus_string_lengthen (str, n_bytes))
02024 return FALSE;
02025
02026 p = _dbus_string_get_data_len (str, old_len, n_bytes);
02027
02028 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02029
02030 return TRUE;
02031 }
02032
02041 dbus_bool_t
02042 _dbus_generate_random_bytes (DBusString *str,
02043 int n_bytes)
02044 {
02045 int old_len;
02046 int fd;
02047
02048
02049
02050
02051
02052
02053
02054 old_len = _dbus_string_get_length (str);
02055 fd = -1;
02056
02057
02058 fd = open ("/dev/urandom", O_RDONLY);
02059 if (fd < 0)
02060 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02061
02062 if (_dbus_read (fd, str, n_bytes) != n_bytes)
02063 {
02064 _dbus_close (fd, NULL);
02065 _dbus_string_set_length (str, old_len);
02066 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02067 }
02068
02069 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02070 n_bytes);
02071
02072 _dbus_close (fd, NULL);
02073
02074 return TRUE;
02075 }
02076
02082 void
02083 _dbus_exit (int code)
02084 {
02085 _exit (code);
02086 }
02087
02095 const char*
02096 _dbus_strerror (int error_number)
02097 {
02098 const char *msg;
02099
02100 msg = strerror (error_number);
02101 if (msg == NULL)
02102 msg = "unknown";
02103
02104 return msg;
02105 }
02106
02110 void
02111 _dbus_disable_sigpipe (void)
02112 {
02113 signal (SIGPIPE, SIG_IGN);
02114 }
02115
02123 void
02124 _dbus_fd_set_close_on_exec (int fd)
02125 {
02126 int val;
02127
02128 val = fcntl (fd, F_GETFD, 0);
02129
02130 if (val < 0)
02131 return;
02132
02133 val |= FD_CLOEXEC;
02134
02135 fcntl (fd, F_SETFD, val);
02136 }
02137
02145 dbus_bool_t
02146 _dbus_close (int fd,
02147 DBusError *error)
02148 {
02149 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02150
02151 again:
02152 if (close (fd) < 0)
02153 {
02154 if (errno == EINTR)
02155 goto again;
02156
02157 dbus_set_error (error, _dbus_error_from_errno (errno),
02158 "Could not close fd %d", fd);
02159 return FALSE;
02160 }
02161
02162 return TRUE;
02163 }
02164
02172 dbus_bool_t
02173 _dbus_set_fd_nonblocking (int fd,
02174 DBusError *error)
02175 {
02176 int val;
02177
02178 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02179
02180 val = fcntl (fd, F_GETFL, 0);
02181 if (val < 0)
02182 {
02183 dbus_set_error (error, _dbus_error_from_errno (errno),
02184 "Failed to get flags from file descriptor %d: %s",
02185 fd, _dbus_strerror (errno));
02186 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02187 _dbus_strerror (errno));
02188 return FALSE;
02189 }
02190
02191 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02192 {
02193 dbus_set_error (error, _dbus_error_from_errno (errno),
02194 "Failed to set nonblocking flag of file descriptor %d: %s",
02195 fd, _dbus_strerror (errno));
02196 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02197 fd, _dbus_strerror (errno));
02198
02199 return FALSE;
02200 }
02201
02202 return TRUE;
02203 }
02204
02210 void
02211 _dbus_print_backtrace (void)
02212 {
02213 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02214 void *bt[500];
02215 int bt_size;
02216 int i;
02217 char **syms;
02218
02219 bt_size = backtrace (bt, 500);
02220
02221 syms = backtrace_symbols (bt, bt_size);
02222
02223 i = 0;
02224 while (i < bt_size)
02225 {
02226
02227 fprintf (stderr, " %s\n", syms[i]);
02228 ++i;
02229 }
02230 fflush (stderr);
02231
02232 free (syms);
02233 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02234 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
02235 #else
02236 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02237 #endif
02238 }
02239
02255 dbus_bool_t
02256 _dbus_full_duplex_pipe (int *fd1,
02257 int *fd2,
02258 dbus_bool_t blocking,
02259 DBusError *error)
02260 {
02261 #ifdef HAVE_SOCKETPAIR
02262 int fds[2];
02263
02264 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02265
02266 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
02267 {
02268 dbus_set_error (error, _dbus_error_from_errno (errno),
02269 "Could not create full-duplex pipe");
02270 return FALSE;
02271 }
02272
02273 if (!blocking &&
02274 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02275 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02276 {
02277 dbus_set_error (error, _dbus_error_from_errno (errno),
02278 "Could not set full-duplex pipe nonblocking");
02279
02280 _dbus_close (fds[0], NULL);
02281 _dbus_close (fds[1], NULL);
02282
02283 return FALSE;
02284 }
02285
02286 *fd1 = fds[0];
02287 *fd2 = fds[1];
02288
02289 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02290 *fd1, *fd2);
02291
02292 return TRUE;
02293 #else
02294 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02295 dbus_set_error (error, DBUS_ERROR_FAILED,
02296 "_dbus_full_duplex_pipe() not implemented on this OS");
02297 return FALSE;
02298 #endif
02299 }
02300
02301
02310 int
02311 _dbus_printf_string_upper_bound (const char *format,
02312 va_list args)
02313 {
02314 char c;
02315 return vsnprintf (&c, 1, format, args);
02316 }
02317
02324 const char*
02325 _dbus_get_tmpdir(void)
02326 {
02327 static const char* tmpdir = NULL;
02328
02329 if (tmpdir == NULL)
02330 {
02331
02332
02333
02334
02335 if (tmpdir == NULL)
02336 tmpdir = getenv("TMPDIR");
02337
02338
02339
02340
02341 if (tmpdir == NULL)
02342 tmpdir = getenv("TMP");
02343 if (tmpdir == NULL)
02344 tmpdir = getenv("TEMP");
02345
02346
02347 if (tmpdir == NULL)
02348 tmpdir = "/tmp";
02349 }
02350
02351 _dbus_assert(tmpdir != NULL);
02352
02353 return tmpdir;
02354 }
02355
02368 dbus_bool_t
02369 _dbus_get_autolaunch_address (DBusString *address,
02370 DBusError *error)
02371 {
02372 static char *argv[5];
02373 int address_pipe[2];
02374 pid_t pid;
02375 int ret;
02376 int status;
02377 int orig_len;
02378 int i;
02379 DBusString uuid;
02380 dbus_bool_t retval;
02381
02382 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02383 retval = FALSE;
02384
02385 _dbus_string_init (&uuid);
02386
02387 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
02388 {
02389 _DBUS_SET_OOM (error);
02390 goto out;
02391 }
02392
02393 i = 0;
02394 argv[i] = "dbus-launch";
02395 ++i;
02396 argv[i] = "--autolaunch";
02397 ++i;
02398 argv[i] = _dbus_string_get_data (&uuid);
02399 ++i;
02400 argv[i] = "--binary-syntax";
02401 ++i;
02402 argv[i] = NULL;
02403 ++i;
02404
02405 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
02406
02407 orig_len = _dbus_string_get_length (address);
02408
02409 #define READ_END 0
02410 #define WRITE_END 1
02411 if (pipe (address_pipe) < 0)
02412 {
02413 dbus_set_error (error, _dbus_error_from_errno (errno),
02414 "Failed to create a pipe: %s",
02415 _dbus_strerror (errno));
02416 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
02417 _dbus_strerror (errno));
02418 goto out;
02419 }
02420
02421 pid = fork ();
02422 if (pid < 0)
02423 {
02424 dbus_set_error (error, _dbus_error_from_errno (errno),
02425 "Failed to fork(): %s",
02426 _dbus_strerror (errno));
02427 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
02428 _dbus_strerror (errno));
02429 goto out;
02430 }
02431
02432 if (pid == 0)
02433 {
02434
02435 int fd = open ("/dev/null", O_RDWR);
02436 if (fd == -1)
02437
02438 _exit (1);
02439
02440
02441 close (address_pipe[READ_END]);
02442 close (0);
02443 close (1);
02444 close (2);
02445
02446 if (dup2 (fd, 0) == -1)
02447 _exit (1);
02448 if (dup2 (address_pipe[WRITE_END], 1) == -1)
02449 _exit (1);
02450 if (dup2 (fd, 2) == -1)
02451 _exit (1);
02452
02453 close (fd);
02454 close (address_pipe[WRITE_END]);
02455
02456 execv (DBUS_BINDIR "/dbus-launch", argv);
02457
02458
02459 execvp ("dbus-launch", argv);
02460
02461
02462 _exit (1);
02463 }
02464
02465
02466 close (address_pipe[WRITE_END]);
02467 ret = 0;
02468 do
02469 {
02470 ret = _dbus_read (address_pipe[READ_END], address, 1024);
02471 }
02472 while (ret > 0);
02473
02474
02475 do
02476 {
02477 ret = waitpid (pid, &status, 0);
02478 }
02479 while (ret == -1 && errno == EINTR);
02480
02481
02482
02483 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
02484 _dbus_string_get_length (address) == orig_len)
02485 {
02486
02487 _dbus_string_set_length (address, orig_len);
02488 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
02489 "Failed to execute dbus-launch to autolaunch D-Bus session");
02490 goto out;
02491 }
02492
02493 retval = TRUE;
02494
02495 out:
02496 if (retval)
02497 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02498 else
02499 _DBUS_ASSERT_ERROR_IS_SET (error);
02500
02501 _dbus_string_free (&uuid);
02502 return retval;
02503 }
02504
02523 dbus_bool_t
02524 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
02525 dbus_bool_t create_if_not_found,
02526 DBusError *error)
02527 {
02528 DBusString filename;
02529 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
02530 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
02531 }
02532
02533 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
02534
02535 static dbus_bool_t
02536 split_paths_and_append (DBusString *dirs,
02537 const char *suffix,
02538 DBusList **dir_list)
02539 {
02540
02541 int start;
02542 int i;
02543 int len;
02544 char *cpath;
02545 const DBusString file_suffix;
02546
02547 start = 0;
02548 i = 0;
02549
02550 _dbus_string_init_const (&file_suffix, suffix);
02551
02552 len = _dbus_string_get_length (dirs);
02553
02554 while (_dbus_string_find (dirs, start, ":", &i))
02555 {
02556 DBusString path;
02557
02558 if (!_dbus_string_init (&path))
02559 goto oom;
02560
02561 if (!_dbus_string_copy_len (dirs,
02562 start,
02563 i - start,
02564 &path,
02565 0))
02566 {
02567 _dbus_string_free (&path);
02568 goto oom;
02569 }
02570
02571 _dbus_string_chop_white (&path);
02572
02573
02574 if (_dbus_string_get_length (&path) == 0)
02575 goto next;
02576
02577 if (!_dbus_concat_dir_and_file (&path,
02578 &file_suffix))
02579 {
02580 _dbus_string_free (&path);
02581 goto oom;
02582 }
02583
02584 if (!_dbus_string_copy_data(&path, &cpath))
02585 {
02586 _dbus_string_free (&path);
02587 goto oom;
02588 }
02589
02590 if (!_dbus_list_append (dir_list, cpath))
02591 {
02592 _dbus_string_free (&path);
02593 dbus_free (cpath);
02594 goto oom;
02595 }
02596
02597 next:
02598 _dbus_string_free (&path);
02599 start = i + 1;
02600 }
02601
02602 if (start != len)
02603 {
02604 DBusString path;
02605
02606 if (!_dbus_string_init (&path))
02607 goto oom;
02608
02609 if (!_dbus_string_copy_len (dirs,
02610 start,
02611 len - start,
02612 &path,
02613 0))
02614 {
02615 _dbus_string_free (&path);
02616 goto oom;
02617 }
02618
02619 if (!_dbus_concat_dir_and_file (&path,
02620 &file_suffix))
02621 {
02622 _dbus_string_free (&path);
02623 goto oom;
02624 }
02625
02626 if (!_dbus_string_copy_data(&path, &cpath))
02627 {
02628 _dbus_string_free (&path);
02629 goto oom;
02630 }
02631
02632 if (!_dbus_list_append (dir_list, cpath))
02633 {
02634 _dbus_string_free (&path);
02635 dbus_free (cpath);
02636 goto oom;
02637 }
02638
02639 _dbus_string_free (&path);
02640 }
02641
02642 return TRUE;
02643
02644 oom:
02645 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);
02646 _dbus_list_clear (dir_list);
02647 return FALSE;
02648 }
02649
02667 dbus_bool_t
02668 _dbus_get_standard_session_servicedirs (DBusList **dirs)
02669 {
02670 const char *xdg_data_home;
02671 const char *xdg_data_dirs;
02672 DBusString servicedir_path;
02673
02674 if (!_dbus_string_init (&servicedir_path))
02675 return FALSE;
02676
02677 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
02678 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
02679
02680 if (xdg_data_dirs != NULL)
02681 {
02682 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
02683 goto oom;
02684
02685 if (!_dbus_string_append (&servicedir_path, ":"))
02686 goto oom;
02687 }
02688 else
02689 {
02690 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
02691 goto oom;
02692 }
02693
02694
02695
02696
02697
02698
02699
02700 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
02701 goto oom;
02702
02703 if (xdg_data_home != NULL)
02704 {
02705 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
02706 goto oom;
02707 }
02708 else
02709 {
02710 const DBusString *homedir;
02711 const DBusString local_share;
02712
02713 if (!_dbus_homedir_from_current_process (&homedir))
02714 goto oom;
02715
02716 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
02717 goto oom;
02718
02719 _dbus_string_init_const (&local_share, "/.local/share");
02720 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
02721 goto oom;
02722 }
02723
02724 if (!split_paths_and_append (&servicedir_path,
02725 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
02726 dirs))
02727 goto oom;
02728
02729 _dbus_string_free (&servicedir_path);
02730 return TRUE;
02731
02732 oom:
02733 _dbus_string_free (&servicedir_path);
02734 return FALSE;
02735 }
02736
02737