1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "dbus-sysdeps.h"
25: #include "dbus-sysdeps-unix.h"
26: #include "dbus-internals.h"
27: #include "dbus-protocol.h"
28: #include "dbus-string.h"
29: #define DBUS_USERDB_INCLUDES_PRIVATE 1
30: #include "dbus-userdb.h"
31: #include "dbus-test.h"
32:
33: #include <sys/types.h>
34: #include <stdlib.h>
35: #include <string.h>
36: #include <signal.h>
37: #include <unistd.h>
38: #include <stdio.h>
39: #include <errno.h>
40: #include <fcntl.h>
41: #include <sys/stat.h>
42: #include <grp.h>
43: #include <sys/socket.h>
44: #include <dirent.h>
45: #include <sys/un.h>
46:
47: #ifdef HAVE_SYS_SYSLIMITS_H
48: #include <sys/syslimits.h>
49: #endif
50:
51: #ifndef O_BINARY
52: #define O_BINARY 0
53: #endif
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68: dbus_bool_t
69: _dbus_become_daemon (const DBusString *pidfile,
70: int print_pid_fd,
71: DBusError *error)
72: {
73: const char *s;
74: pid_t child_pid;
75: int dev_null_fd;
76:
77: _dbus_verbose ("Becoming a daemon...\n");
78:
79: _dbus_verbose ("chdir to /\n");
80: if (chdir ("/") < 0)
81: {
82: dbus_set_error (error, DBUS_ERROR_FAILED,
83: "Could not chdir() to root directory");
84: return FALSE;
85: }
86:
87: _dbus_verbose ("forking...\n");
88: switch ((child_pid = fork ()))
89: {
90: case -1:
91: _dbus_verbose ("fork failed\n");
92: dbus_set_error (error, _dbus_error_from_errno (errno),
93: "Failed to fork daemon: %s", _dbus_strerror (errno));
94: return FALSE;
95: break;
96:
97: case 0:
98: _dbus_verbose ("in child, closing std file descriptors\n");
99:
100:
101:
102:
103:
104:
105: dev_null_fd = open ("/dev/null", O_RDWR);
106: if (dev_null_fd >= 0)
107: {
108: dup2 (dev_null_fd, 0);
109: dup2 (dev_null_fd, 1);
110:
111: s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
112: if (s == NULL || *s == '\0')
113: dup2 (dev_null_fd, 2);
114: else
115: _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
116: }
117:
118:
119: _dbus_verbose ("setting umask\n");
120: umask (022);
121: break;
122:
123: default:
124: if (pidfile)
125: {
126: _dbus_verbose ("parent writing pid file\n");
127: if (!_dbus_write_pid_file (pidfile,
128: child_pid,
129: error))
130: {
131: _dbus_verbose ("pid file write failed, killing child\n");
132: kill (child_pid, SIGTERM);
133: return FALSE;
134: }
135: }
136:
137:
138: if (print_pid_fd >= 0)
139: {
140: DBusString pid;
141: int bytes;
142:
143: if (!_dbus_string_init (&pid))
144: {
145: _DBUS_SET_OOM (error);
146: kill (child_pid, SIGTERM);
147: return FALSE;
148: }
149:
150: if (!_dbus_string_append_int (&pid, child_pid) ||
151: !_dbus_string_append (&pid, "\n"))
152: {
153: _dbus_string_free (&pid);
154: _DBUS_SET_OOM (error);
155: kill (child_pid, SIGTERM);
156: return FALSE;
157: }
158:
159: bytes = _dbus_string_get_length (&pid);
160: if (_dbus_write_socket (print_pid_fd, &pid, 0, bytes) != bytes)
161: {
162: dbus_set_error (error, DBUS_ERROR_FAILED,
163: "Printing message bus PID: %s\n",
164: _dbus_strerror (errno));
165: _dbus_string_free (&pid);
166: kill (child_pid, SIGTERM);
167: return FALSE;
168: }
169:
170: _dbus_string_free (&pid);
171: }
172: _dbus_verbose ("parent exiting\n");
173: _exit (0);
174: break;
175: }
176:
177: _dbus_verbose ("calling setsid()\n");
178: if (setsid () == -1)
179: _dbus_assert_not_reached ("setsid() failed");
180:
181: return TRUE;
182: }
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193: dbus_bool_t
194: _dbus_write_pid_file (const DBusString *filename,
195: unsigned long pid,
196: DBusError *error)
197: {
198: const char *cfilename;
199: int fd;
200: FILE *f;
201:
202: cfilename = _dbus_string_get_const_data (filename);
203:
204: fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
205:
206: if (fd < 0)
207: {
208: dbus_set_error (error, _dbus_error_from_errno (errno),
209: "Failed to open \"%s\": %s", cfilename,
210: _dbus_strerror (errno));
211: return FALSE;
212: }
213:
214: if ((f = fdopen (fd, "w")) == NULL)
215: {
216: dbus_set_error (error, _dbus_error_from_errno (errno),
217: "Failed to fdopen fd %d: %s", fd, _dbus_strerror (errno));
218: _dbus_close (fd, NULL);
219: return FALSE;
220: }
221:
222: if (fprintf (f, "%lu\n", pid) < 0)
223: {
224: dbus_set_error (error, _dbus_error_from_errno (errno),
225: "Failed to write to \"%s\": %s", cfilename,
226: _dbus_strerror (errno));
227:
228: fclose (f);
229: return FALSE;
230: }
231:
232: if (fclose (f) == EOF)
233: {
234: dbus_set_error (error, _dbus_error_from_errno (errno),
235: "Failed to close \"%s\": %s", cfilename,
236: _dbus_strerror (errno));
237: return FALSE;
238: }
239:
240: return TRUE;
241: }
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252: dbus_bool_t
253: _dbus_change_identity (dbus_uid_t uid,
254: dbus_gid_t gid,
255: DBusError *error)
256: {
257:
258:
259:
260:
261:
262:
263:
264: if (setgroups (0, NULL) < 0)
265: _dbus_warn ("Failed to drop supplementary groups: %s\n",
266: _dbus_strerror (errno));
267:
268:
269:
270:
271: if (setgid (gid) < 0)
272: {
273: dbus_set_error (error, _dbus_error_from_errno (errno),
274: "Failed to set GID to %lu: %s", gid,
275: _dbus_strerror (errno));
276: return FALSE;
277: }
278:
279: if (setuid (uid) < 0)
280: {
281: dbus_set_error (error, _dbus_error_from_errno (errno),
282: "Failed to set UID to %lu: %s", uid,
283: _dbus_strerror (errno));
284: return FALSE;
285: }
286:
287: return TRUE;
288: }
289:
290:
291:
292:
293:
294:
295: void
296: _dbus_set_signal_handler (int sig,
297: DBusSignalHandler handler)
298: {
299: struct sigaction act;
300: sigset_t empty_mask;
301:
302: sigemptyset (&empty_mask);
303: act.sa_handler = handler;
304: act.sa_mask = empty_mask;
305: act.sa_flags = 0;
306: sigaction (sig, &act, NULL);
307: }
308:
309:
310:
311:
312:
313:
314:
315:
316:
317: dbus_bool_t
318: _dbus_delete_directory (const DBusString *filename,
319: DBusError *error)
320: {
321: const char *filename_c;
322:
323: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
324:
325: filename_c = _dbus_string_get_const_data (filename);
326:
327: if (rmdir (filename_c) != 0)
328: {
329: dbus_set_error (error, DBUS_ERROR_FAILED,
330: "Failed to remove directory %s: %s\n",
331: filename_c, _dbus_strerror (errno));
332: return FALSE;
333: }
334:
335: return TRUE;
336: }
337:
338:
339:
340:
341:
342:
343: dbus_bool_t
344: _dbus_file_exists (const char *file)
345: {
346: return (access (file, F_OK) == 0);
347: }
348:
349:
350:
351:
352:
353:
354:
355: dbus_bool_t
356: _dbus_user_at_console (const char *username,
357: DBusError *error)
358: {
359:
360: DBusString f;
361: dbus_bool_t result;
362:
363: result = FALSE;
364: if (!_dbus_string_init (&f))
365: {
366: _DBUS_SET_OOM (error);
367: return FALSE;
368: }
369:
370: if (!_dbus_string_append (&f, DBUS_CONSOLE_AUTH_DIR))
371: {
372: _DBUS_SET_OOM (error);
373: goto out;
374: }
375:
376:
377: if (!_dbus_string_append (&f, username))
378: {
379: _DBUS_SET_OOM (error);
380: goto out;
381: }
382:
383: result = _dbus_file_exists (_dbus_string_get_const_data (&f));
384:
385: out:
386: _dbus_string_free (&f);
387:
388: return result;
389: }
390:
391:
392:
393:
394:
395:
396:
397:
398: dbus_bool_t
399: _dbus_path_is_absolute (const DBusString *filename)
400: {
401: if (_dbus_string_get_length (filename) > 0)
402: return _dbus_string_get_byte (filename, 0) == '/';
403: else
404: return FALSE;
405: }
406:
407:
408:
409:
410:
411:
412:
413:
414:
415: dbus_bool_t
416: _dbus_stat (const DBusString *filename,
417: DBusStat *statbuf,
418: DBusError *error)
419: {
420: const char *filename_c;
421: struct stat sb;
422:
423: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
424:
425: filename_c = _dbus_string_get_const_data (filename);
426:
427: if (stat (filename_c, &sb) < 0)
428: {
429: dbus_set_error (error, _dbus_error_from_errno (errno),
430: "%s", _dbus_strerror (errno));
431: return FALSE;
432: }
433:
434: statbuf->mode = sb.st_mode;
435: statbuf->nlink = sb.st_nlink;
436: statbuf->uid = sb.st_uid;
437: statbuf->gid = sb.st_gid;
438: statbuf->size = sb.st_size;
439: statbuf->atime = sb.st_atime;
440: statbuf->mtime = sb.st_mtime;
441: statbuf->ctime = sb.st_ctime;
442:
443: return TRUE;
444: }
445:
446:
447:
448:
449:
450: struct DBusDirIter
451: {
452: DIR *d;
453:
454: };
455:
456:
457:
458:
459:
460:
461:
462:
463: DBusDirIter*
464: _dbus_directory_open (const DBusString *filename,
465: DBusError *error)
466: {
467: DIR *d;
468: DBusDirIter *iter;
469: const char *filename_c;
470:
471: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
472:
473: filename_c = _dbus_string_get_const_data (filename);
474:
475: d = opendir (filename_c);
476: if (d == NULL)
477: {
478: dbus_set_error (error, _dbus_error_from_errno (errno),
479: "Failed to read directory \"%s\": %s",
480: filename_c,
481: _dbus_strerror (errno));
482: return NULL;
483: }
484: iter = dbus_new0 (DBusDirIter, 1);
485: if (iter == NULL)
486: {
487: closedir (d);
488: dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
489: "Could not allocate memory for directory iterator");
490: return NULL;
491: }
492:
493: iter->d = d;
494:
495: return iter;
496: }
497:
498:
499:
500:
501:
502:
503:
504:
505:
506: static dbus_bool_t
507: dirent_buf_size(DIR * dirp, size_t *size)
508: {
509: long name_max;
510: # if defined(HAVE_FPATHCONF) && defined(_PC_NAME_MAX)
511: # if defined(HAVE_DIRFD)
512: name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
513: # elif defined(HAVE_DDFD)
514: name_max = fpathconf(dirp->dd_fd, _PC_NAME_MAX);
515: # else
516: name_max = fpathconf(dirp->__dd_fd, _PC_NAME_MAX);
517: # endif
518: if (name_max == -1)
519: # if defined(NAME_MAX)
520: name_max = NAME_MAX;
521: # else
522: return FALSE;
523: # endif
524: # elif defined(MAXNAMELEN)
525: name_max = MAXNAMELEN;
526: # else
527: # if defined(NAME_MAX)
528: name_max = NAME_MAX;
529: # else
530: # error "buffer size for readdir_r cannot be determined"
531: # endif
532: # endif
533: if (size)
534: *size = (size_t)offsetof(struct dirent, d_name) + name_max + 1;
535: else
536: return FALSE;
537:
538: return TRUE;
539: }
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551: dbus_bool_t
552: _dbus_directory_get_next_file (DBusDirIter *iter,
553: DBusString *filename,
554: DBusError *error)
555: {
556: struct dirent *d, *ent;
557: size_t buf_size;
558: int err;
559:
560: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
561:
562: if (!dirent_buf_size (iter->d, &buf_size))
563: {
564: dbus_set_error (error, DBUS_ERROR_FAILED,
565: "Can't calculate buffer size when reading directory");
566: return FALSE;
567: }
568:
569: d = (struct dirent *)dbus_malloc (buf_size);
570: if (!d)
571: {
572: dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
573: "No memory to read directory entry");
574: return FALSE;
575: }
576:
577: again:
578: err = readdir_r (iter->d, d, &ent);
579: if (err || !ent)
580: {
581: if (err != 0)
582: dbus_set_error (error,
583: _dbus_error_from_errno (err),
584: "%s", _dbus_strerror (err));
585:
586: dbus_free (d);
587: return FALSE;
588: }
589: else if (ent->d_name[