Ticket #3393: tor_ecc9a364c2_check_private_dir_with_effective_user.diff

File tor_ecc9a364c2_check_private_dir_with_effective_user.diff, 8.5 KB (added by lunar, 9 years ago)

Patch against today HEAD

  • src/common/util.c

    diff --git a/src/common/util.c b/src/common/util.c
    index a5a6ea3..629c339 100644
    a b file_status(const char *fname) 
    16781678 * is group-readable, but in all cases we create the directory mode 0700.
    16791679 * If CPD_CHECK_MODE_ONLY is set, then we don't alter the directory permissions
    16801680 * if they are too permissive: we just return -1.
     1681 * When effective_user is not NULL, check permissions against the given user and
     1682 * its primary group.
    16811683 */
    16821684int
    1683 check_private_dir(const char *dirname, cpd_check_t check)
     1685check_private_dir(const char *dirname, cpd_check_t check, const char *effective_user)
    16841686{
    16851687  int r;
    16861688  struct stat st;
    16871689  char *f;
    16881690#ifndef MS_WINDOWS
    16891691  int mask;
     1692  struct passwd *pw = NULL;
     1693  uid_t running_uid;
     1694  gid_t running_gid;
    16901695#endif
    16911696
    16921697  tor_assert(dirname);
    check_private_dir(const char *dirname, cpd_check_t check) 
    17251730    return -1;
    17261731  }
    17271732#ifndef MS_WINDOWS
    1728   if (st.st_uid != getuid()) {
     1733  if (effective_user) {
     1734    /* Lookup the user and group information, if we have a problem, bail out. */
     1735    pw = getpwnam(effective_user);
     1736    if (pw == NULL) {
     1737      log_warn(LD_CONFIG, "Error setting configured user: %s not found", effective_user);
     1738      return -1;
     1739    }
     1740    running_uid = pw->pw_uid;
     1741    running_gid = pw->pw_gid;
     1742  } else {
     1743    running_uid = getuid();
     1744    running_gid = getgid();
     1745  }
     1746
     1747  if (st.st_uid != running_uid) {
    17291748    struct passwd *pw = NULL;
    17301749    char *process_ownername = NULL;
    17311750
    1732     pw = getpwuid(getuid());
     1751    pw = getpwuid(running_uid);
    17331752    process_ownername = pw ? tor_strdup(pw->pw_name) : tor_strdup("<unknown>");
    17341753
    17351754    pw = getpwuid(st.st_uid);
    17361755
    17371756    log_warn(LD_FS, "%s is not owned by this user (%s, %d) but by "
    17381757        "%s (%d). Perhaps you are running Tor as the wrong user?",
    1739                          dirname, process_ownername, (int)getuid(),
     1758                         dirname, process_ownername, (int)running_uid,
    17401759                         pw ? pw->pw_name : "<unknown>", (int)st.st_uid);
    17411760
    17421761    tor_free(process_ownername);
    17431762    return -1;
    17441763  }
    1745   if ((check & CPD_GROUP_OK) && st.st_gid != getgid()) {
     1764  if ((check & CPD_GROUP_OK) && st.st_gid != running_gid) {
    17461765    struct group *gr;
    17471766    char *process_groupname = NULL;
    1748     gr = getgrgid(getgid());
     1767    gr = getgrgid(running_gid);
    17491768    process_groupname = gr ? tor_strdup(gr->gr_name) : tor_strdup("<unknown>");
    17501769    gr = getgrgid(st.st_gid);
    17511770
    17521771    log_warn(LD_FS, "%s is not owned by this group (%s, %d) but by group "
    17531772             "%s (%d).  Are you running Tor as the wrong user?",
    1754              dirname, process_groupname, (int)getgid(),
     1773             dirname, process_groupname, (int)running_gid,
    17551774             gr ?  gr->gr_name : "<unknown>", (int)st.st_gid);
    17561775
    17571776    tor_free(process_groupname);
  • src/common/util.h

    diff --git a/src/common/util.h b/src/common/util.h
    index 2974ab7..6496c42 100644
    a b typedef unsigned int cpd_check_t; 
    292292#define CPD_CHECK 2
    293293#define CPD_GROUP_OK 4
    294294#define CPD_CHECK_MODE_ONLY 8
    295 int check_private_dir(const char *dirname, cpd_check_t check);
     295int check_private_dir(const char *dirname, cpd_check_t check,
     296                      const char *effective_user);
    296297#define OPEN_FLAGS_REPLACE (O_WRONLY|O_CREAT|O_TRUNC)
    297298#define OPEN_FLAGS_APPEND (O_WRONLY|O_CREAT|O_APPEND)
    298299typedef struct open_file_t open_file_t;
  • src/or/config.c

    diff --git a/src/or/config.c b/src/or/config.c
    index d663336..53ecca2 100644
    a b options_act_reversible(or_options_t *old_options, char **msg) 
    10471047
    10481048  /* Ensure data directory is private; create if possible. */
    10491049  if (check_private_dir(options->DataDirectory,
    1050                         running_tor ? CPD_CREATE : CPD_CHECK)<0) {
     1050                        running_tor ? CPD_CREATE : CPD_CHECK,
     1051                        options->User)<0) {
    10511052    tor_asprintf(msg,
    10521053              "Couldn't access/create private data directory \"%s\"",
    10531054              options->DataDirectory);
    options_act_reversible(or_options_t *old_options, char **msg) 
    10601061    char *fn = tor_malloc(len);
    10611062    tor_snprintf(fn, len, "%s"PATH_SEPARATOR"cached-status",
    10621063                 options->DataDirectory);
    1063     if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK) < 0) {
     1064    if (check_private_dir(fn, running_tor ? CPD_CREATE : CPD_CHECK,
     1065                          options->User) < 0) {
    10641066      tor_asprintf(msg,
    10651067                "Couldn't access/create private data directory \"%s\"", fn);
    10661068      tor_free(fn);
  • src/or/connection.c

    diff --git a/src/or/connection.c b/src/or/connection.c
    index 81f0cdf..e0b5b96 100644
    a b check_location_for_unix_socket(or_options_t *options, const char *path) 
    910910  if (options->ControlSocketsGroupWritable)
    911911    flags |= CPD_GROUP_OK;
    912912
    913   if (check_private_dir(p, flags) < 0) {
     913  if (check_private_dir(p, flags, options->User) < 0) {
    914914    char *escpath, *escdir;
    915915    escpath = esc_for_log(path);
    916916    escdir = esc_for_log(p);
  • src/or/geoip.c

    diff --git a/src/or/geoip.c b/src/or/geoip.c
    index 71ed3be..d369b45 100644
    a b geoip_dirreq_stats_write(time_t now) 
    990990  geoip_remove_old_clients(start_of_dirreq_stats_interval);
    991991
    992992  statsdir = get_datadir_fname("stats");
    993   if (check_private_dir(statsdir, CPD_CREATE) < 0)
     993  if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0)
    994994    goto done;
    995995  filename = get_datadir_fname2("stats", "dirreq-stats");
    996996  data_v2 = geoip_get_client_history(GEOIP_CLIENT_NETWORKSTATUS_V2);
    geoip_bridge_stats_write(time_t now) 
    12291229
    12301230  /* Write it to disk. */
    12311231  statsdir = get_datadir_fname("stats");
    1232   if (check_private_dir(statsdir, CPD_CREATE) < 0)
     1232  if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0)
    12331233    goto done;
    12341234  filename = get_datadir_fname2("stats", "bridge-stats");
    12351235
    geoip_entry_stats_write(time_t now) 
    13241324  geoip_remove_old_clients(start_of_entry_stats_interval);
    13251325
    13261326  statsdir = get_datadir_fname("stats");
    1327   if (check_private_dir(statsdir, CPD_CREATE) < 0)
     1327  if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0)
    13281328    goto done;
    13291329  filename = get_datadir_fname2("stats", "entry-stats");
    13301330  data = geoip_get_client_history(GEOIP_CLIENT_CONNECT);
  • src/or/rendservice.c

    diff --git a/src/or/rendservice.c b/src/or/rendservice.c
    index 79abc57..f4dcd8a 100644
    a b rend_service_load_keys(void) 
    570570             s->directory);
    571571
    572572    /* Check/create directory */
    573     if (check_private_dir(s->directory, CPD_CREATE) < 0)
     573    if (check_private_dir(s->directory, CPD_CREATE, get_options()->User) < 0)
    574574      return -1;
    575575
    576576    /* Load key */
  • src/or/rephist.c

    diff --git a/src/or/rephist.c b/src/or/rephist.c
    index 8f359c7..40c7b35 100644
    a b rep_hist_exit_stats_write(time_t now) 
    22972297
    22982298  /* Try to write to disk. */
    22992299  statsdir = get_datadir_fname("stats");
    2300   if (check_private_dir(statsdir, CPD_CREATE) < 0) {
     2300  if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0) {
    23012301    log_warn(LD_HIST, "Unable to create stats/ directory!");
    23022302    goto done;
    23032303  }
    rep_hist_buffer_stats_write(time_t now) 
    24862486  smartlist_clear(circuits_for_buffer_stats);
    24872487  /* write to file */
    24882488  statsdir = get_datadir_fname("stats");
    2489   if (check_private_dir(statsdir, CPD_CREATE) < 0)
     2489  if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0)
    24902490    goto done;
    24912491  filename = get_datadir_fname2("stats", "buffer-stats");
    24922492  out = start_writing_to_stdio_file(filename, OPEN_FLAGS_APPEND,
    rep_hist_conn_stats_write(time_t now) 
    27572757
    27582758  /* Try to write to disk. */
    27592759  statsdir = get_datadir_fname("stats");
    2760   if (check_private_dir(statsdir, CPD_CREATE) < 0) {
     2760  if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0) {
    27612761    log_warn(LD_HIST, "Unable to create stats/ directory!");
    27622762    goto done;
    27632763  }
  • src/or/router.c

    diff --git a/src/or/router.c b/src/or/router.c
    index 34ea8ba..3dcd3dd 100644
    a b init_keys(void) 
    535535    return 0;
    536536  }
    537537  /* Make sure DataDirectory exists, and is private. */
    538   if (check_private_dir(options->DataDirectory, CPD_CREATE)) {
     538  if (check_private_dir(options->DataDirectory, CPD_CREATE, options->User)) {
    539539    return -1;
    540540  }
    541541  /* Check the key directory. */
    542542  keydir = get_datadir_fname("keys");
    543   if (check_private_dir(keydir, CPD_CREATE)) {
     543  if (check_private_dir(keydir, CPD_CREATE, options->User)) {
    544544    tor_free(keydir);
    545545    return -1;
    546546  }