1 #include "config.h"
2 /*
3 ** Copyright 2003 Double Precision, Inc.  See COPYING for
4 ** distribution information.
5 **
6 ** Original author: Jesse D. Guardiani, wingnet.net
7 */
8 
9 /*
10 */
11 
12 #include	<stdio.h>
13 #include	<stdlib.h>
14 #include	<string.h>
15 
16 #include	"logindomainlist.h"
17 
18 /* LINELEN is the maximum length of a line in the file we are reading. */
19 #define		LINELEN 500
20 #define		NUM_WC_EN_MODS 2
21 
22 /* constants */
23 static const int g_delim=':';
24 static const int g_wildcard_char='*';
25 
26 /* array of wildcard enabled modifiers */
27 static const char g_wc_en_mods[NUM_WC_EN_MODS][2] = { "@", "-" };
28 
29 /* --------------------------------------------------------------
30  * Function : mystrsep()
31  * Created  : 03/03/03
32  * Author   : JDG
33  * Purpose  : Emulate the BSD strsep() function.
34  * Notes    :
35  * This function is designed to emulate the BSD strsep function
36  * without introducing any doubts that it is a custom
37  * implementation. It's probably quite a bit slower than the
38  * original BSD strsep(), but it'll do for most purposes.
39  * mystrsep's functionality should be nearly identical to the
40  * BSD strsep, except that it takes an int as argument for the
41  * delimiter.
42  * -------------------------------------------------------------- */
mystrsep(char ** stringp,int delim)43 static char *mystrsep( char **stringp, int delim )
44 {
45 	char *orig_stringp=*stringp;
46 
47 	/* Make sure we return NULL if we are given NULL */
48 	if (*stringp == NULL) return orig_stringp;
49 
50 	/* Locate first occurance of delim in stringp */
51 	*stringp=strchr(*stringp, delim);
52 
53 	/* If no more delimiters were found, return the last substring */
54 	if (*stringp == NULL) return orig_stringp;
55 
56 	/* Set that first occurance to NUL */
57 	**stringp='\0';
58 
59 	/* move pointer in front of NUL character */
60 	++(*stringp);
61 
62 	/* Return original value of *stringp */
63 	return orig_stringp;
64 
65 }
66 
67 
68 /* --------------------------------------------------------------
69  * Function : ldl_haswildcard()
70  * Created  : 04/08/03
71  * Author   : JDG
72  * Purpose  : Determine if the NUL terminated stringp contains
73  *            the wildcard character specified in wildcard.
74  * Notes    : Returns 0 if wildcard doesn't exist in stringp.
75  *            Returns 1 if stringp does contain wildcard.
76  * -------------------------------------------------------------- */
ldl_haswildcard(char * stringp,int wildcard)77 static int ldl_haswildcard( char *stringp, int wildcard)
78 {
79 	char *wildcardp;
80 
81 	/* get pointer to wildcard within stringp */
82 	wildcardp = strchr(stringp, wildcard);
83 
84 	if (wildcardp == NULL) return 0;
85 
86 	return 1;
87 }
88 
89 
90 /* --------------------------------------------------------------
91  * Function : ldl_getfields()
92  * Created  : 03/04/03
93  * Modified : 04/07/03 by JDG
94  * Author   : JDG
95  * Purpose  : Retrieve fields from a logindomainlist statement.
96  * Notes    : This function is designed to provide a standard
97  *            interface to retrieve fields from a logindomainlist
98  *            statement line.
99  *
100  *            This function should never generate a NULL pointer,
101  *            even if a field is empty.
102  * -------------------------------------------------------------- */
ldl_getfields(char * statementp,char * firstfieldp,char * secondfieldp,char * thirdfieldp)103 static void ldl_getfields( char *statementp, char *firstfieldp, char *secondfieldp, char *thirdfieldp )
104 {
105 	int  delim=g_delim;
106 	char *tempfirst;
107 	char *tempsecond;
108 	char *tempthird;
109 	char *bufp=statementp;
110 
111 
112 	/* get pointers to individual fields from file */
113 	tempfirst=mystrsep(&bufp, delim);
114 	tempsecond=mystrsep(&bufp, delim);
115 	tempthird=mystrsep(&bufp, delim);
116 
117 	/* fix NULL pointers */
118 	if (tempfirst == NULL) tempfirst="";
119 	if (tempsecond == NULL) tempsecond="";
120 	if (tempthird == NULL) tempthird="";
121 
122 	/* copy strings */
123 	strcpy(firstfieldp, tempfirst);
124 	strcpy(secondfieldp, tempsecond);
125 	strcpy(thirdfieldp, tempthird);
126 }
127 
128 
129 /* --------------------------------------------------------------
130  * Function : ldl_invalidstatement()
131  * Created  : 03/04/03
132  * Modified : 04/07/03
133  * Author   : JDG
134  * Purpose  : Examine line and determine if it is a valid state-
135  *            ment.
136  * Notes    : This function can be used to filter out comments,
137  *            empty lines, and anything else that shouldn't be in
138  *            a valid statement line. Returns 1 (one) if
139  *            statementp is a comment or other invalid statement.
140  *
141  *            Returns zero otherwise.
142  * -------------------------------------------------------------- */
ldl_invalidstatement(char * statementp)143 static int ldl_invalidstatement( char *statementp )
144 {
145 	const int TRUE = 1;
146 	const int FALSE = 0;
147 
148 	/* comments aren't valid statements */
149 	if (statementp[0] == '#') return TRUE;
150 
151 	/* empty lines aren't valid statements */
152 	if (statementp[0] == ' ' ||
153 	    statementp[0] == '\t' ||
154 	    statementp[0] == '\n') return TRUE;
155 
156 	/* extra long lines aren't valid statements either... */
157 	if (strlen(statementp) > LINELEN) return TRUE;
158 
159 	/* might be a valid statement line */
160 	return FALSE;
161 }
162 
163 
164 /* --------------------------------------------------------------
165  * Function : extract_wildcardvalue()
166  * Created  : 04/07/03
167  * Author   : JDG
168  * Purpose  : compare wildcardedstringp and realstringp. If the
169  *            two match, then replace the contents of realstringp
170  *            with the contents of the wildcard character in
171  *            wildcardedstringp.
172  * Notes    : If the substring beforewildcardp appears at the
173  *            absolute beginning of realstringp, then
174  *            beforewildcardp is deleted from realstring.
175  *            If the substring afterwildcardp appears at the
176  *            absolute end of realstringp, then afterwildcardp
177  *            is deleted from realstringp.
178  *
179  *            The string remaining in realstringp represents the
180  *            contents of our wildcard character in
181  *            wildcardedstringp.
182  *
183  *            For example, if:
184  *
185  *            wildcardedstringp = my*domain.com
186  *            realstringp       = myexampledomain.com
187  *
188  *            Then extract_wildcardvalue() will replace the
189  *            contents of realstringp with the following string:
190  *
191  *            example
192  *
193  *            If no wildcard character exists in
194  *            wildcardedstringp or if wildcardedstringp and
195  *            realstringp don't match, extract_wildcardvalue()
196  *            will return zero.
197  *
198  *            Otherwise, extract_wildcardvalue() returns non
199  *            zero.
200  * -------------------------------------------------------------- */
extract_wildcardvalue(char * wildcardedstringp,char * realstringp,int wildcard)201 static int extract_wildcardvalue( char *wildcardedstringp, char *realstringp, int wildcard) {
202 	char wildcardedstring[LINELEN]="";
203 	char *beforewildcardp;
204 	char *afterwildcardp;
205 	char *wildcardedstringpp=NULL;
206 
207 
208 	/* Continue only if there is actually a wildcard character in wildcardedstring */
209 	if (ldl_haswildcard(wildcardedstringp, wildcard)) {
210 		/* Copy argument to buffer so as not to modify the original. */
211 		strcpy(wildcardedstring, wildcardedstringp);
212 
213 		/* create a pointer to a pointer of a copy*/
214 		wildcardedstringpp = wildcardedstring;
215 
216 
217 		/* tokenize wildcardstring with '\0's */
218 		beforewildcardp=mystrsep(&wildcardedstringpp, wildcard);
219 		afterwildcardp=mystrsep(&wildcardedstringpp, wildcard);
220 
221 
222 		if (beforewildcardp != NULL && strcmp(beforewildcardp, "") != 0)
223 		{
224 			/* If beforewildcardp string exists at the absolute
225 			 * beginning of realstring */
226 			if (strstr(realstringp, beforewildcardp) == realstringp)
227 			{
228 				char *tmpp=realstringp;
229 				char *p;
230 
231 				/* move pointer to the end of beforewildcardp in
232 				 * realstring. */
233 				tmpp=tmpp + strlen(beforewildcardp);
234 
235 				/* Now, "delete" beforewildcardp from the very
236 				 * beginning of realstring. Note that we're not
237 				 * actually deleting it. We're just copying the
238 				 * remaining string in realstring from the
239 				 * location that tmpp points to in realstring.
240 				 * However, this has the same effect as if we
241 				 * had somehow "deleted" beforewildcardp from
242 				 * the beginning of realstring. */
243 
244 				p=realstringp;
245 
246 				while ((*p++= *tmpp++) != 0)
247 					;
248 			}
249 			else
250 			{
251 				/* if beforewildcardp does not exist at the
252 				 * beginning of realstringp, return non zero. */
253 				return 0;
254 			}
255 		}
256 
257 
258 		if (afterwildcardp != NULL && strcmp(afterwildcardp, "") != 0)
259 		{
260 			/* If afterwildcardp exists at the very end of realstring */
261 			size_t n=strlen(realstringp);
262 			size_t o=strlen(afterwildcardp);
263 
264 			if (n >= o &&
265 			    strcmp(realstringp+n-o, afterwildcardp) == 0)
266 			{
267 				char *tmpp=realstringp;
268 
269 				/* move temp pointer to the end of the NUL
270 				 * terminated string in realstringp, then
271 				 * backspace the length of afterwildcardp
272 				 * and write a NUL character.
273 				 *
274 				 * This effectively "deletes"
275 				 * afterwildcardp from realstringp as far
276 				 * as any string manipulation functions
277 				 * that rely on a terminating NUL character
278 				 * are concerned. */
279 				tmpp=tmpp + n - o;
280 				*tmpp='\0';
281 			}
282 			else
283 			{
284 				/* if afterwildcardp does not exist at the
285 				 * end of realstringp, return non zero. */
286 				return 0;
287 			}
288 		}
289 
290 
291 		/* if we made it here, then we must have
292 		 * successfully removed everything but
293 		 * the value of the wildcard in
294 		 * wildcardedstringp from realstringp.
295 		 *
296 		 * Return zero. */
297 		return 1;
298 	} else {
299 		/* no wildcard in wildcardedstringp */
300 		return 0;
301 	}
302 }
303 
304 
305 /* --------------------------------------------------------------
306  * Function : replace_wildcard()
307  * Created  : 04/07/03
308  * Author   : JDG
309  * Purpose  : replace wildcard character in wildcardedstringp
310  *            with contents of wildcardvalue.
311  * Notes    : return non zero on success. return zero otherwise.
312  * -------------------------------------------------------------- */
replace_wildcard(char * wildcardedstringp,char * wildcardvaluep,int wildcard)313 static int replace_wildcard( char *wildcardedstringp, char *wildcardvaluep, int wildcard) {
314 	char wildcardedstring[LINELEN]="";
315 	char *beforewildcardp;
316 	char *afterwildcardp;
317 	char *wildcardedstringpp=NULL;
318 
319 
320 	/* Continue only if there is actually a wildcard in wildcardedstringp */
321 	if (ldl_haswildcard(wildcardedstringp, wildcard)) {
322 		/* Copy wildcardedstringp so as not to modify the original. */
323 		strcpy(wildcardedstring, wildcardedstringp);
324 
325 		/* create a pointer to a pointer of a copy */
326 		wildcardedstringpp = wildcardedstring;
327 
328 
329 		/* tokenize first field */
330 		beforewildcardp=mystrsep(&wildcardedstringpp, wildcard);
331 		afterwildcardp=mystrsep(&wildcardedstringpp, wildcard);
332 
333 		/* start with a clean slate */
334 		strcpy(wildcardedstringp, "");
335 
336 		if (beforewildcardp != NULL &&
337 		    strcmp(beforewildcardp, "") != 0)
338 		{
339 			/* Place string contents of beforewildcardp in wildcardedstringp */
340 			strcpy(wildcardedstringp, beforewildcardp);
341 		}
342 
343 		/* Add wildcardvaluep string to end of wildcardedstringp */
344 		strncat(wildcardedstringp, wildcardvaluep,
345 			LINELEN-1-strlen(wildcardedstringp));
346 
347 		if (afterwildcardp != NULL &&
348 		    strcmp(afterwildcardp, "") != 0)
349 		{
350 			/* Add afterwildcardp string to end of wildcardedstringp */
351 			strncat(wildcardedstringp, afterwildcardp,
352 				LINELEN-1-strlen(wildcardedstringp));
353 		}
354 
355 		/* all is well */
356 		return 1;
357 
358 	} else {
359 		/* no wildcard in wildcardedstringp */
360 		return 0;
361 	}
362 }
363 
364 
365 /* --------------------------------------------------------------
366  * Function : get_defaultdomainfields()
367  * Created  : 02/25/03
368  * Modified : 04/07/03 by JDG
369  * Author   : JDG
370  * Purpose  : Retrieve default domain from 'LOGINDOMAINLIST' file
371  *            using either 'SERVER_ADDR' or 'HTTP_HOST' CGI
372  *            variables.
373  * Notes    :
374  *
375  * LOGINDOMAINLIST file can have the following format:
376  *
377  * DOMAIN1:IP1:MODIFIER
378  * DOMAIN2:DOMAIN3:MODIFIER
379  * DOMAIN4:DOMAIN5:MODIFIER
380  * etc...
381  *
382  * The first field contains the mail domain, and it is this field
383  * that appears in the drop down list if a drop down is specified
384  * by the modifier field.
385  *
386  * The second field can contain either an IP address or a domain
387  * name. This field is campared against the contents of the
388  * HTTP_HOST and/or SERVER_ADDR CGI environment variables. If a
389  * match is found, then the first and third (last) fields are
390  * written to domainp and modifyp, respectively.
391  *
392  * The third field, or modifier, can be an "*", an "@", or an
393  * rbitrary group identifier string. See README.logindomainlist
394  * in the main distribution directory for more details regarding
395  * LOGINDOMAINLIST file syntax.
396  * -------------------------------------------------------------- */
get_defaultdomainfields(FILE * fp,char * domainp,char * modifyp)397 static void get_defaultdomainfields( FILE *fp, char *domainp, char *modifyp)
398 {
399 	char buf[LINELEN]="";
400 	char *serveraddr=getenv("SERVER_ADDR");
401 	char *httphost=getenv("HTTP_HOST");
402 
403 	if (!serveraddr) serveraddr="";
404 	if (!httphost) httphost="";
405 
406 	/* rewind the file pointer */
407 	rewind(fp);
408 
409 	/* Read one line at a time from fp */
410 	while (fgets(buf, sizeof(buf), fp))
411 	{
412 		int count = 0;
413 		char firstfield[LINELEN]="";
414 		char secondfield[LINELEN]="";
415 		char thirdfield[LINELEN]="";
416 		/* get the position of the newline (if it exists) */
417 		char *p=strchr(buf, '\n');
418 
419 		/* replace the newline with NUL */
420 		if (*p) *p='\0';
421 
422 		/* ignore comments, empty lines, etc... */
423 		if (ldl_invalidstatement(buf)) continue;
424 
425 
426 		/* get individual fields from line */
427 		ldl_getfields(buf, firstfield, secondfield, thirdfield);
428 
429 		/* process any wildcard enabled modifiers */
430 		for (count = 0; count < NUM_WC_EN_MODS; count++)
431 		{
432 			const char *current_modifier = &g_wc_en_mods[count][0];
433 
434 			/* If this record is using wildcard domain mapping... */
435 			if (strcmp(thirdfield, current_modifier) == 0)
436 			{
437 				int  wildcard = g_wildcard_char;
438 
439 				/* If either the first or second field contains a wildcard char */
440 				if (ldl_haswildcard(firstfield, wildcard) ||
441 				    ldl_haswildcard(secondfield, wildcard))
442 				{
443 					char finaldomain[LINELEN] = "";
444 					char wildcardvalue[LINELEN] = "";
445 					char tempbuf[LINELEN] = "";
446 
447 					/* extract the string that the wildcard in
448 					 * secondfield represents when compared
449 					 * with currentdomain */
450 
451 					/* seed wildcardvalue with contents of
452 					 * httphost. Sorry - no IP wildcarding. */
453 					strcpy( wildcardvalue, httphost);
454 
455 					/* if secondfield and wildcardvalue match,
456 					 * extract_wildcardvalue will "chop off"
457 					 * the text before and after the wildcard
458 					 * character in secondfield from
459 					 * wildcardvalue */
460 					if (extract_wildcardvalue(secondfield, wildcardvalue, wildcard))
461 					{
462 						/* wildcardvalue may now contain the final
463 						 * domain name to use as default domain if
464 						 * firstfield does NOT contain a wildcard.
465 						 *
466 						 * That is why we save the contents of
467 						 * wildcardvalue in finaldomain here. */
468 						strcpy(finaldomain, wildcardvalue);
469 					}
470 					else
471 					{
472 						/* Make sure this wildcardless record
473 						 * actually matches httphost before doing
474 						 * anything else */
475 						if (strcmp(secondfield, httphost) != 0) continue;
476 
477 						/* we don't have a wildcard in the second
478 						 * field, so just do a straight copy */
479 						strcpy(finaldomain, secondfield);
480 					}
481 
482 
483 					/* seed tempbuf with contents of firstfield */
484 					strcpy(tempbuf, firstfield);
485 
486 					/* Replace wildcard character in tempbuf
487 					 * with contents of wildcardvalue */
488 					if (replace_wildcard(tempbuf, wildcardvalue, wildcard))
489 					{
490 
491 						/* The above replace_wildcard() must have
492 						 * been seccessful if we're still here,
493 						 * so save the contents of tempbuf in
494 						 * finaldomain. */
495 						strcpy(finaldomain, tempbuf);
496 					}
497 					else
498 					{
499 						/* we don't have a wildcard in the first
500 						 * field, so just do a straight copy */
501 						strcpy(finaldomain, firstfield);
502 					}
503 
504 					/* return default domain */
505 					strcpy(domainp, finaldomain);
506 					strcpy(modifyp, thirdfield);
507 					return;
508 				}
509 				else
510 				{
511 					/* Fall through to matching against serveraddr
512 					 * and httphost if no wildcards exist in either
513 					 * firstfield or secondfield */
514 				}
515 			}
516 		}
517 
518 
519 		/* This is reached if the third field (modifier) is NOT a wildcard */
520 		/* compare second field against CGI variables */
521 		if (strcmp(secondfield, serveraddr) == 0 ||
522 		    strcmp(secondfield, httphost) == 0)
523 		{
524 			strcpy(domainp, firstfield);
525 			strcpy(modifyp, thirdfield);
526 			return;
527 		}
528 
529 	}
530 }
531 
532 
533 /* --------------------------------------------------------------
534  * Function : ldl_displayhidden()
535  * Created  : 04/05/03
536  * Author   : JDG
537  * Purpose  : display an HTML hidden input field with
538  *            value="defaultdomain"
539  * Notes    : none
540  * -------------------------------------------------------------- */
ldl_displayhiddenfield(char * defaultdomainp)541 static void ldl_displayhiddenfield( char *defaultdomainp) {
542 
543 	if (strlen(defaultdomainp) > 0)
544 	{
545 		/* This is displayed only if defaultdomain is NOT
546 		 * empty */
547 		printf("<input type=\"hidden\" name=\"logindomain\" value=\"%s\" />@%s",
548 				defaultdomainp, defaultdomainp);
549 	}
550 	else
551 	{
552 		/* Do nothing. This is here so that nothing will
553 		 * be displayed if defaultdomain is empty. */
554 	}
555 }
556 
557 
558 /* --------------------------------------------------------------
559  * Function : ldl_displaytextfield()
560  * Created  : 04/07/03
561  * Author   : JDG
562  * Purpose  : display an HTML text input field with
563  *            value="defaultdomain"
564  * Notes    : none
565  * -------------------------------------------------------------- */
ldl_displaytextfield(char * defaultdomainp)566 static void ldl_displaytextfield( char *defaultdomainp) {
567 
568 	if (strlen(defaultdomainp) > 0)
569 	{
570 		/* This is displayed only if defaultdomain is NOT
571 		 * empty */
572 		printf("@<input type=\"text\" name=\"logindomain\" value=\"%s\" size=\"%d\" />",
573 				defaultdomainp, (int)strlen(defaultdomainp)+2);
574 	}
575 	else
576 	{
577 		/* Do nothing. This is here so that nothing will
578 		 * be displayed if defaultdomain is empty. */
579 	}
580 }
581 
582 /* --------------------------------------------------------------
583  * Function : ldl_displaydropdown()
584  * Created  : 04/05/03
585  * Modified : 04/07/03
586  * Author   : JDG
587  * Purpose  : Display an HTML drop down menu containing only
588  *            records from fp with a third field identical to
589  *            defaultgroupp.
590  *            Set the record with a first field matching
591  *            defaultdomainp as 'selected'.
592  * Notes    : none
593  * -------------------------------------------------------------- */
ldl_displaydropdown(FILE * fp,char * defaultdomainp,char * defaultgroupp)594 static void ldl_displaydropdown( FILE *fp, char *defaultdomainp, char *defaultgroupp) {
595 
596 	char buf[LINELEN];
597 
598 	/* This is a flag that is toggled once the first match has been
599 	 * made. */
600 	int firstmatch=0;
601 
602 
603 	/* rewind file pointer */
604 	rewind(fp);
605 
606 
607 	/* Read one line at a time from fp */
608 	while (fgets(buf, sizeof(buf), fp))
609 	{
610 		char firstfield[LINELEN]="";
611 		char secondfield[LINELEN]="";
612 		char thirdfield[LINELEN]="";
613 		/* get the position of the newline (if it exists) */
614 		char *p=strchr(buf, '\n');
615 
616 		/* replace the newline with NUL */
617 		if (*p) *p='\0';
618 
619 		/* ignore comments, empty lines, etc... */
620 		if (ldl_invalidstatement(buf)) continue;
621 
622 		/* get individual fields from file */
623 		ldl_getfields(buf, firstfield, secondfield, thirdfield);
624 
625 		/* only display this option if it's group field (thirdfield)
626 		 * is identical to defaultgroupp. */
627 		if (strcmp(thirdfield, defaultgroupp) == 0)
628 		{
629 			/* Only display the select tag the first time we
630 			 * find a match. */
631 			if (firstmatch == 0)
632 			{
633 				printf("@<select name=\"logindomain\"><option value=\"\">&nbsp;</option>\n");
634 				firstmatch=1;
635 			}
636 
637 			/* Do not display options with empty first fields. */
638 			if (strlen(firstfield) > 0)
639 			{
640 				/* If 'defaultdomainp' is identical to firstfield
641 				 * then set this option as 'selected'. */
642 				if (strcmp(defaultdomainp, firstfield) == 0)
643 				{
644 					printf("<option value=\"%s\" selected=\"selected\">%s</option>\n",
645 							firstfield, firstfield);
646 				}
647 				else
648 				{
649 					printf("<option value=\"%s\">%s</option>\n",
650 							firstfield, firstfield);
651 				}
652 			}
653 		}
654 	}
655 
656 	/* Display a closing select tag only if we displayed
657 	 * a starting select tag */
658 	if (firstmatch > 0) printf("</select>");
659 }
660 
661 
662 /* --------------------------------------------------------------
663  * Function : print_logindomainlist()
664  * Created  : 03/04/03
665  * Modified : 04/07/03 - JDG
666  * Author   : JDG
667  * Purpose  : parse fp and print proper output.
668  * Notes    : none
669  * -------------------------------------------------------------- */
print_logindomainlist(FILE * fp)670 void print_logindomainlist( FILE *fp )
671 {
672 	char defaultdomain[LINELEN]="";
673 	char modifierfield[LINELEN]="";
674 
675 	/* get default domain field and the corresponding default
676 	 * group field (if applicable) from fp. */
677 	get_defaultdomainfields(fp, defaultdomain, modifierfield);
678 
679 
680 	/* There are basically two ways to graphically display the
681 	 * default domain.
682 	 *
683 	 * 1.) As a hidden field with descriptive text.
684 	 * 2.) As a drop down menu with a defaulted option.
685 	 *
686 	 * The modifiers '@' and '*' display a hidden field.
687 	 *
688 	 * If the modifier field contains anything else, then we
689 	 * consider it's contents a 'group' identifier and we
690 	 * display a drop down. */
691 	if (strcmp(modifierfield, "@") == 0)
692 	{
693 		/* ----------------------
694 		 * DISPLAY HIDDEN FIELD
695 		 * ---------------------- */
696 
697 		ldl_displayhiddenfield(defaultdomain);
698 	}
699 	else if (strcmp(modifierfield, "-") == 0)
700 	{
701 		/* ----------------------
702 		 * DISPLAY TEXT FIELD
703 		 * ---------------------- */
704 
705 		ldl_displaytextfield(defaultdomain);
706 	}
707 	else
708 	{
709 		/* ----------------------
710 		 * DISPLAY DROP DOWN MENU
711 		 * ---------------------- */
712 
713 		ldl_displaydropdown(fp, defaultdomain, modifierfield);
714 	}
715 }
716