summaryrefslogtreecommitdiff
path: root/ftp/proftpd-devel/files/patch-bb
diff options
context:
space:
mode:
Diffstat (limited to 'ftp/proftpd-devel/files/patch-bb')
-rw-r--r--ftp/proftpd-devel/files/patch-bb1023
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 */
-+};