Ejemplo n.º 1
0
END_TEST

START_TEST (find_config2_test) {
  int res;
  config_rec *c;
  xaset_t *set = NULL;
  const char *name;
  unsigned long flags = 0;

  c = find_config2(NULL, -1, NULL, FALSE, flags);
  fail_unless(c == NULL, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Failed to set errno to EINVAL, got %d (%s)",
    errno, strerror(errno));

  mark_point();

  name = "foo";
  c = add_config_param_set(&set, name, 0);
  fail_unless(c != NULL, "Failed to add config '%s': %s", name,
    strerror(errno));

  name = "bar";
  c = find_config2(set, -1, name, FALSE, flags);
  fail_unless(c == NULL, "Failed to handle null arguments");
  fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
    errno, strerror(errno));

  mark_point();

  /* We expect to find "foo", but a 'next' should be empty. */
  name = "foo";
  c = find_config2(set, -1, name, FALSE, flags);
  fail_unless(c != NULL, "Failed to find config '%s': %s", name,
    strerror(errno));

  mark_point();

  c = find_config_next2(c, c->next, -1, name, FALSE, flags);
  fail_unless(c == NULL, "Found next config unexpectedly");
  fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
    errno, strerror(errno));

  /* Now add another config, find "foo" again; this time, a 'next' should
   * NOT be empty; it should find the 2nd config we added.
   */

  name = "foo2";
  c = add_config_param_set(&set, name, 0);
  fail_unless(c != NULL, "Failed to add config '%s': %s", name,
    strerror(errno));

  name = NULL;
  c = find_config2(set, -1, name, FALSE, flags);
  fail_unless(c != NULL, "Failed to find any config: %s", strerror(errno));

  mark_point();

  c = find_config_next2(c, c->next, -1, name, FALSE, flags);
  fail_unless(c != NULL, "Expected to find another config");

  mark_point();

  name = "foo";
  res = remove_config(set, name, FALSE);
  fail_unless(res > 0, "Failed to remove config '%s': %s", name,
    strerror(errno));

  mark_point();

  c = find_config2(set, -1, name, FALSE, flags);
  fail_unless(c == NULL, "Found config '%s' unexpectedly", name);
  fail_unless(errno == ENOENT, "Failed to set errno to ENOENT, got %d (%s)",
    errno, strerror(errno));
}
Ejemplo n.º 2
0
/* This is one messy function.  Yuck.  Yay legacy code. */
config_rec *pr_auth_get_anon_config(pool *p, char **login_name,
    char **user_name, char **anon_name) {
  config_rec *c = NULL, *topc = NULL;
  char *config_user_name, *config_anon_name = NULL;
  unsigned char is_alias = FALSE, *auth_alias_only = NULL;
  unsigned long config_flags = (PR_CONFIG_FIND_FL_SKIP_DIR|PR_CONFIG_FIND_FL_SKIP_LIMIT|PR_CONFIG_FIND_FL_SKIP_DYNDIR);

  /* Precendence rules:
   *   1. Search for UserAlias directive.
   *   2. Search for Anonymous directive.
   *   3. Normal user login
   */

  config_user_name = get_param_ptr(main_server->conf, "UserName", FALSE);
  if (config_user_name &&
      user_name) {
    *user_name = config_user_name;
  }

  /* If the main_server->conf->set list is large (e.g. there are many
   * config_recs in the list, as can happen if MANY <Directory> sections are
   * configured), the login can timeout because this find_config() call takes
   * a long time.  The reason this issue strikes HERE first in the login
   * process is that this appears to the first find_config() call which has
   * a TRUE recurse flag.
   *
   * The find_config() call below is looking for a UserAlias directive
   * anywhere in the configuration, no matter how deeply buried in nested
   * config contexts it might be.
   */

  c = find_config2(main_server->conf, CONF_PARAM, "UserAlias", TRUE,
    config_flags);
  if (c != NULL) {
    do {
      pr_signals_handle();

      if (strncmp(c->argv[0], "*", 2) == 0 ||
          strcmp(c->argv[0], *login_name) == 0) {
        is_alias = TRUE;
        break;
      }

    } while ((c = find_config_next2(c, c->next, CONF_PARAM, "UserAlias",
      TRUE, config_flags)) != NULL);
  }

  /* This is where things get messy, rapidly. */
  topc = c;

  while (c && c->parent &&
    (auth_alias_only = get_param_ptr(c->parent->set, "AuthAliasOnly", FALSE))) {

    /* while() loops should always handle signals. */
    pr_signals_handle();

    if (auth_alias_only) {
      /* If AuthAliasOnly is on, ignore this one and continue. */
      if (*auth_alias_only == TRUE) {
        c = find_config_next2(c, c->next, CONF_PARAM, "UserAlias", TRUE,
          config_flags);
        continue;
      }
    }

    /* At this point, we have found an "AuthAliasOnly off" config in
     * c->parent->set.  See if there's a UserAlias in the same config set.
     */

    is_alias = FALSE;

    find_config_set_top(topc);
    c = find_config_next2(c, c->next, CONF_PARAM, "UserAlias", TRUE,
      config_flags);

    if (c &&
        (strncmp(c->argv[0], "*", 2) == 0 ||
         strcmp(c->argv[0], *login_name) == 0)) {
      is_alias = TRUE;
    }
  }

  if (c) {
    *login_name = c->argv[1];

    /* If the alias is applied inside an <Anonymous> context, we have found
     * our anon block.
     */
    if (c->parent &&
        c->parent->config_type == CONF_ANON) {
      c = c->parent;

    } else {
      c = NULL;
    }
  }

  /* Next, search for an anonymous entry. */

  if (c == NULL) {
    c = find_config(main_server->conf, CONF_ANON, NULL, FALSE);

  } else {
    find_config_set_top(c);
  }

  if (c) {
    do {
      pr_signals_handle();

      config_anon_name = get_param_ptr(c->subset, "UserName", FALSE);

      if (!config_anon_name)
        config_anon_name = config_user_name;

      if (config_anon_name &&
          strcmp(config_anon_name, *login_name) == 0) {
         if (anon_name)
           *anon_name = config_anon_name;
         break;
      }
 
    } while ((c = find_config_next(c, c->next, CONF_ANON, NULL,
      FALSE)) != NULL);
  }

  if (!is_alias) {
    /* Yes, we do want to be using c here.  Otherwise, we risk a regression
     * of Bug#3501.
     */

    auth_alias_only = get_param_ptr(c ? c->subset : main_server->conf,
      "AuthAliasOnly", FALSE);

    if (auth_alias_only &&
        *auth_alias_only == TRUE) {
      if (c &&
          c->config_type == CONF_ANON) {
        c = NULL;

      } else {
        *login_name = NULL;
      }

      auth_alias_only = get_param_ptr(main_server->conf, "AuthAliasOnly",
        FALSE);
      if (*login_name &&
          auth_alias_only &&
          *auth_alias_only == TRUE) {
        *login_name = NULL;
      }

      if ((!login_name || !c) &&
          anon_name) {
        *anon_name = NULL;
      }
    }
  }

  return c;
}