/* web_ldap.c * Form Processing Web application that returns html based * LDAP data with definitions from a configuration file. * * Jens Moller - Dec 11, 1998 */ #include "portable.h" #include #include #include #include #include #include #include #include #include #include #include "ldif.h" #include "maint_form.h" /* for HTML Form manipulations */ /* default values */ #ifndef LDAP_PORT #define LDAP_PORT 389 #endif #ifndef SERVER #define SERVER "ldap.bigfoot.com" #endif #ifndef CONFIG #define CONFIG "web_ldap.cfg" #endif #define MAX_ATTRIB 100 #define MAX_CHARS 256 #define version "v 1.1" entry entries[MAX_ENTRIES]; typedef struct { char servername[MAX_CHARS]; char query[MAX_CHARS]; char searchbase[MAX_CHARS]; char htmlfile[MAX_CHARS]; int ldap_port_num; int num_of_attrib; int debug; /* if zero, no debug text displayed */ } LDAP_INFO; typedef struct { char title[40]; } ATTRIB_TITLE; /* function Prototypes */ void process_cfg(char *config, LDAP_INFO *ldap_data, char *attribute_array[], ATTRIB_TITLE *disp_attrib); int strscn(char *istring, char *tstring); void upcase_string(char *array, char *uparray); int find_comma(char *array); int find_colon(char *array); void squeeze_blanks(char *array); /* Pass in nothing and use the default config file, or * pass in the config file to use */ main(int argc, char ** argv) { LDAP *ld; LDAPMessage *res, *e; int i, j, cl, x, how_many; char *a, *dn, *value; BerElement *ptr; char **vals; char *read_attrs[MAX_ATTRIB]; /* up to MAX_ATTRIB attribs returned */ struct berval **bvals; char attrs_name[MAX_CHARS]; char config_file[MAX_CHARS]; char temp[MAX_CHARS]; char passed_in[MAX_CHARS]; LDAP_INFO ldap_data; ATTRIB_TITLE attribute[MAX_ATTRIB]; time_t now; FILE *logfp; /* html initialization */ printf("Content-type: text/html\n\n"); printf("\n\nWeb Ldap Results\n"); printf("\n"); printf("\n"); printf("

Web LDAP Results

\n"); /* initialize ldap_data structure */ memset(ldap_data.servername,0,MAX_CHARS); memset(ldap_data.query,0,MAX_CHARS); memset(ldap_data.searchbase,0,MAX_CHARS); memset(ldap_data.htmlfile,0,MAX_CHARS); ldap_data.ldap_port_num = 0; ldap_data.num_of_attrib = 0; ldap_data.debug = 0; memset(passed_in,0,MAX_CHARS); if (argc > 1) { /* interactive mode */ /* To use in this fashion when run from a Unix command line: * * > web_ldap DEF "cn=j*moller" * > web_ldap DEF cn=jens moller * * NOTE: The quotes are required if a special * character is a part of the LDAP request such * as the asterix (*) in the above example. */ /* Parameters passed in are * * argv[0] = Program Name (argc = 1) * argv[1] = Config File Name (argc = 2) * argv[2] = Ldap Request (argc => 3) */ /* do we use a different config file ? */ strcpy(config_file, CONFIG); if (argc == 2){ if ((strcmp(argv[1],"DEF")) == 0) { strcpy(config_file, CONFIG); } else { strcpy(config_file, argv[1]); } } /* is there an LDAP request? * if so, it may take up to 3 argv[x] values */ if (argc >= 3) { if (argc == 3) { strcpy(temp, argv[2]); } if (argc == 4) { strcpy(temp, argv[2]); strcat(temp, " "); strcat(temp, argv[3]); } if (argc == 5) { strcpy(temp, argv[2]); strcat(temp, " "); strcat(temp, argv[3]); strcat(temp, " "); strcat(temp, argv[4]); } j = 0; for (i=0; i++ Error - This script should be referenced with a METHOD of POST.\n"); exit( EXIT_FAILURE ); } if (strcompare(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) { printf("

++ Error - This script can only be used to decode form results. \n"); exit( EXIT_FAILURE ); } cl = atoi(getenv("CONTENT_LENGTH")); for(x=0; cl && (!feof(stdin));x++) { entries[x].val = fmakeword(stdin,'&',&cl); plustospace(entries[x].val); unescape_url(entries[x].val); entries[x].name = makeword(entries[x].val,'='); how_many = x; /* keep track of how many we got */ #ifdef DEBUG_TEXT printf("entries[%d].name=%s - ",x,entries[x].name); printf("entries[%d].val =%s
\n",x,entries[x].val); #endif } entries[x].name = NULL; /* entry after last valid one */ entries[x].val = NULL; /* is set to NULL */ if(!getvalue(entries, "FORM", &value)) { printf("%s%s%s", "This script expected a 'FORM' value returned ", "and did not get one. Make sure the HTML used for this ", "script is correct."); exit( EXIT_FAILURE ); } /* Looking for: * LDAP_REQUEST - actual LDAP request, ie 'cn=j*moller' * CONFIG = Configuration file */ strcpy(config_file, CONFIG); if(getvalue(entries, "LDAP_REQUEST", &value)) { strcpy(passed_in,value); } if(getvalue(entries, "CONFIG", &value)) { if ((strcmp("DEF",value)) == 0) { strcpy(config_file, CONFIG); } else { strcpy(config_file, value); } } } /* zero out the attribute pointers/data area */ for (i = 0; i < MAX_ATTRIB; i++) { read_attrs[i] = NULL; memset(attribute[i].title,0,40); } /* read in the config file */ process_cfg(config_file, &ldap_data, read_attrs, attribute); if (passed_in[0] != 0) { strcpy(ldap_data.query,passed_in); } if (ldap_data.debug != 0) { if ((logfp = fopen("web_ldap.log","w")) == 0) { printf("\n"); printf("

Unable to open requested log file: web_ldap.log

\n"); printf("\n"); } else { time(&now); sprintf(temp,"==> web_ldap request made at: %s\n",ctime(&now)); fputs(temp,logfp); if (argc > 1) { sprintf(temp," Interactive Unix Command Line Request:\n\n"); } else { sprintf(temp," Browser/Form Request:\n\n"); } fputs(temp,logfp); sprintf(temp," Server Name: %s\n", ldap_data.servername); fputs(temp,logfp); sprintf(temp," Query: %s\n", ldap_data.query); fputs(temp,logfp); sprintf(temp," Passed In: %s\n", passed_in); fputs(temp,logfp); sprintf(temp," Searchbase: %s\n",ldap_data.searchbase); fputs(temp,logfp); if (ldap_data.htmlfile[0] != 0) { sprintf(temp," HTML File: %s\n",ldap_data.htmlfile); } else { sprintf(temp," HTML File: Non Provided - Use Default Processing\n"); } fputs(temp,logfp); sprintf(temp," LDAP Port: %d\n",ldap_data.ldap_port_num); fputs(temp,logfp); sprintf(temp," Number of Attributes: %d\n",ldap_data.num_of_attrib); fputs(temp,logfp); if (ldap_data.num_of_attrib > 0) { for (i = 0; i < ldap_data.num_of_attrib; i++) { sprintf(temp," - %s\n",read_attrs[i]); fputs(temp,logfp); } } sprintf(temp,"\n==< Process Arguments: %d >==\n\n argv[0]: %s\n", argc, argv[0]); fputs(temp,logfp); if (argc >= 2) { sprintf(temp," argv[1]: %s\n",argv[1]); fputs(temp,logfp); } if (argc >= 3) { sprintf(temp," argv[2]: %s\n",argv[2]); fputs(temp,logfp); } if (argc >= 4) { sprintf(temp," argv[3]: %s\n",argv[3]); fputs(temp,logfp); } if (argc >= 5) { sprintf(temp," argv[4]: %s\n",argv[4]); fputs(temp,logfp); } fflush(logfp); fclose(logfp); } } if (ldap_data.debug != 0) { if ((logfp = fopen("web_ldap.log","a")) == 0) { } else { time(&now); sprintf(temp,"\n==< Results >==\n\n"); fputs(temp,logfp); sprintf(temp,"** performing ldap_init at %s\n", ctime(&now)); fputs(temp,logfp); fflush(logfp); fclose(logfp); } } if ( (ld = ldap_init(ldap_data.servername, ldap_data.ldap_port_num) ) == NULL) { printf("ldap_init error\n"); if (ldap_data.debug != 0) { if ((logfp = fopen("web_ldap.log","a")) == 0) { } else { sprintf(temp,"++ ldap_init error\n"); fputs(temp,logfp); fflush(logfp); fclose(logfp); } } printf("\n\n"); exit( EXIT_FAILURE ); } /*authenticate as nobody */ if (ldap_data.debug != 0) { if ((logfp = fopen("web_ldap.log","a")) == 0) { } else { time(&now); sprintf(temp,"** performing ldap_bind_s at %s\n",ctime(&now)); fputs(temp,logfp); fflush(logfp); fclose(logfp); } } if(ldap_bind_s(ld, "", "", LDAP_AUTH_SIMPLE) != 0) { printf(""); ldap_perror (ld, "ldap_simple_bind_s"); printf("\n"); if (ldap_data.debug != 0) { if ((logfp = fopen("web_ldap.log","a")) == 0) { } else { sprintf(temp,"++ ldap_bind_s error\n"); fputs(temp,logfp); fflush(logfp); fclose(logfp); } } printf("\n\n"); exit( EXIT_FAILURE ); } printf("Directory Lookup Results\n

\n");
   printf("

\n

\n");
   
   /* Get data */
   if (ldap_data.debug != 0) {
      if ((logfp = fopen("web_ldap.log","a")) == 0) {
      }
      else {
	 time(&now);
	 sprintf(temp,"** performing ldap_search_s at %s\n",ctime(&now));
	 fputs(temp,logfp);
	 fflush(logfp);
	 fclose(logfp);
      }
   }
   if(ldap_search_s(ld, ldap_data.searchbase, LDAP_SCOPE_SUBTREE,
		    ldap_data.query, read_attrs, 0, &res)
      != LDAP_SUCCESS)
     {
	ldap_perror(ld, "ldap_search_s");
     }
   
   for (e=ldap_first_entry(ld, res); e != NULL; e=ldap_next_entry(ld, e))
     {
	dn = ldap_get_dn(ld, e);
	
	if (ldap_data.debug != 0) {	
	   if ((logfp = fopen("web_ldap.log","a")) == 0) {
	   }
	   else {
	      sprintf(temp," dn=%s\n", dn);
	      fputs(temp,logfp);
	      fflush(logfp);
	      fclose(logfp);
	   }
	}
	
	/*print each attribute */
	for (a = ldap_first_attribute(ld, e, &ptr);
	     a != NULL;
	     a = ldap_next_attribute(ld, e, ptr) )
	  {
	     strcpy(attrs_name, a);
	     /* print attribute name */
	     printf("%s: ", attrs_name);
	     
	     /*print each value */
	     
	     vals = ldap_get_values(ld, e, a);
	     
	     for(i=0; vals[i] != NULL; i++)
	       /* print value of attribute */
	       printf("%s\n", vals[i],strlen(vals[i]));
	   
	     ldap_value_free(vals);
	  } /*end for*/
	free(a);
	free(dn);
	printf("

\n"); } /*free the search results */ ldap_msgfree (res); printf("

\n"); ldap_unbind(ld); if (ldap_data.debug != 0) { if ((logfp = fopen("web_ldap.log","a")) == 0) { } else { time(&now); sprintf(temp,"\nFinished gathering results at %s\n",ctime(&now)); fputs(temp,logfp); sprintf(temp,"==< Done >==\n"); fputs(temp,logfp); fflush(logfp); fclose(logfp); } } printf("\n\n"); } /* Process the user passed in configuration file */ void process_cfg(char *config, LDAP_INFO *ldap_data, char *attribute_array[], ATTRIB_TITLE *disp_attrib) { char file_data[1024]; char upfile_data[1024]; char temp[1024]; int lcomma, lcolon, attrib_pos; FILE * fp; strcpy(ldap_data->servername,SERVER); ldap_data->ldap_port_num = LDAP_PORT; strcpy(ldap_data->query,"cn=jens*moller"); /* config file needs to be in the cgi-bin directory */ if ((fp = fopen(config,"r")) == 0) { return; } attrib_pos = 0; for (;;) { /* read until eof */ fgets (file_data,1024,fp); if (feof(fp)) break; if (file_data[0] != '#') { /* skip commented lines */ upcase_string(file_data,upfile_data); /* get the server specific data */ if (strscn(upfile_data,"SERVER:") == 0) { lcolon = find_colon(file_data) + 1; lcomma = find_comma(file_data); if (lcomma > 0) { memset(ldap_data->servername,0,MAX_CHARS); strncpy(ldap_data->servername,&file_data[lcolon], lcomma - lcolon); ldap_data->ldap_port_num = atoi(&file_data[lcomma + 1]); } else { strcpy(ldap_data->servername,&file_data[lcolon]); } squeeze_blanks(ldap_data->servername); } else if (strscn(upfile_data,"SEARCHBASE:") == 0) { lcolon = find_colon(file_data) + 1; strcpy(ldap_data->searchbase,&file_data[lcolon]); squeeze_blanks(ldap_data->searchbase); } else if (strscn(upfile_data,"HTMLFILE:") == 0) { lcolon = find_colon(file_data) + 1; strcpy(ldap_data->htmlfile,&file_data[lcolon]); } else if (strscn(upfile_data,"DEBUG:") == 0) { lcolon = find_colon(file_data) + 1; ldap_data->debug = atoi(&file_data[lcolon]); } /* get the attribute list */ else if ((file_data[0] != ' ') && (file_data[0] != 0)) { memset(temp,0,1024); /* data appears as a comma delimited list, where: * * attrib_name (char),display_length (int) * * (default length = 20 if display_length undefined) * * is how each record is defined */ lcomma = find_comma(file_data); if (lcomma < 0) { strcpy(temp,file_data); squeeze_blanks(temp); } else { strncpy(temp,file_data,lcomma); squeeze_blanks(temp); } attribute_array[attrib_pos] = malloc(strlen(temp)); strcpy(attribute_array[attrib_pos],temp); attrib_pos++; ldap_data->num_of_attrib = attrib_pos; } } } } /* find character substring matches */ int strscn(char * istring, char * tstring) { int i, status, icmp, len; status = -1; len = (strlen(istring) + 1) - strlen(tstring); if (len < 1) len = 1; for (i=0;i