/* * 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); }
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); }
/* 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); }
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); }
/* 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); }
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); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }
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); }
/* 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); }
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); }
/* * 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); }
/* 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); }
/* 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); }
/* 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); }
/* * 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); }