diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 | 
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 | 
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /sqwebmail/logindomainlist.c | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-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.c | 715 | 
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=\"\"> </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); +	} +} | 
