/*
-** Copyright 2000-2005 Double Precision, Inc. See COPYING for
+** Copyright 2000-2010 Double Precision, Inc. See COPYING for
** distribution information.
*/
#define err courier_auth_err
-/* siefca@pld.org.pl */
-#define MAX_SUBSTITUTION_LEN 32
-#define SV_BEGIN_MARK "$("
-#define SV_END_MARK ")"
-#define SV_BEGIN_LEN ((sizeof(SV_BEGIN_MARK))-1)
-#define SV_END_LEN ((sizeof(SV_END_MARK))-1)
-
-static const char rcsid[]="$Id: authmysqllib.c,v 1.45 2007/10/07 02:50:45 mrsam Exp $";
-
-/* siefca@pld.org.pl */
-struct var_data {
- const char *name;
- const char *value;
- const size_t size;
- size_t value_length;
- } ;
-
-/* siefca@pld.org.pl */
-typedef int (*parsefunc)(const char *, size_t, void *);
-
static const char *read_env(const char *env)
{
-static char *mysqlauth=0;
-static size_t mysqlauth_size=0;
-size_t i;
-char *p=0;
-int l=strlen(env);
+ return authgetconfig(AUTHMYSQLRC, env);
+}
- if (!mysqlauth)
- {
- FILE *f=fopen(AUTHMYSQLRC, "r");
- struct stat buf;
+static MYSQL mysql_buf;
- if (!f) return (0);
- if (fstat(fileno(f), &buf) ||
- (mysqlauth=malloc(buf.st_size+2)) == 0)
- {
- fclose(f);
- return (0);
- }
- if (fread(mysqlauth, buf.st_size, 1, f) != 1)
- {
- free(mysqlauth);
- mysqlauth=0;
- fclose(f);
- return (0);
- }
- mysqlauth[mysqlauth_size=buf.st_size]=0;
-
- for (i=0; i<mysqlauth_size; i++)
- if (mysqlauth[i] == '\n')
- { /* siefca@pld.org.pl */
- if (!i || mysqlauth[i-1] != '\\')
- {
- mysqlauth[i]='\0';
- }
- else
- {
- mysqlauth[i]=mysqlauth[i-1]= ' ';
- }
- }
- fclose(f);
- }
+static MYSQL *mysql=0;
- for (i=0; i<mysqlauth_size; )
- {
- p=mysqlauth+i;
- if (memcmp(p, env, l) == 0 &&
- isspace((int)(unsigned char)p[l]))
- {
- p += l;
- while (*p && *p != '\n' &&
- isspace((int)(unsigned char)*p))
- ++p;
- break;
- }
+static char *escape_str(const char *c, size_t n)
+{
+ char *buf=malloc(n*2+1);
- while (i < mysqlauth_size)
- if (mysqlauth[i++] == 0) break;
+ if (!buf)
+ {
+ perror("malloc");
+ return NULL;
}
- if (i < mysqlauth_size)
- return (p);
- return (0);
+ mysql_real_escape_string(mysql, buf, c, n);
+ return buf;
}
-static MYSQL mysql_buf;
+static void set_session_options(void)
+/*
+* session variables can be set once for the whole session
+*/
+{
+/* Anton Dobkin <anton@viansib.ru>, VIAN, Ltd. */
+#if MYSQL_VERSION_ID >= 41000
+ const char *character_set=read_env("MYSQL_CHARACTER_SET"), *check;
+
+ if(character_set){
-static MYSQL *mysql=0;
+ /*
+ * This function works like the SET NAMES statement, but also sets
+ * the value of mysql->charset, and thus affects the character set
+ * used by mysql_real_escape_string()
+ *
+ * (return value apparently work the opposite of what is documented)
+ */
+ mysql_set_character_set(mysql, character_set);
+ check = mysql_character_set_name(mysql);
+ if (strcmp(character_set, check) != 0)
+ {
+ err("Cannot set MySQL character set \"%s\", working with \"%s\"\n",
+ character_set, check);
+ }
+ else
+ {
+ DPRINTF("Install of a character set for MySQL: %s", character_set);
+ }
+ }
+#endif /* 41000 */
+}
static int do_connect()
{
mysql=0;
return (-1);
}
+
+ DPRINTF("authmysqllib: connected. Versions: "
+ "header %lu, "
+ "client %lu, "
+ "server %lu",
+ (long)MYSQL_VERSION_ID,
+ mysql_get_client_version(),
+ mysql_get_server_version(mysql));
+
+ set_session_options();
return (0);
}
memset(&ui, 0, sizeof(ui));
}
-static void append_username(char *p, const char *username,
- const char *defdomain)
-{
- for (strcpy(p, username); *p; p++)
- if (*p == '\'' || *p == '"' || *p == '\\' ||
- (int)(unsigned char)*p < ' ')
- *p=' '; /* No funny business */
- if (strchr(username, '@') == 0 && defdomain && *defdomain)
- strcat(strcpy(p, "@"), defdomain);
-}
-
-/* siefca@pld.org.pl */
-static struct var_data *get_variable (const char *begin, size_t len,
- struct var_data *vdt)
-{
-struct var_data *vdp;
-
- if (!begin || !vdt) /* should never happend */
- {
- err("authmysql: critical error while "
- "parsing substitution variable");
- return NULL;
- }
- if (len < 1)
- {
- err("authmysql: unknown empty substitution "
- "variable - aborting");
- return NULL;
- }
- if (len > MAX_SUBSTITUTION_LEN)
- {
- err("authmysql: variable name too long "
- "while parsing substitution. "
- "name begins with "
- SV_BEGIN_MARK
- "%.*s...", MAX_SUBSTITUTION_LEN, begin);
- return NULL;
- }
-
- for (vdp=vdt; vdp->name; vdp++)
- if (vdp->size == len+1 &&
- !strncmp(begin, vdp->name, len))
- {
- if (!vdp->value)
- vdp->value = "";
- if (!vdp->value_length) /* length cache */
- vdp->value_length = strlen (vdp->value);
- return vdp;
- }
-
- err("authmysql: unknown substitution variable "
- SV_BEGIN_MARK
- "%.*s"
- SV_END_MARK
- , (int)len, begin);
-
- return NULL;
-}
-
-/* siefca@pld.org.pl */
-static int ParsePlugin_counter (const char *p, size_t length, void *vp)
-{
- if (!p || !vp || length < 0)
- {
- err("authmysql: bad arguments while counting "
- "query string");
- return -1;
- }
-
- *((size_t *)vp) += length;
-
- return 0;
-}
-
-/* siefca@pld.org.pl */
-static int ParsePlugin_builder (const char *p, size_t length, void *vp)
-{
-char **strptr = (char **) vp;
-
- if (!p || !vp || length < 0)
- {
- err("authmysql: bad arguments while building "
- "query string");
- return -1;
- }
-
- if (!length) return 0;
- memcpy ((void *) *strptr, (void *) p, length);
- *strptr += length;
-
- return 0;
-}
-
-/* siefca@pld.org.pl */
-static int parse_core (const char *source, struct var_data *vdt,
- parsefunc outfn, void *result)
-{
-size_t v_size = 0,
- t_size = 0;
-const char *p, *q, *e,
- *v_begin, *v_end,
- *t_begin, *t_end;
-struct var_data *v_ptr;
-
- if (!source)
- source = "";
- if (!result)
- {
- err("authmysql: no memory allocated for result "
- "while parser core was invoked");
- return -1;
- }
- if (!vdt)
- {
- err("authmysql: no substitution table found "
- "while parser core was invoked");
- return -1;
- }
-
- q = source;
- while ( (p=strstr(q, SV_BEGIN_MARK)) )
- {
- e = strstr (p, SV_END_MARK);
- if (!e)
- {
- err("authmysql: syntax error in "
- "substitution "
- "- no closing symbol found! "
- "bad variable begins with:"
- "%.*s...", MAX_SUBSTITUTION_LEN, p);
- return -1;
- }
-
- /*
- **
- ** __________sometext$(variable_name)_________
- ** | | | |
- ** t_begin' t_end' `v_begin `v_end
- **
- */
-
- v_begin = p+SV_BEGIN_LEN; /* variable field ptr */
- v_end = e-SV_END_LEN; /* variable field last character */
- v_size = v_end-v_begin+1;/* variable field length */
-
- t_begin = q; /* text field ptr */
- t_end = p-1; /* text field last character */
- t_size = t_end-t_begin+1;/* text field length */
-
- /* work on text */
- if ( (outfn (t_begin, t_size, result)) == -1 )
- return -1;
-
- /* work on variable */
- v_ptr = get_variable (v_begin, v_size, vdt);
- if (!v_ptr) return -1;
-
- if ( (outfn (v_ptr->value, v_ptr->value_length, result)) == -1 )
- return -1;
-
- q = e + 1;
- }
-
- /* work on last part of text if any */
- if (*q != '\0')
- if ( (outfn (q, strlen(q), result)) == -1 )
- return -1;
-
- return 0;
-}
-
-/* siefca@pld.org.pl */
-static char *parse_string (const char *source, struct var_data *vdt)
-{
-struct var_data *vdp = NULL;
-char *output_buf = NULL,
- *pass_buf = NULL;
-size_t buf_size = 2;
-
- if (source == NULL || *source == '\0' ||
- vdt == NULL || vdt[0].name == NULL)
- {
- err("authmysql: source clause is empty "
- "- this is critical error");
- return NULL;
- }
-
- /* zero var_data length cache - important! */
- for (vdp=vdt; vdp->name; vdp++)
- vdp->value_length = 0;
-
-
- /* phase 1 - count and validate string */
- if ( (parse_core (source, vdt, &ParsePlugin_counter, &buf_size)) != 0)
- return NULL;
-
- /* phase 2 - allocate memory */
- output_buf = malloc (buf_size);
- if (!output_buf)
- {
- perror ("malloc");
- return NULL;
- }
- pass_buf = output_buf;
-
- /* phase 3 - build the output string */
- if ( (parse_core (source, vdt, &ParsePlugin_builder, &pass_buf)) != 0)
- {
- free (output_buf);
- return NULL;
- }
- *pass_buf = '\0';
-
- return output_buf;
-}
-
-/* siefca@pld.org.pl */
-static const char *get_localpart (const char *username)
-{
-size_t lbuf = 0;
-const char *l_end, *p;
-char *q;
-static char localpart_buf[130];
-
- if (!username || *username == '\0') return NULL;
-
- p = strchr(username,'@');
- if (p)
- {
- if ((p-username) > 128)
- return NULL;
- l_end = p;
- }
- else
- {
- if ((lbuf = strlen(username)) > 128)
- return NULL;
- l_end = username + lbuf;
- }
-
- p=username;
- q=localpart_buf;
-
- while (*p && p != l_end)
- if (*p == '\"' || *p == '\\' ||
- *p == '\'' || (int)(unsigned char)*p < ' ')
- p++;
- else
- *q++ = *p++;
-
- *q = '\0';
- return localpart_buf;
-}
-
-/* siefca@pld.org.pl */
-static const char *get_domain (const char *username, const char *defdomain)
-{
-static char domain_buf[260];
-const char *p;
-char *q;
-
- if (!username || *username == '\0') return NULL;
- p = strchr(username,'@');
-
- if (!p || *(p+1) == '\0')
- {
- if (defdomain && *defdomain)
- return defdomain;
- else
- return NULL;
- }
-
- p++;
- if ((strlen(p)) > 256)
- return NULL;
-
- q = domain_buf;
- while (*p)
- if (*p == '\"' || *p == '\\' ||
- *p == '\'' || (int)(unsigned char)*p < ' ')
- p++;
- else
- *q++ = *p++;
-
- *q = '\0';
- return domain_buf;
-}
-
-/* siefca@pld.org.pl */
-
-static const char *validateMyPassword (const char *password)
-{
-static char pass_buf[2][540]; /* Use two buffers, see parse_chpass_clause */
-static int next_pass=0;
-const char *p;
-char *q, *endq;
-
- if (!password || *password == '\0' || (strlen(password)) > 256)
- return NULL;
-
- next_pass= 1-next_pass;
-
- p = password;
- q = pass_buf[next_pass];
- endq = q + sizeof pass_buf[next_pass];
-
- while (*p && q < endq)
- {
- if (*p == '\"' || *p == '\\' || *p == '\'')
- *q++ = '\\';
- *q++ = *p++;
- }
-
- if (q >= endq)
- return NULL;
-
- *q = '\0';
- return pass_buf[next_pass];
-}
-
-/* siefca@pld.org.pl */
-static char *parse_select_clause (const char *clause, const char *username,
- const char *defdomain,
- const char *service)
-{
-static struct var_data vd[]={
- {"local_part", NULL, sizeof("local_part"), 0},
- {"domain", NULL, sizeof("domain"), 0},
- {"service", NULL, sizeof("service"), 0},
- {NULL, NULL, 0, 0}};
-
- if (clause == NULL || *clause == '\0' ||
- !username || *username == '\0')
- return NULL;
-
- vd[0].value = get_localpart (username);
- vd[1].value = get_domain (username, defdomain);
- if (!vd[0].value || !vd[1].value)
- return NULL;
- vd[2].value = service;
-
- return (parse_string (clause, vd));
-}
-
-/* siefca@pld.org.pl */
-static char *parse_chpass_clause (const char *clause, const char *username,
- const char *defdomain, const char *newpass,
- const char *newpass_crypt)
-{
-static struct var_data vd[]={
- {"local_part", NULL, sizeof("local_part"), 0},
- {"domain", NULL, sizeof("domain"), 0},
- {"newpass", NULL, sizeof("newpass"), 0},
- {"newpass_crypt", NULL, sizeof("newpass_crypt"), 0},
- {NULL, NULL, 0, 0}};
-
- if (clause == NULL || *clause == '\0' ||
- !username || *username == '\0' ||
- !newpass || *newpass == '\0' ||
- !newpass_crypt || *newpass_crypt == '\0') return NULL;
-
- vd[0].value = get_localpart (username);
- vd[1].value = get_domain (username, defdomain);
- vd[2].value = validateMyPassword (newpass);
- vd[3].value = validateMyPassword (newpass_crypt);
-
- if (!vd[0].value || !vd[1].value ||
- !vd[2].value || !vd[3].value) return NULL;
-
- return (parse_string (clause, vd));
-}
-
struct authmysqluserinfo *auth_mysql_getuserinfo(const char *username,
const char *service)
{
const char *defdomain =NULL;
-char *querybuf, *p;
+char *querybuf;
MYSQL_ROW row;
MYSQL_RES *result;
int num_fields;
const char *select_clause; /* siefca@pld.org.pl */
-static const char query[]=
- "SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = \"";
+#define DEFAULT_SELECT_QUERY "SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = '%s%s%s' %s%s%s", \
+ login_field, crypt_field, clear_field, uid_field,\
+ gid_field, home_field, maildir_field, quota_field,\
+ name_field, options_field, user_table, login_field,\
+ username_escaped,\
+ has_domain || !*defdomain ? "":"@", has_domain ? "":defdomain, \
+ *where_clause ? " AND (":"", where_clause,\
+ *where_clause ? ")":""
if (do_connect()) return (0);
*quota_field,
*options_field,
*where_clause;
+ char *username_escaped;
+ size_t query_size;
+ char dummy_buf[1];
+ int has_domain;
user_table=read_env("MYSQL_USER_TABLE");
where_clause=read_env("MYSQL_WHERE_CLAUSE");
if (!where_clause) where_clause = "";
- querybuf=malloc(sizeof(query) + 100
- + 2 * strlen(login_field)
- + strlen(crypt_field)
- + strlen(clear_field)
- + strlen(uid_field) + strlen(gid_field)
- + strlen(home_field)
- + strlen(maildir_field)
- + strlen(quota_field)
- + strlen(name_field)
- + strlen(options_field)
- + strlen(user_table)
- + strlen(username)
- + strlen(defdomain)
- + strlen(where_clause));
+ username_escaped=malloc(strlen(username)*2+1);
- if (!querybuf)
+ if (!username_escaped)
{
perror("malloc");
return (0);
}
- sprintf(querybuf, query, login_field, crypt_field, clear_field,
- uid_field, gid_field, home_field, maildir_field, quota_field,
- name_field, options_field, user_table, login_field);
+ mysql_real_escape_string(mysql, username_escaped,
+ username, strlen(username));
- p=querybuf+strlen(querybuf);
+ has_domain=strchr(username, '@') != NULL;
- append_username(p, username, defdomain);
- strcat(p, "\"");
-
- if (strcmp(where_clause, "")) {
- strcat(p, " AND (");
- strcat(p, where_clause);
- strcat(p, ")");
+ query_size=snprintf(dummy_buf, 1, DEFAULT_SELECT_QUERY);
+
+ querybuf=malloc(query_size+1);
+
+ if (!querybuf)
+ {
+ free(username_escaped);
+ perror("malloc");
+ return(0);
}
+
+ snprintf(querybuf, query_size+1, DEFAULT_SELECT_QUERY);
+ free(username_escaped);
+
}
else
{
/* siefca@pld.org.pl */
- querybuf=parse_select_clause (select_clause, username,
- defdomain, service);
+ querybuf=auth_parse_select_clause (escape_str,
+ select_clause, username,
+ defdomain, service);
if (!querybuf)
{
DPRINTF("parse_select_clause failed (DEFAULT_DOMAIN not set?)");
}
}
-/* Anton Dobkin <anton@viansib.ru>, VIAN, Ltd. */
-#if MYSQL_VERSION_ID >= 41000
- const char *character_set=read_env("MYSQL_CHARACTER_SET");
-
- if(character_set){
-
- char *character_set_buf;
-
- character_set_buf=malloc(strlen(character_set)+11);
-
- if (!character_set_buf)
- {
- perror("malloc");
- return (0);
- }
-
- strcpy(character_set_buf, "SET NAMES ");
- strcat(character_set_buf, character_set);
-
- DPRINTF("Install of a character set for MySQL. SQL query: SET NAMES %s", character_set);
-
- if(mysql_query (mysql, character_set_buf))
- {
- err("Install of a character set for MySQL is failed: %s MYSQL_CHARACTER_SET: may be invalid character set", mysql_error(mysql));
- auth_mysql_cleanup();
-
- if (do_connect())
- {
- free(character_set_buf);
- return (0);
- }
- }
-
- free(character_set_buf);
- }
-#endif
-
DPRINTF("SQL query: %s", querybuf);
if (mysql_query (mysql, querybuf))
{
const char *oldpass)
{
char *newpass_crypt;
- const char *p;
- int l;
char *sql_buf;
- const char *comma;
int rc=0;
+ char *clear_escaped;
+ char *crypt_escaped;
+
const char *clear_field =NULL,
*crypt_field =NULL,
*defdomain =NULL,
*login_field =NULL,
*chpass_clause =NULL; /* siefca@pld.org.pl */
- if (!mysql)
- return (-1);
-
+ if (do_connect()) return (-1);
if (!(newpass_crypt=authcryptpasswd(pass, oldpass)))
return (-1);
- for (l=0, p=pass; *p; p++)
+ clear_escaped=malloc(strlen(pass)*2+1);
+
+ if (!clear_escaped)
{
- if ((int)(unsigned char)*p < ' ')
- {
- free(newpass_crypt);
- return (-1);
- }
- if (*p == '"' || *p == '\\')
- ++l;
- ++l;
+ perror("malloc");
+ free(newpass_crypt);
+ return -1;
}
+ crypt_escaped=malloc(strlen(newpass_crypt)*2+1);
+
+ if (!crypt_escaped)
+ {
+ perror("malloc");
+ free(clear_escaped);
+ free(newpass_crypt);
+ return -1;
+ }
+
+ mysql_real_escape_string(mysql, clear_escaped, pass, strlen(pass));
+ mysql_real_escape_string(mysql, crypt_escaped,
+ newpass_crypt, strlen(newpass_crypt));
+
/* siefca@pld.org.pl */
chpass_clause=read_env("MYSQL_CHPASS_CLAUSE");
defdomain=read_env("DEFAULT_DOMAIN");
user_table=read_env("MYSQL_USER_TABLE");
if (!chpass_clause)
{
+ int has_domain=strchr(user, '@') != NULL;
+ char *username_escaped;
+ char dummy_buf[1];
+ size_t sql_buf_size;
+
+ username_escaped=malloc(strlen(user)*2+1);
+
+ if (!username_escaped)
+ {
+ perror("malloc");
+ free(clear_escaped);
+ free(crypt_escaped);
+ free(newpass_crypt);
+ return -1;
+ }
+
+ mysql_real_escape_string(mysql, username_escaped,
+ user, strlen(user));
+
login_field = read_env("MYSQL_LOGIN_FIELD");
if (!login_field) login_field = "id";
crypt_field=read_env("MYSQL_CRYPT_PWFIELD");
clear_field=read_env("MYSQL_CLEAR_PWFIELD");
where_clause=read_env("MYSQL_WHERE_CLAUSE");
- sql_buf=malloc(strlen(crypt_field ? crypt_field:"")
- + strlen(clear_field ? clear_field:"")
- + strlen(defdomain ? defdomain:"")
- + strlen(login_field) + l + strlen(newpass_crypt)
- + strlen(user_table)
- + strlen(where_clause ? where_clause:"")
- + 200);
- }
- else
- {
- sql_buf=parse_chpass_clause(chpass_clause,
- user,
- defdomain,
- pass,
- newpass_crypt);
- }
-
- if (!sql_buf)
- {
- free(newpass_crypt);
- return (-1);
- }
+ if (!where_clause)
+ where_clause="";
- if (!chpass_clause) /*siefca@pld.org.pl */
- {
- sprintf(sql_buf, "UPDATE %s SET", user_table);
+ if (!crypt_field)
+ crypt_field="";
- comma="";
+ if (!clear_field)
+ clear_field="";
- if (clear_field && *clear_field)
- {
- char *q;
+ if (!defdomain)
+ defdomain="";
- strcat(strcat(strcat(sql_buf, " "), clear_field),
- "=\"");
+#define DEFAULT_SETPASS_UPDATE \
+ "UPDATE %s SET %s%s%s%s %s %s%s%s%s WHERE %s='%s%s%s' %s%s%s", \
+ user_table, \
+ *clear_field ? clear_field:"", \
+ *clear_field ? "='":"", \
+ *clear_field ? clear_escaped:"", \
+ *clear_field ? "'":"", \
+ \
+ *clear_field && *crypt_field ? ",":"", \
+ \
+ *crypt_field ? crypt_field:"", \
+ *crypt_field ? "='":"", \
+ *crypt_field ? crypt_escaped:"", \
+ *crypt_field ? "'":"", \
+ login_field, \
+ username_escaped, \
+ has_domain || !*defdomain ? "":"@", \
+ has_domain ? "":defdomain, \
+ *where_clause ? " AND (":"", where_clause, \
+ *where_clause ? ")":""
- q=sql_buf+strlen(sql_buf);
- while (*pass)
- {
- if (*pass == '"' || *pass == '\\')
- *q++= '\\';
- *q++ = *pass++;
- }
- strcpy(q, "\"");
- comma=", ";
- }
-
- if (crypt_field && *crypt_field)
- {
- strcat(strcat(strcat(strcat(strcat(strcat(sql_buf, comma),
- " "),
- crypt_field),
- "=\""),
- newpass_crypt),
- "\"");
- }
- free(newpass_crypt);
- strcat(strcat(strcat(sql_buf, " WHERE "),
- login_field),
- "=\"");
+ sql_buf_size=snprintf(dummy_buf, 1, DEFAULT_SETPASS_UPDATE);
- append_username(sql_buf+strlen(sql_buf), user, defdomain);
+ sql_buf=malloc(sql_buf_size+1);
- strcat(sql_buf, "\"");
+ if (sql_buf)
+ snprintf(sql_buf, sql_buf_size+1,
+ DEFAULT_SETPASS_UPDATE);
- if (where_clause && *where_clause)
- {
- strcat(sql_buf, " AND (");
- strcat(sql_buf, where_clause);
- strcat(sql_buf, ")");
- }
-
+ free(username_escaped);
}
else
{
- free(newpass_crypt);
+ sql_buf=auth_parse_chpass_clause(escape_str,
+ chpass_clause,
+ user,
+ defdomain,
+ clear_escaped,
+ crypt_escaped);
}
-
+
+ free(clear_escaped);
+ free(crypt_escaped);
+ free(newpass_crypt);
if (courier_authdebug_login_level >= 2)
{
void *void_arg)
{
const char *defdomain, *select_clause;
- char *querybuf, *p;
+ char *querybuf;
MYSQL_ROW row;
MYSQL_RES *result;
- static const char query[]=
- "SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE 1=1";
-
- if (do_connect()) return;
+ if (do_connect())
+ {
+ (*cb_func)(NULL, 0, 0, NULL, NULL, NULL, void_arg);
+ return;
+ }
initui();
*maildir_field,
*options_field,
*where_clause;
+ char dummy_buf[1];
+ size_t query_len;
user_table=read_env("MYSQL_USER_TABLE");
where_clause=read_env("MYSQL_WHERE_CLAUSE");
if (!where_clause) where_clause = "";
- querybuf=malloc(sizeof(query) + 100
- + strlen(login_field)
- + strlen(uid_field) + strlen(gid_field)
- + strlen(home_field)
- + strlen(maildir_field)
- + strlen(options_field)
- + strlen(user_table)
- + strlen(where_clause));
+
+#define DEFAULT_ENUMERATE_QUERY \
+ "SELECT %s, %s, %s, %s, %s, %s FROM %s %s%s",\
+ login_field, uid_field, gid_field, \
+ home_field, maildir_field, \
+ options_field, user_table, \
+ *where_clause ? " WHERE ":"", \
+ where_clause
+
+ query_len=snprintf(dummy_buf, 1, DEFAULT_ENUMERATE_QUERY);
+
+ querybuf=malloc(query_len+1);
if (!querybuf)
{
return;
}
- sprintf(querybuf, query, login_field,
- uid_field, gid_field, home_field, maildir_field,
- options_field, user_table);
-
- p=querybuf+strlen(querybuf);
-
- if (strcmp(where_clause, "")) {
- strcat(p, " AND (");
- strcat(p, where_clause);
- strcat(p, ")");
- }
+ snprintf(querybuf, query_len+1, DEFAULT_ENUMERATE_QUERY);
}
else
{
/* siefca@pld.org.pl */
- querybuf=parse_select_clause (select_clause, "*",
- defdomain, "enumerate");
+ querybuf=auth_parse_select_clause (escape_str,
+ select_clause, "*",
+ defdomain, "enumerate");
if (!querybuf)
{
DPRINTF("authmysql: parse_select_clause failed");
while ((row = mysql_fetch_row (result)) != NULL)
{
if(!row[0] || !row[0][0]
- || !row[1] || !row[1][0]
- || !row[2] || !row[2][0]
- || !row[3] || !row[3][0])
+ || !row[1] || !row[1][0]
+ || !row[2] || !row[2][0]
+ || !row[3] || !row[3][0])
{
continue;
}