Example #1
0
/*
 * cmd_close: attempts to close the named connection.
 *
 * Inputs:
 *  cmd->argv[0]: connection name
 * Optional:
 *  cmd->argv[1]: close immediately
 *
 * Returns:
 *  either a properly filled error modret_t if a connection could not be
 *  closed, or a simple non-error modret_t.  For the case of mod_sql_postgres,
 *  there are no error codes returned by the close call; other backends
 *  may be able to return a useful error message.
 *
 * Notes:
 *  mod_sql depends on these semantics -- a backend should not open
 *  a connection unless mod_sql requests it, nor close one unless 
 *  mod_sql requests it.  Connection counting is *REQUIRED* for complete
 *  compatibility; a connection should not be closed unless the count
 *  reaches 0, and should not need to be re-opened for counts > 1.
 * 
 *  If argv[1] exists and is not NULL, the connection should be immediately
 *  closed and the connection count should be reset to 0.
 */
MODRET cmd_close(cmd_rec *cmd) {
  conn_entry_t *entry = NULL;
  db_conn_t *conn = NULL;

  sql_log(DEBUG_FUNC, "%s", "entering \tpostgres cmd_close");

  _sql_check_cmd(cmd, "cmd_close");

  if ((cmd->argc < 1) || (cmd->argc > 2)) {
    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_close");
    return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION, "badly formed request");
  }

  /* get the named connection */
  if (!(entry = _sql_get_connection(cmd->argv[0]))) {
    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_close");
    return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION,
      "unknown named connection");
  }

  conn = (db_conn_t *) entry->data;

  /* if we're closed already (connections == 0) return HANDLED */
  if (entry->connections == 0) {
    sql_log(DEBUG_INFO, "connection '%s' count is now %d", entry->name,
      entry->connections);

    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_close");
    return PR_HANDLED(cmd);
  }

  /* decrement connections. If our count is 0 or we received a second arg
   * close the connection, explicitly set the counter to 0, and remove any
   * timers.
   */
  if (((--entry->connections) == 0 ) || ((cmd->argc == 2) && (cmd->argv[1]))) {
    PQfinish(conn->postgres);
    conn->postgres = NULL;
    entry->connections = 0;

    if (entry->timer) {
      pr_timer_remove(entry->timer, &sql_postgres_module);
      entry->timer = 0;
      sql_log(DEBUG_INFO, "connection '%s' - timer stopped", entry->name);
    }

    sql_log(DEBUG_INFO, "connection '%s' closed", entry->name);
  }

  sql_log(DEBUG_INFO, "connection '%s' count is now %d", entry->name,
    entry->connections);
  sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_close");
  
  return PR_HANDLED(cmd);
}
/* usage:
 *  CounterMaxReaders max
 *  CounterMaxWriters max
 */
MODRET set_countermaxreaderswriters(cmd_rec *cmd) {
  int count;
  config_rec *c;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL|CONF_ANON|CONF_DIR);

  /* A count of zero means that an unlimited number of readers (or writers),
   * as is the default without this module, is in effect.
   */

  count = atoi(cmd->argv[1]);
  if (count < 0 ||
      count > INT_MAX) {
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "invalid number: ", cmd->argv[1],
      NULL));
  }

  c = add_config_param(cmd->argv[0], 1, NULL);
  c->argv[0] = pcalloc(c->pool, sizeof(int));
  *((int *) c->argv[0]) = count;
  c->flags |= CF_MERGEDOWN;

  return PR_HANDLED(cmd);
}
Example #3
0
MODRET authfile_auth(cmd_rec *cmd) {
  char *tmp = NULL, *cleartxt_pass = NULL;
  const char *name = cmd->argv[0];

  if (af_setpwent() < 0) {
    return PR_DECLINED(cmd);
  }

  /* Lookup the cleartxt password for this user. */
  tmp = af_getpwpass(name);
  if (tmp == NULL) {

    /* For now, return DECLINED.  Ideally, we could stash an auth module
     * identifier in the session structure, so that all auth modules could
     * coordinate/use their methods as long as they matched the auth module
     * used.
     */
    return PR_DECLINED(cmd);

#if 0
    /* When the above is implemented, and if the user being checked was
     * provided by mod_auth_file, we'd return this.
     */
    return PR_ERROR_INT(cmd, PR_AUTH_NOPWD);
#endif
  }

  cleartxt_pass = pstrdup(cmd->tmp_pool, tmp);

  if (pr_auth_check(cmd->tmp_pool, cleartxt_pass, name, cmd->argv[1]))
    return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);

  session.auth_mech = "mod_auth_file.c";
  return PR_HANDLED(cmd);
}
Example #4
0
/* usage: MemcacheConnectFailures count */
MODRET set_memcacheconnectfailures(cmd_rec *cmd) {
  char *ptr = NULL;
  config_rec *c;
  uint64_t count = 0;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

#ifdef HAVE_STRTOULL
  count = strtoull(cmd->argv[1], &ptr, 10);
#else
  count = strtoul(cmd->argv[1], &ptr, 10);
#endif /* HAVE_STRTOULL */

  if (ptr &&
      *ptr) {
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "bad connect failures parameter: ",
      cmd->argv[1], NULL));
  }

  c = add_config_param(cmd->argv[0], 1, NULL);
  c->argv[0] = palloc(c->pool, sizeof(uint64_t));
  *((uint64_t *) c->argv[0]) = count;

  return PR_HANDLED(cmd);
}
Example #5
0
MODRET pw_auth(cmd_rec *cmd) {
  time_t now;
  char *cpw;
  time_t lstchg = -1, max = -1, inact = -1, disable = -1;
  const char *name;

  name = cmd->argv[0];
  time(&now);

  cpw = _get_pw_info(cmd->tmp_pool, name, &lstchg, NULL, &max, NULL, &inact,
    &disable);

  if (!cpw)
    return PR_DECLINED(cmd);

  if (pr_auth_check(cmd->tmp_pool, cpw, cmd->argv[0], cmd->argv[1]))
    return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);

  if (lstchg > (time_t) 0 &&
      max > (time_t) 0 &&
      inact > (time_t)0)
    if (now > lstchg + max + inact)
      return PR_ERROR_INT(cmd, PR_AUTH_AGEPWD);

  if (disable > (time_t) 0 &&
      now > disable)
    return PR_ERROR_INT(cmd, PR_AUTH_DISABLEDPWD);

  session.auth_mech = "mod_auth_unix.c";
  return PR_HANDLED(cmd);
}
Example #6
0
/* usage: MemcacheOptions opt1 opt2 ... */
MODRET set_memcacheoptions(cmd_rec *cmd) {
  config_rec *c = NULL;
  register unsigned int i = 0;
  unsigned long opts = 0UL;

  if (cmd->argc-1 == 0) {
    CONF_ERROR(cmd, "wrong number of parameters");
  }

  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  c = add_config_param(cmd->argv[0], 1, NULL);

  for (i = 1; i < cmd->argc; i++) {
    if (strcmp(cmd->argv[i], "NoBinaryProtocol") == 0) {
      opts |= PR_MEMCACHE_FL_NO_BINARY_PROTOCOL;

    } else if (strcmp(cmd->argv[i], "NoRandomReplicaReads") == 0) {
      opts |= PR_MEMCACHE_FL_NO_RANDOM_REPLICA_READ;

    } else {
      CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, ": unknown MemcacheOption '",
        cmd->argv[i], "'", NULL));
    }
  }

  c->argv[0] = pcalloc(c->pool, sizeof(unsigned long));
  *((unsigned long *) c->argv[0]) = opts;

  return PR_HANDLED(cmd);
}
Example #7
0
MODRET authfile_chkpass(cmd_rec *cmd) {
  const char *ciphertxt_pass = cmd->argv[0];
  const char *cleartxt_pass = cmd->argv[2];
  char *crypted_pass = NULL;
  size_t ciphertxt_passlen = 0;
  int xerrno;

  if (ciphertxt_pass == NULL) {
    pr_log_debug(DEBUG2, MOD_AUTH_FILE_VERSION
      ": missing ciphertext password for comparison");
    return PR_DECLINED(cmd);
  }

  if (cleartxt_pass == NULL) {
    pr_log_debug(DEBUG2, MOD_AUTH_FILE_VERSION
      ": missing client-provided password for comparison");
    return PR_DECLINED(cmd);
  }

  /* Even though the AuthUserFile is not used here, there must be one
   * configured before this function should attempt to check the password.
   * Otherwise, it could be checking a password retrieved by some other
   * auth module.
   */
  if (af_user_file == NULL) {
    return PR_DECLINED(cmd);
  }

  crypted_pass = crypt(cleartxt_pass, ciphertxt_pass);
  xerrno = errno;

  ciphertxt_passlen = strlen(ciphertxt_pass);
  if (handle_empty_salt == TRUE &&
      ciphertxt_passlen == 0) {
    crypted_pass = "";
  }

  if (crypted_pass == NULL) {
    const char *user;

    user = cmd->argv[1];
    pr_log_debug(DEBUG0, MOD_AUTH_FILE_VERSION
      ": error using crypt(3) for user '%s': %s", user, strerror(xerrno));

    if (ciphertxt_passlen > 0 &&
        (xerrno == EINVAL ||
         xerrno == EPERM)) {
      check_unsupported_algo(user, ciphertxt_pass, ciphertxt_passlen);
    }

    return PR_DECLINED(cmd);
  }

  if (strcmp(crypted_pass, ciphertxt_pass) == 0) {
    session.auth_mech = "mod_auth_file.c";
    return PR_HANDLED(cmd);
  }  

  return PR_DECLINED(cmd);
}
Example #8
0
/* usage: TCPServiceName <name> */
MODRET set_tcpservicename(cmd_rec *cmd) {
  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
  return PR_HANDLED(cmd);
}
Example #9
0
/* usage: SFTPPAMOptions opt1 ... */
MODRET set_sftppamoptions(cmd_rec *cmd) {
  config_rec *c = NULL;
  register unsigned int i = 0;
  unsigned long opts = 0UL;

  if (cmd->argc-1 == 0)
    CONF_ERROR(cmd, "wrong number of parameters");

  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  c = add_config_param(cmd->argv[0], 1, NULL);

  for (i = 1; i < cmd->argc; i++) {
    if (strcmp(cmd->argv[i], "NoTTY") == 0) {
      opts |= SFTP_PAM_OPT_NO_TTY;

    } else if (strcmp(cmd->argv[i], "NoInfoMsgs") == 0) {
      opts |= SFTP_PAM_OPT_NO_INFO_MSGS;

    } else if (strcmp(cmd->argv[i], "NoRadioMsgs") == 0) {
      opts |= SFTP_PAM_OPT_NO_RADIO_MSGS;

    } else {
      CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, ": unknown SFTPPAMOption: '",
        cmd->argv[i], "'", NULL));
    }
  }

  c->argv[0] = pcalloc(c->pool, sizeof(unsigned long));
  *((unsigned long *) c->argv[0]) = opts;

  return PR_HANDLED(cmd);
}
MODRET add_lmd_allow_from(cmd_rec *cmd) {
    config_rec *c;
    int i;
    array_header *allowed_acls;

    if(cmd->argc < 2 )
        CONF_ERROR(cmd, "argument missing");

    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* argv => LMDMemcachedHost 127.0.0.1 192.168.0.1 ... */
    c = find_config(main_server->conf, CONF_PARAM, "LMDBAllow", FALSE);
    if(c && c->argv[0]) {
        allowed_acls = c->argv[0];
    } else {
        c = add_config_param(cmd->argv[0], 0, NULL);
        c->argv[0] = allowed_acls =
          make_array(cmd->server->pool, 0, sizeof(char *));
    }

    for(i=1; i < cmd->argc; i++) {
        char *entry = cmd->argv[i];
        if (strcasecmp(entry, "all") == 0 ||
            strcasecmp(entry, "none") == 0) {
            break;
        }
        pr_netacl_t *acl = pr_netacl_create(cmd->server->pool, entry);
        *((pr_netacl_t **) push_array(allowed_acls)) = acl;
        pr_log_debug(DEBUG2,
            "%s: add LMDBAllow[%d] %s", MODULE_NAME, i, entry);
    }

    return PR_HANDLED(cmd);
}
MODRET add_lmd_memcached_host(cmd_rec *cmd) {
    int i;
    memcached_return rc;
    memcached_server_st *server = NULL;

    if(cmd->argc < 2 )
        CONF_ERROR(cmd, "argument missing");

    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* NOTICE: i = 1 */
    for(i=1; i < cmd->argc; i++) {
        const char *arg = cmd->argv[i];
        server = memcached_servers_parse(arg);
        rc = memcached_server_push(memcached_deny_blacklist_mmc, server);
        if(rc != MEMCACHED_SUCCESS){
            pr_log_auth(PR_LOG_ERR,
              "Fatal %s: failed memcached_strerror(): %s",
              MODULE_NAME, memcached_strerror(memcached_deny_blacklist_mmc, rc));
            exit(1);
        }
        pr_log_debug(DEBUG2,
            "%s: add memcached server %s", MODULE_NAME, arg);
    }
    is_set_server = true;
    return PR_HANDLED(cmd);
}
Example #12
0
/* usage: ModulePath path */
MODRET set_modulepath(cmd_rec *cmd) {
  int res;
  struct stat st;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT);

  if (pr_fs_valid_path(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, "must be an absolute path");

  /* Make sure that the configured path is not world-writeable. */
  res = pr_fsio_stat(cmd->argv[1], &st);
  if (res < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error checking '",
      cmd->argv[1], "': ", strerror(errno), NULL)); 

  if (!S_ISDIR(st.st_mode))
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, cmd->argv[1], " is not a directory",
      NULL));

  if (st.st_mode & S_IWOTH)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, cmd->argv[1], " is world-writable",
      NULL));

  if (lt_dlsetsearchpath(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error setting module path: ",
      lt_dlerror(), NULL));

  dso_module_path = pstrdup(dso_pool, cmd->argv[1]);
  return PR_HANDLED(cmd);
}
Example #13
0
/* usage: ModuleControlsACLs actions|all allow|deny user|group list */
MODRET set_modulectrlsacls(cmd_rec *cmd) {
#ifdef PR_USE_CTRLS
  char *bad_action = NULL, **actions = NULL;

  CHECK_ARGS(cmd, 4);
  CHECK_CONF(cmd, CONF_ROOT);

  actions = ctrls_parse_acl(cmd->tmp_pool, cmd->argv[1]);

  if (strcmp(cmd->argv[2], "allow") != 0 &&
      strcmp(cmd->argv[2], "deny") != 0)
    CONF_ERROR(cmd, "second parameter must be 'allow' or 'deny'");

  if (strcmp(cmd->argv[3], "user") != 0 &&
      strcmp(cmd->argv[3], "group") != 0)
    CONF_ERROR(cmd, "third parameter must be 'user' or 'group'");

  bad_action = pr_ctrls_set_module_acls(dso_acttab, dso_pool, actions,
    cmd->argv[2], cmd->argv[3], cmd->argv[4]);
  if (bad_action != NULL)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, ": unknown action: '",
      bad_action, "'", NULL));

  return PR_HANDLED(cmd);
#else
  CONF_ERROR(cmd, "requires Controls support (--enable-ctrls)");
#endif
}
/* usage: CounterFile path */
MODRET set_counterfile(cmd_rec *cmd) {
  config_rec *c;
  const char *path;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL|CONF_ANON|CONF_DIR);

  path = cmd->argv[1];
  if (*path != '/') {
    CONF_ERROR(cmd, "must be an absolute path");
  }

  /* In theory, we could open a filehandle on the configured path right
   * here, and fail if the file couldn't be created/opened.  Then we
   * could just stash that filehandle in the cmd_rec.  Easy.
   *
   * However, that would mean that we would have open descriptors for
   * vhosts to which the client may not connect.  We would also need to
   * use pr_fs_get_usable_fd() so that these filehandles don't use the wrong
   * fds.  Instead, then, we wait to open the filehandles in sess_init(),
   * where we know vhost to which the client connected.
   */

  c = add_config_param_str(cmd->argv[0], 1, path);
  c->flags |= CF_MERGEDOWN;

  return PR_HANDLED(cmd);
}
Example #15
0
/* usage: LoadModule module */
MODRET set_loadmodule(cmd_rec *cmd) {

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT);

  if (dso_load_module(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error loading module '",
      cmd->argv[1], "': ", strerror(errno), NULL));

  return PR_HANDLED(cmd);
}
/* usage: CounterLog path|"none" */
MODRET set_counterlog(cmd_rec *cmd) {
  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  if (pr_fs_valid_path(cmd->argv[1]) < 0) {
    CONF_ERROR(cmd, "must be an absolute path");
  }

  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
  return PR_HANDLED(cmd);
}
Example #17
0
/* usage: DynMasqRefresh <seconds> */
MODRET set_dynmasqrefresh(cmd_rec *cmd) {
    CHECK_CONF(cmd, CONF_ROOT);
    CHECK_ARGS(cmd, 1);

    dynmasq_timer_interval = atoi(cmd->argv[1]);
    if (dynmasq_timer_interval < 1)
        CONF_ERROR(cmd, pstrcat(cmd->tmp_pool,
                                "must be greater than zero: '", cmd->argv[1], "'", NULL));

    return PR_HANDLED(cmd);
}
Example #18
0
/* usage: LoadFile path */
MODRET set_loadfile(cmd_rec *cmd) {

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT);

  if (pr_fs_valid_path(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, "must be an absolute path");

  if (dso_load_file(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error loading '", cmd->argv[1],
      "': ", strerror(errno), NULL));

  return PR_HANDLED(cmd);
}
/* usage: FailureLog path [logfmt-name] */
MODRET set_failurelog(cmd_rec *cmd) {
  config_rec *c;
  const char *path;
  char *log_fmt = NULL;

  if (cmd->argc < 2 ||
      cmd->argc > 3) {
    CONF_ERROR(cmd, "wrong number of parameters");
  }

  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  path = cmd->argv[1];
  if (*path != '/') {
    CONF_ERROR(cmd, "must be an absolute path");
  }

  if (cmd->argc == 3) {
    const char *fmt_name;

    fmt_name = cmd->argv[2];

    /* Double-check that logfmt-name is valid, defined, etc. Look up the
     * format string, and stash a pointer to that in the config_rec (but NOT
     * a copy of the format string; don't need to use that much memory).
     */
    c = find_config(cmd->server->conf, CONF_PARAM, "LogFormat", FALSE);
    while (c != NULL) {
      if (strcmp(c->argv[0], fmt_name) == 0) {
        log_fmt = c->argv[1];
        break;
      }

      log_fmt = NULL;
      c = find_config_next(c, c->next, CONF_PARAM, "LogFormat", FALSE);
    }

    if (log_fmt == NULL) {
      CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "no such LogFormat '",
        cmd->argv[2], "' configured", NULL));
    }
  }

  c = add_config_param(cmd->argv[0], 2, NULL, NULL);
  c->argv[0] = pstrdup(c->pool, path);
  c->argv[1] = log_fmt;

  return PR_HANDLED(cmd);
}
MODRET set_lmd_ignore_memcached_down(cmd_rec *cmd) {
  int ignore = -1;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  ignore = get_boolean(cmd, 1);
  if (ignore == -1)
    CONF_ERROR(cmd, "expected Boolean parameter");

  if(ignore == TRUE) {
      ignore_memcached_down = true;
  }

  return PR_HANDLED(cmd);
}
Example #21
0
MODRET sftppam_auth(cmd_rec *cmd) {
  if (!sftppam_handle_auth) {
    return PR_DECLINED(cmd);
  }

  if (sftppam_auth_code != PR_AUTH_OK) {
    if (sftppam_authoritative) {
      return PR_ERROR_INT(cmd, sftppam_auth_code);
    }

    return PR_DECLINED(cmd);
  }

  session.auth_mech = "mod_sftp_pam.c";
  pr_event_register(&sftp_pam_module, "core.exit", sftppam_exit_ev, NULL);
  return PR_HANDLED(cmd);
}
Example #22
0
/* usage: CopyEngine on|off */
MODRET set_copyengine(cmd_rec *cmd) {
  int engine = -1;
  config_rec *c;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  engine = get_boolean(cmd, 1);
  if (engine == -1) {
    CONF_ERROR(cmd, "expected Boolean parameter");
  }

  c = add_config_param(cmd->argv[0], 1, NULL);
  c->argv[0] = palloc(c->pool, sizeof(int));
  *((int *) c->argv[0]) = engine;

  return PR_HANDLED(cmd);
}
Example #23
0
MODRET authfile_chkpass(cmd_rec *cmd) {
  const char *ciphertxt_pass = cmd->argv[0];
  const char *cleartxt_pass = cmd->argv[2];
  char *crypted_pass = NULL;

  if (!ciphertxt_pass) {
    pr_log_debug(DEBUG2, MOD_AUTH_FILE_VERSION
      ": missing ciphertext password for comparison");
    return PR_DECLINED(cmd);
  }

  if (!cleartxt_pass) {
    pr_log_debug(DEBUG2, MOD_AUTH_FILE_VERSION
      ": missing client-provided password for comparison");
    return PR_DECLINED(cmd);
  }

  /* Even though the AuthUserFile is not used here, there must be one
   * configured before this function should attempt to check the password.
   * Otherwise, it could be checking a password retrieved by some other
   * auth module.
   */
  if (!af_user_file)
    return PR_DECLINED(cmd);

  crypted_pass = crypt(cleartxt_pass, ciphertxt_pass);
  if (handle_empty_salt == TRUE &&
      strlen(ciphertxt_pass) == 0) {
    crypted_pass = "";
  }

  if (crypted_pass == NULL) {
    pr_log_debug(DEBUG0, MOD_AUTH_FILE_VERSION
      ": error using crypt(3): %s", strerror(errno));
    return PR_DECLINED(cmd);
  }

  if (strcmp(crypted_pass, ciphertxt_pass) == 0) {
    session.auth_mech = "mod_auth_file.c";
    return PR_HANDLED(cmd);
  }  

  return PR_DECLINED(cmd);
}
Example #24
0
/*
 * cmd_exit: closes all open connections.
 *
 * Inputs:
 *  None
 *
 * Returns:
 *  A simple non-error modret_t.
 */
static modret_t *cmd_exit(cmd_rec *cmd) {
  register unsigned int i = 0;

  sql_log(DEBUG_FUNC, "%s", "entering \tpostgres cmd_exit");

  for (i = 0; i < conn_cache->nelts; i++) {
    conn_entry_t *entry = ((conn_entry_t **) conn_cache->elts)[i];

    if (entry->connections > 0) {
      cmd_rec *close_cmd = _sql_make_cmd(conn_pool, 2, entry->name, "1");
      cmd_close(close_cmd);
      destroy_pool(close_cmd->pool);
    }
  }

  sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_exit");

  return PR_HANDLED(cmd);
}
Example #25
0
/* usage: QoSOptions */
MODRET set_qosoptions(cmd_rec *cmd) {
  register unsigned int i;
  config_rec *c;
  int ctrlqos = 0, dataqos = 0;

  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL);

  /* Make sure we have the right number of parameters. */
  if ((cmd->argc-1) % 2 != 0) {
   CONF_ERROR(cmd, "bad number of parameters");
  }

  for (i = 1; i < cmd->argc; i++) {
    if (strcasecmp(cmd->argv[i], "dataqos") == 0) {
      dataqos = qos_get_int(cmd->argv[++i]);
      if (dataqos == -1) {
        CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unknown dataqos parameter '",
          cmd->argv[i-1], "'", NULL));
      }

    } else if (strcasecmp(cmd->argv[i], "ctrlqos") == 0) {
      ctrlqos = qos_get_int(cmd->argv[++i]);
      if (ctrlqos == -1) {
        CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "unknown ctrlqos parameter '",
          cmd->argv[i-1], "'", NULL));
      }

    } else {
      CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, ": unknown QoS option: '",
        cmd->argv[i], "'", NULL));
    }
  }

  c = add_config_param(cmd->argv[0], 2, NULL, NULL);
  c->argv[0] = pcalloc(c->pool, sizeof(int));
  *((int *) c->argv[0]) = ctrlqos;
  c->argv[1] = pcalloc(c->pool, sizeof(int));
  *((int *) c->argv[1]) = dataqos;

  return PR_HANDLED(cmd);
}
Example #26
0
/* usage: MemcacheServers host1[:port1] ... */
MODRET set_memcacheservers(cmd_rec *cmd) {
  register unsigned int i;
  config_rec *c;
  char *str = "";
  int ctxt;
  memcached_server_st *memcache_servers = NULL;

  if (cmd->argc-1 < 1) {
    CONF_ERROR(cmd, "wrong number of parameters");
  }

  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  c = add_config_param(cmd->argv[0], 1, NULL);
  for (i = 1; i < cmd->argc; i++) {
    str = pstrcat(cmd->pool, str, *str ? ", " : "", cmd->argv[i], NULL);
  }

  memcache_servers = memcached_servers_parse(str);
  if (memcache_servers == NULL) {
    CONF_ERROR(cmd, "unable to parse server parameters");
  }

  ctxt = (cmd->config && cmd->config->config_type != CONF_PARAM ?
    cmd->config->config_type : cmd->server->config_type ?
    cmd->server->config_type : CONF_ROOT);

  if (ctxt == CONF_ROOT) {
    /* If we're the "server config" context, set the server list now.  This
     * would let mod_memcache talk to those servers for e.g. ftpdctl actions.
     */
    memcache_set_servers(memcache_servers);
  }

  c->argv[0] = memcache_servers;

  /* Add the libmemcached-allocated pointer to a list, for later freeing. */
  *((memcached_server_st **) push_array(memcache_server_lists)) = memcache_servers;
  return PR_HANDLED(cmd);
}
MODRET add_lmd_allow_user(cmd_rec *cmd) {
    config_rec *c;
    int i;
    pr_table_t *explicit_users;

    if(cmd->argc < 2)
        CONF_ERROR(cmd, "missing argument");

    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* argv => LMDBAllowedUser nobody nobody1 nobody2 */
    c = find_config(main_server->conf, CONF_PARAM, "LMDBAllowedUser", FALSE);
    if(c && c->argv[0]) {
        explicit_users = c->argv[0];
    } else {
        c = add_config_param(cmd->argv[0], 0, NULL);
        c->argv[0] = explicit_users = pr_table_alloc(main_server->pool, 0);
    }

    for(i=1; i < cmd->argc; i++) {
        const char *account = pstrdup(main_server->pool, cmd->argv[i]);
        if(pr_table_exists(explicit_users, account) > 0) {
            pr_log_debug(DEBUG2,
                "%s: %s is already registerd", MODULE_NAME, account);
            continue;
        }

        if(pr_table_add_dup(explicit_users, account, "y", 0) < 0){
            pr_log_pri(PR_LOG_ERR,
                "%s: failed pr_table_add_dup(): %s",
                 MODULE_NAME, strerror(errno));
            exit(1);
        }
        pr_log_debug(DEBUG2,
            "%s: add LMDBAllowedUser[%d] %s", MODULE_NAME, i, account);
    }

    return PR_HANDLED(cmd);
}
Example #28
0
/* usage: DynMasqControlsACLs actions|all allow|deny user|group list */
MODRET set_dynmasqctrlsacls(cmd_rec *cmd) {
#ifdef PR_USE_CTRLS
    char *bad_action = NULL, **actions = NULL;

    CHECK_ARGS(cmd, 4);
    CHECK_CONF(cmd, CONF_ROOT);

    /* We can cheat here, and use the ctrls_parse_acl() routine to
     * separate the given string...
     */
    actions = ctrls_parse_acl(cmd->tmp_pool, cmd->argv[1]);

    /* Check the second parameter to make sure it is "allow" or "deny" */
    if (strcmp(cmd->argv[2], "allow") != 0 &&
            strcmp(cmd->argv[2], "deny") != 0) {
        CONF_ERROR(cmd, "second parameter must be 'allow' or 'deny'");
    }

    /* Check the third parameter to make sure it is "user" or "group" */
    if (strcmp(cmd->argv[3], "user") != 0 &&
            strcmp(cmd->argv[3], "group") != 0) {
        CONF_ERROR(cmd, "third parameter must be 'user' or 'group'");
    }

    bad_action = pr_ctrls_set_module_acls(dynmasq_acttab, dynmasq_act_pool,
                                          actions, cmd->argv[2], cmd->argv[3], cmd->argv[4]);
    if (bad_action != NULL) {
        CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, ": unknown action: '",
                                bad_action, "'", NULL));
    }

    return PR_HANDLED(cmd);
#else
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "The ", cmd->argv[0],
                            " directive requires Controls support (--enable-ctrls)", NULL));
#endif /* PR_USE_CTRLS */
}
MODRET add_lmd_allow_user_regex(cmd_rec *cmd) {
    array_header *list;
    pr_regex_t *pre;
    int i, res;
    config_rec *c;

    if(cmd->argc < 2)
        CONF_ERROR(cmd, "missing argument");
    CHECK_CONF(cmd, CONF_ROOT|CONF_GLOBAL);

    /* argv => LMDBAllowUserRegex ^test */
    c = find_config(cmd->server->conf, CONF_PARAM, "LMDBAllowedUserRegex", FALSE);
    if(c && c->argv[0]) {
        list = c->argv[0];
    } else {
        c = add_config_param(cmd->argv[0], 0, NULL);
        c->argv[0] = list = make_array(cmd->server->pool, 0, sizeof(regex_t *));
    }

    for(i=1; i < cmd->argc; i++) {
        pre = pr_regexp_alloc(&libmemcached_deny_blacklist_module);
        res = pr_regexp_compile(pre, cmd->argv[i], REG_NOSUB);
        if (res != 0) {
            char errstr[200] = {'\0'};
            pr_regexp_error(res, pre, errstr, sizeof(errstr));
            pr_regexp_free(NULL, pre);
            CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "'", cmd->argv[i], "' failed "
               "regex compilation: ", errstr, NULL));
        }
        *((pr_regex_t **) push_array(list)) = pre;
        pr_log_debug(DEBUG2,
            "%s: add LMDBAllowedUserRegex[%d] %s", MODULE_NAME, i, cmd->argv[i]);
    }

    return PR_HANDLED(cmd);
}
Example #30
0
/*
 * cmd_insert: executes an INSERT query, properly constructing the query
 *  based on the inputs.
 *
 * cmd_insert takes either exactly two inputs, or exactly four.  If only
 *  two inputs are given, the second is a monolithic query string.  See 
 *  the examples below.
 *
 * Inputs:
 *  cmd->argv[0]: connection name
 *  cmd->argv[1]: table
 *  cmd->argv[2]: field string
 *  cmd->argv[3]: value string
 *
 * Returns:
 *  either a properly filled error modret_t if the insert failed, or a 
 *  simple non-error modret_t.
 *
 * Example:
 *  These are example queries that would be executed for Postgres; other
 *  backends will have different SQL syntax.
 *  
 *  argv[] = "default","log","userid, date, count", "'aah', now(), 2"
 *  query  = "INSERT INTO log (userid, date, count) VALUES ('aah', now(), 2)"
 *
 *  argv[] = "default"," INTO foo VALUES ('do','re','mi','fa')"
 *  query  = "INSERT INTO foo VALUES ('do','re','mi','fa')"
 *
 * Notes:
 *  none
 */
MODRET cmd_insert(cmd_rec *cmd) {
  conn_entry_t *entry = NULL;
  db_conn_t *conn = NULL;
  modret_t *cmr = NULL;
  modret_t *dmr = NULL;
  char *query = NULL;
  cmd_rec *close_cmd;

  sql_log(DEBUG_FUNC, "%s", "entering \tpostgres cmd_insert");

  _sql_check_cmd(cmd, "cmd_insert");

  if ((cmd->argc != 2) && (cmd->argc != 4)) {
    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_insert");
    return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION, "badly formed request");
  }

  /* get the named connection */
  entry = _sql_get_connection(cmd->argv[0]);
  if (!entry) {
    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_insert");
    return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION,
      "unknown named connection");
  }

  conn = (db_conn_t *) entry->data;

  cmr = cmd_open(cmd);
  if (MODRET_ERROR(cmr)) {
    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_insert");
    return cmr;
  }

  /* construct the query string */
  if (cmd->argc == 2) {
    query = pstrcat(cmd->tmp_pool, "INSERT ", cmd->argv[1], NULL);
  } else {
    query = pstrcat( cmd->tmp_pool, "INSERT INTO ", cmd->argv[1], " (",
		     cmd->argv[2], ") VALUES (", cmd->argv[3], ")",
		     NULL );
  }

  /* log the query string */
  sql_log(DEBUG_INFO, "query \"%s\"", query);

  /* perform the query.  if it doesn't work, log the error, close the
   * connection then return the error from the query processing.
   */
  if (!(conn->result = PQexec(conn->postgres, query)) ||
      (PQresultStatus(conn->result) != PGRES_COMMAND_OK)) {
    dmr = _build_error( cmd, conn );

    if (conn->result) PQclear(conn->result);

    close_cmd = _sql_make_cmd( cmd->tmp_pool, 1, entry->name );
    cmd_close(close_cmd);
    SQL_FREE_CMD(close_cmd);

    sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_insert");
    return dmr;
  }

  PQclear(conn->result);

  /* close the connection and return HANDLED. */
  close_cmd = _sql_make_cmd( cmd->tmp_pool, 1, entry->name );
  cmd_close(close_cmd);
  SQL_FREE_CMD(close_cmd);

  sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_insert");
  return PR_HANDLED(cmd);
}