+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