-diff -ur courier-imap-1.3.12.orig/authlib/authmysqllib.c courier-imap-1.3.12/authlib/authmysqllib.c
+diff -Nur courier-imap-1.3.12.orig/authlib/README.myownquery courier-imap-1.3.12/authlib/README.myownquery
+--- courier-imap-1.3.12.orig/authlib/README.myownquery Thu Jan 1 01:00:00 1970
++++ courier-imap-1.3.12/authlib/README.myownquery Fri Dec 28 01:25:14 2001
+@@ -0,0 +1,605 @@
++
++
++
++
++ Developer Notes for courier-imap-myownquery.patch
++
++
++
++
++ document version: 1.02
++ author: Pawel Wilk
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++0 What's that?
++
++1 Modifications overview
++
++2 Definitions
++
++3 New data types
++ 3.1 struct var_data
++ 3.2 typedef size_t (*parsefunc)
++
++4 New functions
++ 4.1 parse_core
++ 4.2 ParsePlugin_variable_len
++ 4.3 ParsePlugin_value_len
++ 4.4 ParsePlugin_validate
++ 4.5 ParsePlugin_build
++ 4.6 get_var_value
++ 4.7 parse_string
++ 4.8 validate_password
++ 4.9 get_localpart
++ 4.10 get_domain
++ 4.11 parse_select_clause
++ 4.12 parse_chpass_clause
++
++5 Ideas and TODO
++
++
++
++
++
++
++ *-----------------------
++ 0 What's that?
++ *-----------------------
++
++Courier-imap-myownquery.patch allows administrator to set own MySQL queries
++used by authdaemon to authenticate user (including fetchig credentials) and to
++change user's password. It allows to construct SELECT or UPDATE clause in the
++configuration file (authmysqlrc) by adding two new configuration variables:
++MYSQL_SELECT_CLAUSE and MYSQL_CHPASS_CLAUSE. It may be useful in the mail
++environments where there is such a need to have different database structure
++and/or tables scheme than expected by authmysql module.
++
++It also implements a small parsing engine for substitution variables which
++may appear in the clauses and are used to put informations like username
++or domain into the right place of a query.
++
++This patch was created using `diff -Nur` on courier-imap-1.3.12 source.
++
++
++
++
++
++ *-----------------------
++ 1 Modifications overview
++ *-----------------------
++
++Modified files: authmysqllib.c authmysqlrc
++
++Each modified set of instructions is marked by my e-mail address:
++siefca@pld.org.pl
++
++Changes in the current source code are related to:
++
++- sections where the queries are constructed
++ (including memory allocation for the buffers)
++
++ when MYSQL_SELECT_CLAUSE or MYSQL_CHPASS_CLAUSE is
++ used then the query goes through the parsing functions
++ passing over current memory allocation and query construction
++ subroutines
++
++- section where the configuration file is read
++
++ i've had to modify read_env() function to allow line breaks
++ - now each sequence of the backslash as a first character and
++ newline as the second is replaced by two whitespaces while
++ putting into the buffer
++
++- sections where the query is constructed
++
++ selection is made, depending on configuration variables which
++ are set or not - if own query is used
++
++
++
++
++
++ *-----------------------
++ 2 Definitions
++ *-----------------------
++
++#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)
++
++These definitions allows to change substitution marks in an easy way.
++SV_BEGIN_MARK refers to sequence of characters treated as a prefix of
++each substitution variable and SV_END_MARK refers to string which is
++a closing suffix. If the expected substitution variable is called
++'local_part' (without apostrophes) then '$(local_part)' is a valid
++string representation for SV_BEGIN_MARK set to "$(" and SV_END_MARK to ")".
++
++The last two definitions are just for code simplification.
++
++
++
++
++
++
++ *-----------------------
++ 3 New data types
++ *-----------------------
++
++This section describes new data type definitions and variables.
++
++3.1 struct var_data
++
++struct var_data {
++ const char *name;
++ const char *value;
++ const size_t size;
++ size_t value_length;
++ } ;
++
++This structure holds information needed by parsing routines.
++Using var_data array you may specify a set of string substitutions
++which should be done while parsing a query. Last element in array
++should have all fields set to zero (null).
++
++name field - should contain substituted variable name
++value - should contain string which replaces it
++size - should contain string size including the last zero byte ('\0')
++value_length - should be set to zero - it is used as a value size cache
++
++
++explanation: size is used to increase speed of calculation proccess
++ value_length is used to cache length of a value during the
++ parsing subroutines - it helps when substitution variable
++ occures more than once within the query
++
++Example:
++
++struct var_data vd[] = {
++ {"some", "replacement", sizeof("some"), 0},
++ {"anotha", NULL, sizeof("anotha"), 0},
++ {NULL, NULL, 0, 0}
++};
++
++In this example we've declared that $(some) in the query should be
++replaced by 'replacement' text, and replacement for $(anotha) will
++be defined in the code before passing on the array pointer to
++the paring function.
++
++
++3.2 typedef size_t (*parsefunc)
++
++typedef size_t (*parsefunc)(const char *, size_t, struct var_data *);
++
++This type definition refers to the function pointer, which is used
++to pass plugin functions into the core parsing subroutine. This definition
++is included to simplify the declaration of plugin functions.
++
++
++
++
++
++ *-----------------------
++ 4 New functions
++ *-----------------------
++
++This section describes added functions.
++
++4.1 parse_core
++
++NAME
++
++ parse_core
++
++SYNOPSIS
++ static size_t parse_core (const char *source, struct var_data *vd,
++ parsefunc outfn, char *result);
++
++DESCRIPTION
++
++ This is the parsing routine for query strings containing the
++ substitution variables. It reads the string pointed with source
++ and tries to catch a valid substitution variables from the
++ var_data structure pointed with vd. For each found substitution
++ variable it calls outfn function using function pointer of
++ parsefunc type, which accords to:
++
++ size_t (*parsefunc)(const char *variable_name,
++ size_t string_size,
++ struct var_data *vd);
++
++ variable name is a pointer to the string where the found
++ substitution variable was found. string_size is a length
++ of that variable name (plugin function needs to know how
++ much characters of a string have to be read). vd structure
++ pointer points to the first element of an array containing
++ replacement instructions.
++
++ Example:
++
++ Example string "$(local_part) AND $(domain)" will cause the
++ outfn() to be called twice. First time when variable_name
++ points the third character and string_size is set to 10.
++ Second time variable_name will point 'd' character (first
++ letter of the second substitution variable) and string_size
++ will be set to 6. The vd argument is simply passed as-is.
++
++WORKING MODES
++
++ This function has two working modes: counting mode and building
++ mode.
++
++ When the function is in counting mode is summarizes return
++ values of each subsequent outfn() calls, and then returns the
++ calculated value as a result. Remember, that each outfn() call
++ refers to one substitution variable found in the source string.
++
++ When the function is in building mode it produces output string
++ (using get_var_value() function) and places it into the buffer
++ pointed by result argument.
++
++ Function determines the working mode looking at its last
++ argument (result). If it is set to NULL then function assumes
++ that we are expecting it to work in the counting mode. If it
++ points to the existing memory area then the output is produced.
++
++ Note that in building mode outfn argument has no meaning. It implies
++ the fact, that the ParsePlugin_build function pointer is always set
++ to NULL.
++
++RETURN VALUE
++
++ This function returns -1 when an error has occured. If the function
++ was called in the counting mode it returns summarized return values
++ of outfn() called for each found substiution variable. In the building
++ mode it returns 0 on success.
++
++
++4.2 ParsePlugin_variable_len
++
++NAME
++
++ ParsePlugin_variable_len
++
++SYNOPSIS
++
++ size_t ParsePlugin_variable_len (const char *begin, size_t len,
++ struct var_data *vd);
++
++DESCRIPTION
++
++ This is parsing plugin function. It returns the length of
++ string of the passed substitution variable name, including
++ the special symbols length.
++
++WORKING MODE
++
++ Destinated to be called in parse_core()'s counting mode.
++
++RETURN VALUE
++
++ This function returns the variable size or -1 if an error
++ has occured.
++
++4.3 ParsePlugin_value_len
++
++NAME
++
++ ParsePlugin_value_len
++
++SYNOPSIS
++
++ size_t ParsePlugin_value_len (const char *begin, size_t len,
++ struct var_data *vd);
++
++DESCRIPTION
++
++ This is parsing plugin function. It returns the length of
++ string of the value found while looking at vd array for the
++ substitution variable name pointed by the begin argument and
++ length specified by len argument.
++
++ The function updates a simple length cache inside of the
++ proper element of array containing var_data structure elements.
++ It checks the value_length field and calculates string length for the
++ variable's value if it founds 0 there, and stores the result then.
++ If it founds non-zero value it uses that value instead of
++ recalculating.
++
++WORKING MODE
++
++ Destinated to be called in parse_core()'s counting mode.
++
++RETURN VALUE
++
++ This function returns the variable's value size or -1 if an error
++ has occured.
++
++
++4.4 ParsePlugin_validate
++
++NAME
++
++ ParsePlugin_validate
++
++SYNOPSIS
++
++ size_t ParsePlugin_validate (const char *begin, size_t len,
++ struct var_data *vd);
++
++DESCRIPTION
++
++ This is parsing plugin function. It checks whether the
++ substituion variable identified by the name passed by
++ the begin pointer and len bytes of length is a correct,
++ existing variable with a proper length and a defined value.
++
++WORKING MODE
++
++ Destinated to be called in parse_core()'s counting mode.
++
++RETURN VALUE
++
++ This function returns 0 on success or -1 if an error
++ has occured or specified variable is invalid or unknown.
++
++
++4.5 ParsePlugin_build
++
++NAME
++
++ ParsePlugin_build
++
++SYNOPSIS
++
++ typedef size_t (*parsefunc)(const char *, size_t, struct var_data *);
++
++ parsefunc ParsePlugin_build = NULL;
++
++DESCRIPTION
++
++ This is parsing plugin pseudo-function. It is a NULL function pointer.
++ It has only easthetic meaning.
++
++WORKING MODE
++
++ Destinated to be called in parse_core()'s building mode.
++
++RETURN VALUE
++
++ None.
++
++
++4.6 get_var_value
++
++NAME
++
++ get_var_value
++
++SYNOPSIS
++
++ static const char *get_var_value (const char *begin, size_t len,
++ struct var_data *vd);
++
++DESCRIPTION
++
++ This function searches an array pointed by vd and tries to find
++ the substitution variable defined with begin pointer and length
++ of len bytes long.
++
++RETURN VALUE
++
++ This function returns a pointer to the value field of the
++ var_data array entry, which contains value assigned to the
++ substitution variable of a given name. It returns -1 on
++ error or failure.
++
++
++4.7 parse_string
++
++NAME
++ parse_string
++
++SYNOPSIS
++
++ static char *parse_string (const char *source, struct var_data *vd);
++
++DESCRIPTION
++
++ This function parses the string pointed with source according to the
++ replacement instructions set in var_data array, which is passed with
++ its pointer vd. It produces changed string located in newly allocated
++ memory area.
++
++ This function calls parse_core() function repeatedly with
++ various parsing subroutines passed as function pointers:
++
++ Just after the function is called it invokes parse_core() with
++ plugin function set to ParsePlugin_validate to make the source string
++ validation probes against specified set of substitution variables
++ which are expected to be made.
++
++ In the next step it uses parse_core() with ParsePlugin_value_len
++ and then with ParsePlugin_variable_len to obtain the total amount
++ of memory needed for the output string.
++
++ Then it allocates the memory.
++
++ In the last phase the output string is built. parse_core() is
++ used once again with ParsePlugin_build function pointer, which
++ is NULL pointer indeed. The result is keept in the memory area
++ allocated before. In this phase the parse_core() is called in
++ the building mode - pointer to the area is passed by the last
++ argument.
++
++RETURN VALUE
++
++ Function returns pointer to the result buffer or NULL
++ if an error has occured.
++
++WARNINGS
++
++ This function allocates some amount of memory using standard
++ ANSI C routines. Memory allocated by this function should be
++ freed with free().
++
++
++4.8 validate_password
++
++NAME
++ validate_password
++
++SYNOPSIS
++
++ static const char *validate_password (const char *password);
++
++DESCRIPTION
++
++ This function checks whether password string does contain
++ any dangerous characters, which may be used to pass command
++ strings to the database connection stream. If it founds one
++ it replaces it by the backslash character.
++
++RETURN VALUE
++
++ It returns a pointer to the static buffer which contains
++ validated password string or NULL if an error has occured.
++
++
++4.9 get_localpart
++
++NAME
++
++ get_localpart
++
++SYNOPSIS
++
++ static const char *get_localpart (const char *username);
++
++DESCRIPTION
++
++ This function detaches local part of an e-mail address
++ from string pointed with username and puts it to the
++ buffer of the fixed length. All necessary cleaning is
++ made on the result string.
++
++RETURN VALUE
++
++ Pointer to the static buffer containing local part or
++ NULL if there was some error.
++
++
++4.10 get_domain
++
++NAME
++
++ get_domain
++
++SYNOPSIS
++
++ static const char *get_domain (const char *username,
++ const char *defdomain);
++
++DESCRIPTION
++
++ This function detaches domain part of an e-mail address
++ from string pointed with username and puts it to the
++ buffer of the fixed length. All necessary cleaning is
++ made on the result string. If function cannot find domain
++ part in the string the string pointed by defdomain is
++ used instead.
++
++RETURN VALUE
++
++ Pointer to the static buffer containing domain name or
++ NULL if there was some error.
++
++
++4.11 parse_select_clause
++
++NAME
++
++ parse_select_clause
++
++SYNOPSIS
++
++ static char *parse_select_clause (const char *clause,
++ const char *username,
++ const char *defdomain);
++
++DESCRIPTION
++
++ This function is a simple wrapper to the parse_string()
++ function. It parses a query pointed by caluse. username
++ and defdomain strings are used to replace corresponding
++ substitution strings if present in the query: $(local_part)
++ and $(domain).
++
++
++RETURN VALUE
++
++ Same as parse_string().
++
++
++4.12 parse_chpass_clause
++
++NAME
++
++ parse_chpass_clause
++
++SYNOPSIS
++
++ static char *parse_chpass_clause (const char *clause,
++ const char *username,
++ const char *defdomain,
++ const char *newpass,
++ const char *newpass_crypt);
++
++DESCRIPTION
++
++ This function is a simple wrapper to the parse_string()
++ function. It parses a query pointed by caluse. username,
++ defdomain, newpass and newpass_crypt strings are used to
++ replace corresponding substitution strings if present in
++ the query: $(local_part), $(domain), $(newpass),
++ $(newpass_crypt).
++
++RETURN VALUE
++
++ Same as parse_string().
++
++
++
++
++
++ *------------------------
++ 5 Ideas and TODO
++ *-----------------------
++
++- solve problem with fixed buffer length of local part and the domain part
++ strings after split (problem?)
++- allow admin to set a group name instead of numerical group id
++- allow admin to set a username instead of numerical user id
++
++- add clauses:
++
++ - MYSQL_PRESELECT_CLAUSE (query which comes before MYSQL_SELECT_CLAUSE)
++ - MYSQL_POSTSELECT_CLAUSE (query which comes after MYSQL_SELECT_CLAUSE)
++
++
++---------------------------------------------------------------------------
++
+diff -Nur courier-imap-1.3.12.orig/authlib/authmysqllib.c courier-imap-1.3.12/authlib/authmysqllib.c
--- courier-imap-1.3.12.orig/authlib/authmysqllib.c Mon Aug 6 05:12:39 2001
-+++ courier-imap-1.3.12/authlib/authmysqllib.c Wed Dec 26 05:46:05 2001
++++ courier-imap-1.3.12/authlib/authmysqllib.c Fri Dec 28 01:11:49 2001
@@ -3,7 +3,6 @@
** distribution information.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-@@ -20,6 +19,17 @@
+@@ -18,8 +17,25 @@
+ #include "authmysqlrc.h"
+ #include "auth.h"
++/* siefca@pld.org.pl */
++#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$";
+struct var_data {
static const char *read_env(const char *env)
{
static char *mysqlauth=0;
-@@ -51,7 +61,13 @@
+@@ -51,7 +67,13 @@
for (i=0; i<mysqlauth_size; i++)
if (mysqlauth[i] == '\n')
fclose(f);
}
-@@ -199,17 +215,356 @@
+@@ -199,17 +221,384 @@
strcat(strcpy(p, "@"), defdomain);
}
+ }
+
+ fprintf (stderr, "authmysql: unknown substitution variable "
-+ "$(%.*s)\n", len, begin);
++ SV_BEGIN_MARK
++ "%.*s"
++ SV_END_MARK
++ "\n", len, begin);
+
+ return NULL;
+}
+static size_t parse_core (const char *source, struct var_data *vd,
+ parsefunc outfn, char *result)
+{
-+size_t counter = 0,
-+ s = 0,
-+ v_size = 0,
-+ t_size = 0;
++size_t counter = 0,
++ s = 0,
++ v_size = 0,
++ t_size = 0;
+const char *p, *q, *e,
+ *v_begin, *v_end,
+ *t_begin, *t_end,
+ *result = '\0';
+
+ q = source;
-+ while ( (p=strstr(q, "$(")) )
++ while ( (p=strstr(q, SV_BEGIN_MARK)) )
+ {
-+ e = strchr (p, ')');
++ e = strstr (p, SV_END_MARK);
+ if (!e)
+ {
+ fprintf (stderr, "authmysql: syntax error in "
+ "substitution variable "
-+ "- no closing bracket!\n"
++ "- missing: "
++ SV_END_MARK
++ "\n"
+ "authmysql: bad variable begins "
+ "with: %.*s...\n", 20, p);
+ return -1;
+ **
+ */
+
-+ v_begin = p+2; /* variable field ptr */
-+ v_end = e-1; /* variable field last character */
++ 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 */
+size_t ParsePlugin_variable_len (const char *begin, size_t len,
+ struct var_data *vd)
+{
-+ return (len + 3);
++ return (len + SV_BEGIN_LEN + SV_END_LEN);
+}
+
+/* siefca@pld.org.pl */
+ fprintf (stderr, "authmysql: variable name too long "
+ "while parsing substitution\n"
+ "authmysql: name begins with "
-+ "$(%.*s...\n", 32, begin);
++ SV_BEGIN_MARK
++ "%.*s...\n", 32, begin);
+ return -1;
+ }
+
+ return 0;
+
+ fprintf (stderr, "authmysql: unknown substitution variable "
-+ "$(%.*s)\n", len, begin);
++ SV_BEGIN_MARK
++ "%.*s"
++ SV_END_MARK
++ "\n", len, begin);
+ return -1;
+}
+
+/* siefca@pld.org.pl */
+static const char *get_localpart (const char *username)
+{
-+char *p;
-+static char localpart_buf[130];
++size_t lbuf = 0;
++const char *l_end, *p;
++char *q;
++static char localpart_buf[130];
++
++ if (!username || *username == '\0') return NULL;
+
-+ if (!username || *username == '\0') return NULL;
+ p = strchr(username,'@');
+ if (p)
+ {
-+ if (p-username > 128) return NULL;
-+ strncpy (localpart_buf, username, p-username);
++ if ((p-username) > 128)
++ return NULL;
++ l_end = p;
+ }
+ else
+ {
-+ if ((strlen(username)) > 128) return NULL;
-+ strcpy (localpart_buf, username);
++ if ((lbuf = strlen(username)) > 128)
++ return NULL;
++ l_end = username + lbuf;
+ }
+
-+ for (p = localpart_buf; *p; p++)
++ p=username;
++ q=localpart_buf;
++
++ while (*p && p != l_end)
+ if (*p == '\"' || *p == '\\' ||
+ *p == '\'' || (int)(unsigned char)*p < ' ')
-+ *p=' ';
++ p++;
++ else
++ *q++ = *p++;
+
++ *q = '\0';
+ return localpart_buf;
+}
+
+static const char *get_domain (const char *username, const char *defdomain)
+{
+static char domain_buf[260];
-+char *p, *q;
++const char *p;
++char *q;
+
-+ if (!username || *username == '\0') return NULL;
++ if (!username || *username == '\0') return NULL;
+ p = strchr(username,'@');
+
-+ if (p && *(p+1))
-+ {
-+ p++;
-+ if ((strlen(p)) > 256) return NULL;
-+ for (q=domain_buf; *p; p++, q++)
-+ if (*p == '\"' || *p == '\\' ||
-+ *p == '\'' || (int)(unsigned char)*p < ' ')
-+ *p=' ';
-+ else
-+ *q=*p;
-+ *q='\0';
-+ return domain_buf;
-+ }
-+ if (defdomain && *defdomain) return defdomain;
-+
-+ return NULL;
++ 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 *validate_password (const char *password)
+{
+static char pass_buf[260];
+const char *p;
+char *q;
+
-+ if (!password || *password == '\0') return NULL;
++ if (!password || *password == '\0' || (strlen(password)) > 256)
++ return NULL;
+
-+ if ((strlen(password)) > 256) return NULL;
-+ strcpy (pass_buf, password);
-+ for (p=password,q=pass_buf; *p != '\0'; p++, q++)
-+ {
++ p = password;
++ q = pass_buf;
++
++ while (*p)
+ if (*p == '\"' || *p == '\\' || *p == '\'')
+ *q++ = '\\';
-+ *q = *p;
-+ }
++ else
++ *q++ = *p++;
+
+ *q = '\0';
-+
+ return pass_buf;
+}
+
+ {NULL, NULL, 0, 0}};
+
+ if (clause == NULL || *clause == '\0' ||
-+ !username || *username == '\0') return NULL;
++ !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;
++ if (!vd[0].value || !vd[1].value)
++ return NULL;
+
+ return (parse_string (clause, vd));
+}
+ if (clause == NULL || *clause == '\0' ||
+ !username || *username == '\0' ||
+ !newpass || *newpass == '\0' ||
-+ !newpass_crypt || *newpass_crypt == '\0') return NULL;
++ !newpass_crypt || *newpass_crypt == '\0') return NULL;
+
+ vd[0].value = get_localpart (username);
+ vd[1].value = get_domain (username, defdomain);
static const char query[]=
"SELECT %s, %s, %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = \"";
-@@ -232,79 +587,95 @@
+@@ -232,79 +621,95 @@
free(ui.fullname);
memset(&ui, 0, sizeof(ui));
+ crypt_field=read_env("MYSQL_CRYPT_PWFIELD");
+ clear_field=read_env("MYSQL_CLEAR_PWFIELD");
+ name_field=read_env("MYSQL_NAME_FIELD");
-
-- uid_field = read_env("MYSQL_UID_FIELD");
-- if (!uid_field) uid_field = "uid";
++
+ if (!crypt_field && !clear_field)
+ {
+ fprintf(stderr,
+ if (!clear_field) clear_field="\"\"";
+ if (!name_field) name_field="\"\"";
-- gid_field = read_env("MYSQL_GID_FIELD");
-- if (!gid_field) gid_field = "gid";
+- uid_field = read_env("MYSQL_UID_FIELD");
+- if (!uid_field) uid_field = "uid";
+ uid_field = read_env("MYSQL_UID_FIELD");
+ if (!uid_field) uid_field = "uid";
-- login_field = read_env("MYSQL_LOGIN_FIELD");
-- if (!login_field) login_field = "id";
+- gid_field = read_env("MYSQL_GID_FIELD");
+- if (!gid_field) gid_field = "gid";
+ gid_field = read_env("MYSQL_GID_FIELD");
+ if (!gid_field) gid_field = "gid";
-- home_field = read_env("MYSQL_HOME_FIELD");
-- if (!home_field) home_field = "home";
+- login_field = read_env("MYSQL_LOGIN_FIELD");
+- if (!login_field) login_field = "id";
+ login_field = read_env("MYSQL_LOGIN_FIELD");
+ if (!login_field) login_field = "id";
-- maildir_field=read_env("MYSQL_MAILDIR_FIELD");
-- if (!maildir_field) maildir_field="\"\"";
+- home_field = read_env("MYSQL_HOME_FIELD");
+- if (!home_field) home_field = "home";
+ home_field = read_env("MYSQL_HOME_FIELD");
+ if (!home_field) home_field = "home";
-- quota_field=read_env("MYSQL_QUOTA_FIELD");
-- if (!quota_field) quota_field="\"\"";
+- maildir_field=read_env("MYSQL_MAILDIR_FIELD");
+- if (!maildir_field) maildir_field="\"\"";
+ maildir_field=read_env("MYSQL_MAILDIR_FIELD");
+ if (!maildir_field) maildir_field="\"\"";
-- where_clause=read_env("MYSQL_WHERE_CLAUSE");
-- if (!where_clause) where_clause = "";
+- quota_field=read_env("MYSQL_QUOTA_FIELD");
+- if (!quota_field) quota_field="\"\"";
+ quota_field=read_env("MYSQL_QUOTA_FIELD");
+ if (!quota_field) quota_field="\"\"";
-+
+
+- where_clause=read_env("MYSQL_WHERE_CLAUSE");
+- if (!where_clause) where_clause = "";
+ where_clause=read_env("MYSQL_WHERE_CLAUSE");
+ if (!where_clause) where_clause = "";
+ }
+ + strlen(uid_field) + strlen(gid_field) + 2 * strlen(login_field)
+ + strlen(home_field) + strlen(quota_field) + strlen(where_clause)
+ + strlen(name_field));
-
-- sprintf(querybuf, query, login_field, crypt_field, clear_field,
-- uid_field, gid_field, home_field, maildir_field, quota_field,
-- name_field, user_table, login_field);
-- p=querybuf+strlen(querybuf);
++
+ if (!querybuf)
+ {
+ 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, user_table, login_field);
+- p=querybuf+strlen(querybuf);
+ sprintf(querybuf, query, login_field, crypt_field, clear_field,
+ uid_field, gid_field, home_field, maildir_field, quota_field,
+ name_field, user_table, login_field);
-+
-+ p=querybuf+strlen(querybuf);
- append_username(p, username, defdomain);
- strcat(p, "\"");
++ p=querybuf+strlen(querybuf);
++
+ append_username(p, username, defdomain);
+ strcat(p, "\"");
if (mysql_query (mysql, querybuf))
{
/* <o.blasnik@nextra.de> */
-@@ -379,12 +750,13 @@
+@@ -379,12 +784,13 @@
const char *comma;
int rc=0;
if (!mysql)
return (-1);
-@@ -412,21 +784,34 @@
+@@ -412,21 +818,34 @@
++l;
}
if (!sql_buf)
{
-@@ -434,53 +819,57 @@
+@@ -434,53 +853,57 @@
return (-1);
}
if (mysql_query (mysql, sql_buf))
{
-diff -ur courier-imap-1.3.12.orig/authlib/authmysqlrc courier-imap-1.3.12/authlib/authmysqlrc
+diff -Nur courier-imap-1.3.12.orig/authlib/authmysqlrc courier-imap-1.3.12/authlib/authmysqlrc
--- courier-imap-1.3.12.orig/authlib/authmysqlrc Sun Oct 7 18:32:56 2001
-+++ courier-imap-1.3.12/authlib/authmysqlrc Thu Dec 27 03:43:47 2001
++++ courier-imap-1.3.12/authlib/authmysqlrc Fri Dec 28 01:11:49 2001
@@ -141,4 +141,65 @@
#
# MYSQL_WHERE_CLAUSE server='mailhost.example.com'