diff options
Diffstat (limited to 'ftp/proftpd-devel/files/patch-bb')
-rw-r--r-- | ftp/proftpd-devel/files/patch-bb | 1023 |
1 files changed, 0 insertions, 1023 deletions
diff --git a/ftp/proftpd-devel/files/patch-bb b/ftp/proftpd-devel/files/patch-bb deleted file mode 100644 index 7d17d667f7dc..000000000000 --- a/ftp/proftpd-devel/files/patch-bb +++ /dev/null @@ -1,1023 +0,0 @@ ---- contrib/mod_sqlpw.c.old Sun Feb 11 19:47:34 2001 -+++ contrib/mod_sqlpw.c Sun Feb 11 19:45:37 2001 -@@ -0,0 +1,1020 @@ -+/* -+ * ProFTPD: mod_sql -- SQL frontend and user interface. -+ * Time-stamp: <1999-10-04 03:58:01 root> -+ * Copyright (c) 1998-1999 Johnie Ingram. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#define MOD_SQL_VERSION "mod_sqlpw/2.0" -+ -+/* This is mod_sqlpw, contrib software for proftpd 1.2.0pre3 and above. -+ For more information contact Johnie Ingram <johnie@netgod.net>. -+ -+ History Log: -+ -+ * 2000-03-16: Added SQLKeyField and SQLKey directive, which -+ should allow authentication of different logins for different -+ VirtualHosts to be in the same database table. -+ Jake Buchholz <jake@execpc.com> -+ -+ * 1999-09-19: v2.0: Backend directives split into mod_mysql. -+ Runtime API added. Username/passwords now escaped for SQL. -+ -+ * 1999-09-16: v1.0: Added documentation, made directives more -+ generic ("MySQL" -> "SQL" except for MySQLInfo). Dir part of -+ SQLLogDirs finally made optional. -+ -+ * 1999-06-01: v0.3: fixed segfault, changed 'strncmp' typo which -+ should have been copy. Made uid/gid support optional. -+ -+ * 1999-05-03: v0.2: Removed dead code, fix bug with interaction -+ with anon-user support. Added MySQLLogHits and MySQLHomedir -+ directives. Fixed atoi() invocation that could segfault. -+ Copious debugging code added. -+ -+ * 1999-04-09: v0.1: Initial attempt (mod_mysql). -+ -+*/ -+ -+#include "conf.h" -+#ifdef HAVE_CRYPT_H -+#include <crypt.h> -+#endif -+ -+#include <mysql.h> -+ -+/* *INDENT-OFF* */ -+ -+/* The Debian defintion of nobody/nogroup, minus 1 (used in getgwnam). */ -+#define MOD_SQL_MAGIC_USER 65533 -+#define MOD_SQL_MAGIC_GROUP 65533 -+ -+/* A uid or gid less than this is mapped to the magic numbers above -+ instead of simply rejected (which is arguably better, hmm.) */ -+#define MOD_SQL_MIN_ID 999 -+ -+#define MOD_SQL_MAGIC_SHELL "/bin/sh" -+ -+/* Maximum username field to expect, etc. */ -+#define ARBITRARY_MAX 128 -+ -+static struct { -+ char user [ARBITRARY_MAX]; -+ struct passwd pw; /* Scratch space for the getpwnam call. */ -+ char *pass; /* The password from db. */ -+ -+ char *homedir; /* Set when getpwnam is called. */ -+ int pwnamed; /* Set when getpwnam is called. */ -+ int sqled; /* Set if sql auth was used. */ -+ -+ char *sql_usertable; /* CREATE TABLE users ( */ -+ char *sql_userid; /* userid varchar(50) NOT NULL, */ -+ char *sql_passwd; /* passwd varchar(15), */ -+ -+ char *sql_uid; /* uid int(5), */ -+ char *sql_gid; /* gid int(5), */ -+ -+ char *sql_fstor; /* fstor int(11) NOT NULL DEFAULT '0', */ -+ char *sql_fretr; /* fretr int(11) NOT NULL DEFAULT '0', */ -+ char *sql_bstor; /* bstor int(11) NOT NULL DEFAULT '0', */ -+ char *sql_bretr; /* bretr int(11) NOT NULL DEFAULT '0', */ -+ -+ char *sql_fhdir; /* fhdir varchar(255), */ -+ -+ char *sql_fhost; /* fhost varchar(50), */ -+ char *sql_faddr; /* faddr char(15), */ -+ char *sql_ftime; /* ftime timestamp, */ -+ -+ char *sql_fcdir; /* fcdir varchar(255), */ -+ -+ char *sql_frate; /* frate int(11) NOT NULL DEFAULT '5', */ -+ char *sql_fcred; /* fcred int(2) NOT NULL DEFAULT '15', */ -+ char *sql_brate; /* brate int(11) NOT NULL DEFAULT '5', */ -+ char *sql_bcred; /* bcred int(2) NOT NULL DEFAULT '150000', */ -+ -+ char *sql_flogs; /* flogs int(11) NOT NULL DEFAULT '0', */ -+ -+ char *sql_hittable; -+ char *sql_dir; -+ char *sql_filename; -+ char *sql_hits; -+ -+ char *sql_keyfld; /* table column name that stores the key */ -+ char *sql_key; /* the key to match db table entries against */ -+ -+ char *loginmsg; -+ int ok; -+ -+} g; -+ -+/* *INDENT-ON* */ -+ -+/* **************************************************************** */ -+ -+/* Functions make_cmd and dispatch liberally stolen from auth.c. */ -+ -+static cmd_rec * -+_make_cmd (pool * cp, int argc, ...) -+{ -+ va_list args; -+ cmd_rec *c; -+ int i; -+ -+ c = pcalloc (cp, sizeof (cmd_rec)); -+ c->argc = argc; -+ c->symtable_index = -1; -+ -+ c->argv = pcalloc (cp, sizeof (void *) * (argc + 1)); -+ c->argv[0] = MOD_SQL_VERSION; -+ va_start (args, argc); -+ for (i = 0; i < argc; i++) -+ c->argv[i + 1] = (void *) va_arg (args, char *); -+ va_end (args); -+ -+ return c; -+} -+ -+static modret_t * -+_dispatch_sql (cmd_rec * cmd, char *match) -+{ -+ authtable *m; -+ modret_t *mr = NULL; -+ -+ m = mod_find_auth_symbol (match, &cmd->symtable_index, NULL); -+ while (m) -+ { -+ mr = call_module_auth (m->m, m->handler, cmd); -+ if (MODRET_ISHANDLED (mr) || MODRET_ISERROR (mr)) -+ break; -+ m = mod_find_auth_symbol (match, &cmd->symtable_index, m); -+ } -+ if (MODRET_ISERROR (mr)) -+ log_debug (DEBUG0, "Aiee! sql internal! %s", MODRET_ERRMSG (mr)); -+ return mr; -+} -+ -+MODRET -+modsql_open (cmd_rec * cmd) -+{ -+ cmd_rec *c; -+ modret_t *mr; -+ -+ c = _make_cmd (cmd ? cmd->tmp_pool : permanent_pool, 0); -+ mr = _dispatch_sql (c, "dbd_open"); -+ if (c->tmp_pool) -+ destroy_pool (c->tmp_pool); -+ return mr; -+} -+ -+MODRET -+modsql_close (cmd_rec * cmd) -+{ -+ cmd_rec *c; -+ modret_t *mr; -+ -+ c = _make_cmd (cmd ? cmd->tmp_pool : permanent_pool, 0); -+ mr = _dispatch_sql (c, "dbd_close"); -+ if (c->tmp_pool) -+ destroy_pool (c->tmp_pool); -+ return mr; -+} -+ -+MODRET -+modsql_update (cmd_rec * cmd, const char *query) -+{ -+ cmd_rec *c; -+ modret_t *mr; -+ -+ c = _make_cmd (cmd->tmp_pool, 1, query); -+ mr = _dispatch_sql (c, "dbd_update"); -+ if (c->tmp_pool) -+ destroy_pool (c->tmp_pool); -+ return mr; -+} -+ -+MODRET -+modsql_select (cmd_rec * cmd, const char *query) -+{ -+ cmd_rec *c; -+ modret_t *mr; -+ -+ c = _make_cmd (cmd->tmp_pool, 1, query); -+ mr = _dispatch_sql (c, "dbd_select"); -+ if (c->tmp_pool) -+ destroy_pool (c->tmp_pool); -+ return mr; -+} -+ -+MODRET -+modsql_queryuser (cmd_rec * cmd, const char *user, const char *query, -+ int update) -+{ -+ char *realquery; -+ -+ if ((update) && (!g.sql_keyfld)) -+ realquery = pstrcat (cmd->tmp_pool, "update ", g.sql_usertable, -+ " set ", query, " where ", g.sql_userid, " = '", -+ user, "'", NULL); -+ else if ((update) && (g.sql_keyfld)) -+ realquery = pstrcat (cmd->tmp_pool, "update ", g.sql_usertable, -+ " set ", query, " where ", g.sql_userid, " = '", -+ user, "' and ", g.sql_keyfld, " = '", -+ g.sql_key, "'", NULL); -+ else if ((!update) && (!g.sql_keyfld)) -+ realquery = pstrcat (cmd->tmp_pool, "select ", query, " from ", -+ g.sql_usertable, " where ", g.sql_userid, -+ " = '", user, "'", NULL); -+ else -+ realquery = pstrcat (cmd->tmp_pool, "select ", query, " from ", -+ g.sql_usertable, " where ", g.sql_userid, -+ " = '", user, "' and ", g.sql_keyfld, " = '", -+ g.sql_key, "'", NULL); -+ return (update) ? modsql_update (cmd, realquery) -+ : modsql_select (cmd, realquery); -+} -+ -+/* **************************************************************** */ -+ -+static char * -+_uservar (cmd_rec * cmd, const char *user, const char *var) -+{ -+ cmd_rec *c; -+ modret_t *mr; -+ char *query; -+ char **data; -+ -+ if (!g.sql_keyfld) -+ query = pstrcat (cmd->tmp_pool, "select ", var, " from ", -+ g.sql_usertable, " where ", g.sql_userid, -+ " = '", user, "'", NULL); -+ else -+ query = pstrcat (cmd->tmp_pool, "select ", var, " from ", -+ g.sql_usertable, " where ", g.sql_userid, -+ " = '", user, "' and ", g.sql_keyfld, " = '", -+ g.sql_key, "'", NULL); -+ c = _make_cmd (cmd->tmp_pool, 1, query); -+ -+ mr = _dispatch_sql (c, "dbd_select"); -+ -+ if (c->tmp_pool) -+ destroy_pool (c->tmp_pool); -+ if (MODRET_ISHANDLED (mr)) -+ { -+ data = mr->data; -+ return (data) ? data[0] : NULL; -+ } -+ -+ return NULL; -+} -+ -+/* Note: This function is called once by the master proftpd process -+ before it forks, so thankfully the homedir field is only set in the -+ child_init(). */ -+ -+MODRET -+auth_cmd_getpwnam (cmd_rec * cmd) -+{ -+ const char *homedir; -+ -+ if (!g.sql_fhdir && !g.homedir) -+ return DECLINED (cmd); -+ -+ /* Only try this for the USER command (is also called twice after -+ PASS for some reason. [update: 1 is dir_realpath/defroot related.] */ -+ if (!g.homedir && !g.pwnamed++) -+ { -+ if ((homedir = _uservar (cmd, cmd->argv[0], g.sql_fhdir))) -+ g.homedir = pstrdup (session.pool, homedir); -+ } -+ if (!g.homedir) -+ return DECLINED (cmd); -+ -+ if (!g.pw.pw_name) -+ { -+ g.pw.pw_name = pstrdup(session.pool, cmd->argv[0]); -+ if (g.sql_uid) -+ g.pw.pw_uid = atoi (_uservar (cmd, cmd->argv[0], g.sql_uid) ? : "0"); -+ if (g.pw.pw_uid < MOD_SQL_MIN_ID) -+ g.pw.pw_uid = MOD_SQL_MAGIC_USER; -+ if (g.sql_gid) -+ g.pw.pw_gid = atoi (_uservar (cmd, cmd->argv[0], g.sql_gid) ? : "0"); -+ if (g.pw.pw_gid < MOD_SQL_MIN_ID) -+ g.pw.pw_gid = MOD_SQL_MAGIC_GROUP; -+ g.pw.pw_shell = MOD_SQL_MAGIC_SHELL; -+ g.pw.pw_dir = (char *) g.homedir; -+ log_debug (DEBUG3, "sqlpw: user \"%s\" (%i/%i) for %s", -+ cmd->argv[0], g.pw.pw_uid, g.pw.pw_gid, g.pw.pw_dir); -+ -+ /* Copy username so proftpd anon handling won't confuse the issue. */ -+ -+ /* FIXME: unnecessary mysqlism */ -+ mysql_escape_string (g.user, g.pw.pw_name, strlen (g.pw.pw_name)); -+ g.user[ARBITRARY_MAX - 1] = 0; -+ } -+ -+ return mod_create_data (cmd, &g.pw); -+} -+ -+/* Returns 1 on successful match, 0 unsuccessful match, -1 on error. */ -+ -+static int -+_checkpass (cmd_rec * cmd, const char *user, const char *pass) -+{ -+ int success = 0; -+ char *query; -+ int emptyok, cplain, ccrypt; -+ char **row; -+ MODRET mr; -+ -+ emptyok = get_param_int (CURRENT_CONF, "SQLEmptyPasswords", FALSE); -+ cplain = get_param_int (CURRENT_CONF, "SQLPlaintextPasswords", FALSE); -+ ccrypt = get_param_int (CURRENT_CONF, "SQLEncryptedPasswords", FALSE); -+ -+ if (!g.sql_keyfld) -+ query = pstrcat (cmd->tmp_pool, "select ", g.sql_passwd, " from ", -+ g.sql_usertable, " where ", g.sql_userid, -+ " = '", user, "'", " limit 2", NULL); -+ else -+ query = pstrcat (cmd->tmp_pool, "select ", g.sql_passwd, " from ", -+ g.sql_usertable, " where ", g.sql_userid, -+ " = '", user, "' and ", g.sql_keyfld, " = '", -+ g.sql_key, "' limit 2", NULL); -+ mr = modsql_select (cmd, query); -+ if (!(MODRET_HASDATA (mr))) -+ return -1; -+ -+ row = mr->data; -+ if (row[0] == 0) -+ return 0; -+ -+ if (!row[0]) -+ { -+ log_debug (DEBUG4, "sqlpw: %s auth declined for NULL pass", user); -+ return 0; -+ } -+ -+ if (row[1]) -+ { -+ log_debug (DEBUG3, "sqlpw: %s pass result was not unique", user); -+ return -1; -+ } -+ -+ if (emptyok == TRUE && !strlen (row[0])) -+ { -+ log_debug (DEBUG4, "sqlpw: warning: %s has empty password", user); -+ success = 1; -+ } -+ -+ if (!success && cplain == TRUE && !strncasecmp (row[0], pass, 10)) -+ { -+ success = 1; -+ } -+ -+ /* Deliberate: ccrypt same if TRUE or -1 (unspecified). */ -+ if (!success && ccrypt) -+ { -+ if (!strcmp (query = (char *) crypt (pass, row[0]), row[0])) -+ success = 1; -+ } -+ -+ if (!success) -+ log_debug (DEBUG5, "sqlpw: %s auth failed: '%s' != '%s'", -+ user, pass, row ? row[0] : ""); -+ return success; -+} -+ -+MODRET -+auth_cmd_auth (cmd_rec * cmd) -+{ -+ char *user, *pass; -+ int return_type; -+ int retval = AUTH_NOPWD; -+ -+ if (!g.sql_passwd || !g.homedir) -+ return DECLINED (cmd); -+ -+ /* Figure out our default return style: Whether or not SQL should -+ * allow other auth modules a shot at this user or not is controlled -+ * by the parameter "SQLAuthoritative". Like mod_pam this -+ * defaults to no. */ -+ if((return_type = get_param_int (CURRENT_CONF, -+ "SQLAuthoritative", FALSE)) == -1) { -+ return_type = 0; -+ } -+ -+ /* Just in case... */ -+ if (cmd->argc != 2) -+ return return_type ? ERROR (cmd) : DECLINED (cmd); -+ if ((user = cmd->argv[0]) == NULL) -+ return return_type ? ERROR (cmd) : DECLINED (cmd); -+ if ((pass = cmd->argv[1]) == NULL) -+ return return_type ? ERROR (cmd) : DECLINED (cmd); -+ -+ if (!g.pass -+ && get_param_int (CURRENT_CONF, "SQLEmptyPasswords", FALSE) == 2) -+ { -+ char *query; -+ char passbuf[ARBITRARY_MAX] = {'\0'}; -+ -+ /* FIXME: unnecessary mysqlism */ -+ mysql_escape_string (passbuf, cmd->argv[1], strlen (cmd->argv[1])); -+ g.user[ARBITRARY_MAX - 1] = 0; -+ -+ if (!g.sql_keyfld) -+ query = pstrcat (cmd->tmp_pool, "update ", g.sql_usertable, -+ " set ", g.sql_passwd, " = '", passbuf, -+ "' where ", g.sql_userid, " = '", g.user, "'", 0); -+ else -+ query = pstrcat (cmd->tmp_pool, "update ", g.sql_usertable, -+ " set ", g.sql_passwd, " = '", passbuf, -+ "' where ", g.sql_userid, " = '", g.user, "' and ", -+ g.sql_keyfld, " = '", g.sql_key, "'", 0); -+ log_debug (DEBUG3, "sqlpw: %s NULL pass set to '%s'", user, -+ cmd->argv[1], query); -+ modsql_update (cmd, query); -+ } -+ -+ if (_checkpass (cmd, g.user, pass) != 1) -+ return return_type ? ERROR_INT (cmd, retval) : DECLINED (cmd); -+ -+ g.sqled++; -+ return HANDLED (cmd); -+} -+ -+MODRET -+auth_cmd_getstats (cmd_rec * cmd) -+{ -+ MODRET mr; -+ char *query; -+ -+ if (g.sql_fstor) -+ { -+ if (!g.sql_keyfld) -+ query = pstrcat (cmd->tmp_pool, "select ", g.sql_fstor, ", ", -+ g.sql_fretr, ", ", g.sql_bstor, ", ", -+ g.sql_bretr, " from ", g.sql_usertable, " where ", -+ g.sql_userid, " = '", g.user, "'", NULL); -+ else -+ query = pstrcat (cmd->tmp_pool, "select ", g.sql_fstor, ", ", -+ g.sql_fretr, ", ", g.sql_bstor, ", ", -+ g.sql_bretr, " from ", g.sql_usertable, " where ", -+ g.sql_userid, " = '", g.user, "' and ", g.sql_keyfld, -+ " = '", g.sql_key, "'", NULL); -+ mr = modsql_select (cmd, query); -+ if (MODRET_HASDATA (mr)) -+ return mr; -+ } -+ return DECLINED (cmd); -+} -+ -+MODRET -+auth_cmd_getratio (cmd_rec * cmd) -+{ -+ MODRET mr; -+ char *query; -+ -+ if (g.sql_frate) -+ { -+ if (!g.sql_keyfld) -+ query = pstrcat (cmd->tmp_pool, "select ", g.sql_frate, ", ", -+ g.sql_fcred, ", ", g.sql_brate, ", ", -+ g.sql_bcred, " from ", g.sql_usertable, " where ", -+ g.sql_userid, " = '", g.user, "'", NULL); -+ else -+ query = pstrcat (cmd->tmp_pool, "select ", g.sql_frate, ", ", -+ g.sql_fcred, ", ", g.sql_brate, ", ", -+ g.sql_bcred, " from ", g.sql_usertable, " where ", -+ g.sql_userid, " = '", g.user, "' and ", g.sql_keyfld, -+ " = '", g.sql_key, "'", NULL); -+ mr = modsql_select (cmd, query); -+ if (MODRET_HASDATA (mr)) -+ return mr; -+ } -+ return DECLINED (cmd); -+} -+ -+static authtable sqlpw_authtab[] = { -+ -+ {0, "auth", auth_cmd_auth}, -+ {0, "getpwnam", auth_cmd_getpwnam}, -+ {0, "getstats", auth_cmd_getstats}, -+ {0, "getratio", auth_cmd_getratio}, -+ {0, NULL, NULL} -+}; -+ -+/* **************************************************************** */ -+ -+static void -+_setstats (cmd_rec * cmd, int fstor, int fretr, int bstor, int bretr) -+{ -+ char query[ARBITRARY_MAX] = {'\0'}; -+ snprintf (query, sizeof (query), -+ "%s = %s + %i, %s = %s + %i, %s = %s + %i, %s = %s + %i", -+ g.sql_fstor, g.sql_fstor, fstor, -+ g.sql_fretr, g.sql_fretr, fretr, -+ g.sql_bstor, g.sql_bstor, bstor, g.sql_bretr, g.sql_bretr, bretr); -+ modsql_queryuser (cmd, g.user, query, TRUE); -+} -+ -+MODRET -+pre_cmd_quit (cmd_rec * cmd) -+{ -+ if (g.ok) -+ modsql_close (cmd); -+ return DECLINED (cmd); -+} -+ -+MODRET -+cmd_user (cmd_rec * cmd) -+{ -+ if (!g.user[0]) -+ sstrncpy (g.user, cmd->argv[1], ARBITRARY_MAX); -+ -+ if (g.sql_passwd) -+ { -+ g.pass = (char *) _uservar (cmd, cmd->argv[1], g.sql_passwd); -+ if (!g.pass -+ && get_param_int (CURRENT_CONF, "SQLEmptyPasswords", FALSE) == 2) -+ if (_uservar (cmd, cmd->argv[1], "1")) -+ add_response (R_331, "Changing password for %s -- " -+ "this password will be saved.", cmd->argv[1]); -+ } -+ return DECLINED (cmd); -+} -+ -+MODRET -+cmd_pass (cmd_rec * cmd) -+{ -+ if (g.sql_passwd && !g.pass -+ && get_param_int (CURRENT_CONF, "SQLEmptyPasswords", FALSE) == 2) -+ add_response (R_230, "\"%s\" is the new user \"%s\" password.", -+ cmd->argv[1], g.user); -+ -+ /* This is called before the disconnect() in log_cmd_pass. */ -+ if (g.sql_fcdir) -+ { -+ const char *d = _uservar (cmd, g.user, g.sql_fcdir); -+ if (d) -+ add_response (R_230, "\"%s\" was last directory.", d); -+ } -+ -+ return DECLINED (cmd); -+} -+ -+MODRET -+post_cmd_pass (cmd_rec * cmd) -+{ -+ if (g.sql_passwd && g.sqled) -+ session.anon_user = session.user = (char *) g.user; -+ return DECLINED (cmd); -+} -+ -+MODRET -+post_cmd_stor (cmd_rec * cmd) -+{ -+ if (g.sql_fstor) -+ _setstats (cmd, 1, 0, session.xfer.total_bytes, 0); -+ return DECLINED (cmd); -+} -+ -+MODRET -+cmd_retr (cmd_rec * cmd) -+{ -+ int i; -+ char *path, *filename, *query; -+ if (g.sql_hittable) -+ { -+ path = dir_realpath (cmd->tmp_pool, cmd->argv[1]); -+ if (g.sql_dir && g.sql_dir[0]) -+ { -+ for (i = strlen (path), filename = path + i; -+ *filename != '/' && i > 1; i--) -+ filename--; -+ *filename++ = 0; -+ query = pstrcat (cmd->tmp_pool, "update ", g.sql_hittable, -+ " set ", g.sql_hits, " = ", g.sql_hits, -+ " + 1 where ", g.sql_dir, " = '", ++path, -+ "' and ", g.sql_filename, " = '", filename, -+ "'", 0); -+ } -+ else -+ query = pstrcat (cmd->tmp_pool, "update ", g.sql_hittable, -+ " set ", g.sql_hits, " = ", g.sql_hits, -+ " + 1 where ", g.sql_filename, " = '", path, "'", 0); -+ modsql_update (cmd, query); -+ } -+ return DECLINED (cmd); -+} -+ -+MODRET -+post_cmd_retr (cmd_rec * cmd) -+{ -+ if (g.sql_fretr) -+ _setstats (cmd, 0, 1, 0, session.xfer.total_bytes); -+ return DECLINED (cmd); -+} -+ -+MODRET -+log_cmd_pass (cmd_rec * cmd) -+{ -+ char *query; -+ -+ if (g.sql_fhost) -+ { -+ query = pstrcat (cmd->tmp_pool, g.sql_fhost, " = '", -+ session.c->remote_name, "', ", g.sql_faddr, -+ " = '", inet_ntoa (*session.c->remote_ipaddr), -+ "', ", g.sql_ftime, " = now()", NULL); -+ modsql_queryuser (cmd, g.user, query, TRUE); -+ } -+ if (g.sql_flogs) -+ { -+ query = pstrcat (cmd->tmp_pool, g.sql_flogs, " = ", g.sql_flogs, -+ " + 1", NULL); -+ modsql_queryuser (cmd, g.user, query, TRUE); -+ } -+ -+ /* Autononpersistence: disconnect now if no other feature is being used. */ -+ if (!g.sql_fstor && !g.sql_fcdir && !g.sql_hittable) -+ modsql_close (cmd); -+ return DECLINED (cmd); -+} -+ -+MODRET -+log_cmd_cwd (cmd_rec * cmd) -+{ -+ if (g.sql_fcdir) -+ { -+ char *query = pstrcat (cmd->tmp_pool, g.sql_fcdir, " = '", -+ session.cwd, "'", NULL); -+ modsql_queryuser (cmd, g.user, query, TRUE); -+ } -+ return DECLINED (cmd); -+} -+ -+static cmdtable sqlpw_cmdtab[] = { -+/* *INDENT-OFF* */ -+ -+ { PRE_CMD, C_QUIT, G_NONE, pre_cmd_quit, FALSE, FALSE }, -+ { CMD, C_USER, G_NONE, cmd_user, FALSE, FALSE }, -+ { CMD, C_PASS, G_NONE, cmd_pass, FALSE, FALSE }, -+ { POST_CMD, C_PASS, G_NONE, post_cmd_pass, FALSE, FALSE }, -+ { POST_CMD, C_STOR, G_NONE, post_cmd_stor, FALSE, FALSE }, -+ { POST_CMD, C_RETR, G_NONE, post_cmd_retr, FALSE, FALSE }, -+ { CMD, C_RETR, G_NONE, cmd_retr, FALSE, FALSE }, -+ { LOG_CMD, C_PASS, G_NONE, log_cmd_pass, FALSE, FALSE }, -+ { LOG_CMD, C_CWD, G_NONE, log_cmd_cwd, FALSE, FALSE }, -+ { LOG_CMD, C_CDUP, G_NONE, log_cmd_cwd, FALSE, FALSE }, -+ -+ { 0, NULL } -+ -+/* *INDENT-ON* */ -+}; -+ -+/* **************************************************************** */ -+ -+MODRET -+set_sqlloghosts (cmd_rec * cmd) -+{ -+ int b; -+ -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ switch (cmd->argc - 1) -+ { -+ default: -+ CONF_ERROR (cmd, "requires a boolean or 3 field names: " -+ "fhost faddr ftime"); -+ case 1: -+ if ((b = get_boolean (cmd, 1)) == -1) -+ CONF_ERROR (cmd, "requires a boolean or 3 field names: " -+ "fhost faddr ftime"); -+ if (b) -+ add_config_param_str ("SQLLogHosts", 3, "fhost", "faddr", "ftime"); -+ break; -+ -+ case 3: -+ add_config_param_str ("SQLLogHosts", 3, -+ (void *) cmd->argv[1], (void *) cmd->argv[2], -+ (void *) cmd->argv[3]); -+ } -+ return HANDLED (cmd); -+} -+ -+MODRET -+set_sqllogstats (cmd_rec * cmd) -+{ -+ int b; -+ -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ switch (cmd->argc - 1) -+ { -+ default: -+ CONF_ERROR (cmd, "requires a boolean or 4 field names: " -+ "fstor fretr bstor bretr"); -+ case 1: -+ if ((b = get_boolean (cmd, 1)) == -1) -+ CONF_ERROR (cmd, "requires a boolean or 4 field names: " -+ "fstor fretr bstor bretr"); -+ if (b) -+ add_config_param_str ("SQLLogStats", 4, -+ "fstor", "fretr", "bstor", "bretr"); -+ break; -+ -+ case 4: -+ add_config_param_str ("SQLLogStats", 4, -+ (void *) cmd->argv[1], (void *) cmd->argv[2], -+ (void *) cmd->argv[3], (void *) cmd->argv[4]); -+ } -+ return HANDLED (cmd); -+} -+ -+MODRET -+set_sqlloghits (cmd_rec * cmd) -+{ -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ switch (cmd->argc - 1) -+ { -+ default: -+ CONF_ERROR (cmd, "requires a table or table plus 3 fields: " -+ "[table] filename count dir"); -+ case 1: -+ add_config_param_str ("SQLLogHits", 4, (void *) cmd->argv[1], -+ "filename", "count", ""); -+ break; -+ case 3: -+ add_config_param_str ("SQLLogHits", 4, -+ (void *) cmd->argv[1], (void *) cmd->argv[2], -+ (void *) cmd->argv[3], ""); -+ -+ case 4: -+ add_config_param_str ("SQLLogHits", 4, -+ (void *) cmd->argv[1], (void *) cmd->argv[2], -+ (void *) cmd->argv[3], (void *) cmd->argv[4]); -+ } -+ return HANDLED (cmd); -+} -+ -+MODRET -+set_sqllogdirs (cmd_rec * cmd) -+{ -+ int b; -+ -+ CHECK_ARGS (cmd, 1); -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ if ((b = get_boolean (cmd, 1)) == -1) -+ add_config_param_str ("SQLLogDirs", 1, (void *) cmd->argv[1]); -+ else if (b) -+ add_config_param_str ("SQLLogDirs", 1, "fcdir"); -+ return HANDLED (cmd); -+} -+ -+MODRET -+set_sqlratios (cmd_rec * cmd) -+{ -+ int b; -+ -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ switch (cmd->argc - 1) -+ { -+ default: -+ CONF_ERROR (cmd, "requires a boolean or 4 field names: " -+ "frate fcred brate bcred"); -+ case 1: -+ if ((b = get_boolean (cmd, 1)) == -1) -+ CONF_ERROR (cmd, "requires a boolean or 4 field names: " -+ "frate fcred brate bcred"); -+ if (b) -+ add_config_param_str ("SQLRatios", 4, -+ "frate", "fcred", "brate", "bcred"); -+ break; -+ -+ case 4: -+ add_config_param_str ("SQLRatios", 4, -+ (void *) cmd->argv[1], (void *) cmd->argv[2], -+ (void *) cmd->argv[3], (void *) cmd->argv[4]); -+ } -+ return HANDLED (cmd); -+} -+ -+MODRET -+set_sqlempty (cmd_rec * cmd) -+{ -+ int b; -+ config_rec *c; -+ -+ CHECK_ARGS (cmd, 1); -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ -+ if ((b = get_boolean (cmd, 1)) == -1) -+ { -+ if (!strcasecmp (cmd->argv[1], "set")) -+ b = 2; -+ else -+ CONF_ERROR (cmd, "requires 'set' or a boolean value"); -+ } -+ c = add_config_param (cmd->argv[0], 1, (void *) b); -+ c->flags |= CF_MERGEDOWN; -+ return HANDLED (cmd); -+} -+ -+MODRET -+add_globalstr (cmd_rec * cmd) -+{ -+ CHECK_ARGS (cmd, 1); -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ add_config_param_str (cmd->argv[0], 1, (void *) cmd->argv[1]); -+ return HANDLED (cmd); -+} -+ -+MODRET -+add_virtualstr (cmd_rec * cmd) -+{ -+ CHECK_ARGS (cmd, 1); -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL | CONF_VIRTUAL); -+ add_config_param_str (cmd->argv[0], 1, (void *) cmd->argv[1]); -+ return HANDLED (cmd); -+} -+ -+MODRET -+add_globalbool (cmd_rec * cmd) -+{ -+ int b; -+ config_rec *c; -+ -+ CHECK_ARGS (cmd, 1); -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL); -+ -+ b = get_boolean (cmd, 1); -+ if (b == -1) -+ CONF_ERROR (cmd, "requires a boolean value"); -+ c = add_config_param (cmd->argv[0], 1, (void *) b); -+ c->flags |= CF_MERGEDOWN; -+ return HANDLED (cmd); -+} -+ -+MODRET -+add_virtualbool (cmd_rec * cmd) -+{ -+ int b; -+ config_rec *c; -+ -+ CHECK_ARGS (cmd, 1); -+ CHECK_CONF (cmd, CONF_ROOT | CONF_GLOBAL | CONF_VIRTUAL); -+ -+ b = get_boolean (cmd, 1); -+ if (b == -1) -+ CONF_ERROR (cmd, "requires a boolean value"); -+ c = add_config_param (cmd->argv[0], 1, (void *) b); -+ c->flags |= CF_MERGEDOWN; -+ return HANDLED (cmd); -+} -+ -+static conftable sqlpw_conftab[] = { -+/* *INDENT-OFF* */ -+ -+ { "SQLLogHosts", set_sqlloghosts, NULL }, -+ { "SQLLogStats", set_sqllogstats, NULL }, -+ { "SQLLogHits", set_sqlloghits, NULL }, -+ { "SQLLogDirs", set_sqllogdirs, NULL }, -+ { "SQLRatios", set_sqlratios, NULL }, -+ { "SQLEmptyPasswords", set_sqlempty, NULL }, -+ -+ { "SQLUserTable", add_globalstr, NULL }, -+ { "SQLUsernameField", add_globalstr, NULL }, -+ { "SQLUidField", add_globalstr, NULL }, -+ { "SQLGidField", add_globalstr, NULL }, -+ { "SQLPasswordField", add_globalstr, NULL }, -+ { "SQLHomedirField", add_globalstr, NULL }, -+ { "SQLLoginCountField", add_globalstr, NULL }, -+ { "SQLHomedir", add_globalstr, NULL }, -+ -+ { "SQLKeyField", add_globalstr, NULL }, -+ { "SQLKey", add_virtualstr, NULL }, -+ -+ { "SQLAuthoritative", add_virtualbool, NULL }, -+ { "SQLEncryptedPasswords", add_globalbool, NULL }, -+ { "SQLPlaintextPasswords", add_globalbool, NULL }, -+ -+ { NULL, NULL, NULL } -+ -+/* *INDENT-ON* */ -+}; -+ -+/* **************************************************************** */ -+ -+static int -+sqlpw_child_init () -+{ -+ config_rec *c; -+ MODRET mr; -+ -+ memset (&g, 0, sizeof (g)); -+ g.ok = TRUE; -+ -+ g.sql_passwd = get_param_ptr (CURRENT_CONF, "SQLPasswordField", FALSE); -+ g.sql_flogs = get_param_ptr (CURRENT_CONF, "SQLLoginCountField", FALSE); -+ g.sql_uid = get_param_ptr (CURRENT_CONF, "SQLUidField", FALSE); -+ g.sql_gid = get_param_ptr (CURRENT_CONF, "SQLGidField", FALSE); -+ -+ if (!(g.homedir = get_param_ptr (CURRENT_CONF, "SQLHomedir", FALSE))) -+ { -+ g.sql_fhdir = get_param_ptr (CURRENT_CONF, "SQLHomedirField", FALSE); -+ } -+ if ((c = find_config (CURRENT_CONF, CONF_PARAM, "SQLLogHosts", FALSE))) -+ { -+ g.sql_fhost = c->argv[0]; -+ g.sql_faddr = c->argv[1]; -+ g.sql_ftime = c->argv[2]; -+ } -+ if ((c = find_config (CURRENT_CONF, CONF_PARAM, "SQLLogStats", FALSE))) -+ { -+ g.sql_fstor = c->argv[0]; -+ g.sql_fretr = c->argv[1]; -+ g.sql_bstor = c->argv[2]; -+ g.sql_bretr = c->argv[3]; -+ } -+ if ((c = find_config (CURRENT_CONF, CONF_PARAM, "SQLRatios", FALSE))) -+ { -+ if (!g.sql_fstor) -+ log_pri (LOG_WARNING, "sqlpw: warning: SQLRatios directive " -+ "ineffective without SQLLogStats on"); -+ g.sql_frate = c->argv[0]; -+ g.sql_fcred = c->argv[1]; -+ g.sql_brate = c->argv[2]; -+ g.sql_bcred = c->argv[3]; -+ } -+ if ((c = find_config (CURRENT_CONF, CONF_PARAM, "SQLLogHits", FALSE))) -+ { -+ g.sql_hittable = c->argv[0]; -+ g.sql_filename = c->argv[1]; -+ g.sql_hits = c->argv[2]; -+ g.sql_dir = c->argv[3]; -+ } -+ g.sql_fcdir = get_param_ptr (CURRENT_CONF, "SQLLogDirs", FALSE); -+ -+ g.sql_usertable = get_param_ptr (CURRENT_CONF, "SQLUserTable", -+ FALSE) ? : "users"; -+ g.sql_userid = get_param_ptr (CURRENT_CONF, "SQLUsernameField", -+ FALSE) ? : "userid"; -+ -+ g.sql_keyfld = get_param_ptr (CURRENT_CONF, "SQLKeyField", FALSE); -+ g.sql_key = get_param_ptr (CURRENT_CONF, "SQLKey", FALSE); -+ -+ if (!(g.homedir || g.sql_fhdir) && !g.sql_fhost -+ && !g.sql_fstor && !g.sql_fcdir) -+ return 0; -+ -+ mr = modsql_open (NULL); -+ if (MODRET_ISHANDLED (mr)) -+ { -+ log_debug (DEBUG3, "%s: configured: %s%s%s%s%s%s%s%s", -+ MOD_SQL_VERSION, -+ (g.sql_passwd && (g.homedir || g.sql_fhdir)) -+ ? "auth " : "", -+ g.homedir ? "homedir " : "", -+ g.sql_fhdir ? "homedirfield " : "", -+ g.sql_fhost ? "loghosts " : "", -+ g.sql_fstor ? "logstats " : "", -+ g.sql_frate ? "ratios " : "", -+ g.sql_hittable ? "loghits " : "", -+ g.sql_fcdir ? "logdirs " : ""); -+ } -+ else -+ { -+ memset (&g, 0, sizeof (g)); -+ log_debug (DEBUG3, "%s: unconfigured: no backend could connect", -+ MOD_SQL_VERSION); -+ } -+ return 0; -+} -+ -+static int -+sqlpw_parent_init (void) -+{ -+ /* FIXME: add db init stuff once parent_init() actually works. */ -+ return 0; -+} -+ -+module sqlpw_module = { -+ NULL, NULL, /* Always NULL */ -+ 0x20, /* API Version 2.0 */ -+ "sql", -+ sqlpw_conftab, /* SQL configuration handler table */ -+ sqlpw_cmdtab, /* SQL command handler table */ -+ sqlpw_authtab, /* SQL authentication handler table */ -+ sqlpw_parent_init, /* Pre-fork "parent mode" init */ -+ sqlpw_child_init /* Post-fork "child mode" init */ -+}; |