Exemplo n.º 1
0
char *dir_canonical_path(pool *p, const char *path) {
  char buf[PR_TUNABLE_PATH_MAX + 1]  = {'\0'};
  char work[PR_TUNABLE_PATH_MAX + 1] = {'\0'};

  if (p == NULL ||
      path == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (*path == '~') {
    if (pr_fs_interpolate(path, work, sizeof(work)-1) != 1) {
      if (pr_fs_dircat(work, sizeof(work), pr_fs_getcwd(), path) < 0) {
        return NULL;
      }
    }

  } else {
    if (pr_fs_dircat(work, sizeof(work), pr_fs_getcwd(), path) < 0) {
      return NULL;
    }
  }

  pr_fs_clean_path(work, buf, sizeof(buf)-1);
  return pstrdup(p, buf);
}
Exemplo n.º 2
0
/* dir_best_path() creates the "most" fully canonicalized path possible
 * (i.e. if path components at the end don't exist, they are ignored).
 */
char *dir_best_path(pool *p, const char *path) {
  char workpath[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
  char realpath_buf[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
  char *target = NULL, *ntarget;
  int fini = 0;

  if (*path == '~') {
    if (pr_fs_interpolate(path, workpath, sizeof(workpath)-1) != 1) {
      if (pr_fs_dircat(workpath, sizeof(workpath), pr_fs_getcwd(), path) < 0)
        return NULL;
    }

  } else {
    if (pr_fs_dircat(workpath, sizeof(workpath), pr_fs_getcwd(), path) < 0)
      return NULL;
  }

  pr_fs_clean_path(pstrdup(p, workpath), workpath, sizeof(workpath)-1);

  while (!fini && *workpath) {
    if (pr_fs_resolve_path(workpath, realpath_buf,
        sizeof(realpath_buf)-1, 0) != -1)
      break;

    ntarget = strrchr(workpath, '/');
    if (ntarget) {
      if (target) {
        if (pr_fs_dircat(workpath, sizeof(workpath), workpath, target) < 0)
          return NULL;
      }

      target = ntarget;
      *target++ = '\0';

    } else
      fini++;
  }

  if (!fini && *workpath) {
    if (target) {
      if (pr_fs_dircat(workpath, sizeof(workpath), realpath_buf, target) < 0)
        return NULL;

    } else
      sstrncpy(workpath, realpath_buf, sizeof(workpath));

  } else {
    if (pr_fs_dircat(workpath, sizeof(workpath), "/", target) < 0)
      return NULL;
  }

  return pstrdup(p, workpath);
}
Exemplo n.º 3
0
/* Takes a directory and returns its absolute version.  ~username references
 * are appropriately interpolated.  "Absolute" includes a _full_ reference
 * based on the root directory, not upon a chrooted dir.
 */
char *dir_abs_path(pool *p, const char *path, int interpolate) {
  char *res = NULL;

  if (p == NULL ||
      path == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (interpolate) {
    char buf[PR_TUNABLE_PATH_MAX+1];

    memset(buf, '\0', sizeof(buf));
    switch (pr_fs_interpolate(path, buf, sizeof(buf)-1)) {
      case -1:
        return NULL;

      case 0:
        /* Do nothing; path exists */
        break;

      case 1:
        /* Interpolation occurred; make a copy of the interpolated path. */
        path = pstrdup(p, buf);
        break;
    }
  }

  if (*path != '/') {
    if (session.chroot_path) {
      res = pdircat(p, session.chroot_path, pr_fs_getcwd(), path, NULL);

    } else {
      res = pdircat(p, pr_fs_getcwd(), path, NULL);
    }

  } else {
    if (session.chroot_path) {
      if (strncmp(path, session.chroot_path,
          strlen(session.chroot_path)) != 0) {
        res = pdircat(p, session.chroot_path, path, NULL);
 
      } else {
        res = pstrdup(p, path);
      }
 
    } else {
      res = pstrdup(p, path);
    }
  }

  return res;
}
Exemplo n.º 4
0
int proxy_session_setup_env(pool *p, const char *user, int flags) {
  struct passwd *pw;
  config_rec *c;
  int i, res = 0, xerrno = 0;
  const char *xferlog = NULL;

  session.hide_password = TRUE;

  /* Note: the given user name may not be known locally on the proxy; thus
   * having pr_auth_getpwnam() returning NULL here is not an unexpected
   * use case.
   */

  pw = pr_auth_getpwnam(p, user);
  if (pw != NULL) {
    if (pw->pw_uid == PR_ROOT_UID) {
      int root_login = FALSE;

      pr_event_generate("mod_auth.root-login", NULL);

      c = find_config(main_server->conf, CONF_PARAM, "RootLogin", FALSE);
      if (c != NULL) {
        root_login = *((int *) c->argv[0]);
      }

      if (root_login == FALSE) {
        (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
          "root login attempted, denied by RootLogin configuration");
        pr_log_auth(PR_LOG_NOTICE, "SECURITY VIOLATION: Root login attempted.");
        return -1;
      }

      pr_log_auth(PR_LOG_WARNING, "ROOT proxy login successful");
    }

    res = pr_auth_is_valid_shell(main_server->conf, pw->pw_shell);
    if (res == FALSE) {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "authentication for user '%s' failed: Invalid shell", user);
      pr_log_auth(PR_LOG_NOTICE, "USER %s (Login failed): Invalid shell: '%s'",
        user, pw->pw_shell);
      errno = EPERM;
      return -1;
    }

    res = pr_auth_banned_by_ftpusers(main_server->conf, pw->pw_name);
    if (res == TRUE) {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "authentication for user '%s' failed: User in " PR_FTPUSERS_PATH, user);
      pr_log_auth(PR_LOG_NOTICE, "USER %s (Login failed): User in "
        PR_FTPUSERS_PATH, pw->pw_name);
      errno = EPERM;
      return -1;
    }
  
    session.user = pstrdup(p, pw->pw_name);
    session.group = pstrdup(p, pr_auth_gid2name(p, pw->pw_gid));

    session.login_uid = pw->pw_uid;
    session.login_gid = pw->pw_gid;

  } else {
    session.user = pstrdup(session.pool, user);

    /* XXX What should session.group, session.login_uid, session.login_gid
     * be?  Kept as is?
     */
  }
 
  if (session.gids == NULL &&
      session.groups == NULL) {
    res = pr_auth_getgroups(p, session.user, &session.gids, &session.groups);
    if (res < 1 &&
        errno != ENOENT) {
      (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
        "no supplemental groups found for user '%s'", session.user);
    }
  }

  if (flags & PROXY_SESSION_FL_CHECK_LOGIN_ACL) {
    int login_acl;

    login_acl = login_check_limits(main_server->conf, FALSE, TRUE, &i);
    if (!login_acl) {
      pr_log_auth(PR_LOG_NOTICE, "USER %s (Login failed): Limit configuration "
        "denies login", user);
      return -1;
    }
  }

  /* XXX Will users want wtmp logging for a proxy login? */
  session.wtmp_log = FALSE;

  c = find_config(main_server->conf, CONF_PARAM, "TransferLog", FALSE);
  if (c == NULL) {
    xferlog = PR_XFERLOG_PATH;

  } else {
    xferlog = c->argv[0];
  }

  PRIVS_ROOT

  if (strncasecmp(xferlog, "none", 5) == 0) {
    xferlog_open(NULL);

  } else {
    xferlog_open(xferlog);
  }

  res = xerrno = 0;

  if (pw != NULL) {
    res = set_groups(p, pw->pw_gid, session.gids);
    xerrno = errno;
  }

  PRIVS_RELINQUISH

  if (res < 0) {
    pr_log_pri(PR_LOG_WARNING, "unable to set process groups: %s",
      strerror(xerrno));
  }

  session.disable_id_switching = TRUE;

  session.proc_prefix = pstrdup(session.pool, session.c->remote_name);
  session.sf_flags = 0;

  pr_scoreboard_entry_update(session.pid,
    PR_SCORE_USER, session.user,
    PR_SCORE_CWD, pr_fs_getcwd(),
    NULL);

  if (session.group != NULL) {
    session.group = pstrdup(session.pool, session.group);
  }

  if (session.groups != NULL) {
    session.groups = copy_array_str(session.pool, session.groups);
  }

  proxy_sess_state |= PROXY_SESS_STATE_PROXY_AUTHENTICATED;
  pr_timer_remove(PR_TIMER_LOGIN, ANY_MODULE);
  return 0;
}