tutor.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /** --- BEGIN COPYRIGHT BLOCK ---
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. --- END COPYRIGHT BLOCK --- */
  6. /*
  7. * tutor.c - Take a qs, and spit out the appropriate tutorial
  8. *
  9. * All blame to Mike McCool
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include "dsgw.h"
  14. #define BASE_MAN_DIRECTORY "manual/"
  15. #define BASE_INFO_DIRECTORY "info/"
  16. #define HELP_INDEX_HTML "manual/index.html"
  17. /*#define MANUAL_HPATH "bin/lang?file=" DSGW_MANUALSHORTCUT "/"*/
  18. /* Copied from ldapserver/lib/base/util.c */
  19. static int
  20. my_util_uri_is_evil(char *t)
  21. {
  22. register int x;
  23. for(x = 0; t[x]; ++x) {
  24. if(t[x] == '/') {
  25. if(t[x+1] == '/')
  26. return 1;
  27. if(t[x+1] == '.') {
  28. switch(t[x+2]) {
  29. case '.':
  30. if((!t[x+3]) || (t[x+3] == '/'))
  31. return 1;
  32. case '/':
  33. case '\0':
  34. return 1;
  35. }
  36. }
  37. }
  38. #ifdef XP_WIN32
  39. /* On NT, the directory "abc...." is the same as "abc"
  40. * The only cheap way to catch this globally is to disallow
  41. * names with the trailing "."s. Hopefully this is not over
  42. * restrictive
  43. */
  44. if ((t[x] == '.') && ( (t[x+1] == '/') || (t[x+1] == '\0') )) {
  45. return 1;
  46. }
  47. #endif
  48. }
  49. return 0;
  50. }
  51. FILE *
  52. _open_html_file( char *filename )
  53. {
  54. FILE *f;
  55. char *mypath;
  56. char *p;
  57. p = dsgw_file2path( DSGW_MANROOT, "slapd/gw/" );
  58. mypath = (char *)dsgw_ch_malloc( strlen( p ) +
  59. strlen( filename ) + 1 );
  60. sprintf( mypath, "%s%s", p, filename );
  61. if (!(f = fopen( mypath, "r" ))) {
  62. dsgw_error( DSGW_ERR_OPENHTMLFILE, filename, DSGW_ERROPT_EXIT,
  63. 0, NULL );
  64. }
  65. free( p );
  66. free( mypath );
  67. return f;
  68. }
  69. /* Had to copy and paste so wouldn't set referer. */
  70. void _my_return_html_file(char *filename, char *base) {
  71. char line[BIG_LINE];
  72. FILE *html = _open_html_file(filename);
  73. if(base) {
  74. char *tmp;
  75. char *surl=getenv("SERVER_URL");
  76. char *sn=dsgw_ch_strdup(getenv("SCRIPT_NAME"));
  77. tmp=strchr(&(sn[1]), '/');
  78. *tmp='\0';
  79. dsgw_emitf("<BASE href=\"%s%s/%s\">\n", surl, sn, base);
  80. }
  81. while( fgets(line, BIG_LINE, html)) {
  82. dsgw_emits( line );
  83. }
  84. }
  85. int
  86. main(
  87. int argc,
  88. char *argv[]
  89. #ifdef DSGW_DEBUG
  90. ,char *env[]
  91. #endif
  92. )
  93. {
  94. char *qs = getenv("QUERY_STRING");
  95. char *html=NULL;
  96. char *base=NULL;
  97. #ifdef DSGW_DEBUG
  98. dsgw_logstringarray( "env", env );
  99. #endif
  100. if(qs == NULL || *qs == '\0') {
  101. dsgw_send_header();
  102. _my_return_html_file(BASE_MAN_DIRECTORY HELP_INDEX_HTML, NULL);
  103. exit(0);
  104. } else {
  105. /* parse the query string: */
  106. auto char *p, *iter = NULL;
  107. /*get a pointer to the context. It should be the last part of the qs*/
  108. p = ldap_utf8strtok_r( qs, "&", &iter );
  109. /*
  110. * Get the conf file name. It'll be translated
  111. * into /dsgw/context/CONTEXT.conf if
  112. * CONTEXT is all alphanumeric (no slahes,
  113. * or dots). CONTEXT is passed into the cgi.
  114. * if context=CONTEXT is not there, or PATH_INFO
  115. * was used, then use dsgw.conf
  116. */
  117. if ( iter != NULL && !strncasecmp( iter, "context=", 8 )) {
  118. context = dsgw_ch_strdup( iter + 8 );
  119. dsgw_form_unescape( context );
  120. }
  121. }
  122. dsgw_init( argc, argv, DSGW_METHOD_GET );
  123. html = (char *) dsgw_ch_malloc(strlen(qs)+10+10);
  124. sprintf(html, "%s.html", qs);
  125. if (my_util_uri_is_evil(html)) {
  126. dsgw_send_header();
  127. dsgw_emits( "<CENTER><H2>Error</H2></CENTER>\n"
  128. "<P>\n"
  129. "URL contains dangerous characters. Cannot display\n"
  130. "help text." );
  131. exit( 0 );
  132. }
  133. if(qs[0]=='!') {
  134. qs++;
  135. if(!strncmp(qs, BASE_INFO_DIRECTORY, strlen(BASE_INFO_DIRECTORY))) {
  136. sprintf(html, "%s.html", qs);
  137. } else if(!strncmp(qs, BASE_MAN_DIRECTORY, strlen(BASE_MAN_DIRECTORY))) {
  138. if(!strstr(qs, ".html")) {
  139. sprintf(html, "%s.htm", qs);
  140. } else {
  141. sprintf(html, "%s", qs);
  142. }
  143. base=qs;
  144. }
  145. else {
  146. char line[BIG_LINE];
  147. FILE *map=NULL;
  148. char *man_index=NULL;
  149. man_index = dsgw_file2path ( DSGW_MANROOT, "slapd/gw/manual/index.map" );
  150. html[0]='\0';
  151. map=fopen(man_index, "r");
  152. if(!map)
  153. goto ohwell;
  154. while(fgets(line, BIG_LINE, map)) {
  155. if(line[0]==';')
  156. continue;
  157. else if(ldap_utf8isspace(line))
  158. continue;
  159. else {
  160. /* parse out the line */
  161. register char *head=NULL, *tail=NULL;
  162. int found;
  163. head=&(line[0]);
  164. tail=head;
  165. found=0;
  166. while(*tail) {
  167. if(ldap_utf8isspace(tail) || *tail=='=') {
  168. *tail='\0';
  169. found=1;
  170. /* get rid of extra stuff at the end */
  171. tail++;
  172. while(1) {
  173. if (*tail == 0) {
  174. ++tail; /* This looks wrong. */
  175. break;
  176. }
  177. LDAP_UTF8INC(tail);
  178. if((!ldap_utf8isspace(tail)) && (*tail!='='))
  179. break;
  180. }
  181. break;
  182. }
  183. LDAP_UTF8INC(tail);
  184. }
  185. if(!found) continue;
  186. /* script name is in head */
  187. if(strncasecmp(head, qs, strlen(qs))) {
  188. continue;
  189. }
  190. /* match found. get the actual file name */
  191. head=tail;
  192. /* Step on CRs and LFs. */
  193. while(*tail) {
  194. if((*tail=='\r') || (*tail=='\n') || (*tail==';')) {
  195. *tail='\0';
  196. break;
  197. }
  198. LDAP_UTF8INC(tail);
  199. }
  200. #if 0
  201. /* No longer remove whitespace at end of line. Now is whitespace in link. */
  202. while(*LDAP_UTF8DEC(tail)) {
  203. if(ldap_utf8isspace(tail)) *tail='\0';
  204. else break;
  205. }
  206. #endif
  207. /* assumedly, head should now have the proper HTML file
  208. * from the manual inside. redirect the client 'cause
  209. * there's no other way to get them to jump to the
  210. * right place.
  211. * Looks like:
  212. * http://host:port/dsgw/bin/lang?context=CONTEXT&file=.MANUAL/FILE.HTM
  213. * Where MANUAL is literal
  214. */
  215. dsgw_emitf("Location: %s%s/%s\n\n",
  216. gc->gc_urlpfxmain, DSGW_MANUALSHORTCUT, head);
  217. fclose(map);
  218. exit(0);
  219. }
  220. }
  221. fclose(map);
  222. free( man_index );
  223. ohwell:
  224. if(!html[0])
  225. sprintf(html, "%s%s.html", BASE_MAN_DIRECTORY, qs);
  226. }
  227. dsgw_send_header();
  228. _my_return_html_file(html, base);
  229. } else {
  230. dsgw_send_header();
  231. dsgw_emits("<TITLE>Directory Server Gateway Help</TITLE>\n");
  232. dsgw_emits("\n");
  233. dsgw_emits("<frameset BORDER=0 FRAMEBORDER=NO rows=\"57,*\" "
  234. "onLoad=\"top.master=top.opener.top;top.master.helpwin=self;\" "
  235. "onUnload=\"if (top.master) { top.master.helpwin=0; }\">\n" );
  236. dsgw_emitf("<frame src=\"%s?!info/infonav&context=%s\" scrolling=no "
  237. "marginwidth=0 marginheight=0 "
  238. "name=\"infobuttons\">\n", dsgw_getvp(DSGW_CGINUM_TUTOR), context);
  239. dsgw_emitf("<frame src=\"%s?!%s&context=%s\" "
  240. "name=\"infotopic\">\n", dsgw_getvp(DSGW_CGINUM_TUTOR), qs, context);
  241. dsgw_emits("</frameset>\n");
  242. }
  243. return 1;
  244. }