2 * Form Processing Web application that returns html based
3 * LDAP data with definitions from a configuration file.
5 * Jens Moller - Dec 11, 1998
10 #include <sys/types.h>
15 #include <ac/stdlib.h>
16 #include <ac/string.h>
18 #include <ac/unistd.h>
23 #include "maint_form.h" /* for HTML Form manipulations */
30 #define SERVER "ldap.bigfoot.com"
33 #define CONFIG "web_ldap.cfg"
36 #define MAX_ATTRIB 100
38 #define version "v 1.1"
40 entry entries[MAX_ENTRIES];
43 char servername[MAX_CHARS];
44 char query[MAX_CHARS];
45 char searchbase[MAX_CHARS];
46 char htmlfile[MAX_CHARS];
49 int debug; /* if zero, no debug text displayed */
56 /* function Prototypes */
57 void process_cfg(char *config,
59 char *attribute_array[],
60 ATTRIB_TITLE *disp_attrib);
62 int strscn(char *istring,
65 void upcase_string(char *array,
68 int find_comma(char *array);
70 int find_colon(char *array);
72 void squeeze_blanks(char *array);
74 /* Pass in nothing and use the default config file, or
75 * pass in the config file to use */
77 main(int argc, char ** argv) {
80 int i, j, cl, x, how_many;
84 char *read_attrs[MAX_ATTRIB]; /* up to MAX_ATTRIB attribs returned */
85 struct berval **bvals;
86 char attrs_name[MAX_CHARS];
87 char config_file[MAX_CHARS];
89 char passed_in[MAX_CHARS];
91 ATTRIB_TITLE attribute[MAX_ATTRIB];
96 /* html initialization */
97 printf("Content-type: text/html\n\n");
98 printf("<html>\n<head>\n<title>Web Ldap Results</title>\n");
100 printf("<body text=\"#000000\" bgcolor=\"#FFFFFF\">\n");
101 printf("<h2>Web LDAP Results</h2>\n");
103 /* initialize ldap_data structure */
104 memset(ldap_data.servername,0,MAX_CHARS);
105 memset(ldap_data.query,0,MAX_CHARS);
106 memset(ldap_data.searchbase,0,MAX_CHARS);
107 memset(ldap_data.htmlfile,0,MAX_CHARS);
108 ldap_data.ldap_port_num = 0;
109 ldap_data.num_of_attrib = 0;
112 memset(passed_in,0,MAX_CHARS);
114 if (argc > 1) { /* interactive mode */
116 /* To use in this fashion when run from a Unix command line:
118 * > web_ldap DEF "cn=j*moller"
119 * > web_ldap DEF cn=jens moller
121 * NOTE: The quotes are required if a special
122 * character is a part of the LDAP request such
123 * as the asterix (*) in the above example.
126 /* Parameters passed in are
128 * argv[0] = Program Name (argc = 1)
129 * argv[1] = Config File Name (argc = 2)
130 * argv[2] = Ldap Request (argc => 3)
133 /* do we use a different config file ? */
134 strcpy(config_file, CONFIG);
137 if ((strcmp(argv[1],"DEF")) == 0) {
138 strcpy(config_file, CONFIG);
141 strcpy(config_file, argv[1]);
145 /* is there an LDAP request?
146 * if so, it may take up to 3 argv[x] values */
150 strcpy(temp, argv[2]);
154 strcpy(temp, argv[2]);
156 strcat(temp, argv[3]);
160 strcpy(temp, argv[2]);
162 strcat(temp, argv[3]);
164 strcat(temp, argv[4]);
168 for (i=0; i<strlen(temp);i++) {
169 if ((temp[i] != '"') &&
171 passed_in[j] = temp[i];
177 else { /* Non Interactive Mode - read from a form */
178 if (strcompare(getenv("REQUEST_METHOD"),"POST"))
180 printf("<p>++ Error - This script should be referenced with a METHOD of POST.\n");
181 exit( EXIT_FAILURE );
183 if (strcompare(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded"))
185 printf("<p>++ Error - This script can only be used to decode form results. \n");
186 exit( EXIT_FAILURE );
188 cl = atoi(getenv("CONTENT_LENGTH"));
190 for(x=0; cl && (!feof(stdin));x++)
192 entries[x].val = fmakeword(stdin,'&',&cl);
193 plustospace(entries[x].val);
194 unescape_url(entries[x].val);
195 entries[x].name = makeword(entries[x].val,'=');
196 how_many = x; /* keep track of how many we got */
199 printf("entries[%d].name=%s - ",x,entries[x].name);
200 printf("entries[%d].val =%s<br>\n",x,entries[x].val);
204 entries[x].name = NULL; /* entry after last valid one */
205 entries[x].val = NULL; /* is set to NULL */
207 if(!getvalue(entries, "FORM", &value))
209 printf("%s%s%s", "This script expected a 'FORM' value returned ",
210 "and did not get one. Make sure the HTML used for this ",
211 "script is correct.");
212 exit( EXIT_FAILURE );
216 * LDAP_REQUEST - actual LDAP request, ie 'cn=j*moller'
217 * CONFIG = Configuration file
220 strcpy(config_file, CONFIG);
222 if(getvalue(entries, "LDAP_REQUEST", &value)) {
223 strcpy(passed_in,value);
226 if(getvalue(entries, "CONFIG", &value)) {
227 if ((strcmp("DEF",value)) == 0) {
228 strcpy(config_file, CONFIG);
231 strcpy(config_file, value);
237 /* zero out the attribute pointers/data area */
238 for (i = 0; i < MAX_ATTRIB; i++) {
239 read_attrs[i] = NULL;
240 memset(attribute[i].title,0,40);
243 /* read in the config file */
244 process_cfg(config_file, &ldap_data, read_attrs, attribute);
246 if (passed_in[0] != 0) {
247 strcpy(ldap_data.query,passed_in);
250 if (ldap_data.debug != 0) {
251 if ((logfp = fopen("web_ldap.log","w")) == 0) {
252 printf("<font color=red size=5>\n");
253 printf("<p>Unable to open requested log file: web_ldap.log<p>\n");
258 sprintf(temp,"==> web_ldap request made at: %s\n",ctime(&now));
261 sprintf(temp," Interactive Unix Command Line Request:\n\n");
264 sprintf(temp," Browser/Form Request:\n\n");
267 sprintf(temp," Server Name: %s\n", ldap_data.servername);
269 sprintf(temp," Query: %s\n", ldap_data.query);
271 sprintf(temp," Passed In: %s\n", passed_in);
273 sprintf(temp," Searchbase: %s\n",ldap_data.searchbase);
275 if (ldap_data.htmlfile[0] != 0) {
276 sprintf(temp," HTML File: %s\n",ldap_data.htmlfile);
279 sprintf(temp," HTML File: Non Provided - Use Default Processing\n");
282 sprintf(temp," LDAP Port: %d\n",ldap_data.ldap_port_num);
284 sprintf(temp," Number of Attributes: %d\n",ldap_data.num_of_attrib);
286 if (ldap_data.num_of_attrib > 0) {
287 for (i = 0; i < ldap_data.num_of_attrib; i++) {
288 sprintf(temp," - %s\n",read_attrs[i]);
293 sprintf(temp,"\n==< Process Arguments: %d >==\n\n argv[0]: %s\n",
297 sprintf(temp," argv[1]: %s\n",argv[1]);
301 sprintf(temp," argv[2]: %s\n",argv[2]);
305 sprintf(temp," argv[3]: %s\n",argv[3]);
309 sprintf(temp," argv[4]: %s\n",argv[4]);
317 if (ldap_data.debug != 0) {
318 if ((logfp = fopen("web_ldap.log","a")) == 0) {
322 sprintf(temp,"\n==< Results >==\n\n");
324 sprintf(temp,"** performing ldap_init at %s\n", ctime(&now));
330 if ( (ld = ldap_init(ldap_data.servername, ldap_data.ldap_port_num) ) == NULL)
332 printf("<font color=red><b>ldap_init error</b></font>\n");
333 if (ldap_data.debug != 0) {
334 if ((logfp = fopen("web_ldap.log","a")) == 0) {
337 sprintf(temp,"++ ldap_init error\n");
343 printf("</body>\n</html>\n");
344 exit( EXIT_FAILURE );
347 /*authenticate as nobody */
348 if (ldap_data.debug != 0) {
349 if ((logfp = fopen("web_ldap.log","a")) == 0) {
353 sprintf(temp,"** performing ldap_bind_s at %s\n",ctime(&now));
359 if(ldap_bind_s(ld, "", "", LDAP_AUTH_SIMPLE) != 0)
361 printf("<font color=red><b>");
362 ldap_perror (ld, "ldap_simple_bind_s");
363 printf("</b></font>\n");
365 if (ldap_data.debug != 0) {
366 if ((logfp = fopen("web_ldap.log","a")) == 0) {
369 sprintf(temp,"++ ldap_bind_s error\n");
375 printf("</body>\n</html>\n");
376 exit( EXIT_FAILURE );
379 printf("<b>Directory Lookup Results</b>\n<pre>\n");
380 printf("<hr><p>\n<pre>\n");
383 if (ldap_data.debug != 0) {
384 if ((logfp = fopen("web_ldap.log","a")) == 0) {
388 sprintf(temp,"** performing ldap_search_s at %s\n",ctime(&now));
394 if(ldap_search_s(ld, ldap_data.searchbase, LDAP_SCOPE_SUBTREE,
395 ldap_data.query, read_attrs, 0, &res)
398 ldap_perror(ld, "ldap_search_s");
401 for (e=ldap_first_entry(ld, res); e != NULL; e=ldap_next_entry(ld, e))
403 dn = ldap_get_dn(ld, e);
405 if (ldap_data.debug != 0) {
406 if ((logfp = fopen("web_ldap.log","a")) == 0) {
409 sprintf(temp," dn=%s\n", dn);
416 /*print each attribute */
417 for (a = ldap_first_attribute(ld, e, &ptr);
419 a = ldap_next_attribute(ld, e, ptr) )
421 strcpy(attrs_name, a);
422 /* print attribute name */
423 printf("%s: ", attrs_name);
425 /*print each value */
427 vals = ldap_get_values(ld, e, a);
429 for(i=0; vals[i] != NULL; i++)
430 /* print value of attribute */
431 printf("%s\n", vals[i],strlen(vals[i]));
433 ldap_value_free(vals);
439 /*free the search results */
446 if (ldap_data.debug != 0) {
447 if ((logfp = fopen("web_ldap.log","a")) == 0) {
451 sprintf(temp,"\nFinished gathering results at %s\n",ctime(&now));
453 sprintf(temp,"==< Done >==\n");
459 printf("</body>\n</html>\n");
462 /* Process the user passed in configuration file */
463 void process_cfg(char *config,
464 LDAP_INFO *ldap_data,
465 char *attribute_array[],
466 ATTRIB_TITLE *disp_attrib) {
468 char file_data[1024];
469 char upfile_data[1024];
471 int lcomma, lcolon, attrib_pos;
474 strcpy(ldap_data->servername,SERVER);
475 ldap_data->ldap_port_num = LDAP_PORT;
476 strcpy(ldap_data->query,"cn=jens*moller");
478 /* config file needs to be in the cgi-bin directory */
479 if ((fp = fopen(config,"r")) == 0) {
485 for (;;) { /* read until eof */
486 fgets (file_data,1024,fp);
488 if (file_data[0] != '#') { /* skip commented lines */
489 upcase_string(file_data,upfile_data);
491 /* get the server specific data */
492 if (strscn(upfile_data,"SERVER:") == 0) {
493 lcolon = find_colon(file_data) + 1;
494 lcomma = find_comma(file_data);
496 memset(ldap_data->servername,0,MAX_CHARS);
497 strncpy(ldap_data->servername,&file_data[lcolon],
499 ldap_data->ldap_port_num = atoi(&file_data[lcomma + 1]);
502 strcpy(ldap_data->servername,&file_data[lcolon]);
504 squeeze_blanks(ldap_data->servername);
506 else if (strscn(upfile_data,"SEARCHBASE:") == 0) {
507 lcolon = find_colon(file_data) + 1;
508 strcpy(ldap_data->searchbase,&file_data[lcolon]);
509 squeeze_blanks(ldap_data->searchbase);
511 else if (strscn(upfile_data,"HTMLFILE:") == 0) {
512 lcolon = find_colon(file_data) + 1;
513 strcpy(ldap_data->htmlfile,&file_data[lcolon]);
515 else if (strscn(upfile_data,"DEBUG:") == 0) {
516 lcolon = find_colon(file_data) + 1;
517 ldap_data->debug = atoi(&file_data[lcolon]);
520 /* get the attribute list */
521 else if ((file_data[0] != ' ') && (file_data[0] != 0)) {
523 /* data appears as a comma delimited list, where:
525 * attrib_name (char),display_length (int)
527 * (default length = 20 if display_length undefined)
529 * is how each record is defined */
530 lcomma = find_comma(file_data);
532 strcpy(temp,file_data);
533 squeeze_blanks(temp);
536 strncpy(temp,file_data,lcomma);
537 squeeze_blanks(temp);
539 attribute_array[attrib_pos] = malloc(strlen(temp));
540 strcpy(attribute_array[attrib_pos],temp);
542 ldap_data->num_of_attrib = attrib_pos;
548 /* find character substring matches */
549 int strscn(char * istring,
551 int i, status, icmp, len;
553 len = (strlen(istring) + 1) - strlen(tstring);
554 if (len < 1) len = 1;
555 for (i=0;i<len ;i++) {
556 icmp = memcmp(&istring[i],tstring,strlen(tstring));
565 /* convert the array to uparray, where uparray contains upper
567 void upcase_string(char *array,
570 for (i=0; i < strlen(array); i++) {
571 uparray[i] = toupper((unsigned char) array[i]);
577 /* return the position of the first comma - ',' - from within a string */
578 int find_comma(char *array){
580 for (i = 0; i < strlen(array); i++) {
581 if (array[i] == ',') return(i);
586 /* return the position of the first colon - '.' - from within a string */
587 int find_colon(char *array){
589 for (i = 0; i < strlen(array); i++) {
590 if (array[i] == ':') return(i);
595 /* Remove unneeded blanks from a character array. Don't leave
596 * any at the end & throw away any newline characters */
597 void squeeze_blanks(char *array){
602 pos = 0; /* location within temp array */
603 blank = 0; /* # of blanks written in a row */
605 for (i = 0; i < strlen(array); i++) {
606 if (array[i] != ' ') {
607 temp[pos] = array[i];
611 else if ((blank == 0) &&
614 temp[pos] = array[i];
620 if (array[strlen(array) - 1] <= ' ')
621 array[strlen(array) - 1] = 0;