summaryrefslogtreecommitdiffstats
path: root/sqwebmail/logindomainlist.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /sqwebmail/logindomainlist.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'sqwebmail/logindomainlist.c')
-rw-r--r--sqwebmail/logindomainlist.c715
1 files changed, 715 insertions, 0 deletions
diff --git a/sqwebmail/logindomainlist.c b/sqwebmail/logindomainlist.c
new file mode 100644
index 0000000..050f8d4
--- /dev/null
+++ b/sqwebmail/logindomainlist.c
@@ -0,0 +1,715 @@
+#include "config.h"
+/*
+** Copyright 2003 Double Precision, Inc. See COPYING for
+** distribution information.
+**
+** Original author: Jesse D. Guardiani, wingnet.net
+*/
+
+/*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "logindomainlist.h"
+
+/* LINELEN is the maximum length of a line in the file we are reading. */
+#define LINELEN 500
+#define NUM_WC_EN_MODS 2
+
+/* constants */
+static const int g_delim=':';
+static const int g_wildcard_char='*';
+
+/* array of wildcard enabled modifiers */
+static const char g_wc_en_mods[NUM_WC_EN_MODS][2] = { "@", "-" };
+
+/* --------------------------------------------------------------
+ * Function : mystrsep()
+ * Created : 03/03/03
+ * Author : JDG
+ * Purpose : Emulate the BSD strsep() function.
+ * Notes :
+ * This function is designed to emulate the BSD strsep function
+ * without introducing any doubts that it is a custom
+ * implementation. It's probably quite a bit slower than the
+ * original BSD strsep(), but it'll do for most purposes.
+ * mystrsep's functionality should be nearly identical to the
+ * BSD strsep, except that it takes an int as argument for the
+ * delimiter.
+ * -------------------------------------------------------------- */
+static char *mystrsep( char **stringp, int delim )
+{
+ char *orig_stringp=*stringp;
+
+ /* Make sure we return NULL if we are given NULL */
+ if (*stringp == NULL) return orig_stringp;
+
+ /* Locate first occurance of delim in stringp */
+ *stringp=strchr(*stringp, delim);
+
+ /* If no more delimiters were found, return the last substring */
+ if (*stringp == NULL) return orig_stringp;
+
+ /* Set that first occurance to NUL */
+ **stringp='\0';
+
+ /* move pointer in front of NUL character */
+ ++(*stringp);
+
+ /* Return original value of *stringp */
+ return orig_stringp;
+
+}
+
+
+/* --------------------------------------------------------------
+ * Function : ldl_haswildcard()
+ * Created : 04/08/03
+ * Author : JDG
+ * Purpose : Determine if the NUL terminated stringp contains
+ * the wildcard character specified in wildcard.
+ * Notes : Returns 0 if wildcard doesn't exist in stringp.
+ * Returns 1 if stringp does contain wildcard.
+ * -------------------------------------------------------------- */
+static int ldl_haswildcard( char *stringp, int wildcard)
+{
+ char *wildcardp;
+
+ /* get pointer to wildcard within stringp */
+ wildcardp = strchr(stringp, wildcard);
+
+ if (wildcardp == NULL) return 0;
+
+ return 1;
+}
+
+
+/* --------------------------------------------------------------
+ * Function : ldl_getfields()
+ * Created : 03/04/03
+ * Modified : 04/07/03 by JDG
+ * Author : JDG
+ * Purpose : Retrieve fields from a logindomainlist statement.
+ * Notes : This function is designed to provide a standard
+ * interface to retrieve fields from a logindomainlist
+ * statement line.
+ *
+ * This function should never generate a NULL pointer,
+ * even if a field is empty.
+ * -------------------------------------------------------------- */
+static void ldl_getfields( char *statementp, char *firstfieldp, char *secondfieldp, char *thirdfieldp )
+{
+ int delim=g_delim;
+ char *tempfirst;
+ char *tempsecond;
+ char *tempthird;
+ char *bufp=statementp;
+
+
+ /* get pointers to individual fields from file */
+ tempfirst=mystrsep(&bufp, delim);
+ tempsecond=mystrsep(&bufp, delim);
+ tempthird=mystrsep(&bufp, delim);
+
+ /* fix NULL pointers */
+ if (tempfirst == NULL) tempfirst="";
+ if (tempsecond == NULL) tempsecond="";
+ if (tempthird == NULL) tempthird="";
+
+ /* copy strings */
+ strcpy(firstfieldp, tempfirst);
+ strcpy(secondfieldp, tempsecond);
+ strcpy(thirdfieldp, tempthird);
+}
+
+
+/* --------------------------------------------------------------
+ * Function : ldl_invalidstatement()
+ * Created : 03/04/03
+ * Modified : 04/07/03
+ * Author : JDG
+ * Purpose : Examine line and determine if it is a valid state-
+ * ment.
+ * Notes : This function can be used to filter out comments,
+ * empty lines, and anything else that shouldn't be in
+ * a valid statement line. Returns 1 (one) if
+ * statementp is a comment or other invalid statement.
+ *
+ * Returns zero otherwise.
+ * -------------------------------------------------------------- */
+static int ldl_invalidstatement( char *statementp )
+{
+ const int TRUE = 1;
+ const int FALSE = 0;
+
+ /* comments aren't valid statements */
+ if (statementp[0] == '#') return TRUE;
+
+ /* empty lines aren't valid statements */
+ if (statementp[0] == ' ' ||
+ statementp[0] == '\t' ||
+ statementp[0] == '\n') return TRUE;
+
+ /* extra long lines aren't valid statements either... */
+ if (strlen(statementp) > LINELEN) return TRUE;
+
+ /* might be a valid statement line */
+ return FALSE;
+}
+
+
+/* --------------------------------------------------------------
+ * Function : extract_wildcardvalue()
+ * Created : 04/07/03
+ * Author : JDG
+ * Purpose : compare wildcardedstringp and realstringp. If the
+ * two match, then replace the contents of realstringp
+ * with the contents of the wildcard character in
+ * wildcardedstringp.
+ * Notes : If the substring beforewildcardp appears at the
+ * absolute beginning of realstringp, then
+ * beforewildcardp is deleted from realstring.
+ * If the substring afterwildcardp appears at the
+ * absolute end of realstringp, then afterwildcardp
+ * is deleted from realstringp.
+ *
+ * The string remaining in realstringp represents the
+ * contents of our wildcard character in
+ * wildcardedstringp.
+ *
+ * For example, if:
+ *
+ * wildcardedstringp = my*domain.com
+ * realstringp = myexampledomain.com
+ *
+ * Then extract_wildcardvalue() will replace the
+ * contents of realstringp with the following string:
+ *
+ * example
+ *
+ * If no wildcard character exists in
+ * wildcardedstringp or if wildcardedstringp and
+ * realstringp don't match, extract_wildcardvalue()
+ * will return zero.
+ *
+ * Otherwise, extract_wildcardvalue() returns non
+ * zero.
+ * -------------------------------------------------------------- */
+static int extract_wildcardvalue( char *wildcardedstringp, char *realstringp, int wildcard) {
+ char wildcardedstring[LINELEN]="";
+ char *beforewildcardp;
+ char *afterwildcardp;
+ char *wildcardedstringpp=NULL;
+
+
+ /* Continue only if there is actually a wildcard character in wildcardedstring */
+ if (ldl_haswildcard(wildcardedstringp, wildcard)) {
+ /* Copy argument to buffer so as not to modify the original. */
+ strcpy(wildcardedstring, wildcardedstringp);
+
+ /* create a pointer to a pointer of a copy*/
+ wildcardedstringpp = wildcardedstring;
+
+
+ /* tokenize wildcardstring with '\0's */
+ beforewildcardp=mystrsep(&wildcardedstringpp, wildcard);
+ afterwildcardp=mystrsep(&wildcardedstringpp, wildcard);
+
+
+ if (beforewildcardp != NULL && strcmp(beforewildcardp, "") != 0)
+ {
+ /* If beforewildcardp string exists at the absolute
+ * beginning of realstring */
+ if (strstr(realstringp, beforewildcardp) == realstringp)
+ {
+ char *tmpp=realstringp;
+ char *p;
+
+ /* move pointer to the end of beforewildcardp in
+ * realstring. */
+ tmpp=tmpp + strlen(beforewildcardp);
+
+ /* Now, "delete" beforewildcardp from the very
+ * beginning of realstring. Note that we're not
+ * actually deleting it. We're just copying the
+ * remaining string in realstring from the
+ * location that tmpp points to in realstring.
+ * However, this has the same effect as if we
+ * had somehow "deleted" beforewildcardp from
+ * the beginning of realstring. */
+
+ p=realstringp;
+
+ while ((*p++= *tmpp++) != 0)
+ ;
+ }
+ else
+ {
+ /* if beforewildcardp does not exist at the
+ * beginning of realstringp, return non zero. */
+ return 0;
+ }
+ }
+
+
+ if (afterwildcardp != NULL && strcmp(afterwildcardp, "") != 0)
+ {
+ /* If afterwildcardp exists at the very end of realstring */
+ size_t n=strlen(realstringp);
+ size_t o=strlen(afterwildcardp);
+
+ if (n >= o &&
+ strcmp(realstringp+n-o, afterwildcardp) == 0)
+ {
+ char *tmpp=realstringp;
+
+ /* move temp pointer to the end of the NUL
+ * terminated string in realstringp, then
+ * backspace the length of afterwildcardp
+ * and write a NUL character.
+ *
+ * This effectively "deletes"
+ * afterwildcardp from realstringp as far
+ * as any string manipulation functions
+ * that rely on a terminating NUL character
+ * are concerned. */
+ tmpp=tmpp + n - o;
+ *tmpp='\0';
+ }
+ else
+ {
+ /* if afterwildcardp does not exist at the
+ * end of realstringp, return non zero. */
+ return 0;
+ }
+ }
+
+
+ /* if we made it here, then we must have
+ * successfully removed everything but
+ * the value of the wildcard in
+ * wildcardedstringp from realstringp.
+ *
+ * Return zero. */
+ return 1;
+ } else {
+ /* no wildcard in wildcardedstringp */
+ return 0;
+ }
+}
+
+
+/* --------------------------------------------------------------
+ * Function : replace_wildcard()
+ * Created : 04/07/03
+ * Author : JDG
+ * Purpose : replace wildcard character in wildcardedstringp
+ * with contents of wildcardvalue.
+ * Notes : return non zero on success. return zero otherwise.
+ * -------------------------------------------------------------- */
+static int replace_wildcard( char *wildcardedstringp, char *wildcardvaluep, int wildcard) {
+ char wildcardedstring[LINELEN]="";
+ char *beforewildcardp;
+ char *afterwildcardp;
+ char *wildcardedstringpp=NULL;
+
+
+ /* Continue only if there is actually a wildcard in wildcardedstringp */
+ if (ldl_haswildcard(wildcardedstringp, wildcard)) {
+ /* Copy wildcardedstringp so as not to modify the original. */
+ strcpy(wildcardedstring, wildcardedstringp);
+
+ /* create a pointer to a pointer of a copy */
+ wildcardedstringpp = wildcardedstring;
+
+
+ /* tokenize first field */
+ beforewildcardp=mystrsep(&wildcardedstringpp, wildcard);
+ afterwildcardp=mystrsep(&wildcardedstringpp, wildcard);
+
+ /* start with a clean slate */
+ strcpy(wildcardedstringp, "");
+
+ if (beforewildcardp != NULL &&
+ strcmp(beforewildcardp, "") != 0)
+ {
+ /* Place string contents of beforewildcardp in wildcardedstringp */
+ strcpy(wildcardedstringp, beforewildcardp);
+ }
+
+ /* Add wildcardvaluep string to end of wildcardedstringp */
+ strncat(wildcardedstringp, wildcardvaluep,
+ LINELEN-1-strlen(wildcardedstringp));
+
+ if (afterwildcardp != NULL &&
+ strcmp(afterwildcardp, "") != 0)
+ {
+ /* Add afterwildcardp string to end of wildcardedstringp */
+ strncat(wildcardedstringp, afterwildcardp,
+ LINELEN-1-strlen(wildcardedstringp));
+ }
+
+ /* all is well */
+ return 1;
+
+ } else {
+ /* no wildcard in wildcardedstringp */
+ return 0;
+ }
+}
+
+
+/* --------------------------------------------------------------
+ * Function : get_defaultdomainfields()
+ * Created : 02/25/03
+ * Modified : 04/07/03 by JDG
+ * Author : JDG
+ * Purpose : Retrieve default domain from 'LOGINDOMAINLIST' file
+ * using either 'SERVER_ADDR' or 'HTTP_HOST' CGI
+ * variables.
+ * Notes :
+ *
+ * LOGINDOMAINLIST file can have the following format:
+ *
+ * DOMAIN1:IP1:MODIFIER
+ * DOMAIN2:DOMAIN3:MODIFIER
+ * DOMAIN4:DOMAIN5:MODIFIER
+ * etc...
+ *
+ * The first field contains the mail domain, and it is this field
+ * that appears in the drop down list if a drop down is specified
+ * by the modifier field.
+ *
+ * The second field can contain either an IP address or a domain
+ * name. This field is campared against the contents of the
+ * HTTP_HOST and/or SERVER_ADDR CGI environment variables. If a
+ * match is found, then the first and third (last) fields are
+ * written to domainp and modifyp, respectively.
+ *
+ * The third field, or modifier, can be an "*", an "@", or an
+ * rbitrary group identifier string. See README.logindomainlist
+ * in the main distribution directory for more details regarding
+ * LOGINDOMAINLIST file syntax.
+ * -------------------------------------------------------------- */
+static void get_defaultdomainfields( FILE *fp, char *domainp, char *modifyp)
+{
+ char buf[LINELEN]="";
+ char *serveraddr=getenv("SERVER_ADDR");
+ char *httphost=getenv("HTTP_HOST");
+
+ if (!serveraddr) serveraddr="";
+ if (!httphost) httphost="";
+
+ /* rewind the file pointer */
+ rewind(fp);
+
+ /* Read one line at a time from fp */
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ int count = 0;
+ char firstfield[LINELEN]="";
+ char secondfield[LINELEN]="";
+ char thirdfield[LINELEN]="";
+ /* get the position of the newline (if it exists) */
+ char *p=strchr(buf, '\n');
+
+ /* replace the newline with NUL */
+ if (*p) *p='\0';
+
+ /* ignore comments, empty lines, etc... */
+ if (ldl_invalidstatement(buf)) continue;
+
+
+ /* get individual fields from line */
+ ldl_getfields(buf, firstfield, secondfield, thirdfield);
+
+ /* process any wildcard enabled modifiers */
+ for (count = 0; count < NUM_WC_EN_MODS; count++)
+ {
+ const char *current_modifier = &g_wc_en_mods[count][0];
+
+ /* If this record is using wildcard domain mapping... */
+ if (strcmp(thirdfield, current_modifier) == 0)
+ {
+ int wildcard = g_wildcard_char;
+
+ /* If either the first or second field contains a wildcard char */
+ if (ldl_haswildcard(firstfield, wildcard) ||
+ ldl_haswildcard(secondfield, wildcard))
+ {
+ char finaldomain[LINELEN] = "";
+ char wildcardvalue[LINELEN] = "";
+ char tempbuf[LINELEN] = "";
+
+ /* extract the string that the wildcard in
+ * secondfield represents when compared
+ * with currentdomain */
+
+ /* seed wildcardvalue with contents of
+ * httphost. Sorry - no IP wildcarding. */
+ strcpy( wildcardvalue, httphost);
+
+ /* if secondfield and wildcardvalue match,
+ * extract_wildcardvalue will "chop off"
+ * the text before and after the wildcard
+ * character in secondfield from
+ * wildcardvalue */
+ if (extract_wildcardvalue(secondfield, wildcardvalue, wildcard))
+ {
+ /* wildcardvalue may now contain the final
+ * domain name to use as default domain if
+ * firstfield does NOT contain a wildcard.
+ *
+ * That is why we save the contents of
+ * wildcardvalue in finaldomain here. */
+ strcpy(finaldomain, wildcardvalue);
+ }
+ else
+ {
+ /* Make sure this wildcardless record
+ * actually matches httphost before doing
+ * anything else */
+ if (strcmp(secondfield, httphost) != 0) continue;
+
+ /* we don't have a wildcard in the second
+ * field, so just do a straight copy */
+ strcpy(finaldomain, secondfield);
+ }
+
+
+ /* seed tempbuf with contents of firstfield */
+ strcpy(tempbuf, firstfield);
+
+ /* Replace wildcard character in tempbuf
+ * with contents of wildcardvalue */
+ if (replace_wildcard(tempbuf, wildcardvalue, wildcard))
+ {
+
+ /* The above replace_wildcard() must have
+ * been seccessful if we're still here,
+ * so save the contents of tempbuf in
+ * finaldomain. */
+ strcpy(finaldomain, tempbuf);
+ }
+ else
+ {
+ /* we don't have a wildcard in the first
+ * field, so just do a straight copy */
+ strcpy(finaldomain, firstfield);
+ }
+
+ /* return default domain */
+ strcpy(domainp, finaldomain);
+ strcpy(modifyp, thirdfield);
+ return;
+ }
+ else
+ {
+ /* Fall through to matching against serveraddr
+ * and httphost if no wildcards exist in either
+ * firstfield or secondfield */
+ }
+ }
+ }
+
+
+ /* This is reached if the third field (modifier) is NOT a wildcard */
+ /* compare second field against CGI variables */
+ if (strcmp(secondfield, serveraddr) == 0 ||
+ strcmp(secondfield, httphost) == 0)
+ {
+ strcpy(domainp, firstfield);
+ strcpy(modifyp, thirdfield);
+ return;
+ }
+
+ }
+}
+
+
+/* --------------------------------------------------------------
+ * Function : ldl_displayhidden()
+ * Created : 04/05/03
+ * Author : JDG
+ * Purpose : display an HTML hidden input field with
+ * value="defaultdomain"
+ * Notes : none
+ * -------------------------------------------------------------- */
+static void ldl_displayhiddenfield( char *defaultdomainp) {
+
+ if (strlen(defaultdomainp) > 0)
+ {
+ /* This is displayed only if defaultdomain is NOT
+ * empty */
+ printf("<input type=\"hidden\" name=\"logindomain\" value=\"%s\" />@%s",
+ defaultdomainp, defaultdomainp);
+ }
+ else
+ {
+ /* Do nothing. This is here so that nothing will
+ * be displayed if defaultdomain is empty. */
+ }
+}
+
+
+/* --------------------------------------------------------------
+ * Function : ldl_displaytextfield()
+ * Created : 04/07/03
+ * Author : JDG
+ * Purpose : display an HTML text input field with
+ * value="defaultdomain"
+ * Notes : none
+ * -------------------------------------------------------------- */
+static void ldl_displaytextfield( char *defaultdomainp) {
+
+ if (strlen(defaultdomainp) > 0)
+ {
+ /* This is displayed only if defaultdomain is NOT
+ * empty */
+ printf("@<input type=\"text\" name=\"logindomain\" value=\"%s\" size=\"%d\" />",
+ defaultdomainp, (int)strlen(defaultdomainp)+2);
+ }
+ else
+ {
+ /* Do nothing. This is here so that nothing will
+ * be displayed if defaultdomain is empty. */
+ }
+}
+
+/* --------------------------------------------------------------
+ * Function : ldl_displaydropdown()
+ * Created : 04/05/03
+ * Modified : 04/07/03
+ * Author : JDG
+ * Purpose : Display an HTML drop down menu containing only
+ * records from fp with a third field identical to
+ * defaultgroupp.
+ * Set the record with a first field matching
+ * defaultdomainp as 'selected'.
+ * Notes : none
+ * -------------------------------------------------------------- */
+static void ldl_displaydropdown( FILE *fp, char *defaultdomainp, char *defaultgroupp) {
+
+ char buf[LINELEN];
+
+ /* This is a flag that is toggled once the first match has been
+ * made. */
+ int firstmatch=0;
+
+
+ /* rewind file pointer */
+ rewind(fp);
+
+
+ /* Read one line at a time from fp */
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ char firstfield[LINELEN]="";
+ char secondfield[LINELEN]="";
+ char thirdfield[LINELEN]="";
+ /* get the position of the newline (if it exists) */
+ char *p=strchr(buf, '\n');
+
+ /* replace the newline with NUL */
+ if (*p) *p='\0';
+
+ /* ignore comments, empty lines, etc... */
+ if (ldl_invalidstatement(buf)) continue;
+
+ /* get individual fields from file */
+ ldl_getfields(buf, firstfield, secondfield, thirdfield);
+
+ /* only display this option if it's group field (thirdfield)
+ * is identical to defaultgroupp. */
+ if (strcmp(thirdfield, defaultgroupp) == 0)
+ {
+ /* Only display the select tag the first time we
+ * find a match. */
+ if (firstmatch == 0)
+ {
+ printf("@<select name=\"logindomain\"><option value=\"\">&nbsp;</option>\n");
+ firstmatch=1;
+ }
+
+ /* Do not display options with empty first fields. */
+ if (strlen(firstfield) > 0)
+ {
+ /* If 'defaultdomainp' is identical to firstfield
+ * then set this option as 'selected'. */
+ if (strcmp(defaultdomainp, firstfield) == 0)
+ {
+ printf("<option value=\"%s\" selected=\"selected\">%s</option>\n",
+ firstfield, firstfield);
+ }
+ else
+ {
+ printf("<option value=\"%s\">%s</option>\n",
+ firstfield, firstfield);
+ }
+ }
+ }
+ }
+
+ /* Display a closing select tag only if we displayed
+ * a starting select tag */
+ if (firstmatch > 0) printf("</select>");
+}
+
+
+/* --------------------------------------------------------------
+ * Function : print_logindomainlist()
+ * Created : 03/04/03
+ * Modified : 04/07/03 - JDG
+ * Author : JDG
+ * Purpose : parse fp and print proper output.
+ * Notes : none
+ * -------------------------------------------------------------- */
+void print_logindomainlist( FILE *fp )
+{
+ char defaultdomain[LINELEN]="";
+ char modifierfield[LINELEN]="";
+
+ /* get default domain field and the corresponding default
+ * group field (if applicable) from fp. */
+ get_defaultdomainfields(fp, defaultdomain, modifierfield);
+
+
+ /* There are basically two ways to graphically display the
+ * default domain.
+ *
+ * 1.) As a hidden field with descriptive text.
+ * 2.) As a drop down menu with a defaulted option.
+ *
+ * The modifiers '@' and '*' display a hidden field.
+ *
+ * If the modifier field contains anything else, then we
+ * consider it's contents a 'group' identifier and we
+ * display a drop down. */
+ if (strcmp(modifierfield, "@") == 0)
+ {
+ /* ----------------------
+ * DISPLAY HIDDEN FIELD
+ * ---------------------- */
+
+ ldl_displayhiddenfield(defaultdomain);
+ }
+ else if (strcmp(modifierfield, "-") == 0)
+ {
+ /* ----------------------
+ * DISPLAY TEXT FIELD
+ * ---------------------- */
+
+ ldl_displaytextfield(defaultdomain);
+ }
+ else
+ {
+ /* ----------------------
+ * DISPLAY DROP DOWN MENU
+ * ---------------------- */
+
+ ldl_displaydropdown(fp, defaultdomain, modifierfield);
+ }
+}