• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37 #include "dbus-nonce.h"
38 
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <unistd.h>
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <sys/socket.h>
47 #include <dirent.h>
48 #include <sys/un.h>
49 #include <pwd.h>
50 #include <time.h>
51 #include <locale.h>
52 #include <sys/time.h>
53 #include <sys/stat.h>
54 #include <sys/wait.h>
55 #include <netinet/in.h>
56 #include <netdb.h>
57 #include <grp.h>
58 #include <cutils/sockets.h>
59 
60 #ifdef HAVE_ERRNO_H
61 #include <errno.h>
62 #endif
63 #ifdef HAVE_WRITEV
64 #include <sys/uio.h>
65 #endif
66 #ifdef HAVE_POLL
67 #include <sys/poll.h>
68 #endif
69 #ifdef HAVE_BACKTRACE
70 #include <execinfo.h>
71 #endif
72 #ifdef HAVE_GETPEERUCRED
73 #include <ucred.h>
74 #endif
75 
76 #ifdef HAVE_ADT
77 #include <bsm/adt.h>
78 #endif
79 
80 // Android specific atomic operation header.
81 #ifdef ANDROID_ATOMIC
82 #include <cutils/atomic.h>
83 #endif
84 
85 #include "sd-daemon.h"
86 
87 #ifndef O_BINARY
88 #define O_BINARY 0
89 #endif
90 
91 #ifndef AI_ADDRCONFIG
92 #define AI_ADDRCONFIG 0
93 #endif
94 
95 #ifndef HAVE_SOCKLEN_T
96 #define socklen_t int
97 #endif
98 
99 static dbus_bool_t
_dbus_open_socket(int * fd_p,int domain,int type,int protocol,DBusError * error)100 _dbus_open_socket (int              *fd_p,
101                    int               domain,
102                    int               type,
103                    int               protocol,
104                    DBusError        *error)
105 {
106 #ifdef SOCK_CLOEXEC
107   dbus_bool_t cloexec_done;
108 
109   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
110   cloexec_done = *fd_p >= 0;
111 
112   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
113   if (*fd_p < 0 && errno == EINVAL)
114 #endif
115     {
116       *fd_p = socket (domain, type, protocol);
117     }
118 
119   if (*fd_p >= 0)
120     {
121 #ifdef SOCK_CLOEXEC
122       if (!cloexec_done)
123 #endif
124         {
125           _dbus_fd_set_close_on_exec(*fd_p);
126         }
127 
128       _dbus_verbose ("socket fd %d opened\n", *fd_p);
129       return TRUE;
130     }
131   else
132     {
133       dbus_set_error(error,
134                      _dbus_error_from_errno (errno),
135                      "Failed to open socket: %s",
136                      _dbus_strerror (errno));
137       return FALSE;
138     }
139 }
140 
141 dbus_bool_t
_dbus_open_tcp_socket(int * fd,DBusError * error)142 _dbus_open_tcp_socket (int              *fd,
143                        DBusError        *error)
144 {
145   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
146 }
147 
148 /**
149  * Opens a UNIX domain socket (as in the socket() call).
150  * Does not bind the socket.
151  *
152  * This will set FD_CLOEXEC for the socket returned
153  *
154  * @param fd return location for socket descriptor
155  * @param error return location for an error
156  * @returns #FALSE if error is set
157  */
158 dbus_bool_t
_dbus_open_unix_socket(int * fd,DBusError * error)159 _dbus_open_unix_socket (int              *fd,
160                         DBusError        *error)
161 {
162   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
163 }
164 
165 /**
166  * Closes a socket. Should not be used on non-socket
167  * file descriptors or handles.
168  *
169  * @param fd the socket
170  * @param error return location for an error
171  * @returns #FALSE if error is set
172  */
173 dbus_bool_t
_dbus_close_socket(int fd,DBusError * error)174 _dbus_close_socket (int               fd,
175                     DBusError        *error)
176 {
177   return _dbus_close (fd, error);
178 }
179 
180 /**
181  * Like _dbus_read(), but only works on sockets so is
182  * available on Windows.
183  *
184  * @param fd the socket
185  * @param buffer string to append data to
186  * @param count max amount of data to read
187  * @returns number of bytes appended to the string
188  */
189 int
_dbus_read_socket(int fd,DBusString * buffer,int count)190 _dbus_read_socket (int               fd,
191                    DBusString       *buffer,
192                    int               count)
193 {
194   return _dbus_read (fd, buffer, count);
195 }
196 
197 /**
198  * Like _dbus_write(), but only supports sockets
199  * and is thus available on Windows.
200  *
201  * @param fd the file descriptor to write
202  * @param buffer the buffer to write data from
203  * @param start the first byte in the buffer to write
204  * @param len the number of bytes to try to write
205  * @returns the number of bytes written or -1 on error
206  */
207 int
_dbus_write_socket(int fd,const DBusString * buffer,int start,int len)208 _dbus_write_socket (int               fd,
209                     const DBusString *buffer,
210                     int               start,
211                     int               len)
212 {
213 #ifdef MSG_NOSIGNAL
214   const char *data;
215   int bytes_written;
216 
217   data = _dbus_string_get_const_data_len (buffer, start, len);
218 
219  again:
220 
221   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
222 
223   if (bytes_written < 0 && errno == EINTR)
224     goto again;
225 
226   return bytes_written;
227 
228 #else
229   return _dbus_write (fd, buffer, start, len);
230 #endif
231 }
232 
233 /**
234  * Like _dbus_read_socket() but also tries to read unix fds from the
235  * socket. When there are more fds to read than space in the array
236  * passed this function will fail with ENOSPC.
237  *
238  * @param fd the socket
239  * @param buffer string to append data to
240  * @param count max amount of data to read
241  * @param fds array to place read file descriptors in
242  * @param n_fds on input space in fds array, on output how many fds actually got read
243  * @returns number of bytes appended to string
244  */
245 int
_dbus_read_socket_with_unix_fds(int fd,DBusString * buffer,int count,int * fds,int * n_fds)246 _dbus_read_socket_with_unix_fds (int               fd,
247                                  DBusString       *buffer,
248                                  int               count,
249                                  int              *fds,
250                                  int              *n_fds) {
251 #ifndef HAVE_UNIX_FD_PASSING
252   int r;
253 
254   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
255     return r;
256 
257   *n_fds = 0;
258   return r;
259 
260 #else
261   int bytes_read;
262   int start;
263   struct msghdr m;
264   struct iovec iov;
265 
266   _dbus_assert (count >= 0);
267   _dbus_assert (*n_fds >= 0);
268 
269   start = _dbus_string_get_length (buffer);
270 
271   if (!_dbus_string_lengthen (buffer, count))
272     {
273       errno = ENOMEM;
274       return -1;
275     }
276 
277   _DBUS_ZERO(iov);
278   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
279   iov.iov_len = count;
280 
281   _DBUS_ZERO(m);
282   m.msg_iov = &iov;
283   m.msg_iovlen = 1;
284 
285   /* Hmm, we have no clue how long the control data will actually be
286      that is queued for us. The least we can do is assume that the
287      caller knows. Hence let's make space for the number of fds that
288      we shall read at max plus the cmsg header. */
289   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
290 
291   /* It's probably safe to assume that systems with SCM_RIGHTS also
292      know alloca() */
293   m.msg_control = alloca(m.msg_controllen);
294   memset(m.msg_control, 0, m.msg_controllen);
295 
296  again:
297 
298   bytes_read = recvmsg(fd, &m, 0
299 #ifdef MSG_CMSG_CLOEXEC
300                        |MSG_CMSG_CLOEXEC
301 #endif
302                        );
303 
304   if (bytes_read < 0)
305     {
306       if (errno == EINTR)
307         goto again;
308       else
309         {
310           /* put length back (note that this doesn't actually realloc anything) */
311           _dbus_string_set_length (buffer, start);
312           return -1;
313         }
314     }
315   else
316     {
317       struct cmsghdr *cm;
318       dbus_bool_t found = FALSE;
319 
320       if (m.msg_flags & MSG_CTRUNC)
321         {
322           /* Hmm, apparently the control data was truncated. The bad
323              thing is that we might have completely lost a couple of fds
324              without chance to recover them. Hence let's treat this as a
325              serious error. */
326 
327           errno = ENOSPC;
328           _dbus_string_set_length (buffer, start);
329           return -1;
330         }
331 
332       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
333         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
334           {
335             unsigned i;
336 
337             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
338             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
339 
340             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
341             found = TRUE;
342 
343             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
344                worked, hence we need to go through this list and set
345                CLOEXEC everywhere in any case */
346             for (i = 0; i < *n_fds; i++)
347               _dbus_fd_set_close_on_exec(fds[i]);
348 
349             break;
350           }
351 
352       if (!found)
353         *n_fds = 0;
354 
355       /* put length back (doesn't actually realloc) */
356       _dbus_string_set_length (buffer, start + bytes_read);
357 
358 #if 0
359       if (bytes_read > 0)
360         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
361 #endif
362 
363       return bytes_read;
364     }
365 #endif
366 }
367 
368 int
_dbus_write_socket_with_unix_fds(int fd,const DBusString * buffer,int start,int len,const int * fds,int n_fds)369 _dbus_write_socket_with_unix_fds(int               fd,
370                                  const DBusString *buffer,
371                                  int               start,
372                                  int               len,
373                                  const int        *fds,
374                                  int               n_fds) {
375 
376 #ifndef HAVE_UNIX_FD_PASSING
377 
378   if (n_fds > 0) {
379     errno = ENOTSUP;
380     return -1;
381   }
382 
383   return _dbus_write_socket(fd, buffer, start, len);
384 #else
385   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
386 #endif
387 }
388 
389 int
_dbus_write_socket_with_unix_fds_two(int fd,const DBusString * buffer1,int start1,int len1,const DBusString * buffer2,int start2,int len2,const int * fds,int n_fds)390 _dbus_write_socket_with_unix_fds_two(int               fd,
391                                      const DBusString *buffer1,
392                                      int               start1,
393                                      int               len1,
394                                      const DBusString *buffer2,
395                                      int               start2,
396                                      int               len2,
397                                      const int        *fds,
398                                      int               n_fds) {
399 
400 #ifndef HAVE_UNIX_FD_PASSING
401 
402   if (n_fds > 0) {
403     errno = ENOTSUP;
404     return -1;
405   }
406 
407   return _dbus_write_socket_two(fd,
408                                 buffer1, start1, len1,
409                                 buffer2, start2, len2);
410 #else
411 
412   struct msghdr m;
413   struct cmsghdr *cm;
414   struct iovec iov[2];
415   int bytes_written;
416 
417   _dbus_assert (len1 >= 0);
418   _dbus_assert (len2 >= 0);
419   _dbus_assert (n_fds >= 0);
420 
421   _DBUS_ZERO(iov);
422   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
423   iov[0].iov_len = len1;
424 
425   if (buffer2)
426     {
427       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
428       iov[1].iov_len = len2;
429     }
430 
431   _DBUS_ZERO(m);
432   m.msg_iov = iov;
433   m.msg_iovlen = buffer2 ? 2 : 1;
434 
435   if (n_fds > 0)
436     {
437       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
438       m.msg_control = alloca(m.msg_controllen);
439       memset(m.msg_control, 0, m.msg_controllen);
440 
441       cm = CMSG_FIRSTHDR(&m);
442       cm->cmsg_level = SOL_SOCKET;
443       cm->cmsg_type = SCM_RIGHTS;
444       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
445       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
446     }
447 
448  again:
449 
450   bytes_written = sendmsg (fd, &m, 0
451 #ifdef MSG_NOSIGNAL
452                            |MSG_NOSIGNAL
453 #endif
454                            );
455 
456   if (bytes_written < 0 && errno == EINTR)
457     goto again;
458 
459 #if 0
460   if (bytes_written > 0)
461     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
462 #endif
463 
464   return bytes_written;
465 #endif
466 }
467 
468 /**
469  * Like _dbus_write_two() but only works on sockets and is thus
470  * available on Windows.
471  *
472  * @param fd the file descriptor
473  * @param buffer1 first buffer
474  * @param start1 first byte to write in first buffer
475  * @param len1 number of bytes to write from first buffer
476  * @param buffer2 second buffer, or #NULL
477  * @param start2 first byte to write in second buffer
478  * @param len2 number of bytes to write in second buffer
479  * @returns total bytes written from both buffers, or -1 on error
480  */
481 int
_dbus_write_socket_two(int fd,const DBusString * buffer1,int start1,int len1,const DBusString * buffer2,int start2,int len2)482 _dbus_write_socket_two (int               fd,
483                         const DBusString *buffer1,
484                         int               start1,
485                         int               len1,
486                         const DBusString *buffer2,
487                         int               start2,
488                         int               len2)
489 {
490 #ifdef MSG_NOSIGNAL
491   struct iovec vectors[2];
492   const char *data1;
493   const char *data2;
494   int bytes_written;
495   struct msghdr m;
496 
497   _dbus_assert (buffer1 != NULL);
498   _dbus_assert (start1 >= 0);
499   _dbus_assert (start2 >= 0);
500   _dbus_assert (len1 >= 0);
501   _dbus_assert (len2 >= 0);
502 
503   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
504 
505   if (buffer2 != NULL)
506     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
507   else
508     {
509       data2 = NULL;
510       start2 = 0;
511       len2 = 0;
512     }
513 
514   vectors[0].iov_base = (char*) data1;
515   vectors[0].iov_len = len1;
516   vectors[1].iov_base = (char*) data2;
517   vectors[1].iov_len = len2;
518 
519   _DBUS_ZERO(m);
520   m.msg_iov = vectors;
521   m.msg_iovlen = data2 ? 2 : 1;
522 
523  again:
524 
525   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
526 
527   if (bytes_written < 0 && errno == EINTR)
528     goto again;
529 
530   return bytes_written;
531 
532 #else
533   return _dbus_write_two (fd, buffer1, start1, len1,
534                           buffer2, start2, len2);
535 #endif
536 }
537 
538 dbus_bool_t
_dbus_socket_is_invalid(int fd)539 _dbus_socket_is_invalid (int fd)
540 {
541     return fd < 0 ? TRUE : FALSE;
542 }
543 
544 /**
545  * Thin wrapper around the read() system call that appends
546  * the data it reads to the DBusString buffer. It appends
547  * up to the given count, and returns the same value
548  * and same errno as read(). The only exception is that
549  * _dbus_read() handles EINTR for you. Also, _dbus_read() can
550  * return ENOMEM, even though regular UNIX read doesn't.
551  *
552  * Unlike _dbus_read_socket(), _dbus_read() is not available
553  * on Windows.
554  *
555  * @param fd the file descriptor to read from
556  * @param buffer the buffer to append data to
557  * @param count the amount of data to read
558  * @returns the number of bytes read or -1
559  */
560 int
_dbus_read(int fd,DBusString * buffer,int count)561 _dbus_read (int               fd,
562             DBusString       *buffer,
563             int               count)
564 {
565   int bytes_read;
566   int start;
567   char *data;
568 
569   _dbus_assert (count >= 0);
570 
571   start = _dbus_string_get_length (buffer);
572 
573   if (!_dbus_string_lengthen (buffer, count))
574     {
575       errno = ENOMEM;
576       return -1;
577     }
578 
579   data = _dbus_string_get_data_len (buffer, start, count);
580 
581  again:
582 
583   bytes_read = read (fd, data, count);
584 
585   if (bytes_read < 0)
586     {
587       if (errno == EINTR)
588         goto again;
589       else
590         {
591           /* put length back (note that this doesn't actually realloc anything) */
592           _dbus_string_set_length (buffer, start);
593           return -1;
594         }
595     }
596   else
597     {
598       /* put length back (doesn't actually realloc) */
599       _dbus_string_set_length (buffer, start + bytes_read);
600 
601 #if 0
602       if (bytes_read > 0)
603         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
604 #endif
605 
606       return bytes_read;
607     }
608 }
609 
610 /**
611  * Thin wrapper around the write() system call that writes a part of a
612  * DBusString and handles EINTR for you.
613  *
614  * @param fd the file descriptor to write
615  * @param buffer the buffer to write data from
616  * @param start the first byte in the buffer to write
617  * @param len the number of bytes to try to write
618  * @returns the number of bytes written or -1 on error
619  */
620 int
_dbus_write(int fd,const DBusString * buffer,int start,int len)621 _dbus_write (int               fd,
622              const DBusString *buffer,
623              int               start,
624              int               len)
625 {
626   const char *data;
627   int bytes_written;
628 
629   data = _dbus_string_get_const_data_len (buffer, start, len);
630 
631  again:
632 
633   bytes_written = write (fd, data, len);
634 
635   if (bytes_written < 0 && errno == EINTR)
636     goto again;
637 
638 #if 0
639   if (bytes_written > 0)
640     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
641 #endif
642 
643   return bytes_written;
644 }
645 
646 /**
647  * Like _dbus_write() but will use writev() if possible
648  * to write both buffers in sequence. The return value
649  * is the number of bytes written in the first buffer,
650  * plus the number written in the second. If the first
651  * buffer is written successfully and an error occurs
652  * writing the second, the number of bytes in the first
653  * is returned (i.e. the error is ignored), on systems that
654  * don't have writev. Handles EINTR for you.
655  * The second buffer may be #NULL.
656  *
657  * @param fd the file descriptor
658  * @param buffer1 first buffer
659  * @param start1 first byte to write in first buffer
660  * @param len1 number of bytes to write from first buffer
661  * @param buffer2 second buffer, or #NULL
662  * @param start2 first byte to write in second buffer
663  * @param len2 number of bytes to write in second buffer
664  * @returns total bytes written from both buffers, or -1 on error
665  */
666 int
_dbus_write_two(int fd,const DBusString * buffer1,int start1,int len1,const DBusString * buffer2,int start2,int len2)667 _dbus_write_two (int               fd,
668                  const DBusString *buffer1,
669                  int               start1,
670                  int               len1,
671                  const DBusString *buffer2,
672                  int               start2,
673                  int               len2)
674 {
675   _dbus_assert (buffer1 != NULL);
676   _dbus_assert (start1 >= 0);
677   _dbus_assert (start2 >= 0);
678   _dbus_assert (len1 >= 0);
679   _dbus_assert (len2 >= 0);
680 
681 #ifdef HAVE_WRITEV
682   {
683     struct iovec vectors[2];
684     const char *data1;
685     const char *data2;
686     int bytes_written;
687 
688     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
689 
690     if (buffer2 != NULL)
691       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
692     else
693       {
694         data2 = NULL;
695         start2 = 0;
696         len2 = 0;
697       }
698 
699     vectors[0].iov_base = (char*) data1;
700     vectors[0].iov_len = len1;
701     vectors[1].iov_base = (char*) data2;
702     vectors[1].iov_len = len2;
703 
704   again:
705 
706     bytes_written = writev (fd,
707                             vectors,
708                             data2 ? 2 : 1);
709 
710     if (bytes_written < 0 && errno == EINTR)
711       goto again;
712 
713     return bytes_written;
714   }
715 #else /* HAVE_WRITEV */
716   {
717     int ret1;
718 
719     ret1 = _dbus_write (fd, buffer1, start1, len1);
720     if (ret1 == len1 && buffer2 != NULL)
721       {
722         ret2 = _dbus_write (fd, buffer2, start2, len2);
723         if (ret2 < 0)
724           ret2 = 0; /* we can't report an error as the first write was OK */
725 
726         return ret1 + ret2;
727       }
728     else
729       return ret1;
730   }
731 #endif /* !HAVE_WRITEV */
732 }
733 
734 #define _DBUS_MAX_SUN_PATH_LENGTH 99
735 
736 /**
737  * @def _DBUS_MAX_SUN_PATH_LENGTH
738  *
739  * Maximum length of the path to a UNIX domain socket,
740  * sockaddr_un::sun_path member. POSIX requires that all systems
741  * support at least 100 bytes here, including the nul termination.
742  * We use 99 for the max value to allow for the nul.
743  *
744  * We could probably also do sizeof (addr.sun_path)
745  * but this way we are the same on all platforms
746  * which is probably a good idea.
747  */
748 
749 /**
750  * Creates a socket and connects it to the UNIX domain socket at the
751  * given path.  The connection fd is returned, and is set up as
752  * nonblocking.
753  *
754  * Uses abstract sockets instead of filesystem-linked sockets if
755  * requested (it's possible only on Linux; see "man 7 unix" on Linux).
756  * On non-Linux abstract socket usage always fails.
757  *
758  * This will set FD_CLOEXEC for the socket returned.
759  *
760  * @param path the path to UNIX domain socket
761  * @param abstract #TRUE to use abstract namespace
762  * @param error return location for error code
763  * @returns connection file descriptor or -1 on error
764  */
765 int
_dbus_connect_unix_socket(const char * path,dbus_bool_t abstract,DBusError * error)766 _dbus_connect_unix_socket (const char     *path,
767                            dbus_bool_t     abstract,
768                            DBusError      *error)
769 {
770   int fd;
771   size_t path_len;
772   struct sockaddr_un addr;
773 
774   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
775 
776   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
777                  path, abstract);
778 
779 
780   if (!_dbus_open_unix_socket (&fd, error))
781     {
782       _DBUS_ASSERT_ERROR_IS_SET(error);
783       return -1;
784     }
785   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
786 
787   _DBUS_ZERO (addr);
788   addr.sun_family = AF_UNIX;
789   path_len = strlen (path);
790 
791   if (abstract)
792     {
793 #ifdef HAVE_ABSTRACT_SOCKETS
794       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
795       path_len++; /* Account for the extra nul byte added to the start of sun_path */
796 
797       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
798         {
799           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
800                       "Abstract socket name too long\n");
801           _dbus_close (fd, NULL);
802           return -1;
803 	}
804 
805       strncpy (&addr.sun_path[1], path, path_len);
806       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
807 #else /* HAVE_ABSTRACT_SOCKETS */
808       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
809                       "Operating system does not support abstract socket namespace\n");
810       _dbus_close (fd, NULL);
811       return -1;
812 #endif /* ! HAVE_ABSTRACT_SOCKETS */
813     }
814   else
815     {
816       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
817         {
818           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
819                       "Socket name too long\n");
820           _dbus_close (fd, NULL);
821           return -1;
822 	}
823 
824       strncpy (addr.sun_path, path, path_len);
825     }
826 
827   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
828     {
829       dbus_set_error (error,
830                       _dbus_error_from_errno (errno),
831                       "Failed to connect to socket %s: %s",
832                       path, _dbus_strerror (errno));
833 
834       _dbus_close (fd, NULL);
835       fd = -1;
836 
837       return -1;
838     }
839 
840   if (!_dbus_set_fd_nonblocking (fd, error))
841     {
842       _DBUS_ASSERT_ERROR_IS_SET (error);
843 
844       _dbus_close (fd, NULL);
845       fd = -1;
846 
847       return -1;
848     }
849 
850   return fd;
851 }
852 
853 /**
854  * Enables or disables the reception of credentials on the given socket during
855  * the next message transmission.  This is only effective if the #LOCAL_CREDS
856  * system feature exists, in which case the other side of the connection does
857  * not have to do anything special to send the credentials.
858  *
859  * @param fd socket on which to change the #LOCAL_CREDS flag.
860  * @param on whether to enable or disable the #LOCAL_CREDS flag.
861  */
862 static dbus_bool_t
_dbus_set_local_creds(int fd,dbus_bool_t on)863 _dbus_set_local_creds (int fd, dbus_bool_t on)
864 {
865   dbus_bool_t retval = TRUE;
866 
867 #if defined(HAVE_CMSGCRED)
868   /* NOOP just to make sure only one codepath is used
869    *      and to prefer CMSGCRED
870    */
871 #elif defined(LOCAL_CREDS)
872   int val = on ? 1 : 0;
873   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
874     {
875       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
876       retval = FALSE;
877     }
878   else
879     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
880                    on ? "enabled" : "disabled", fd);
881 #endif
882 
883   return retval;
884 }
885 
886 /**
887  * Creates a socket and binds it to the given path,
888  * then listens on the socket. The socket is
889  * set to be nonblocking.
890  *
891  * Uses abstract sockets instead of filesystem-linked
892  * sockets if requested (it's possible only on Linux;
893  * see "man 7 unix" on Linux).
894  * On non-Linux abstract socket usage always fails.
895  *
896  * This will set FD_CLOEXEC for the socket returned
897  *
898  * @param path the socket name
899  * @param abstract #TRUE to use abstract namespace
900  * @param error return location for errors
901  * @returns the listening file descriptor or -1 on error
902  */
903 int
_dbus_listen_unix_socket(const char * path,dbus_bool_t abstract,DBusError * error)904 _dbus_listen_unix_socket (const char     *path,
905                           dbus_bool_t     abstract,
906                           DBusError      *error)
907 {
908   int listen_fd;
909   struct sockaddr_un addr;
910   size_t path_len;
911   unsigned int reuseaddr;
912 
913   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
914 
915   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
916                  path, abstract);
917 #ifdef ANDROID_MANAGED_SOCKET
918   if (strncmp (path, ANDROID_SOCKET_DIR"/", strlen(ANDROID_SOCKET_DIR"/")) == 0)
919     {
920       const char* suffix;
921       /* init has created a socket for us, pick it up from environ */
922       suffix = &path[strlen (ANDROID_SOCKET_DIR"/")];
923       listen_fd = android_get_control_socket (suffix);
924       if (listen_fd == -1)
925         {
926           dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
927                 "Could not obtain fd for android socket %s\n", suffix);
928           return -1;
929         }
930 
931       _dbus_verbose ("Obtained fd for android socket %s\n", suffix);
932     }
933   else
934     {
935       dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
936             "Not an android socket: %s\n", path);
937       return -1;
938     }
939 #else
940 
941   if (!_dbus_open_unix_socket (&listen_fd, error))
942     {
943       _DBUS_ASSERT_ERROR_IS_SET(error);
944       return -1;
945     }
946   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
947 
948   _DBUS_ZERO (addr);
949   addr.sun_family = AF_UNIX;
950   path_len = strlen (path);
951 
952   if (abstract)
953     {
954 #ifdef HAVE_ABSTRACT_SOCKETS
955       /* remember that abstract names aren't nul-terminated so we rely
956        * on sun_path being filled in with zeroes above.
957        */
958       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
959       path_len++; /* Account for the extra nul byte added to the start of sun_path */
960 
961       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
962         {
963           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
964                       "Abstract socket name too long\n");
965           _dbus_close (listen_fd, NULL);
966           return -1;
967 	}
968 
969       strncpy (&addr.sun_path[1], path, path_len);
970       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
971 #else /* HAVE_ABSTRACT_SOCKETS */
972       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
973                       "Operating system does not support abstract socket namespace\n");
974       _dbus_close (listen_fd, NULL);
975       return -1;
976 #endif /* ! HAVE_ABSTRACT_SOCKETS */
977     }
978   else
979     {
980       /* Discussed security implications of this with Nalin,
981        * and we couldn't think of where it would kick our ass, but
982        * it still seems a bit sucky. It also has non-security suckage;
983        * really we'd prefer to exit if the socket is already in use.
984        * But there doesn't seem to be a good way to do this.
985        *
986        * Just to be extra careful, I threw in the stat() - clearly
987        * the stat() can't *fix* any security issue, but it at least
988        * avoids inadvertent/accidental data loss.
989        */
990       {
991         struct stat sb;
992 
993         if (stat (path, &sb) == 0 &&
994             S_ISSOCK (sb.st_mode))
995           unlink (path);
996       }
997 
998       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
999         {
1000           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1001                       "Abstract socket name too long\n");
1002           _dbus_close (listen_fd, NULL);
1003           return -1;
1004 	}
1005 
1006       strncpy (addr.sun_path, path, path_len);
1007     }
1008 
1009   reuseaddr = 1;
1010   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1011     {
1012       _dbus_warn ("Failed to set socket option\"%s\": %s",
1013                   path, _dbus_strerror (errno));
1014     }
1015 
1016   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1017     {
1018       dbus_set_error (error, _dbus_error_from_errno (errno),
1019                       "Failed to bind socket \"%s\": %s",
1020                       path, _dbus_strerror (errno));
1021       _dbus_close (listen_fd, NULL);
1022       return -1;
1023     }
1024 
1025 #endif  /* android init managed sockets */
1026 
1027   if (listen (listen_fd, 30 /* backlog */) < 0)
1028     {
1029       dbus_set_error (error, _dbus_error_from_errno (errno),
1030                       "Failed to listen on socket \"%s\": %s",
1031                       path, _dbus_strerror (errno));
1032       _dbus_close (listen_fd, NULL);
1033       return -1;
1034     }
1035 
1036   if (!_dbus_set_local_creds (listen_fd, TRUE))
1037     {
1038       dbus_set_error (error, _dbus_error_from_errno (errno),
1039                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1040                       path, _dbus_strerror (errno));
1041       close (listen_fd);
1042       return -1;
1043     }
1044 
1045   if (!_dbus_set_fd_nonblocking (listen_fd, error))
1046     {
1047       _DBUS_ASSERT_ERROR_IS_SET (error);
1048       _dbus_close (listen_fd, NULL);
1049       return -1;
1050     }
1051 
1052 #ifndef ANDROID_MANAGED_SOCKET
1053   /* Try opening up the permissions, but if we can't, just go ahead
1054    * and continue, maybe it will be good enough.
1055    */
1056   if (!abstract && chmod (path, 0777) < 0)
1057     _dbus_warn ("Could not set mode 0777 on socket %s\n",
1058                 path);
1059 #endif
1060 
1061   return listen_fd;
1062 }
1063 
1064 /**
1065  * Acquires one or more sockets passed in from systemd. The sockets
1066  * are set to be nonblocking.
1067  *
1068  * This will set FD_CLOEXEC for the sockets returned.
1069  *
1070  * @oaram fds the file descriptors
1071  * @param error return location for errors
1072  * @returns the number of file descriptors
1073  */
1074 int
_dbus_listen_systemd_sockets(int ** fds,DBusError * error)1075 _dbus_listen_systemd_sockets (int       **fds,
1076                               DBusError *error)
1077 {
1078   int r, n;
1079   unsigned fd;
1080   int *new_fds;
1081 
1082   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1083 
1084   n = sd_listen_fds (TRUE);
1085   if (n < 0)
1086     {
1087       dbus_set_error (error, _dbus_error_from_errno (-n),
1088                       "Failed to acquire systemd socket: %s",
1089                       _dbus_strerror (-n));
1090       return -1;
1091     }
1092 
1093   if (n <= 0)
1094     {
1095       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1096                       "No socket received.");
1097       return -1;
1098     }
1099 
1100   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1101     {
1102       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1103       if (r < 0)
1104         {
1105           dbus_set_error (error, _dbus_error_from_errno (-r),
1106                           "Failed to verify systemd socket type: %s",
1107                           _dbus_strerror (-r));
1108           return -1;
1109         }
1110 
1111       if (!r)
1112         {
1113           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1114                           "Passed socket has wrong type.");
1115           return -1;
1116         }
1117     }
1118 
1119   /* OK, the file descriptors are all good, so let's take posession of
1120      them then. */
1121 
1122   new_fds = dbus_new (int, n);
1123   if (!new_fds)
1124     {
1125       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1126                       "Failed to allocate file handle array.");
1127       goto fail;
1128     }
1129 
1130   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1131     {
1132       if (!_dbus_set_local_creds (fd, TRUE))
1133         {
1134           dbus_set_error (error, _dbus_error_from_errno (errno),
1135                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
1136                           _dbus_strerror (errno));
1137           goto fail;
1138         }
1139 
1140       if (!_dbus_set_fd_nonblocking (fd, error))
1141         {
1142           _DBUS_ASSERT_ERROR_IS_SET (error);
1143           goto fail;
1144         }
1145 
1146       new_fds[fd - SD_LISTEN_FDS_START] = fd;
1147     }
1148 
1149   *fds = new_fds;
1150   return n;
1151 
1152  fail:
1153 
1154   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1155     {
1156       _dbus_close (fd, NULL);
1157     }
1158 
1159   dbus_free (new_fds);
1160   return -1;
1161 }
1162 
1163 /**
1164  * Creates a socket and connects to a socket at the given host
1165  * and port. The connection fd is returned, and is set up as
1166  * nonblocking.
1167  *
1168  * This will set FD_CLOEXEC for the socket returned
1169  *
1170  * @param host the host name to connect to
1171  * @param port the port to connect to
1172  * @param family the address family to listen on, NULL for all
1173  * @param error return location for error code
1174  * @returns connection file descriptor or -1 on error
1175  */
1176 int
_dbus_connect_tcp_socket(const char * host,const char * port,const char * family,DBusError * error)1177 _dbus_connect_tcp_socket (const char     *host,
1178                           const char     *port,
1179                           const char     *family,
1180                           DBusError      *error)
1181 {
1182     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1183 }
1184 
1185 int
_dbus_connect_tcp_socket_with_nonce(const char * host,const char * port,const char * family,const char * noncefile,DBusError * error)1186 _dbus_connect_tcp_socket_with_nonce (const char     *host,
1187                                      const char     *port,
1188                                      const char     *family,
1189                                      const char     *noncefile,
1190                                      DBusError      *error)
1191 {
1192   int saved_errno = 0;
1193   int fd = -1, res;
1194   struct addrinfo hints;
1195   struct addrinfo *ai, *tmp;
1196 
1197   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1198 
1199   if (!_dbus_open_tcp_socket (&fd, error))
1200     {
1201       _DBUS_ASSERT_ERROR_IS_SET(error);
1202       return -1;
1203     }
1204 
1205   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1206 
1207   _DBUS_ZERO (hints);
1208 
1209   if (!family)
1210     hints.ai_family = AF_UNSPEC;
1211   else if (!strcmp(family, "ipv4"))
1212     hints.ai_family = AF_INET;
1213   else if (!strcmp(family, "ipv6"))
1214     hints.ai_family = AF_INET6;
1215   else
1216     {
1217       dbus_set_error (error,
1218                       DBUS_ERROR_BAD_ADDRESS,
1219                       "Unknown address family %s", family);
1220       return -1;
1221     }
1222   hints.ai_protocol = IPPROTO_TCP;
1223   hints.ai_socktype = SOCK_STREAM;
1224   hints.ai_flags = AI_ADDRCONFIG;
1225 
1226   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1227     {
1228       dbus_set_error (error,
1229                       _dbus_error_from_errno (errno),
1230                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1231                       host, port, gai_strerror(res), res);
1232       _dbus_close (fd, NULL);
1233       return -1;
1234     }
1235 
1236   tmp = ai;
1237   while (tmp)
1238     {
1239       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1240         {
1241           freeaddrinfo(ai);
1242           _DBUS_ASSERT_ERROR_IS_SET(error);
1243           return -1;
1244         }
1245       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1246 
1247       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1248         {
1249           saved_errno = errno;
1250           _dbus_close(fd, NULL);
1251           fd = -1;
1252           tmp = tmp->ai_next;
1253           continue;
1254         }
1255 
1256       break;
1257     }
1258   freeaddrinfo(ai);
1259 
1260   if (fd == -1)
1261     {
1262       dbus_set_error (error,
1263                       _dbus_error_from_errno (saved_errno),
1264                       "Failed to connect to socket \"%s:%s\" %s",
1265                       host, port, _dbus_strerror(saved_errno));
1266       return -1;
1267     }
1268 
1269   if (noncefile != NULL)
1270     {
1271       DBusString noncefileStr;
1272       dbus_bool_t ret;
1273       _dbus_string_init_const (&noncefileStr, noncefile);
1274       ret = _dbus_send_nonce (fd, &noncefileStr, error);
1275       _dbus_string_free (&noncefileStr);
1276 
1277       if (!ret)
1278     {
1279       _dbus_close (fd, NULL);
1280           return -1;
1281         }
1282     }
1283 
1284   if (!_dbus_set_fd_nonblocking (fd, error))
1285     {
1286       _dbus_close (fd, NULL);
1287       return -1;
1288     }
1289 
1290   return fd;
1291 }
1292 
1293 /**
1294  * Creates a socket and binds it to the given path, then listens on
1295  * the socket. The socket is set to be nonblocking.  In case of port=0
1296  * a random free port is used and returned in the port parameter.
1297  * If inaddr_any is specified, the hostname is ignored.
1298  *
1299  * This will set FD_CLOEXEC for the socket returned
1300  *
1301  * @param host the host name to listen on
1302  * @param port the port to listen on, if zero a free port will be used
1303  * @param family the address family to listen on, NULL for all
1304  * @param retport string to return the actual port listened on
1305  * @param fds_p location to store returned file descriptors
1306  * @param error return location for errors
1307  * @returns the number of listening file descriptors or -1 on error
1308  */
1309 int
_dbus_listen_tcp_socket(const char * host,const char * port,const char * family,DBusString * retport,int ** fds_p,DBusError * error)1310 _dbus_listen_tcp_socket (const char     *host,
1311                          const char     *port,
1312                          const char     *family,
1313                          DBusString     *retport,
1314                          int           **fds_p,
1315                          DBusError      *error)
1316 {
1317   int saved_errno;
1318   int nlisten_fd = 0, *listen_fd = NULL, res, i;
1319   struct addrinfo hints;
1320   struct addrinfo *ai, *tmp;
1321   unsigned int reuseaddr;
1322 
1323   *fds_p = NULL;
1324   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1325 
1326   _DBUS_ZERO (hints);
1327 
1328   if (!family)
1329     hints.ai_family = AF_UNSPEC;
1330   else if (!strcmp(family, "ipv4"))
1331     hints.ai_family = AF_INET;
1332   else if (!strcmp(family, "ipv6"))
1333     hints.ai_family = AF_INET6;
1334   else
1335     {
1336       dbus_set_error (error,
1337                       DBUS_ERROR_BAD_ADDRESS,
1338                       "Unknown address family %s", family);
1339       return -1;
1340     }
1341 
1342   hints.ai_protocol = IPPROTO_TCP;
1343   hints.ai_socktype = SOCK_STREAM;
1344   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1345 
1346  redo_lookup_with_port:
1347   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1348     {
1349       dbus_set_error (error,
1350                       _dbus_error_from_errno (errno),
1351                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1352                       host ? host : "*", port, gai_strerror(res), res);
1353       return -1;
1354     }
1355 
1356   tmp = ai;
1357   while (tmp)
1358     {
1359       int fd = -1, *newlisten_fd;
1360       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1361         {
1362           _DBUS_ASSERT_ERROR_IS_SET(error);
1363           goto failed;
1364         }
1365       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1366 
1367       reuseaddr = 1;
1368       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1369         {
1370           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1371                       host ? host : "*", port, _dbus_strerror (errno));
1372         }
1373 
1374       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1375         {
1376           saved_errno = errno;
1377           _dbus_close(fd, NULL);
1378           if (saved_errno == EADDRINUSE)
1379             {
1380               /* Depending on kernel policy, it may or may not
1381                  be neccessary to bind to both IPv4 & 6 addresses
1382                  so ignore EADDRINUSE here */
1383               tmp = tmp->ai_next;
1384               continue;
1385             }
1386           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1387                           "Failed to bind socket \"%s:%s\": %s",
1388                           host ? host : "*", port, _dbus_strerror (saved_errno));
1389           goto failed;
1390         }
1391 
1392       if (listen (fd, 30 /* backlog */) < 0)
1393         {
1394           saved_errno = errno;
1395           _dbus_close (fd, NULL);
1396           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1397                           "Failed to listen on socket \"%s:%s\": %s",
1398                           host ? host : "*", port, _dbus_strerror (saved_errno));
1399           goto failed;
1400         }
1401 
1402       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1403       if (!newlisten_fd)
1404         {
1405           saved_errno = errno;
1406           _dbus_close (fd, NULL);
1407           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1408                           "Failed to allocate file handle array: %s",
1409                           _dbus_strerror (saved_errno));
1410           goto failed;
1411         }
1412       listen_fd = newlisten_fd;
1413       listen_fd[nlisten_fd] = fd;
1414       nlisten_fd++;
1415 
1416       if (!_dbus_string_get_length(retport))
1417         {
1418           /* If the user didn't specify a port, or used 0, then
1419              the kernel chooses a port. After the first address
1420              is bound to, we need to force all remaining addresses
1421              to use the same port */
1422           if (!port || !strcmp(port, "0"))
1423             {
1424               struct sockaddr_storage addr;
1425               socklen_t addrlen;
1426               char portbuf[50];
1427 
1428               addrlen = sizeof(addr);
1429               getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1430 
1431               if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
1432                                      portbuf, sizeof(portbuf),
1433                                      NI_NUMERICHOST)) != 0)
1434                 {
1435                   dbus_set_error (error, _dbus_error_from_errno (errno),
1436                                   "Failed to resolve port \"%s:%s\": %s (%s)",
1437                                   host ? host : "*", port, gai_strerror(res), res);
1438                   goto failed;
1439                 }
1440               if (!_dbus_string_append(retport, portbuf))
1441                 {
1442                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1443                   goto failed;
1444                 }
1445 
1446               /* Release current address list & redo lookup */
1447               port = _dbus_string_get_const_data(retport);
1448               freeaddrinfo(ai);
1449               goto redo_lookup_with_port;
1450             }
1451           else
1452             {
1453               if (!_dbus_string_append(retport, port))
1454                 {
1455                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1456                     goto failed;
1457                 }
1458             }
1459         }
1460 
1461       tmp = tmp->ai_next;
1462     }
1463   freeaddrinfo(ai);
1464   ai = NULL;
1465 
1466   if (!nlisten_fd)
1467     {
1468       errno = EADDRINUSE;
1469       dbus_set_error (error, _dbus_error_from_errno (errno),
1470                       "Failed to bind socket \"%s:%s\": %s",
1471                       host ? host : "*", port, _dbus_strerror (errno));
1472       return -1;
1473     }
1474 
1475   for (i = 0 ; i < nlisten_fd ; i++)
1476     {
1477       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1478         {
1479           goto failed;
1480         }
1481     }
1482 
1483   *fds_p = listen_fd;
1484 
1485   return nlisten_fd;
1486 
1487  failed:
1488   if (ai)
1489     freeaddrinfo(ai);
1490   for (i = 0 ; i < nlisten_fd ; i++)
1491     _dbus_close(listen_fd[i], NULL);
1492   dbus_free(listen_fd);
1493   return -1;
1494 }
1495 
1496 static dbus_bool_t
write_credentials_byte(int server_fd,DBusError * error)1497 write_credentials_byte (int             server_fd,
1498                         DBusError      *error)
1499 {
1500   int bytes_written;
1501   char buf[1] = { '\0' };
1502 #if defined(HAVE_CMSGCRED)
1503   union {
1504 	  struct cmsghdr hdr;
1505 	  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1506   } cmsg;
1507   struct iovec iov;
1508   struct msghdr msg;
1509   iov.iov_base = buf;
1510   iov.iov_len = 1;
1511 
1512   _DBUS_ZERO(msg);
1513   msg.msg_iov = &iov;
1514   msg.msg_iovlen = 1;
1515 
1516   msg.msg_control = (caddr_t) &cmsg;
1517   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1518   _DBUS_ZERO(cmsg);
1519   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1520   cmsg.hdr.cmsg_level = SOL_SOCKET;
1521   cmsg.hdr.cmsg_type = SCM_CREDS;
1522 #endif
1523 
1524   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1525 
1526  again:
1527 
1528 #if defined(HAVE_CMSGCRED)
1529   bytes_written = sendmsg (server_fd, &msg, 0);
1530 #else
1531   bytes_written = write (server_fd, buf, 1);
1532 #endif
1533 
1534   if (bytes_written < 0 && errno == EINTR)
1535     goto again;
1536 
1537   if (bytes_written < 0)
1538     {
1539       dbus_set_error (error, _dbus_error_from_errno (errno),
1540                       "Failed to write credentials byte: %s",
1541                      _dbus_strerror (errno));
1542       return FALSE;
1543     }
1544   else if (bytes_written == 0)
1545     {
1546       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1547                       "wrote zero bytes writing credentials byte");
1548       return FALSE;
1549     }
1550   else
1551     {
1552       _dbus_assert (bytes_written == 1);
1553       _dbus_verbose ("wrote credentials byte\n");
1554       return TRUE;
1555     }
1556 }
1557 
1558 /**
1559  * Reads a single byte which must be nul (an error occurs otherwise),
1560  * and reads unix credentials if available. Clears the credentials
1561  * object, then adds pid/uid if available, so any previous credentials
1562  * stored in the object are lost.
1563  *
1564  * Return value indicates whether a byte was read, not whether
1565  * we got valid credentials. On some systems, such as Linux,
1566  * reading/writing the byte isn't actually required, but we do it
1567  * anyway just to avoid multiple codepaths.
1568  *
1569  * Fails if no byte is available, so you must select() first.
1570  *
1571  * The point of the byte is that on some systems we have to
1572  * use sendmsg()/recvmsg() to transmit credentials.
1573  *
1574  * @param client_fd the client file descriptor
1575  * @param credentials object to add client credentials to
1576  * @param error location to store error code
1577  * @returns #TRUE on success
1578  */
1579 dbus_bool_t
_dbus_read_credentials_socket(int client_fd,DBusCredentials * credentials,DBusError * error)1580 _dbus_read_credentials_socket  (int              client_fd,
1581                                 DBusCredentials *credentials,
1582                                 DBusError       *error)
1583 {
1584   struct msghdr msg;
1585   struct iovec iov;
1586   char buf;
1587   dbus_uid_t uid_read;
1588   dbus_pid_t pid_read;
1589   int bytes_read;
1590 
1591 #ifdef HAVE_CMSGCRED
1592   union {
1593     struct cmsghdr hdr;
1594     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1595   } cmsg;
1596 
1597 #elif defined(LOCAL_CREDS)
1598   struct {
1599     struct cmsghdr hdr;
1600     struct sockcred cred;
1601   } cmsg;
1602 #endif
1603 
1604   uid_read = DBUS_UID_UNSET;
1605   pid_read = DBUS_PID_UNSET;
1606 
1607   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1608 
1609   /* The POSIX spec certainly doesn't promise this, but
1610    * we need these assertions to fail as soon as we're wrong about
1611    * it so we can do the porting fixups
1612    */
1613   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1614   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1615   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1616 
1617   _dbus_credentials_clear (credentials);
1618 
1619   /* Systems supporting LOCAL_CREDS are configured to have this feature
1620    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1621    * the connection.  Therefore, the received message must carry the
1622    * credentials information without doing anything special.
1623    */
1624 
1625   iov.iov_base = &buf;
1626   iov.iov_len = 1;
1627 
1628   _DBUS_ZERO(msg);
1629   msg.msg_iov = &iov;
1630   msg.msg_iovlen = 1;
1631 
1632 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1633   _DBUS_ZERO(cmsg);
1634   msg.msg_control = (caddr_t) &cmsg;
1635   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1636 #endif
1637 
1638  again:
1639   bytes_read = recvmsg (client_fd, &msg, 0);
1640 
1641   if (bytes_read < 0)
1642     {
1643       if (errno == EINTR)
1644 	goto again;
1645 
1646       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1647        * normally only call read_credentials if the socket was ready
1648        * for reading
1649        */
1650 
1651       dbus_set_error (error, _dbus_error_from_errno (errno),
1652                       "Failed to read credentials byte: %s",
1653                       _dbus_strerror (errno));
1654       return FALSE;
1655     }
1656   else if (bytes_read == 0)
1657     {
1658       /* this should not happen unless we are using recvmsg wrong,
1659        * so is essentially here for paranoia
1660        */
1661       dbus_set_error (error, DBUS_ERROR_FAILED,
1662                       "Failed to read credentials byte (zero-length read)");
1663       return FALSE;
1664     }
1665   else if (buf != '\0')
1666     {
1667       dbus_set_error (error, DBUS_ERROR_FAILED,
1668                       "Credentials byte was not nul");
1669       return FALSE;
1670     }
1671 
1672 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1673   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1674 		  || cmsg.hdr.cmsg_type != SCM_CREDS)
1675     {
1676       dbus_set_error (error, DBUS_ERROR_FAILED,
1677                       "Message from recvmsg() was not SCM_CREDS");
1678       return FALSE;
1679     }
1680 #endif
1681 
1682   _dbus_verbose ("read credentials byte\n");
1683 
1684   {
1685 #ifdef SO_PEERCRED
1686     struct ucred cr;
1687     int cr_len = sizeof (cr);
1688 
1689     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1690 	cr_len == sizeof (cr))
1691       {
1692 	pid_read = cr.pid;
1693 	uid_read = cr.uid;
1694       }
1695     else
1696       {
1697 	_dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1698 		       cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1699       }
1700 #elif defined(HAVE_CMSGCRED)
1701     struct cmsgcred *cred;
1702 
1703     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1704     pid_read = cred->cmcred_pid;
1705     uid_read = cred->cmcred_euid;
1706 #elif defined(LOCAL_CREDS)
1707     pid_read = DBUS_PID_UNSET;
1708     uid_read = cmsg.cred.sc_uid;
1709     /* Since we have already got the credentials from this socket, we can
1710      * disable its LOCAL_CREDS flag if it was ever set. */
1711     _dbus_set_local_creds (client_fd, FALSE);
1712 #elif defined(HAVE_GETPEEREID)
1713     uid_t euid;
1714     gid_t egid;
1715     if (getpeereid (client_fd, &euid, &egid) == 0)
1716       {
1717         uid_read = euid;
1718       }
1719     else
1720       {
1721         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1722       }
1723 #elif defined(HAVE_GETPEERUCRED)
1724     ucred_t * ucred = NULL;
1725     if (getpeerucred (client_fd, &ucred) == 0)
1726       {
1727         pid_read = ucred_getpid (ucred);
1728         uid_read = ucred_geteuid (ucred);
1729 #ifdef HAVE_ADT
1730         /* generate audit session data based on socket ucred */
1731         adt_session_data_t *adth = NULL;
1732         adt_export_data_t *data = NULL;
1733         size_t size = 0;
1734         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1735           {
1736             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1737           }
1738         else
1739           {
1740             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1741               {
1742                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1743               }
1744             else
1745               {
1746                 size = adt_export_session_data (adth, &data);
1747                 if (size <= 0)
1748                   {
1749                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1750                   }
1751                 else
1752                   {
1753                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
1754                     free (data);
1755                   }
1756               }
1757             (void) adt_end_session (adth);
1758           }
1759 #endif /* HAVE_ADT */
1760       }
1761     else
1762       {
1763         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1764       }
1765     if (ucred != NULL)
1766       ucred_free (ucred);
1767 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1768     _dbus_verbose ("Socket credentials not supported on this OS\n");
1769 #endif
1770   }
1771 
1772   _dbus_verbose ("Credentials:"
1773                  "  pid "DBUS_PID_FORMAT
1774                  "  uid "DBUS_UID_FORMAT
1775                  "\n",
1776 		 pid_read,
1777 		 uid_read);
1778 
1779   if (pid_read != DBUS_PID_UNSET)
1780     {
1781       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1782         {
1783           _DBUS_SET_OOM (error);
1784           return FALSE;
1785         }
1786     }
1787 
1788   if (uid_read != DBUS_UID_UNSET)
1789     {
1790       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1791         {
1792           _DBUS_SET_OOM (error);
1793           return FALSE;
1794         }
1795     }
1796 
1797   return TRUE;
1798 }
1799 
1800 /**
1801  * Sends a single nul byte with our UNIX credentials as ancillary
1802  * data.  Returns #TRUE if the data was successfully written.  On
1803  * systems that don't support sending credentials, just writes a byte,
1804  * doesn't send any credentials.  On some systems, such as Linux,
1805  * reading/writing the byte isn't actually required, but we do it
1806  * anyway just to avoid multiple codepaths.
1807  *
1808  * Fails if no byte can be written, so you must select() first.
1809  *
1810  * The point of the byte is that on some systems we have to
1811  * use sendmsg()/recvmsg() to transmit credentials.
1812  *
1813  * @param server_fd file descriptor for connection to server
1814  * @param error return location for error code
1815  * @returns #TRUE if the byte was sent
1816  */
1817 dbus_bool_t
_dbus_send_credentials_socket(int server_fd,DBusError * error)1818 _dbus_send_credentials_socket  (int              server_fd,
1819                                 DBusError       *error)
1820 {
1821   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1822 
1823   if (write_credentials_byte (server_fd, error))
1824     return TRUE;
1825   else
1826     return FALSE;
1827 }
1828 
1829 /**
1830  * Accepts a connection on a listening socket.
1831  * Handles EINTR for you.
1832  *
1833  * This will enable FD_CLOEXEC for the returned socket.
1834  *
1835  * @param listen_fd the listen file descriptor
1836  * @returns the connection fd of the client, or -1 on error
1837  */
1838 int
_dbus_accept(int listen_fd)1839 _dbus_accept  (int listen_fd)
1840 {
1841   int client_fd;
1842   struct sockaddr addr;
1843   socklen_t addrlen;
1844 #ifdef HAVE_ACCEPT4
1845   dbus_bool_t cloexec_done;
1846 #endif
1847 
1848   addrlen = sizeof (addr);
1849 
1850  retry:
1851 
1852 #ifdef HAVE_ACCEPT4
1853   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1854   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1855   cloexec_done = client_fd >= 0;
1856 
1857   if (client_fd < 0 && errno == ENOSYS)
1858 #endif
1859     {
1860       client_fd = accept (listen_fd, &addr, &addrlen);
1861     }
1862 
1863   if (client_fd < 0)
1864     {
1865       if (errno == EINTR)
1866         goto retry;
1867     }
1868 
1869   _dbus_verbose ("client fd %d accepted\n", client_fd);
1870 
1871 #ifdef HAVE_ACCEPT4
1872   if (!cloexec_done)
1873 #endif
1874     {
1875       _dbus_fd_set_close_on_exec(client_fd);
1876     }
1877 
1878   return client_fd;
1879 }
1880 
1881 /**
1882  * Checks to make sure the given directory is
1883  * private to the user
1884  *
1885  * @param dir the name of the directory
1886  * @param error error return
1887  * @returns #FALSE on failure
1888  **/
1889 dbus_bool_t
_dbus_check_dir_is_private_to_user(DBusString * dir,DBusError * error)1890 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1891 {
1892   const char *directory;
1893   struct stat sb;
1894 
1895   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1896 
1897   directory = _dbus_string_get_const_data (dir);
1898 
1899   if (stat (directory, &sb) < 0)
1900     {
1901       dbus_set_error (error, _dbus_error_from_errno (errno),
1902                       "%s", _dbus_strerror (errno));
1903 
1904       return FALSE;
1905     }
1906 
1907   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1908       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1909     {
1910       dbus_set_error (error, DBUS_ERROR_FAILED,
1911                      "%s directory is not private to the user", directory);
1912       return FALSE;
1913     }
1914 
1915   return TRUE;
1916 }
1917 
1918 static dbus_bool_t
fill_user_info_from_passwd(struct passwd * p,DBusUserInfo * info,DBusError * error)1919 fill_user_info_from_passwd (struct passwd *p,
1920                             DBusUserInfo  *info,
1921                             DBusError     *error)
1922 {
1923   _dbus_assert (p->pw_name != NULL);
1924   _dbus_assert (p->pw_dir != NULL);
1925 
1926   info->uid = p->pw_uid;
1927   info->primary_gid = p->pw_gid;
1928   info->username = _dbus_strdup (p->pw_name);
1929   info->homedir = _dbus_strdup (p->pw_dir);
1930 
1931   if (info->username == NULL ||
1932       info->homedir == NULL)
1933     {
1934       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1935       return FALSE;
1936     }
1937 
1938   return TRUE;
1939 }
1940 
1941 static dbus_bool_t
fill_user_info(DBusUserInfo * info,dbus_uid_t uid,const DBusString * username,DBusError * error)1942 fill_user_info (DBusUserInfo       *info,
1943                 dbus_uid_t          uid,
1944                 const DBusString   *username,
1945                 DBusError          *error)
1946 {
1947   const char *username_c;
1948 
1949   /* exactly one of username/uid provided */
1950   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1951   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1952 
1953   info->uid = DBUS_UID_UNSET;
1954   info->primary_gid = DBUS_GID_UNSET;
1955   info->group_ids = NULL;
1956   info->n_group_ids = 0;
1957   info->username = NULL;
1958   info->homedir = NULL;
1959 
1960   if (username != NULL)
1961     username_c = _dbus_string_get_const_data (username);
1962   else
1963     username_c = NULL;
1964 
1965   /* For now assuming that the getpwnam() and getpwuid() flavors
1966    * are always symmetrical, if not we have to add more configure
1967    * checks
1968    */
1969 
1970 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1971   {
1972     struct passwd *p;
1973     int result;
1974     size_t buflen;
1975     char *buf;
1976     struct passwd p_str;
1977 
1978     /* retrieve maximum needed size for buf */
1979     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1980 
1981     /* sysconf actually returns a long, but everything else expects size_t,
1982      * so just recast here.
1983      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1984      */
1985     if ((long) buflen <= 0)
1986       buflen = 1024;
1987 
1988     result = -1;
1989     while (1)
1990       {
1991         buf = dbus_malloc (buflen);
1992         if (buf == NULL)
1993           {
1994             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1995             return FALSE;
1996           }
1997 
1998         p = NULL;
1999 #ifdef HAVE_POSIX_GETPWNAM_R
2000         if (uid != DBUS_UID_UNSET)
2001           result = getpwuid_r (uid, &p_str, buf, buflen,
2002                                &p);
2003         else
2004           result = getpwnam_r (username_c, &p_str, buf, buflen,
2005                                &p);
2006 #else
2007         if (uid != DBUS_UID_UNSET)
2008           p = getpwuid_r (uid, &p_str, buf, buflen);
2009         else
2010           p = getpwnam_r (username_c, &p_str, buf, buflen);
2011         result = 0;
2012 #endif /* !HAVE_POSIX_GETPWNAM_R */
2013         //Try a bigger buffer if ERANGE was returned
2014         if (result == ERANGE && buflen < 512 * 1024)
2015           {
2016             dbus_free (buf);
2017             buflen *= 2;
2018           }
2019         else
2020           {
2021             break;
2022           }
2023       }
2024     if (result == 0 && p == &p_str)
2025       {
2026         if (!fill_user_info_from_passwd (p, info, error))
2027           {
2028             dbus_free (buf);
2029             return FALSE;
2030           }
2031         dbus_free (buf);
2032       }
2033     else
2034       {
2035         dbus_set_error (error, _dbus_error_from_errno (errno),
2036                         "User \"%s\" unknown or no memory to allocate password entry\n",
2037                         username_c ? username_c : "???");
2038         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2039         dbus_free (buf);
2040         return FALSE;
2041       }
2042   }
2043 #else /* ! HAVE_GETPWNAM_R */
2044   {
2045     /* I guess we're screwed on thread safety here */
2046     struct passwd *p;
2047 
2048     if (uid != DBUS_UID_UNSET)
2049       p = getpwuid (uid);
2050     else
2051       p = getpwnam (username_c);
2052 
2053     if (p != NULL)
2054       {
2055         if (!fill_user_info_from_passwd (p, info, error))
2056           {
2057             return FALSE;
2058           }
2059       }
2060     else
2061       {
2062         dbus_set_error (error, _dbus_error_from_errno (errno),
2063                         "User \"%s\" unknown or no memory to allocate password entry\n",
2064                         username_c ? username_c : "???");
2065         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2066         return FALSE;
2067       }
2068   }
2069 #endif  /* ! HAVE_GETPWNAM_R */
2070 
2071   /* Fill this in so we can use it to get groups */
2072   username_c = info->username;
2073 
2074 #ifdef HAVE_GETGROUPLIST
2075   {
2076     gid_t *buf;
2077     int buf_count;
2078     int i;
2079     int initial_buf_count;
2080 
2081     initial_buf_count = 17;
2082     buf_count = initial_buf_count;
2083     buf = dbus_new (gid_t, buf_count);
2084     if (buf == NULL)
2085       {
2086         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2087         goto failed;
2088       }
2089 
2090     if (getgrouplist (username_c,
2091                       info->primary_gid,
2092                       buf, &buf_count) < 0)
2093       {
2094         gid_t *new;
2095         /* Presumed cause of negative return code: buf has insufficient
2096            entries to hold the entire group list. The Linux behavior in this
2097            case is to pass back the actual number of groups in buf_count, but
2098            on Mac OS X 10.5, buf_count is unhelpfully left alone.
2099            So as a hack, try to help out a bit by guessing a larger
2100            number of groups, within reason.. might still fail, of course,
2101            but we can at least print a more informative message.  I looked up
2102            the "right way" to do this by downloading Apple's own source code
2103            for the "id" command, and it turns out that they use an
2104            undocumented library function getgrouplist_2 (!) which is not
2105            declared in any header in /usr/include (!!). That did not seem
2106            like the way to go here.
2107         */
2108         if (buf_count == initial_buf_count)
2109           {
2110             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2111           }
2112         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2113         if (new == NULL)
2114           {
2115             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2116             dbus_free (buf);
2117             goto failed;
2118           }
2119 
2120         buf = new;
2121 
2122         errno = 0;
2123         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2124           {
2125             if (errno == 0)
2126               {
2127                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2128                             username_c, buf_count, buf_count);
2129               }
2130             else
2131               {
2132                 dbus_set_error (error,
2133                                 _dbus_error_from_errno (errno),
2134                                 "Failed to get groups for username \"%s\" primary GID "
2135                                 DBUS_GID_FORMAT ": %s\n",
2136                                 username_c, info->primary_gid,
2137                                 _dbus_strerror (errno));
2138                 dbus_free (buf);
2139                 goto failed;
2140               }
2141           }
2142       }
2143 
2144     info->group_ids = dbus_new (dbus_gid_t, buf_count);
2145     if (info->group_ids == NULL)
2146       {
2147         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2148         dbus_free (buf);
2149         goto failed;
2150       }
2151 
2152     for (i = 0; i < buf_count; ++i)
2153       info->group_ids[i] = buf[i];
2154 
2155     info->n_group_ids = buf_count;
2156 
2157     dbus_free (buf);
2158   }
2159 #else  /* HAVE_GETGROUPLIST */
2160   {
2161     /* We just get the one group ID */
2162     info->group_ids = dbus_new (dbus_gid_t, 1);
2163     if (info->group_ids == NULL)
2164       {
2165         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2166         goto failed;
2167       }
2168 
2169     info->n_group_ids = 1;
2170 
2171     (info->group_ids)[0] = info->primary_gid;
2172   }
2173 #endif /* HAVE_GETGROUPLIST */
2174 
2175   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2176 
2177   return TRUE;
2178 
2179  failed:
2180   _DBUS_ASSERT_ERROR_IS_SET (error);
2181   return FALSE;
2182 }
2183 
2184 /**
2185  * Gets user info for the given username.
2186  *
2187  * @param info user info object to initialize
2188  * @param username the username
2189  * @param error error return
2190  * @returns #TRUE on success
2191  */
2192 dbus_bool_t
_dbus_user_info_fill(DBusUserInfo * info,const DBusString * username,DBusError * error)2193 _dbus_user_info_fill (DBusUserInfo     *info,
2194                       const DBusString *username,
2195                       DBusError        *error)
2196 {
2197   return fill_user_info (info, DBUS_UID_UNSET,
2198                          username, error);
2199 }
2200 
2201 /**
2202  * Gets user info for the given user ID.
2203  *
2204  * @param info user info object to initialize
2205  * @param uid the user ID
2206  * @param error error return
2207  * @returns #TRUE on success
2208  */
2209 dbus_bool_t
_dbus_user_info_fill_uid(DBusUserInfo * info,dbus_uid_t uid,DBusError * error)2210 _dbus_user_info_fill_uid (DBusUserInfo *info,
2211                           dbus_uid_t    uid,
2212                           DBusError    *error)
2213 {
2214   return fill_user_info (info, uid,
2215                          NULL, error);
2216 }
2217 
2218 /**
2219  * Adds the credentials of the current process to the
2220  * passed-in credentials object.
2221  *
2222  * @param credentials credentials to add to
2223  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2224  */
2225 dbus_bool_t
_dbus_credentials_add_from_current_process(DBusCredentials * credentials)2226 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2227 {
2228   /* The POSIX spec certainly doesn't promise this, but
2229    * we need these assertions to fail as soon as we're wrong about
2230    * it so we can do the porting fixups
2231    */
2232   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2233   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2234   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2235 
2236   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2237     return FALSE;
2238   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2239     return FALSE;
2240 
2241   return TRUE;
2242 }
2243 
2244 /**
2245  * Append to the string the identity we would like to have when we
2246  * authenticate, on UNIX this is the current process UID and on
2247  * Windows something else, probably a Windows SID string.  No escaping
2248  * is required, that is done in dbus-auth.c. The username here
2249  * need not be anything human-readable, it can be the machine-readable
2250  * form i.e. a user id.
2251  *
2252  * @param str the string to append to
2253  * @returns #FALSE on no memory
2254  */
2255 dbus_bool_t
_dbus_append_user_from_current_process(DBusString * str)2256 _dbus_append_user_from_current_process (DBusString *str)
2257 {
2258   return _dbus_string_append_uint (str,
2259                                    _dbus_geteuid ());
2260 }
2261 
2262 /**
2263  * Gets our process ID
2264  * @returns process ID
2265  */
2266 dbus_pid_t
_dbus_getpid(void)2267 _dbus_getpid (void)
2268 {
2269   return getpid ();
2270 }
2271 
2272 /** Gets our UID
2273  * @returns process UID
2274  */
2275 dbus_uid_t
_dbus_getuid(void)2276 _dbus_getuid (void)
2277 {
2278   return getuid ();
2279 }
2280 
2281 /** Gets our effective UID
2282  * @returns process effective UID
2283  */
2284 dbus_uid_t
_dbus_geteuid(void)2285 _dbus_geteuid (void)
2286 {
2287   return geteuid ();
2288 }
2289 
2290 /**
2291  * The only reason this is separate from _dbus_getpid() is to allow it
2292  * on Windows for logging but not for other purposes.
2293  *
2294  * @returns process ID to put in log messages
2295  */
2296 unsigned long
_dbus_pid_for_log(void)2297 _dbus_pid_for_log (void)
2298 {
2299   return getpid ();
2300 }
2301 
2302 /**
2303  * Gets a UID from a UID string.
2304  *
2305  * @param uid_str the UID in string form
2306  * @param uid UID to fill in
2307  * @returns #TRUE if successfully filled in UID
2308  */
2309 dbus_bool_t
_dbus_parse_uid(const DBusString * uid_str,dbus_uid_t * uid)2310 _dbus_parse_uid (const DBusString      *uid_str,
2311                  dbus_uid_t            *uid)
2312 {
2313   int end;
2314   long val;
2315 
2316   if (_dbus_string_get_length (uid_str) == 0)
2317     {
2318       _dbus_verbose ("UID string was zero length\n");
2319       return FALSE;
2320     }
2321 
2322   val = -1;
2323   end = 0;
2324   if (!_dbus_string_parse_int (uid_str, 0, &val,
2325                                &end))
2326     {
2327       _dbus_verbose ("could not parse string as a UID\n");
2328       return FALSE;
2329     }
2330 
2331   if (end != _dbus_string_get_length (uid_str))
2332     {
2333       _dbus_verbose ("string contained trailing stuff after UID\n");
2334       return FALSE;
2335     }
2336 
2337   *uid = val;
2338 
2339   return TRUE;
2340 }
2341 
2342 #if !DBUS_USE_SYNC
2343 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2344 #endif
2345 
2346 /**
2347  * Atomically increments an integer
2348  *
2349  * @param atomic pointer to the integer to increment
2350  * @returns the value before incrementing
2351  */
2352 dbus_int32_t
_dbus_atomic_inc(DBusAtomic * atomic)2353 _dbus_atomic_inc (DBusAtomic *atomic)
2354 {
2355 #if DBUS_USE_SYNC
2356   return __sync_add_and_fetch(&atomic->value, 1)-1;
2357 #elif defined(ANDROID_ATOMIC)
2358   return android_atomic_inc (&(atomic->value));
2359 #else
2360   dbus_int32_t res;
2361   _DBUS_LOCK (atomic);
2362   res = atomic->value;
2363   atomic->value += 1;
2364   _DBUS_UNLOCK (atomic);
2365   return res;
2366 #endif
2367 }
2368 
2369 /**
2370  * Atomically decrement an integer
2371  *
2372  * @param atomic pointer to the integer to decrement
2373  * @returns the value before decrementing
2374  */
2375 dbus_int32_t
_dbus_atomic_dec(DBusAtomic * atomic)2376 _dbus_atomic_dec (DBusAtomic *atomic)
2377 {
2378 #if DBUS_USE_SYNC
2379   return __sync_sub_and_fetch(&atomic->value, 1)+1;
2380 #elif defined(ANDROID_ATOMIC)
2381   return android_atomic_dec (&(atomic->value));
2382 #else
2383   dbus_int32_t res;
2384 
2385   _DBUS_LOCK (atomic);
2386   res = atomic->value;
2387   atomic->value -= 1;
2388   _DBUS_UNLOCK (atomic);
2389   return res;
2390 #endif
2391 }
2392 
2393 #ifdef DBUS_BUILD_TESTS
2394 /** Gets our GID
2395  * @returns process GID
2396  */
2397 dbus_gid_t
_dbus_getgid(void)2398 _dbus_getgid (void)
2399 {
2400   return getgid ();
2401 }
2402 #endif
2403 
2404 /**
2405  * Wrapper for poll().
2406  *
2407  * @param fds the file descriptors to poll
2408  * @param n_fds number of descriptors in the array
2409  * @param timeout_milliseconds timeout or -1 for infinite
2410  * @returns numbers of fds with revents, or <0 on error
2411  */
2412 int
_dbus_poll(DBusPollFD * fds,int n_fds,int timeout_milliseconds)2413 _dbus_poll (DBusPollFD *fds,
2414             int         n_fds,
2415             int         timeout_milliseconds)
2416 {
2417 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2418   /* This big thing is a constant expression and should get optimized
2419    * out of existence. So it's more robust than a configure check at
2420    * no cost.
2421    */
2422   if (_DBUS_POLLIN == POLLIN &&
2423       _DBUS_POLLPRI == POLLPRI &&
2424       _DBUS_POLLOUT == POLLOUT &&
2425       _DBUS_POLLERR == POLLERR &&
2426       _DBUS_POLLHUP == POLLHUP &&
2427       _DBUS_POLLNVAL == POLLNVAL &&
2428       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2429       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2430       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2431       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2432       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2433       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2434       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2435     {
2436       return poll ((struct pollfd*) fds,
2437                    n_fds,
2438                    timeout_milliseconds);
2439     }
2440   else
2441     {
2442       /* We have to convert the DBusPollFD to an array of
2443        * struct pollfd, poll, and convert back.
2444        */
2445       _dbus_warn ("didn't implement poll() properly for this system yet\n");
2446       return -1;
2447     }
2448 #else /* ! HAVE_POLL */
2449 
2450   fd_set read_set, write_set, err_set;
2451   int max_fd = 0;
2452   int i;
2453   struct timeval tv;
2454   int ready;
2455 
2456   FD_ZERO (&read_set);
2457   FD_ZERO (&write_set);
2458   FD_ZERO (&err_set);
2459 
2460   for (i = 0; i < n_fds; i++)
2461     {
2462       DBusPollFD *fdp = &fds[i];
2463 
2464       if (fdp->events & _DBUS_POLLIN)
2465 	FD_SET (fdp->fd, &read_set);
2466 
2467       if (fdp->events & _DBUS_POLLOUT)
2468 	FD_SET (fdp->fd, &write_set);
2469 
2470       FD_SET (fdp->fd, &err_set);
2471 
2472       max_fd = MAX (max_fd, fdp->fd);
2473     }
2474 
2475   tv.tv_sec = timeout_milliseconds / 1000;
2476   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2477 
2478   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2479                   timeout_milliseconds < 0 ? NULL : &tv);
2480 
2481   if (ready > 0)
2482     {
2483       for (i = 0; i < n_fds; i++)
2484 	{
2485 	  DBusPollFD *fdp = &fds[i];
2486 
2487 	  fdp->revents = 0;
2488 
2489 	  if (FD_ISSET (fdp->fd, &read_set))
2490 	    fdp->revents |= _DBUS_POLLIN;
2491 
2492 	  if (FD_ISSET (fdp->fd, &write_set))
2493 	    fdp->revents |= _DBUS_POLLOUT;
2494 
2495 	  if (FD_ISSET (fdp->fd, &err_set))
2496 	    fdp->revents |= _DBUS_POLLERR;
2497 	}
2498     }
2499 
2500   return ready;
2501 #endif
2502 }
2503 
2504 /**
2505  * Get current time, as in gettimeofday(). Use the monotonic clock if
2506  * available, to avoid problems when the system time changes.
2507  *
2508  * @param tv_sec return location for number of seconds
2509  * @param tv_usec return location for number of microseconds (thousandths)
2510  */
2511 void
_dbus_get_current_time(long * tv_sec,long * tv_usec)2512 _dbus_get_current_time (long *tv_sec,
2513                         long *tv_usec)
2514 {
2515   struct timeval t;
2516 
2517 #ifdef HAVE_MONOTONIC_CLOCK
2518   struct timespec ts;
2519   clock_gettime (CLOCK_MONOTONIC, &ts);
2520 
2521   if (tv_sec)
2522     *tv_sec = ts.tv_sec;
2523   if (tv_usec)
2524     *tv_usec = ts.tv_nsec / 1000;
2525 #else
2526   gettimeofday (&t, NULL);
2527 
2528   if (tv_sec)
2529     *tv_sec = t.tv_sec;
2530   if (tv_usec)
2531     *tv_usec = t.tv_usec;
2532 #endif
2533 }
2534 
2535 /**
2536  * Creates a directory; succeeds if the directory
2537  * is created or already existed.
2538  *
2539  * @param filename directory filename
2540  * @param error initialized error object
2541  * @returns #TRUE on success
2542  */
2543 dbus_bool_t
_dbus_create_directory(const DBusString * filename,DBusError * error)2544 _dbus_create_directory (const DBusString *filename,
2545                         DBusError        *error)
2546 {
2547   const char *filename_c;
2548 
2549   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2550 
2551   filename_c = _dbus_string_get_const_data (filename);
2552 
2553   if (mkdir (filename_c, 0700) < 0)
2554     {
2555       if (errno == EEXIST)
2556         return TRUE;
2557 
2558       dbus_set_error (error, DBUS_ERROR_FAILED,
2559                       "Failed to create directory %s: %s\n",
2560                       filename_c, _dbus_strerror (errno));
2561       return FALSE;
2562     }
2563   else
2564     return TRUE;
2565 }
2566 
2567 /**
2568  * Appends the given filename to the given directory.
2569  *
2570  * @todo it might be cute to collapse multiple '/' such as "foo//"
2571  * concat "//bar"
2572  *
2573  * @param dir the directory name
2574  * @param next_component the filename
2575  * @returns #TRUE on success
2576  */
2577 dbus_bool_t
_dbus_concat_dir_and_file(DBusString * dir,const DBusString * next_component)2578 _dbus_concat_dir_and_file (DBusString       *dir,
2579                            const DBusString *next_component)
2580 {
2581   dbus_bool_t dir_ends_in_slash;
2582   dbus_bool_t file_starts_with_slash;
2583 
2584   if (_dbus_string_get_length (dir) == 0 ||
2585       _dbus_string_get_length (next_component) == 0)
2586     return TRUE;
2587 
2588   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2589                                                     _dbus_string_get_length (dir) - 1);
2590 
2591   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2592 
2593   if (dir_ends_in_slash && file_starts_with_slash)
2594     {
2595       _dbus_string_shorten (dir, 1);
2596     }
2597   else if (!(dir_ends_in_slash || file_starts_with_slash))
2598     {
2599       if (!_dbus_string_append_byte (dir, '/'))
2600         return FALSE;
2601     }
2602 
2603   return _dbus_string_copy (next_component, 0, dir,
2604                             _dbus_string_get_length (dir));
2605 }
2606 
2607 /** nanoseconds in a second */
2608 #define NANOSECONDS_PER_SECOND       1000000000
2609 /** microseconds in a second */
2610 #define MICROSECONDS_PER_SECOND      1000000
2611 /** milliseconds in a second */
2612 #define MILLISECONDS_PER_SECOND      1000
2613 /** nanoseconds in a millisecond */
2614 #define NANOSECONDS_PER_MILLISECOND  1000000
2615 /** microseconds in a millisecond */
2616 #define MICROSECONDS_PER_MILLISECOND 1000
2617 
2618 /**
2619  * Sleeps the given number of milliseconds.
2620  * @param milliseconds number of milliseconds
2621  */
2622 void
_dbus_sleep_milliseconds(int milliseconds)2623 _dbus_sleep_milliseconds (int milliseconds)
2624 {
2625 #ifdef HAVE_NANOSLEEP
2626   struct timespec req;
2627   struct timespec rem;
2628 
2629   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2630   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2631   rem.tv_sec = 0;
2632   rem.tv_nsec = 0;
2633 
2634   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2635     req = rem;
2636 #elif defined (HAVE_USLEEP)
2637   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2638 #else /* ! HAVE_USLEEP */
2639   sleep (MAX (milliseconds / 1000, 1));
2640 #endif
2641 }
2642 
2643 static dbus_bool_t
_dbus_generate_pseudorandom_bytes(DBusString * str,int n_bytes)2644 _dbus_generate_pseudorandom_bytes (DBusString *str,
2645                                    int         n_bytes)
2646 {
2647   int old_len;
2648   char *p;
2649 
2650   old_len = _dbus_string_get_length (str);
2651 
2652   if (!_dbus_string_lengthen (str, n_bytes))
2653     return FALSE;
2654 
2655   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2656 
2657   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2658 
2659   return TRUE;
2660 }
2661 
2662 /**
2663  * Generates the given number of random bytes,
2664  * using the best mechanism we can come up with.
2665  *
2666  * @param str the string
2667  * @param n_bytes the number of random bytes to append to string
2668  * @returns #TRUE on success, #FALSE if no memory
2669  */
2670 dbus_bool_t
_dbus_generate_random_bytes(DBusString * str,int n_bytes)2671 _dbus_generate_random_bytes (DBusString *str,
2672                              int         n_bytes)
2673 {
2674   int old_len;
2675   int fd;
2676 
2677   /* FALSE return means "no memory", if it could
2678    * mean something else then we'd need to return
2679    * a DBusError. So we always fall back to pseudorandom
2680    * if the I/O fails.
2681    */
2682 
2683   old_len = _dbus_string_get_length (str);
2684   fd = -1;
2685 
2686   /* note, urandom on linux will fall back to pseudorandom */
2687   fd = open ("/dev/urandom", O_RDONLY);
2688   if (fd < 0)
2689     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2690 
2691   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2692 
2693   if (_dbus_read (fd, str, n_bytes) != n_bytes)
2694     {
2695       _dbus_close (fd, NULL);
2696       _dbus_string_set_length (str, old_len);
2697       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2698     }
2699 
2700   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2701                  n_bytes);
2702 
2703   _dbus_close (fd, NULL);
2704 
2705   return TRUE;
2706 }
2707 
2708 /**
2709  * Exit the process, returning the given value.
2710  *
2711  * @param code the exit code
2712  */
2713 void
_dbus_exit(int code)2714 _dbus_exit (int code)
2715 {
2716   _exit (code);
2717 }
2718 
2719 /**
2720  * A wrapper around strerror() because some platforms
2721  * may be lame and not have strerror(). Also, never
2722  * returns NULL.
2723  *
2724  * @param error_number errno.
2725  * @returns error description.
2726  */
2727 const char*
_dbus_strerror(int error_number)2728 _dbus_strerror (int error_number)
2729 {
2730   const char *msg;
2731 
2732   msg = strerror (error_number);
2733   if (msg == NULL)
2734     msg = "unknown";
2735 
2736   return msg;
2737 }
2738 
2739 /**
2740  * signal (SIGPIPE, SIG_IGN);
2741  */
2742 void
_dbus_disable_sigpipe(void)2743 _dbus_disable_sigpipe (void)
2744 {
2745   signal (SIGPIPE, SIG_IGN);
2746 }
2747 
2748 /**
2749  * Sets the file descriptor to be close
2750  * on exec. Should be called for all file
2751  * descriptors in D-Bus code.
2752  *
2753  * @param fd the file descriptor
2754  */
2755 void
_dbus_fd_set_close_on_exec(intptr_t fd)2756 _dbus_fd_set_close_on_exec (intptr_t fd)
2757 {
2758   int val;
2759 
2760   val = fcntl (fd, F_GETFD, 0);
2761 
2762   if (val < 0)
2763     return;
2764 
2765   val |= FD_CLOEXEC;
2766 
2767   fcntl (fd, F_SETFD, val);
2768 }
2769 
2770 /**
2771  * Closes a file descriptor.
2772  *
2773  * @param fd the file descriptor
2774  * @param error error object
2775  * @returns #FALSE if error set
2776  */
2777 dbus_bool_t
_dbus_close(int fd,DBusError * error)2778 _dbus_close (int        fd,
2779              DBusError *error)
2780 {
2781   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2782 
2783  again:
2784   if (close (fd) < 0)
2785     {
2786       if (errno == EINTR)
2787         goto again;
2788 
2789       dbus_set_error (error, _dbus_error_from_errno (errno),
2790                       "Could not close fd %d", fd);
2791       return FALSE;
2792     }
2793 
2794   return TRUE;
2795 }
2796 
2797 /**
2798  * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2799  * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2800  *
2801  * @param fd the file descriptor to duplicate
2802  * @returns duplicated file descriptor
2803  * */
2804 int
_dbus_dup(int fd,DBusError * error)2805 _dbus_dup(int        fd,
2806           DBusError *error)
2807 {
2808   int new_fd;
2809 
2810 #ifdef F_DUPFD_CLOEXEC
2811   dbus_bool_t cloexec_done;
2812 
2813   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2814   cloexec_done = new_fd >= 0;
2815 
2816   if (new_fd < 0 && errno == EINVAL)
2817 #endif
2818     {
2819       new_fd = fcntl(fd, F_DUPFD, 3);
2820     }
2821 
2822   if (new_fd < 0) {
2823 
2824     dbus_set_error (error, _dbus_error_from_errno (errno),
2825                     "Could not duplicate fd %d", fd);
2826     return -1;
2827   }
2828 
2829 #ifdef F_DUPFD_CLOEXEC
2830   if (!cloexec_done)
2831 #endif
2832     {
2833       _dbus_fd_set_close_on_exec(new_fd);
2834     }
2835 
2836   return new_fd;
2837 }
2838 
2839 /**
2840  * Sets a file descriptor to be nonblocking.
2841  *
2842  * @param fd the file descriptor.
2843  * @param error address of error location.
2844  * @returns #TRUE on success.
2845  */
2846 dbus_bool_t
_dbus_set_fd_nonblocking(int fd,DBusError * error)2847 _dbus_set_fd_nonblocking (int             fd,
2848                           DBusError      *error)
2849 {
2850   int val;
2851 
2852   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2853 
2854   val = fcntl (fd, F_GETFL, 0);
2855   if (val < 0)
2856     {
2857       dbus_set_error (error, _dbus_error_from_errno (errno),
2858                       "Failed to get flags from file descriptor %d: %s",
2859                       fd, _dbus_strerror (errno));
2860       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2861                      _dbus_strerror (errno));
2862       return FALSE;
2863     }
2864 
2865   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2866     {
2867       dbus_set_error (error, _dbus_error_from_errno (errno),
2868                       "Failed to set nonblocking flag of file descriptor %d: %s",
2869                       fd, _dbus_strerror (errno));
2870       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2871                      fd, _dbus_strerror (errno));
2872 
2873       return FALSE;
2874     }
2875 
2876   return TRUE;
2877 }
2878 
2879 /**
2880  * On GNU libc systems, print a crude backtrace to stderr.  On other
2881  * systems, print "no backtrace support" and block for possible gdb
2882  * attachment if an appropriate environment variable is set.
2883  */
2884 void
_dbus_print_backtrace(void)2885 _dbus_print_backtrace (void)
2886 {
2887 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2888   void *bt[500];
2889   int bt_size;
2890   int i;
2891   char **syms;
2892 
2893   bt_size = backtrace (bt, 500);
2894 
2895   syms = backtrace_symbols (bt, bt_size);
2896 
2897   i = 0;
2898   while (i < bt_size)
2899     {
2900       /* don't use dbus_warn since it can _dbus_abort() */
2901       fprintf (stderr, "  %s\n", syms[i]);
2902       ++i;
2903     }
2904   fflush (stderr);
2905 
2906   free (syms);
2907 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2908   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
2909 #else
2910   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2911 #endif
2912 }
2913 
2914 /**
2915  * Creates a full-duplex pipe (as in socketpair()).
2916  * Sets both ends of the pipe nonblocking.
2917  *
2918  * Marks both file descriptors as close-on-exec
2919  *
2920  * @todo libdbus only uses this for the debug-pipe server, so in
2921  * principle it could be in dbus-sysdeps-util.c, except that
2922  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2923  * debug-pipe server is used.
2924  *
2925  * @param fd1 return location for one end
2926  * @param fd2 return location for the other end
2927  * @param blocking #TRUE if pipe should be blocking
2928  * @param error error return
2929  * @returns #FALSE on failure (if error is set)
2930  */
2931 dbus_bool_t
_dbus_full_duplex_pipe(int * fd1,int * fd2,dbus_bool_t blocking,DBusError * error)2932 _dbus_full_duplex_pipe (int        *fd1,
2933                         int        *fd2,
2934                         dbus_bool_t blocking,
2935                         DBusError  *error)
2936 {
2937 #ifdef HAVE_SOCKETPAIR
2938   int fds[2];
2939   int retval;
2940 
2941 #ifdef SOCK_CLOEXEC
2942   dbus_bool_t cloexec_done;
2943 
2944   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2945   cloexec_done = retval >= 0;
2946 
2947   if (retval < 0 && errno == EINVAL)
2948 #endif
2949     {
2950       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2951     }
2952 
2953   if (retval < 0)
2954     {
2955       dbus_set_error (error, _dbus_error_from_errno (errno),
2956                       "Could not create full-duplex pipe");
2957       return FALSE;
2958     }
2959 
2960   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2961 
2962 #ifdef SOCK_CLOEXEC
2963   if (!cloexec_done)
2964 #endif
2965     {
2966       _dbus_fd_set_close_on_exec (fds[0]);
2967       _dbus_fd_set_close_on_exec (fds[1]);
2968     }
2969 
2970   if (!blocking &&
2971       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2972        !_dbus_set_fd_nonblocking (fds[1], NULL)))
2973     {
2974       dbus_set_error (error, _dbus_error_from_errno (errno),
2975                       "Could not set full-duplex pipe nonblocking");
2976 
2977       _dbus_close (fds[0], NULL);
2978       _dbus_close (fds[1], NULL);
2979 
2980       return FALSE;
2981     }
2982 
2983   *fd1 = fds[0];
2984   *fd2 = fds[1];
2985 
2986   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2987                  *fd1, *fd2);
2988 
2989   return TRUE;
2990 #else
2991   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2992   dbus_set_error (error, DBUS_ERROR_FAILED,
2993                   "_dbus_full_duplex_pipe() not implemented on this OS");
2994   return FALSE;
2995 #endif
2996 }
2997 
2998 /**
2999  * Measure the length of the given format string and arguments,
3000  * not including the terminating nul.
3001  *
3002  * @param format a printf-style format string
3003  * @param args arguments for the format string
3004  * @returns length of the given format string and args
3005  */
3006 int
_dbus_printf_string_upper_bound(const char * format,va_list args)3007 _dbus_printf_string_upper_bound (const char *format,
3008                                  va_list     args)
3009 {
3010   char c;
3011   return vsnprintf (&c, 1, format, args);
3012 }
3013 
3014 /**
3015  * Gets the temporary files directory by inspecting the environment variables
3016  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3017  *
3018  * @returns location of temp directory
3019  */
3020 const char*
_dbus_get_tmpdir(void)3021 _dbus_get_tmpdir(void)
3022 {
3023   static const char* tmpdir = NULL;
3024 
3025   if (tmpdir == NULL)
3026     {
3027       /* TMPDIR is what glibc uses, then
3028        * glibc falls back to the P_tmpdir macro which
3029        * just expands to "/tmp"
3030        */
3031       if (tmpdir == NULL)
3032         tmpdir = getenv("TMPDIR");
3033 
3034       /* These two env variables are probably
3035        * broken, but maybe some OS uses them?
3036        */
3037       if (tmpdir == NULL)
3038         tmpdir = getenv("TMP");
3039       if (tmpdir == NULL)
3040         tmpdir = getenv("TEMP");
3041 
3042       /* And this is the sane fallback. */
3043       if (tmpdir == NULL)
3044         tmpdir = "/tmp";
3045     }
3046 
3047   _dbus_assert(tmpdir != NULL);
3048 
3049   return tmpdir;
3050 }
3051 
3052 /**
3053  * Execute a subprocess, returning up to 1024 bytes of output
3054  * into @p result.
3055  *
3056  * If successful, returns #TRUE and appends the output to @p
3057  * result. If a failure happens, returns #FALSE and
3058  * sets an error in @p error.
3059  *
3060  * @note It's not an error if the subprocess terminates normally
3061  * without writing any data to stdout. Verify the @p result length
3062  * before and after this function call to cover this case.
3063  *
3064  * @param progname initial path to exec (may or may not be absolute)
3065  * @param path_fallback if %TRUE, search PATH for executable
3066  * @param argv NULL-terminated list of arguments
3067  * @param result a DBusString where the output can be append
3068  * @param error a DBusError to store the error in case of failure
3069  * @returns #TRUE on success, #FALSE if an error happened
3070  */
3071 static dbus_bool_t
_read_subprocess_line_argv(const char * progpath,dbus_bool_t path_fallback,char * const * argv,DBusString * result,DBusError * error)3072 _read_subprocess_line_argv (const char *progpath,
3073                             dbus_bool_t path_fallback,
3074                             char       * const *argv,
3075                             DBusString *result,
3076                             DBusError  *error)
3077 {
3078   int result_pipe[2] = { -1, -1 };
3079   int errors_pipe[2] = { -1, -1 };
3080   pid_t pid;
3081   int ret;
3082   int status;
3083   int orig_len;
3084   int i;
3085 
3086   dbus_bool_t retval;
3087   sigset_t new_set, old_set;
3088 
3089   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3090   retval = FALSE;
3091 
3092   /* We need to block any existing handlers for SIGCHLD temporarily; they
3093    * will cause waitpid() below to fail.
3094    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3095    */
3096   sigemptyset (&new_set);
3097   sigaddset (&new_set, SIGCHLD);
3098   sigprocmask (SIG_BLOCK, &new_set, &old_set);
3099 
3100   orig_len = _dbus_string_get_length (result);
3101 
3102 #define READ_END        0
3103 #define WRITE_END       1
3104   if (pipe (result_pipe) < 0)
3105     {
3106       dbus_set_error (error, _dbus_error_from_errno (errno),
3107                       "Failed to create a pipe to call %s: %s",
3108                       progpath, _dbus_strerror (errno));
3109       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3110                      progpath, _dbus_strerror (errno));
3111       goto out;
3112     }
3113   if (pipe (errors_pipe) < 0)
3114     {
3115       dbus_set_error (error, _dbus_error_from_errno (errno),
3116                       "Failed to create a pipe to call %s: %s",
3117                       progpath, _dbus_strerror (errno));
3118       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3119                      progpath, _dbus_strerror (errno));
3120       goto out;
3121     }
3122 
3123   pid = fork ();
3124   if (pid < 0)
3125     {
3126       dbus_set_error (error, _dbus_error_from_errno (errno),
3127                       "Failed to fork() to call %s: %s",
3128                       progpath, _dbus_strerror (errno));
3129       _dbus_verbose ("Failed to fork() to call %s: %s\n",
3130                      progpath, _dbus_strerror (errno));
3131       goto out;
3132     }
3133 
3134   if (pid == 0)
3135     {
3136       /* child process */
3137       int maxfds;
3138       int fd;
3139 
3140       fd = open ("/dev/null", O_RDWR);
3141       if (fd == -1)
3142         /* huh?! can't open /dev/null? */
3143         _exit (1);
3144 
3145       _dbus_verbose ("/dev/null fd %d opened\n", fd);
3146 
3147       /* set-up stdXXX */
3148       close (result_pipe[READ_END]);
3149       close (errors_pipe[READ_END]);
3150       close (0);                /* close stdin */
3151       close (1);                /* close stdout */
3152       close (2);                /* close stderr */
3153 
3154       if (dup2 (fd, 0) == -1)
3155         _exit (1);
3156       if (dup2 (result_pipe[WRITE_END], 1) == -1)
3157         _exit (1);
3158       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3159         _exit (1);
3160 
3161       maxfds = sysconf (_SC_OPEN_MAX);
3162       /* Pick something reasonable if for some reason sysconf
3163        * says unlimited.
3164        */
3165       if (maxfds < 0)
3166         maxfds = 1024;
3167       /* close all inherited fds */
3168       for (i = 3; i < maxfds; i++)
3169         close (i);
3170 
3171       sigprocmask (SIG_SETMASK, &old_set, NULL);
3172 
3173       /* If it looks fully-qualified, try execv first */
3174       if (progpath[0] == '/')
3175         {
3176           execv (progpath, argv);
3177           /* Ok, that failed.  Now if path_fallback is given, let's
3178            * try unqualified.  This is mostly a hack to work
3179            * around systems which ship dbus-launch in /usr/bin
3180            * but everything else in /bin (because dbus-launch
3181            * depends on X11).
3182            */
3183           if (path_fallback)
3184             /* We must have a slash, because we checked above */
3185             execvp (strrchr (progpath, '/')+1, argv);
3186         }
3187       else
3188         execvp (progpath, argv);
3189 
3190       /* still nothing, we failed */
3191       _exit (1);
3192     }
3193 
3194   /* parent process */
3195   close (result_pipe[WRITE_END]);
3196   close (errors_pipe[WRITE_END]);
3197   result_pipe[WRITE_END] = -1;
3198   errors_pipe[WRITE_END] = -1;
3199 
3200   ret = 0;
3201   do
3202     {
3203       ret = _dbus_read (result_pipe[READ_END], result, 1024);
3204     }
3205   while (ret > 0);
3206 
3207   /* reap the child process to avoid it lingering as zombie */
3208   do
3209     {
3210       ret = waitpid (pid, &status, 0);
3211     }
3212   while (ret == -1 && errno == EINTR);
3213 
3214   /* We succeeded if the process exited with status 0 and
3215      anything was read */
3216   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3217     {
3218       /* The process ended with error */
3219       DBusString error_message;
3220       _dbus_string_init (&error_message);
3221       ret = 0;
3222       do
3223         {
3224           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3225         }
3226       while (ret > 0);
3227 
3228       _dbus_string_set_length (result, orig_len);
3229       if (_dbus_string_get_length (&error_message) > 0)
3230         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3231                         "%s terminated abnormally with the following error: %s",
3232                         progpath, _dbus_string_get_data (&error_message));
3233       else
3234         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3235                         "%s terminated abnormally without any error message",
3236                         progpath);
3237       goto out;
3238     }
3239 
3240   retval = TRUE;
3241 
3242  out:
3243   sigprocmask (SIG_SETMASK, &old_set, NULL);
3244 
3245   if (retval)
3246     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3247   else
3248     _DBUS_ASSERT_ERROR_IS_SET (error);
3249 
3250   if (result_pipe[0] != -1)
3251     close (result_pipe[0]);
3252   if (result_pipe[1] != -1)
3253     close (result_pipe[1]);
3254   if (errors_pipe[0] != -1)
3255     close (errors_pipe[0]);
3256   if (errors_pipe[1] != -1)
3257     close (errors_pipe[1]);
3258 
3259   return retval;
3260 }
3261 
3262 /**
3263  * Returns the address of a new session bus.
3264  *
3265  * If successful, returns #TRUE and appends the address to @p
3266  * address. If a failure happens, returns #FALSE and
3267  * sets an error in @p error.
3268  *
3269  * @param address a DBusString where the address can be stored
3270  * @param error a DBusError to store the error in case of failure
3271  * @returns #TRUE on success, #FALSE if an error happened
3272  */
3273 dbus_bool_t
_dbus_get_autolaunch_address(DBusString * address,DBusError * error)3274 _dbus_get_autolaunch_address (DBusString *address,
3275                               DBusError  *error)
3276 {
3277   static char *argv[6];
3278   int i;
3279   DBusString uuid;
3280   dbus_bool_t retval;
3281 
3282   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3283   retval = FALSE;
3284 
3285   if (!_dbus_string_init (&uuid))
3286     {
3287       _DBUS_SET_OOM (error);
3288       return FALSE;
3289     }
3290 
3291   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3292     {
3293       _DBUS_SET_OOM (error);
3294       goto out;
3295     }
3296 
3297   i = 0;
3298   argv[i] = "dbus-launch";
3299   ++i;
3300   argv[i] = "--autolaunch";
3301   ++i;
3302   argv[i] = _dbus_string_get_data (&uuid);
3303   ++i;
3304   argv[i] = "--binary-syntax";
3305   ++i;
3306   argv[i] = "--close-stderr";
3307   ++i;
3308   argv[i] = NULL;
3309   ++i;
3310 
3311   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3312 
3313   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3314                                        TRUE,
3315                                        argv, address, error);
3316 
3317  out:
3318   _dbus_string_free (&uuid);
3319   return retval;
3320 }
3321 
3322 /**
3323  * Reads the uuid of the machine we're running on from
3324  * the dbus configuration. Optionally try to create it
3325  * (only root can do this usually).
3326  *
3327  * On UNIX, reads a file that gets created by dbus-uuidgen
3328  * in a post-install script. On Windows, if there's a standard
3329  * machine uuid we could just use that, but I can't find one
3330  * with the right properties (the hardware profile guid can change
3331  * without rebooting I believe). If there's no standard one
3332  * we might want to use the registry instead of a file for
3333  * this, and I'm not sure how we'd ensure the uuid gets created.
3334  *
3335  * @param machine_id guid to init with the machine's uuid
3336  * @param create_if_not_found try to create the uuid if it doesn't exist
3337  * @param error the error return
3338  * @returns #FALSE if the error is set
3339  */
3340 dbus_bool_t
_dbus_read_local_machine_uuid(DBusGUID * machine_id,dbus_bool_t create_if_not_found,DBusError * error)3341 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
3342                                dbus_bool_t create_if_not_found,
3343                                DBusError  *error)
3344 {
3345   DBusString filename;
3346   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3347   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3348 }
3349 
3350 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3351 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3352 
3353 /**
3354  * Determines the address of the session bus by querying a
3355  * platform-specific method.
3356  *
3357  * The first parameter will be a boolean specifying whether
3358  * or not a dynamic session lookup is supported on this platform.
3359  *
3360  * If supported is TRUE and the return value is #TRUE, the
3361  * address will be  appended to @p address.
3362  * If a failure happens, returns #FALSE and sets an error in
3363  * @p error.
3364  *
3365  * If supported is FALSE, ignore the return value.
3366  *
3367  * @param supported returns whether this method is supported
3368  * @param address a DBusString where the address can be stored
3369  * @param error a DBusError to store the error in case of failure
3370  * @returns #TRUE on success, #FALSE if an error happened
3371  */
3372 dbus_bool_t
_dbus_lookup_session_address(dbus_bool_t * supported,DBusString * address,DBusError * error)3373 _dbus_lookup_session_address (dbus_bool_t *supported,
3374                               DBusString  *address,
3375                               DBusError   *error)
3376 {
3377   /* On non-Mac Unix platforms, if the session address isn't already
3378    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3379    * fall back to the autolaunch: global default; see
3380    * init_session_address in dbus/dbus-bus.c. */
3381   *supported = FALSE;
3382   return TRUE;
3383 }
3384 
3385 /**
3386  * Returns the standard directories for a session bus to look for service
3387  * activation files
3388  *
3389  * On UNIX this should be the standard xdg freedesktop.org data directories:
3390  *
3391  * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3392  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3393  *
3394  * and
3395  *
3396  * DBUS_DATADIR
3397  *
3398  * @param dirs the directory list we are returning
3399  * @returns #FALSE on OOM
3400  */
3401 
3402 dbus_bool_t
_dbus_get_standard_session_servicedirs(DBusList ** dirs)3403 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3404 {
3405   const char *xdg_data_home;
3406   const char *xdg_data_dirs;
3407   DBusString servicedir_path;
3408 
3409   if (!_dbus_string_init (&servicedir_path))
3410     return FALSE;
3411 
3412   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3413   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3414 
3415   if (xdg_data_dirs != NULL)
3416     {
3417       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3418         goto oom;
3419 
3420       if (!_dbus_string_append (&servicedir_path, ":"))
3421         goto oom;
3422     }
3423   else
3424     {
3425       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3426         goto oom;
3427     }
3428 
3429   /*
3430    * add configured datadir to defaults
3431    * this may be the same as an xdg dir
3432    * however the config parser should take
3433    * care of duplicates
3434    */
3435   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3436         goto oom;
3437 
3438   if (xdg_data_home != NULL)
3439     {
3440       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3441         goto oom;
3442     }
3443   else
3444     {
3445       const DBusString *homedir;
3446       DBusString local_share;
3447 
3448       if (!_dbus_homedir_from_current_process (&homedir))
3449         goto oom;
3450 
3451       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3452         goto oom;
3453 
3454       _dbus_string_init_const (&local_share, "/.local/share");
3455       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3456         goto oom;
3457     }
3458 
3459   if (!_dbus_split_paths_and_append (&servicedir_path,
3460                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3461                                      dirs))
3462     goto oom;
3463 
3464   _dbus_string_free (&servicedir_path);
3465   return TRUE;
3466 
3467  oom:
3468   _dbus_string_free (&servicedir_path);
3469   return FALSE;
3470 }
3471 
3472 
3473 /**
3474  * Returns the standard directories for a system bus to look for service
3475  * activation files
3476  *
3477  * On UNIX this should be the standard xdg freedesktop.org data directories:
3478  *
3479  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3480  *
3481  * and
3482  *
3483  * DBUS_DATADIR
3484  *
3485  * On Windows there is no system bus and this function can return nothing.
3486  *
3487  * @param dirs the directory list we are returning
3488  * @returns #FALSE on OOM
3489  */
3490 
3491 dbus_bool_t
_dbus_get_standard_system_servicedirs(DBusList ** dirs)3492 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3493 {
3494   const char *xdg_data_dirs;
3495   DBusString servicedir_path;
3496 
3497   if (!_dbus_string_init (&servicedir_path))
3498     return FALSE;
3499 
3500   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3501 
3502   if (xdg_data_dirs != NULL)
3503     {
3504       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3505         goto oom;
3506 
3507       if (!_dbus_string_append (&servicedir_path, ":"))
3508         goto oom;
3509     }
3510   else
3511     {
3512       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3513         goto oom;
3514     }
3515 
3516   /*
3517    * add configured datadir to defaults
3518    * this may be the same as an xdg dir
3519    * however the config parser should take
3520    * care of duplicates
3521    */
3522   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3523         goto oom;
3524 
3525   if (!_dbus_split_paths_and_append (&servicedir_path,
3526                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3527                                      dirs))
3528     goto oom;
3529 
3530   _dbus_string_free (&servicedir_path);
3531   return TRUE;
3532 
3533  oom:
3534   _dbus_string_free (&servicedir_path);
3535   return FALSE;
3536 }
3537 
3538 /**
3539  * Append the absolute path of the system.conf file
3540  * (there is no system bus on Windows so this can just
3541  * return FALSE and print a warning or something)
3542  *
3543  * @param str the string to append to
3544  * @returns #FALSE if no memory
3545  */
3546 dbus_bool_t
_dbus_append_system_config_file(DBusString * str)3547 _dbus_append_system_config_file (DBusString *str)
3548 {
3549   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3550 }
3551 
3552 /**
3553  * Append the absolute path of the session.conf file.
3554  *
3555  * @param str the string to append to
3556  * @returns #FALSE if no memory
3557  */
3558 dbus_bool_t
_dbus_append_session_config_file(DBusString * str)3559 _dbus_append_session_config_file (DBusString *str)
3560 {
3561   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3562 }
3563 
3564 /**
3565  * Called when the bus daemon is signaled to reload its configuration; any
3566  * caches should be nuked. Of course any caches that need explicit reload
3567  * are probably broken, but c'est la vie.
3568  *
3569  *
3570  */
3571 void
_dbus_flush_caches(void)3572 _dbus_flush_caches (void)
3573 {
3574   _dbus_user_database_flush_system ();
3575 }
3576 
3577 /**
3578  * Appends the directory in which a keyring for the given credentials
3579  * should be stored.  The credentials should have either a Windows or
3580  * UNIX user in them.  The directory should be an absolute path.
3581  *
3582  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3583  * be something else, since the dotfile convention is not normal on Windows.
3584  *
3585  * @param directory string to append directory to
3586  * @param credentials credentials the directory should be for
3587  *
3588  * @returns #FALSE on no memory
3589  */
3590 dbus_bool_t
_dbus_append_keyring_directory_for_credentials(DBusString * directory,DBusCredentials * credentials)3591 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3592                                                 DBusCredentials *credentials)
3593 {
3594   DBusString homedir;
3595   DBusString dotdir;
3596   dbus_uid_t uid;
3597 
3598   _dbus_assert (credentials != NULL);
3599   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3600 
3601   if (!_dbus_string_init (&homedir))
3602     return FALSE;
3603 
3604   uid = _dbus_credentials_get_unix_uid (credentials);
3605   _dbus_assert (uid != DBUS_UID_UNSET);
3606 
3607   if (!_dbus_homedir_from_uid (uid, &homedir))
3608     goto failed;
3609 
3610 #ifdef DBUS_BUILD_TESTS
3611   {
3612     const char *override;
3613 
3614     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3615     if (override != NULL && *override != '\0')
3616       {
3617         _dbus_string_set_length (&homedir, 0);
3618         if (!_dbus_string_append (&homedir, override))
3619           goto failed;
3620 
3621         _dbus_verbose ("Using fake homedir for testing: %s\n",
3622                        _dbus_string_get_const_data (&homedir));
3623       }
3624     else
3625       {
3626         static dbus_bool_t already_warned = FALSE;
3627         if (!already_warned)
3628           {
3629             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3630             already_warned = TRUE;
3631           }
3632       }
3633   }
3634 #endif
3635 
3636   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3637   if (!_dbus_concat_dir_and_file (&homedir,
3638                                   &dotdir))
3639     goto failed;
3640 
3641   if (!_dbus_string_copy (&homedir, 0,
3642                           directory, _dbus_string_get_length (directory))) {
3643     goto failed;
3644   }
3645 
3646   _dbus_string_free (&homedir);
3647   return TRUE;
3648 
3649  failed:
3650   _dbus_string_free (&homedir);
3651   return FALSE;
3652 }
3653 
3654 //PENDING(kdab) docs
3655 void
_dbus_daemon_publish_session_bus_address(const char * addr)3656 _dbus_daemon_publish_session_bus_address (const char* addr)
3657 {
3658 
3659 }
3660 
3661 //PENDING(kdab) docs
3662 void
_dbus_daemon_unpublish_session_bus_address(void)3663 _dbus_daemon_unpublish_session_bus_address (void)
3664 {
3665 
3666 }
3667 
3668 /**
3669  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3670  * for Winsock so is abstracted)
3671  *
3672  * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3673  */
3674 dbus_bool_t
_dbus_get_is_errno_eagain_or_ewouldblock(void)3675 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3676 {
3677   return errno == EAGAIN || errno == EWOULDBLOCK;
3678 }
3679 
3680 /**
3681  * Removes a directory; Directory must be empty
3682  *
3683  * @param filename directory filename
3684  * @param error initialized error object
3685  * @returns #TRUE on success
3686  */
3687 dbus_bool_t
_dbus_delete_directory(const DBusString * filename,DBusError * error)3688 _dbus_delete_directory (const DBusString *filename,
3689                         DBusError        *error)
3690 {
3691   const char *filename_c;
3692 
3693   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3694 
3695   filename_c = _dbus_string_get_const_data (filename);
3696 
3697   if (rmdir (filename_c) != 0)
3698     {
3699       dbus_set_error (error, DBUS_ERROR_FAILED,
3700                       "Failed to remove directory %s: %s\n",
3701                       filename_c, _dbus_strerror (errno));
3702       return FALSE;
3703     }
3704 
3705   return TRUE;
3706 }
3707 
3708 /**
3709  *  Checks whether file descriptors may be passed via the socket
3710  *
3711  *  @param fd the socket
3712  *  @return TRUE when fd passing over this socket is supported
3713  *
3714  */
3715 dbus_bool_t
_dbus_socket_can_pass_unix_fd(int fd)3716 _dbus_socket_can_pass_unix_fd(int fd) {
3717 
3718 #ifdef SCM_RIGHTS
3719   union {
3720     struct sockaddr sa;
3721     struct sockaddr_storage storage;
3722     struct sockaddr_un un;
3723   } sa_buf;
3724 
3725   socklen_t sa_len = sizeof(sa_buf);
3726 
3727   _DBUS_ZERO(sa_buf);
3728 
3729   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3730     return FALSE;
3731 
3732   return sa_buf.sa.sa_family == AF_UNIX;
3733 
3734 #else
3735   return FALSE;
3736 
3737 #endif
3738 }
3739 
3740 
3741 /*
3742  * replaces the term DBUS_PREFIX in configure_time_path by the
3743  * current dbus installation directory. On unix this function is a noop
3744  *
3745  * @param configure_time_path
3746  * @return real path
3747  */
3748 const char *
_dbus_replace_install_prefix(const char * configure_time_path)3749 _dbus_replace_install_prefix (const char *configure_time_path)
3750 {
3751   return configure_time_path;
3752 }
3753 
3754 /* tests in dbus-sysdeps-util.c */
3755