00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-sysdeps.h"
00025 #include "dbus-sysdeps-unix.h"
00026 #include "dbus-internals.h"
00027 #include "dbus-protocol.h"
00028 #include "dbus-string.h"
00029 #define DBUS_USERDB_INCLUDES_PRIVATE 1
00030 #include "dbus-userdb.h"
00031 #include "dbus-test.h"
00032
00033 #include <sys/types.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <signal.h>
00037 #include <unistd.h>
00038 #include <stdio.h>
00039 #include <errno.h>
00040 #include <fcntl.h>
00041 #include <sys/stat.h>
00042 #include <grp.h>
00043 #include <sys/socket.h>
00044 #include <dirent.h>
00045 #include <sys/un.h>
00046 #ifdef HAVE_LIBAUDIT
00047 #include <sys/prctl.h>
00048 #include <sys/capability.h>
00049 #include <libaudit.h>
00050 #endif
00051
00052 #ifdef HAVE_SYS_SYSLIMITS_H
00053 #include <sys/syslimits.h>
00054 #endif
00055
00056 #ifndef O_BINARY
00057 #define O_BINARY 0
00058 #endif
00059
00074 dbus_bool_t
00075 _dbus_become_daemon (const DBusString *pidfile,
00076 DBusPipe *print_pid_pipe,
00077 DBusError *error)
00078 {
00079 const char *s;
00080 pid_t child_pid;
00081 int dev_null_fd;
00082
00083 _dbus_verbose ("Becoming a daemon...\n");
00084
00085 _dbus_verbose ("chdir to /\n");
00086 if (chdir ("/") < 0)
00087 {
00088 dbus_set_error (error, DBUS_ERROR_FAILED,
00089 "Could not chdir() to root directory");
00090 return FALSE;
00091 }
00092
00093 _dbus_verbose ("forking...\n");
00094 switch ((child_pid = fork ()))
00095 {
00096 case -1:
00097 _dbus_verbose ("fork failed\n");
00098 dbus_set_error (error, _dbus_error_from_errno (errno),
00099 "Failed to fork daemon: %s", _dbus_strerror (errno));
00100 return FALSE;
00101 break;
00102
00103 case 0:
00104 _dbus_verbose ("in child, closing std file descriptors\n");
00105
00106
00107
00108
00109
00110
00111 dev_null_fd = open ("/dev/null", O_RDWR);
00112 if (dev_null_fd >= 0)
00113 {
00114 dup2 (dev_null_fd, 0);
00115 dup2 (dev_null_fd, 1);
00116
00117 s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
00118 if (s == NULL || *s == '\0')
00119 dup2 (dev_null_fd, 2);
00120 else
00121 _dbus_verbose ("keeping stderr open due to DBUS_DEBUG_OUTPUT\n");
00122 }
00123
00124
00125 _dbus_verbose ("setting umask\n");
00126 umask (022);
00127
00128 _dbus_verbose ("calling setsid()\n");
00129 if (setsid () == -1)
00130 _dbus_assert_not_reached ("setsid() failed");
00131
00132 break;
00133
00134 default:
00135 if (!_dbus_write_pid_to_file_and_pipe (pidfile, print_pid_pipe,
00136 child_pid, error))
00137 {
00138 _dbus_verbose ("pid file or pipe write failed: %s\n",
00139 error->message);
00140 kill (child_pid, SIGTERM);
00141 return FALSE;
00142 }
00143
00144 _dbus_verbose ("parent exiting\n");
00145 _exit (0);
00146 break;
00147 }
00148
00149 return TRUE;
00150 }
00151
00152
00161 static dbus_bool_t
00162 _dbus_write_pid_file (const DBusString *filename,
00163 unsigned long pid,
00164 DBusError *error)
00165 {
00166 const char *cfilename;
00167 int fd;
00168 FILE *f;
00169
00170 cfilename = _dbus_string_get_const_data (filename);
00171
00172 fd = open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
00173
00174 if (fd < 0)
00175 {
00176 dbus_set_error (error, _dbus_error_from_errno (errno),
00177 "Failed to open \"%s\": %s", cfilename,
00178 _dbus_strerror (errno));
00179 return FALSE;
00180 }
00181
00182 if ((f = fdopen (fd, "w")) == NULL)
00183 {
00184 dbus_set_error (error, _dbus_error_from_errno (errno),
00185 "Failed to fdopen fd %d: %s", fd, _dbus_strerror (errno));
00186 _dbus_close (fd, NULL);
00187 return FALSE;
00188 }
00189
00190 if (fprintf (f, "%lu\n", pid) < 0)
00191 {
00192 dbus_set_error (error, _dbus_error_from_errno (errno),
00193 "Failed to write to \"%s\": %s", cfilename,
00194 _dbus_strerror (errno));
00195
00196 fclose (f);
00197 return FALSE;
00198 }
00199
00200 if (fclose (f) == EOF)
00201 {
00202 dbus_set_error (error, _dbus_error_from_errno (errno),
00203 "Failed to close \"%s\": %s", cfilename,
00204 _dbus_strerror (errno));
00205 return FALSE;
00206 }
00207
00208 return TRUE;
00209 }
00210
00222 dbus_bool_t
00223 _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
00224 DBusPipe *print_pid_pipe,
00225 dbus_pid_t pid_to_write,
00226 DBusError *error)
00227 {
00228 if (pidfile)
00229 {
00230 _dbus_verbose ("writing pid file %s\n", _dbus_string_get_const_data (pidfile));
00231 if (!_dbus_write_pid_file (pidfile,
00232 pid_to_write,
00233 error))
00234 {
00235 _dbus_verbose ("pid file write failed\n");
00236 _DBUS_ASSERT_ERROR_IS_SET(error);
00237 return FALSE;
00238 }
00239 }
00240 else
00241 {
00242 _dbus_verbose ("No pid file requested\n");
00243 }
00244
00245 if (print_pid_pipe != NULL && _dbus_pipe_is_valid (print_pid_pipe))
00246 {
00247 DBusString pid;
00248 int bytes;
00249
00250 _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd_or_handle);
00251
00252 if (!_dbus_string_init (&pid))
00253 {
00254 _DBUS_SET_OOM (error);
00255 return FALSE;
00256 }
00257
00258 if (!_dbus_string_append_int (&pid, pid_to_write) ||
00259 !_dbus_string_append (&pid, "\n"))
00260 {
00261 _dbus_string_free (&pid);
00262 _DBUS_SET_OOM (error);
00263 return FALSE;
00264 }
00265
00266 bytes = _dbus_string_get_length (&pid);
00267 if (_dbus_pipe_write (print_pid_pipe, &pid, 0, bytes, error) != bytes)
00268 {
00269
00270 if (error != NULL && !dbus_error_is_set(error))
00271 {
00272 dbus_set_error (error, DBUS_ERROR_FAILED,
00273 "Printing message bus PID: did not write enough bytes\n");
00274 }
00275 _dbus_string_free (&pid);
00276 return FALSE;
00277 }
00278
00279 _dbus_string_free (&pid);
00280 }
00281 else
00282 {
00283 _dbus_verbose ("No pid pipe to write to\n");
00284 }
00285
00286 return TRUE;
00287 }
00288
00295 dbus_bool_t
00296 _dbus_verify_daemon_user (const char *user)
00297 {
00298 DBusString u;
00299
00300 _dbus_string_init_const (&u, user);
00301
00302 return _dbus_get_user_id_and_primary_group (&u, NULL, NULL);
00303 }
00304
00312 dbus_bool_t
00313 _dbus_change_to_daemon_user (const char *user,
00314 DBusError *error)
00315 {
00316 dbus_uid_t uid;
00317 dbus_gid_t gid;
00318 DBusString u;
00319 #ifdef HAVE_LIBAUDIT
00320 dbus_bool_t we_were_root;
00321 cap_t new_caps;
00322 #endif
00323
00324 _dbus_string_init_const (&u, user);
00325
00326 if (!_dbus_get_user_id_and_primary_group (&u, &uid, &gid))
00327 {
00328 dbus_set_error (error, DBUS_ERROR_FAILED,
00329 "User '%s' does not appear to exist?",
00330 user);
00331 return FALSE;
00332 }
00333
00334 #ifdef HAVE_LIBAUDIT
00335 we_were_root = _dbus_geteuid () == 0;
00336 new_caps = NULL;
00337
00338
00339
00340
00341 if (we_were_root)
00342 {
00343 cap_value_t new_cap_list[] = { CAP_AUDIT_WRITE };
00344 cap_value_t tmp_cap_list[] = { CAP_AUDIT_WRITE, CAP_SETUID, CAP_SETGID };
00345 cap_t tmp_caps = cap_init();
00346
00347 if (!tmp_caps || !(new_caps = cap_init ()))
00348 {
00349 dbus_set_error (error, DBUS_ERROR_FAILED,
00350 "Failed to initialize drop of capabilities: %s\n",
00351 _dbus_strerror (errno));
00352
00353 if (tmp_caps)
00354 cap_free (tmp_caps);
00355
00356 return FALSE;
00357 }
00358
00359
00360 cap_set_flag (new_caps, CAP_PERMITTED, 1, new_cap_list, CAP_SET);
00361 cap_set_flag (new_caps, CAP_EFFECTIVE, 1, new_cap_list, CAP_SET);
00362 cap_set_flag (tmp_caps, CAP_PERMITTED, 3, tmp_cap_list, CAP_SET);
00363 cap_set_flag (tmp_caps, CAP_EFFECTIVE, 3, tmp_cap_list, CAP_SET);
00364
00365 if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1)
00366 {
00367 dbus_set_error (error, _dbus_error_from_errno (errno),
00368 "Failed to set keep-capabilities: %s\n",
00369 _dbus_strerror (errno));
00370 cap_free (tmp_caps);
00371 goto fail;
00372 }
00373
00374 if (cap_set_proc (tmp_caps) == -1)
00375 {
00376 dbus_set_error (error, DBUS_ERROR_FAILED,
00377 "Failed to drop capabilities: %s\n",
00378 _dbus_strerror (errno));
00379 cap_free (tmp_caps);
00380 goto fail;
00381 }
00382 cap_free (tmp_caps);
00383 }
00384 #endif
00385
00386
00387
00388
00389
00390
00391
00392
00393 if (setgroups (0, NULL) < 0)
00394 _dbus_warn ("Failed to drop supplementary groups: %s\n",
00395 _dbus_strerror (errno));
00396
00397
00398
00399
00400 if (setgid (gid) < 0)
00401 {
00402 dbus_set_error (error, _dbus_error_from_errno (errno),
00403 "Failed to set GID to %lu: %s", gid,
00404 _dbus_strerror (errno));
00405 goto fail;
00406 }
00407
00408 if (setuid (uid) < 0)
00409 {
00410 dbus_set_error (error, _dbus_error_from_errno (errno),
00411 "Failed to set UID to %lu: %s", uid,
00412 _dbus_strerror (errno));
00413 goto fail;
00414 }
00415
00416 #ifdef HAVE_LIBAUDIT
00417 if (we_were_root)
00418 {
00419 if (cap_set_proc (new_caps))
00420 {
00421 dbus_set_error (error, DBUS_ERROR_FAILED,
00422 "Failed to drop capabilities: %s\n",
00423 _dbus_strerror (errno));
00424 goto fail;
00425 }
00426 cap_free (new_caps);
00427
00428
00429 if (prctl (PR_SET_KEEPCAPS, 0, 0, 0, 0) == -1)
00430 {
00431 dbus_set_error (error, _dbus_error_from_errno (errno),
00432 "Failed to unset keep-capabilities: %s\n",
00433 _dbus_strerror (errno));
00434 return FALSE;
00435 }
00436 }
00437 #endif
00438
00439 return TRUE;
00440
00441 fail:
00442 #ifdef HAVE_LIBAUDIT
00443 if (!we_were_root)
00444 {
00445
00446 prctl (PR_SET_KEEPCAPS, 0, 0, 0, 0);
00447 cap_free (new_caps);
00448 }
00449 #endif
00450
00451 return FALSE;
00452 }
00453
00459 void
00460 _dbus_set_signal_handler (int sig,
00461 DBusSignalHandler handler)
00462 {
00463 struct sigaction act;
00464 sigset_t empty_mask;
00465
00466 sigemptyset (&empty_mask);
00467 act.sa_handler = handler;
00468 act.sa_mask = empty_mask;
00469 act.sa_flags = 0;
00470 sigaction (sig, &act, NULL);
00471 }
00472
00473
00481 dbus_bool_t
00482 _dbus_delete_directory (const DBusString *filename,
00483 DBusError *error)
00484 {
00485 const char *filename_c;
00486
00487 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00488
00489 filename_c = _dbus_string_get_const_data (filename);
00490
00491 if (rmdir (filename_c) != 0)
00492 {
00493 dbus_set_error (error, DBUS_ERROR_FAILED,
00494 "Failed to remove directory %s: %s\n",
00495 filename_c, _dbus_strerror (errno));
00496 return FALSE;
00497 }
00498
00499 return TRUE;
00500 }
00501
00507 dbus_bool_t
00508 _dbus_file_exists (const char *file)
00509 {
00510 return (access (file, F_OK) == 0);
00511 }
00512
00519 dbus_bool_t
00520 _dbus_user_at_console (const char *username,
00521 DBusError *error)
00522 {
00523
00524 DBusString f;
00525 dbus_bool_t result;
00526
00527 result = FALSE;
00528 if (!_dbus_string_init (&f))
00529 {
00530 _DBUS_SET_OOM (error);
00531 return FALSE;
00532 }
00533
00534 if (!_dbus_string_append (&f, DBUS_CONSOLE_AUTH_DIR))
00535 {
00536 _DBUS_SET_OOM (error);
00537 goto out;
00538 }
00539
00540
00541 if (!_dbus_string_append (&f, username))
00542 {
00543 _DBUS_SET_OOM (error);
00544 goto out;
00545 }
00546
00547 result = _dbus_file_exists (_dbus_string_get_const_data (&f));
00548
00549 out:
00550 _dbus_string_free (&f);
00551
00552 return result;
00553 }
00554
00555
00562 dbus_bool_t
00563 _dbus_path_is_absolute (const DBusString *filename)
00564 {
00565 if (_dbus_string_get_length (filename) > 0)
00566 return _dbus_string_get_byte (filename, 0) == '/';
00567 else
00568 return FALSE;
00569 }
00570
00579 dbus_bool_t
00580 _dbus_stat (const DBusString *filename,
00581 DBusStat *statbuf,
00582 DBusError *error)
00583 {
00584 const char *filename_c;
00585 struct stat sb;
00586
00587 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00588
00589 filename_c = _dbus_string_get_const_data (filename);
00590
00591 if (stat (filename_c, &sb) < 0)
00592 {
00593 dbus_set_error (error, _dbus_error_from_errno (errno),
00594 "%s", _dbus_strerror (errno));
00595 return FALSE;
00596 }
00597
00598 statbuf->mode = sb.st_mode;
00599 statbuf->nlink = sb.st_nlink;
00600 statbuf->uid = sb.st_uid;
00601 statbuf->gid = sb.st_gid;
00602 statbuf->size = sb.st_size;
00603 statbuf->atime = sb.st_atime;
00604 statbuf->mtime = sb.st_mtime;
00605 statbuf->ctime = sb.st_ctime;
00606
00607 return TRUE;
00608 }
00609
00610
00614 struct DBusDirIter
00615 {
00616 DIR *d;
00618 };
00619
00627 DBusDirIter*
00628 _dbus_directory_open (const DBusString *filename,
00629 DBusError *error)
00630 {
00631 DIR *d;
00632 DBusDirIter *iter;
00633 const char *filename_c;
00634
00635 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00636
00637 filename_c = _dbus_string_get_const_data (filename);
00638
00639 d = opendir (filename_c);
00640 if (d == NULL)
00641 {
00642 dbus_set_error (error, _dbus_error_from_errno (errno),
00643 "Failed to read directory \"%s\": %s",
00644 filename_c,
00645 _dbus_strerror (errno));
00646 return NULL;
00647 }
00648 iter = dbus_new0 (DBusDirIter, 1);
00649 if (iter == NULL)
00650 {
00651 closedir (d);
00652 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00653 "Could not allocate memory for directory iterator");
00654 return NULL;
00655 }
00656
00657 iter->d = d;
00658
00659 return iter;
00660 }
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 static dbus_bool_t
00671 dirent_buf_size(DIR * dirp, size_t *size)
00672 {
00673 long name_max;
00674 # if defined(HAVE_FPATHCONF) && defined(_PC_NAME_MAX)
00675 # if defined(HAVE_DIRFD)
00676 name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
00677 # elif defined(HAVE_DDFD)
00678 name_max = fpathconf(dirp->dd_fd, _PC_NAME_MAX);
00679 # else
00680 name_max = fpathconf(dirp->__dd_fd, _PC_NAME_MAX);
00681 # endif
00682 if (name_max == -1)
00683 # if defined(NAME_MAX)
00684 name_max = NAME_MAX;
00685 # else
00686 return FALSE;
00687 # endif
00688 # elif defined(MAXNAMELEN)
00689 name_max = MAXNAMELEN;
00690 # else
00691 # if defined(NAME_MAX)
00692 name_max = NAME_MAX;
00693 # else
00694 # error "buffer size for readdir_r cannot be determined"
00695 # endif
00696 # endif
00697 if (size)
00698 *size = (size_t)offsetof(struct dirent, d_name) + name_max + 1;
00699 else
00700 return FALSE;
00701
00702 return TRUE;
00703 }
00704
00715 dbus_bool_t
00716 _dbus_directory_get_next_file (DBusDirIter *iter,
00717 DBusString *filename,
00718 DBusError *error)
00719 {
00720 struct dirent *d, *ent;
00721 size_t buf_size;
00722 int err;
00723
00724 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00725
00726 if (!dirent_buf_size (iter->d, &buf_size))
00727 {
00728 dbus_set_error (error, DBUS_ERROR_FAILED,
00729 "Can't calculate buffer size when reading directory");
00730 return FALSE;
00731 }
00732
00733 d = (struct dirent *)dbus_malloc (buf_size);
00734 if (!d)
00735 {
00736 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00737 "No memory to read directory entry");
00738 return FALSE;
00739 }
00740
00741 again:
00742 err = readdir_r (iter->d, d, &ent);
00743 if (err || !ent)
00744 {
00745 if (err != 0)
00746 dbus_set_error (error,
00747 _dbus_error_from_errno (err),
00748 "%s", _dbus_strerror (err));
00749
00750 dbus_free (d);
00751 return FALSE;
00752 }
00753 else if (ent->d_name[0] == '.' &&
00754 (ent->d_name[1] == '\0' ||
00755 (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
00756 goto again;
00757 else
00758 {
00759 _dbus_string_set_length (filename, 0);
00760 if (!_dbus_string_append (filename, ent->d_name))
00761 {
00762 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
00763 "No memory to read directory entry");
00764 dbus_free (d);
00765 return FALSE;
00766 }
00767 else
00768 {
00769 dbus_free (d);
00770 return TRUE;
00771 }
00772 }
00773 }
00774
00778 void
00779 _dbus_directory_close (DBusDirIter *iter)
00780 {
00781 closedir (iter->d);
00782 dbus_free (iter);
00783 }
00784
00785 static dbus_bool_t
00786 fill_user_info_from_group (struct group *g,
00787 DBusGroupInfo *info,
00788 DBusError *error)
00789 {
00790 _dbus_assert (g->gr_name != NULL);
00791
00792 info->gid = g->gr_gid;
00793 info->groupname = _dbus_strdup (g->gr_name);
00794
00795
00796
00797 if (info->groupname == NULL)
00798 {
00799 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00800 return FALSE;
00801 }
00802
00803 return TRUE;
00804 }
00805
00806 static dbus_bool_t
00807 fill_group_info (DBusGroupInfo *info,
00808 dbus_gid_t gid,
00809 const DBusString *groupname,
00810 DBusError *error)
00811 {
00812 const char *group_c_str;
00813
00814 _dbus_assert (groupname != NULL || gid != DBUS_GID_UNSET);
00815 _dbus_assert (groupname == NULL || gid == DBUS_GID_UNSET);
00816
00817 if (groupname)
00818 group_c_str = _dbus_string_get_const_data (groupname);
00819 else
00820 group_c_str = NULL;
00821
00822
00823
00824
00825
00826
00827 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
00828 {
00829 struct group *g;
00830 int result;
00831 size_t buflen;
00832 char *buf;
00833 struct group g_str;
00834 dbus_bool_t b;
00835
00836
00837 buflen = sysconf (_SC_GETGR_R_SIZE_MAX);
00838
00839
00840
00841
00842
00843 if ((long) buflen <= 0)
00844 buflen = 1024;
00845
00846 result = -1;
00847 while (1)
00848 {
00849 buf = dbus_malloc (buflen);
00850 if (buf == NULL)
00851 {
00852 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00853 return FALSE;
00854 }
00855
00856 g = NULL;
00857 #ifdef HAVE_POSIX_GETPWNAM_R
00858 if (group_c_str)
00859 result = getgrnam_r (group_c_str, &g_str, buf, buflen,
00860 &g);
00861 else
00862 result = getgrgid_r (gid, &g_str, buf, buflen,
00863 &g);
00864 #else
00865 g = getgrnam_r (group_c_str, &g_str, buf, buflen);
00866 result = 0;
00867 #endif
00868
00869
00870
00871 if (result == ERANGE && buflen < 512 * 1024)
00872 {
00873 dbus_free (buf);
00874 buflen *= 2;
00875 }
00876 else
00877 {
00878 break;
00879 }
00880 }
00881
00882 if (result == 0 && g == &g_str)
00883 {
00884 b = fill_user_info_from_group (g, info, error);
00885 dbus_free (buf);
00886 return b;
00887 }
00888 else
00889 {
00890 dbus_set_error (error, _dbus_error_from_errno (errno),
00891 "Group %s unknown or failed to look it up\n",
00892 group_c_str ? group_c_str : "???");
00893 dbus_free (buf);
00894 return FALSE;
00895 }
00896 }
00897 #else
00898 {
00899
00900 struct group *g;
00901
00902 g = getgrnam (group_c_str);
00903
00904 if (g != NULL)
00905 {
00906 return fill_user_info_from_group (g, info, error);
00907 }
00908 else
00909 {
00910 dbus_set_error (error, _dbus_error_from_errno (errno),
00911 "Group %s unknown or failed to look it up\n",
00912 group_c_str ? group_c_str : "???");
00913 return FALSE;
00914 }
00915 }
00916 #endif
00917 }
00918
00928 dbus_bool_t
00929 _dbus_group_info_fill (DBusGroupInfo *info,
00930 const DBusString *groupname,
00931 DBusError *error)
00932 {
00933 return fill_group_info (info, DBUS_GID_UNSET,
00934 groupname, error);
00935
00936 }
00937
00947 dbus_bool_t
00948 _dbus_group_info_fill_gid (DBusGroupInfo *info,
00949 dbus_gid_t gid,
00950 DBusError *error)
00951 {
00952 return fill_group_info (info, gid, NULL, error);
00953 }
00954
00963 dbus_bool_t
00964 _dbus_parse_unix_user_from_config (const DBusString *username,
00965 dbus_uid_t *uid_p)
00966 {
00967 return _dbus_get_user_id (username, uid_p);
00968
00969 }
00970
00979 dbus_bool_t
00980 _dbus_parse_unix_group_from_config (const DBusString *groupname,
00981 dbus_gid_t *gid_p)
00982 {
00983 return _dbus_get_group_id (groupname, gid_p);
00984 }
00985
00996 dbus_bool_t
00997 _dbus_unix_groups_from_uid (dbus_uid_t uid,
00998 dbus_gid_t **group_ids,
00999 int *n_group_ids)
01000 {
01001 return _dbus_groups_from_uid (uid, group_ids, n_group_ids);
01002 }
01003
01013 dbus_bool_t
01014 _dbus_unix_user_is_at_console (dbus_uid_t uid,
01015 DBusError *error)
01016 {
01017 return _dbus_is_console_user (uid, error);
01018
01019 }
01020
01028 dbus_bool_t
01029 _dbus_unix_user_is_process_owner (dbus_uid_t uid)
01030 {
01031 return uid == _dbus_geteuid ();
01032 }
01033
01041 dbus_bool_t
01042 _dbus_windows_user_is_process_owner (const char *windows_sid)
01043 {
01044 return FALSE;
01045 }
01046
01048
01060 dbus_bool_t
01061 _dbus_string_get_dirname (const DBusString *filename,
01062 DBusString *dirname)
01063 {
01064 int sep;
01065
01066 _dbus_assert (filename != dirname);
01067 _dbus_assert (filename != NULL);
01068 _dbus_assert (dirname != NULL);
01069
01070
01071 sep = _dbus_string_get_length (filename);
01072 if (sep == 0)
01073 return _dbus_string_append (dirname, ".");
01074
01075 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
01076 --sep;
01077
01078 _dbus_assert (sep >= 0);
01079
01080 if (sep == 0)
01081 return _dbus_string_append (dirname, "/");
01082
01083
01084 _dbus_string_find_byte_backward (filename, sep, '/', &sep);
01085 if (sep < 0)
01086 return _dbus_string_append (dirname, ".");
01087
01088
01089 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
01090 --sep;
01091
01092 _dbus_assert (sep >= 0);
01093
01094 if (sep == 0 &&
01095 _dbus_string_get_byte (filename, 0) == '/')
01096 return _dbus_string_append (dirname, "/");
01097 else
01098 return _dbus_string_copy_len (filename, 0, sep - 0,
01099 dirname, _dbus_string_get_length (dirname));
01100 }
01102