Exemple #1
0
int pr_env_unset(pool *p, const char *key) {
#if defined(HAVE_UNSETENV)
  char *res;
#endif /* !HAVE_UNSETENV */

  if (p == NULL ||
      key == NULL) {
    errno = EINVAL;
    return -1;
  }

#if defined(HAVE_UNSETENV)
  /* The same key may appear multiple times in the environ, so make certain
   * that all such occurrences are removed.
   */
  res = pr_env_get(p, key);
  while (res) {
    pr_signals_handle();

    unsetenv(key);
    res = pr_env_get(p, key);
  }

  return 0;
#else
  errno = ENOSYS;
  return -1;
#endif /* !HAVE_UNSETENV */
}
Exemple #2
0
static char *get_config_word(pool *p, char *word) {
  size_t wordlen;

  /* Should this word be replaced with a value from the environment?
   * If so, tmp will contain the expanded value, otherwise tmp will
   * contain a string duped from the given pool.
   */

  wordlen = strlen(word);

  if (wordlen > 7) {
    char *ptr = NULL;

    /* Does the given word use the environment syntax? We handle this in a
     * while loop in order to handle a) multiple different variables, and b)
     * cases where the substituted value is itself a variable.  Hopefully no
     * one is so clever as to want to actually _use_ the latter approach.
     */
    ptr = strstr(word, "%{env:");
    while (ptr != NULL) {
      char *env, *key, *ptr2, *var;
      unsigned int keylen;

      pr_signals_handle();

      ptr2 = strchr(ptr + 6, '}');
      if (ptr2 == NULL) {
        /* No terminating marker; continue on to the next potential
         * variable in the word.
         */
        ptr2 = ptr + 6;
        ptr = strstr(ptr2, "%{env:");
        continue;
      }

      keylen = (ptr2 - ptr - 6);
      var = pstrndup(p, ptr, (ptr2 - ptr) + 1);

      key = pstrndup(p, ptr + 6, keylen);

      env = pr_env_get(p, key);
      if (env == NULL) {
        /* No value in the environment; continue on to the next potential
         * variable in the word.
         */
        ptr = strstr(ptr2, "%{env:");
        continue;
      }

      word = (char *) sreplace(p, word, var, env, NULL);
      ptr = strstr(word, "%{env:");
    }
  }

  return pstrdup(p, word);
}
Exemple #3
0
void pr_getopt_reset(void) {
#if defined(FREEBSD4) || defined(FREEBSD5) || defined(FREEBSD6) || \
    defined(FREEBSD7) || defined(FREEBSD8) || defined(FREEBSD9) || \
    defined(FREEBSD10) || \
    defined(DARWIN7) || defined(DARWIN8) || defined(DARWIN9) || \
    defined(DARWIN10) || defined(DARWIN11) || defined(DARWIN12)
  optreset = 1;
  opterr = 1;
  optind = 1;

#elif defined(SOLARIS2) || defined(HPUX11)
  opterr = 0;
  optind = 1;

#else
  opterr = 0;
  optind = 0;
#endif /* !FreeBSD, !Mac OSX and !Solaris2 */

  if (pr_env_get(permanent_pool, "POSIXLY_CORRECT") == NULL) {
    pr_env_set(permanent_pool, "POSIXLY_CORRECT", "1");
  }
}
Exemple #4
0
static char *get_config_word(pool *p, char *word) {
  size_t wordlen;

  /* Should this word be replaced with a value from the environment?
   * If so, tmp will contain the expanded value, otherwise tmp will
   * contain a string duped from the given pool.
   */

  wordlen = strlen(word);

  if (wordlen > 7) {
    char *ptr = NULL;

    /* Does the given word use the environment syntax?
     *
     * In the simple (and most common) case, the entire word is the variable
     * syntax.  But we also need to check for cases where the environment
     * variable syntax is embedded within the word string.
     */

    if (strncmp(word, "%{env:", 6) == 0 &&
        word[wordlen-1] == '}') {
      char *env;

      word[wordlen-1] = '\0';

      env = pr_env_get(p, word + 6);

      return env ? pstrdup(p, env) : "";
    }

    /* This is in a while loop in order to handle a) multiple different
     * variables, and b) cases where the substituted value is itself a
     * variable.   (Hopefully no one is so clever as to want to actually
     * _use_ the latter approach.)
     */
    ptr = strstr(word, "%{env:");
    while (ptr != NULL) {
      char *env, *key, *ptr2, *var;
      unsigned int keylen;

      pr_signals_handle();

      ptr2 = strchr(ptr + 6, '}');
      if (ptr2 == NULL) {
        /* No terminating marker; continue on to the next potential
         * variable in the word.
         */
        ptr2 = ptr + 6;
        ptr = strstr(ptr2, "%{env:");
        continue;
      }

      keylen = (ptr2 - ptr - 6);
      var = pstrndup(p, ptr, (ptr2 - ptr) + 1);

      key = pstrndup(p, ptr + 6, keylen);

      env = pr_env_get(p, key);
      if (env == NULL) {
        /* No value in the environment; continue on to the next potential
         * variable in the word.
         */
        ptr = strstr(ptr2, "%{env:");
        continue;
      }

      word = (char *) sreplace(p, word, var, env, NULL);
      ptr = strstr(word, "%{env:");
    }
  }

  return pstrdup(p, word);
}
Exemple #5
0
const char *sftp_display_fh_get_msg(pool *p, pr_fh_t *fh) {
  struct stat st;
  char buf[PR_TUNABLE_BUFFER_SIZE], *msg = "";
  int len, res;
  unsigned int *current_clients = NULL;
  unsigned int *max_clients = NULL;
  off_t fs_size = 0;
  void *v;
  const char *serverfqdn = main_server->ServerFQDN;
  char *outs, mg_size[12] = {'\0'}, mg_size_units[12] = {'\0'},
    mg_max[12] = "unlimited";
  char mg_class_limit[12] = {'\0'}, mg_cur[12] = {'\0'},
    mg_cur_class[12] = {'\0'};
  const char *mg_time;
  char *rfc1413_ident = NULL, *user = NULL;

  /* Stat the opened file to determine the optimal buffer size for IO. */
  memset(&st, 0, sizeof(st));
  if (pr_fsio_fstat(fh, &st) == 0) {
    fh->fh_iosz = st.st_blksize;
  }

  res = pr_fs_fgetsize(fh->fh_fd, &fs_size);
  if (res < 0 &&
      errno != ENOSYS) {
    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
      "error getting filesystem size for '%s': %s", fh->fh_path,
      strerror(errno));
    fs_size = 0;
  }

  snprintf(mg_size, sizeof(mg_size), "%" PR_LU, (pr_off_t) fs_size);
  format_size_str(mg_size_units, sizeof(mg_size_units), fs_size);

  mg_time = pr_strtime(time(NULL));

  max_clients = get_param_ptr(main_server->conf, "MaxClients", FALSE);

  v = pr_table_get(session.notes, "client-count", NULL);
  if (v) {
    current_clients = v;
  }

  snprintf(mg_cur, sizeof(mg_cur), "%u", current_clients ? *current_clients: 1);

  if (session.conn_class != NULL &&
      session.conn_class->cls_name) {
    unsigned int *class_clients = NULL;
    config_rec *maxc = NULL;
    unsigned int maxclients = 0;

    v = pr_table_get(session.notes, "class-client-count", NULL);
    if (v) {
      class_clients = v;
    }

    snprintf(mg_cur_class, sizeof(mg_cur_class), "%u",
      class_clients ? *class_clients : 0);

    /* For the %z variable, first we scan through the MaxClientsPerClass,
     * and use the first applicable one.  If none are found, look for
     * any MaxClients set.
     */

    maxc = find_config(main_server->conf, CONF_PARAM, "MaxClientsPerClass",
      FALSE);

    while (maxc) {
      pr_signals_handle();

      if (strcmp(maxc->argv[0], session.conn_class->cls_name) != 0) {
        maxc = find_config_next(maxc, maxc->next, CONF_PARAM,
          "MaxClientsPerClass", FALSE);
        continue;
      }

      maxclients = *((unsigned int *) maxc->argv[1]);
      break;
    }

    if (maxclients == 0) {
      maxc = find_config(main_server->conf, CONF_PARAM, "MaxClients", FALSE);

      if (maxc)
        maxclients = *((unsigned int *) maxc->argv[0]);
    }

    snprintf(mg_class_limit, sizeof(mg_class_limit), "%u", maxclients);

  } else {
    snprintf(mg_class_limit, sizeof(mg_class_limit), "%u",
      max_clients ? *max_clients : 0);
    snprintf(mg_cur_class, sizeof(mg_cur_class), "%u", 0);
  }

  snprintf(mg_max, sizeof(mg_max), "%u", max_clients ? *max_clients : 0);

  user = pr_table_get(session.notes, "mod_auth.orig-user", NULL);
  if (user == NULL)
    user = "";

  rfc1413_ident = pr_table_get(session.notes, "mod_ident.rfc1413-ident", NULL);
  if (rfc1413_ident == NULL) {
    rfc1413_ident = "UNKNOWN";
  }

  memset(buf, '\0', sizeof(buf));
  while (pr_fsio_gets(buf, sizeof(buf), fh) != NULL) {
    char *tmp;

    pr_signals_handle();

    buf[sizeof(buf)-1] = '\0';
    len = strlen(buf);

    while (len > 0 &&
           (buf[len-1] == '\r' || buf[len-1] == '\n')) {
      pr_signals_handle();

      buf[len-1] = '\0';
      len--;
    }

    /* Check for any Variable-type strings. */
    tmp = strstr(buf, "%{");
    while (tmp) {
      char *key, *tmp2;
      const char *val;

      pr_signals_handle();

      tmp2 = strchr(tmp, '}');
      if (tmp2 == NULL) {
        /* No closing '}' found in this string, so no need to look for any
         * aother '%{' opening sequence.  Just move on.
         */
        tmp = NULL;
        break;
      }

      key = pstrndup(p, tmp, tmp2 - tmp + 1);

      /* There are a couple of special-case keys to watch for:
       *
       *   env:$var
       *   time:$fmt
       *
       * The Var API does not easily support returning values for keys
       * where part of the value depends on part of the key.  That's why
       * these keys are handled here, instead of in pr_var_get().
       */

      if (strncmp(key, "%{time:", 7) == 0) {
        char time_str[128], *fmt;
        time_t now;
        struct tm *time_info;

        fmt = pstrndup(p, key + 7, strlen(key) - 8);

        now = time(NULL);
        time_info = pr_localtime(NULL, &now);

        memset(time_str, 0, sizeof(time_str));
        strftime(time_str, sizeof(time_str), fmt, time_info);

        val = pstrdup(p, time_str);

      } else if (strncmp(key, "%{env:", 6) == 0) {
        char *env_var;

        env_var = pstrndup(p, key + 6, strlen(key) - 7);
        val = pr_env_get(p, env_var);
        if (val == NULL) {
          pr_trace_msg("var", 4,
            "no value set for environment variable '%s', using \"(none)\"",
            env_var);
          val = "(none)";
        }

      } else {
        val = pr_var_get(key);
        if (val == NULL) {
          pr_trace_msg("var", 4,
            "no value set for name '%s', using \"(none)\"", key);
          val = "(none)";
        }
      }

      outs = sreplace(p, buf, key, val, NULL);
      sstrncpy(buf, outs, sizeof(buf));

      tmp = strstr(outs, "%{");
    }

    outs = sreplace(p, buf,
      "%C", (session.cwd[0] ? session.cwd : "(none)"),
      "%E", main_server->ServerAdmin,
      "%F", mg_size,
      "%f", mg_size_units,
      "%i", "0",
      "%K", "0",
      "%k", "0B",
      "%L", serverfqdn,
      "%M", mg_max,
      "%N", mg_cur,
      "%o", "0",
      "%R", (session.c && session.c->remote_name ?
        session.c->remote_name : "(unknown)"),
      "%T", mg_time,
      "%t", "0",
      "%U", user,
      "%u", rfc1413_ident,
      "%V", main_server->ServerName,
      "%x", session.conn_class ? session.conn_class->cls_name : "(unknown)",
      "%y", mg_cur_class,
      "%z", mg_class_limit,
      NULL);

    /* Always make sure that the lines we send are CRLF-terminated. */
    msg = pstrcat(p, msg, outs, "\r\n", NULL);

    /* Clear the buffer for the next read. */
    memset(buf, '\0', sizeof(buf));
  }

  return msg;
}