Update auth.php with LDAP option to specify port
[racktables-incomplete-works] / wwwroot / index.php
1 <?php
2
3 # This file is a part of RackTables, a datacenter and server room management
4 # framework. See accompanying file "COPYING" for the full copyright and
5 # licensing information.
6
7 ob_start();
8 require_once 'inc/pre-init.php';
9 try {
10 // Switch block below is a module request dispatcher.
11 // Dispatches based on module request.
12 // The last string 'interface' is the default.
13 $requestedModule = array_key_exists ('module', $_REQUEST) ? $_REQUEST['module'] : 'interface';
14
15 switch ($requestedModule)
16 {
17 case 'interface':
18 require_once 'inc/interface.php';
19 // init.php has to be included after interface.php, otherwise the bits
20 // set by local.php get lost
21 require_once 'inc/init.php';
22 prepareNavigation();
23 // Security context is built on the requested page/tab/bypass data,
24 // do not override.
25 fixContext();
26 redirectIfNecessary();
27 assertPermission();
28 header ('Content-Type: text/html; charset=UTF-8');
29 // call the main handler - page or tab handler.
30 if (isset ($tabhandler[$pageno][$tabno]))
31 {
32 if (! is_callable ($tabhandler[$pageno][$tabno]))
33 throw new RackTablesError ("Missing handler function for node '${pageno}-${tabno}'", RackTablesError::INTERNAL);
34 call_user_func ($tabhandler[$pageno][$tabno], getBypassValue());
35 }
36 elseif (isset ($page[$pageno]['handler']))
37 {
38 if (! is_callable ($page[$pageno]['handler']))
39 throw new RackTablesError ("Missing handler function for node '${pageno}'", RackTablesError::INTERNAL);
40 $page[$pageno]['handler'] ($tabno);
41 }
42 else
43 throw new RackTablesError ("Failed to find handler for page '${pageno}', tab '${tabno}'", RackTablesError::INTERNAL);
44 // Embed the current text in OB into interface layout (the latter also
45 // empties color message buffer).
46 $contents = ob_get_contents();
47 ob_clean();
48 renderInterfaceHTML ($pageno, $tabno, $contents);
49 break;
50
51 case 'chrome':
52 require_once 'inc/init.php';
53 require_once 'inc/solutions.php';
54 genericAssertion ('uri', 'string');
55 proxyStaticURI ($_REQUEST['uri']);
56 break;
57
58 case 'download':
59 require_once 'inc/init.php';
60 $pageno = 'file';
61 $tabno = 'download';
62 fixContext();
63 assertPermission();
64 $file = getFile (getBypassValue());
65 header("Content-Type: {$file['type']}");
66 header("Content-Length: {$file['size']}");
67 if (! array_key_exists ('asattach', $_REQUEST) or $_REQUEST['asattach'] != 'no')
68 header("Content-Disposition: attachment; filename={$file['name']}");
69 echo $file['contents'];
70 break;
71
72 case 'image':
73 # The difference between "image" and "download" ways to serve the same
74 # picture file is that the former is used in <IMG SRC=...> construct,
75 # and the latter is accessed as a standalone URL and can reply with any
76 # Content-type. Hence "image" module indicates failures with internally
77 # built images, and "download" can return a full-fledged "permission
78 # denied" or "exception" HTML page instead of the file requested.
79 require_once 'inc/init.php'; // for authentication check
80 require_once 'inc/solutions.php';
81 try
82 {
83 dispatchImageRequest();
84 }
85 catch (RTPermissionDenied $e)
86 {
87 ob_clean();
88 renderAccessDeniedImage();
89 }
90 catch (Exception $e)
91 {
92 ob_clean();
93 renderErrorImage();
94 }
95 break;
96
97 case 'svg':
98 require_once 'inc/init.php';
99 require_once 'inc/solutions.php';
100 header ('Content-Type: image/svg+xml');
101 echo '<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>' . "\n";
102 echo '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' . "\n";
103 try
104 {
105 genericAssertion ('view', 'string');
106 if (! array_key_exists ($_REQUEST['view'], $svghandler))
107 throw new InvalidRequestArgException ('view', $_REQUEST['view'], 'undefined view');
108 if (! is_callable ($svghandler[$_REQUEST['view']]))
109 throw new RackTablesError ('missing handler function', RackTablesError::INTERNAL);
110 call_user_func ($svghandler[$_REQUEST['view']]);
111 }
112 catch (RTPermissionDenied $e)
113 {
114 ob_clean();
115 printSVGMessageBar ('permission denied', array ('fill' => 'white'), array ('fill' => 'black', 'stroke' => 'gray'));
116 }
117 catch (InvalidRequestArgException $e)
118 {
119 ob_clean();
120 printSVGMessageBar ('malformed HTTP request', array(), array ('fill' => 'yellow', 'stroke' => 'black'));
121 }
122 catch (EntityNotFoundException $e)
123 {
124 ob_clean();
125 printSVGMessageBar ('no such record', array(), array ('fill' => 'yellow', 'stroke' => 'black'));
126 }
127 catch (RackTablesError $e)
128 {
129 ob_clean();
130 printSVGMessageBar ('RT error: ' . $e->getMessage(), array(), array ('fill' => 'red', 'stroke' => 'black'));
131 }
132 catch (Exception $e)
133 {
134 ob_clean();
135 printSVGMessageBar ('unknown error', array(), array ('fill' => 'red', 'stroke' => 'black'));
136 }
137 break;
138
139 case 'progressbar':
140 # Unlike images (and like static content), progress bars are processed
141 # without a permission check, but only for authenticated users.
142 require_once 'inc/init.php';
143 require_once 'inc/solutions.php';
144 try
145 {
146 genericAssertion ('done', 'uint0');
147 // 'progressbar's never change, make browser cache the result
148 if (checkCachedResponse (0, CACHE_DURATION))
149 break;
150 renderProgressBarImage ($_REQUEST['done']);
151 }
152 catch (Exception $e)
153 {
154 ob_clean();
155 renderProgressBarError();
156 }
157 break;
158
159 case 'progressbar4':
160 # Unlike images (and like static content), progress bars are processed
161 # without a permission check, but only for authenticated users.
162 require_once 'inc/init.php';
163 require_once 'inc/solutions.php';
164 try
165 {
166 renderProgressBar4Image ($_REQUEST['px1'], $_REQUEST['px2'], $_REQUEST['px3']);
167 }
168 catch (Exception $e)
169 {
170 ob_clean();
171 renderProgressBarError();
172 }
173 break;
174
175 case 'ajax':
176 require_once 'inc/init.php';
177 require_once 'inc/ajax-interface.php';
178 require_once 'inc/solutions.php';
179 try
180 {
181 genericAssertion ('ac', 'string');
182 $ac = $_REQUEST['ac'];
183 if (isset ($ajaxhandler[$ac]))
184 $ajaxhandler[$ac]();
185 else
186 {
187 ob_clean();
188 echo "NAK\nMalformed request";
189 }
190 }
191 catch (RTPermissionDenied $e)
192 {
193 ob_clean();
194 # FIXME: the remote client could be expecting JSON data instead
195 echo "NAK\nPermission denied";
196 }
197 catch (Exception $e)
198 {
199 ob_clean();
200 echo "NAK\nRuntime exception: ". $e->getMessage();
201 }
202 break;
203
204 case 'redirect':
205 // Include init after ophandlers/snmp, not before, so local.php can redefine things.
206 require_once 'inc/ophandlers.php';
207 // snmp.php is an exception, it is treated by a special hack
208 if (isset ($_REQUEST['op']) and $_REQUEST['op'] == 'querySNMPData')
209 require_once 'inc/snmp.php';
210 require_once 'inc/init.php';
211 try
212 {
213 genericAssertion ('op', 'string');
214 $op = $_REQUEST['op'];
215 prepareNavigation();
216 $location = buildRedirectURL();
217 // FIXME: find a better way to handle this error
218 if ($op == 'addFile' && !isset($_FILES['file']['error']))
219 throw new RackTablesError ('File upload error, check upload_max_filesize in php.ini', RackTablesError::MISCONFIGURED);
220 fixContext();
221 if
222 (
223 !isset ($ophandler[$pageno][$tabno][$op]) or
224 ! is_callable ($ophandler[$pageno][$tabno][$op])
225 )
226 throw new RackTablesError ("Invalid navigation data for '${pageno}-${tabno}-${op}'", RackTablesError::INTERNAL);
227 // We have a chance to handle an error before starting HTTP header.
228 if (!isset ($delayauth["${pageno}-${tabno}-${op}"]))
229 assertPermission();
230 # Call below does the job of bypass argument assertion, if such is required,
231 # so the ophandler function doesn't have to re-assert this portion of its
232 # arguments. And it would be even better to pass returned value to ophandler,
233 # so it is not necessary to remember the name of bypass in it.
234 getBypassValue();
235 if (strlen ($redirect_to = call_user_func ($ophandler[$pageno][$tabno][$op])))
236 $location = $redirect_to;
237 }
238 // known "soft" failures require a short error message
239 catch (InvalidRequestArgException $e)
240 {
241 ob_clean();
242 showError ($e->getMessage());
243 }
244 catch (RTDatabaseError $e)
245 {
246 ob_clean();
247 showError ('Database error: ' . $e->getMessage());
248 }
249 catch (RTPermissionDenied $e)
250 {
251 ob_clean();
252 showError ('Operation not permitted');
253 }
254 redirectUser ($location);
255 // any other error requires no special handling and will be caught outside
256 break;
257
258 case 'popup':
259 require_once 'inc/popup.php';
260 require_once 'inc/init.php';
261 renderPopupHTML();
262 break;
263
264 case 'upgrade':
265 require_once 'inc/config.php'; // for CODE_VERSION
266 require_once 'inc/dictionary.php';
267 require_once 'inc/functions.php'; // for ip translation functions
268 require_once 'inc/upgrade.php';
269 renderUpgraderHTML();
270 break;
271
272 case 'installer':
273 require_once 'inc/dictionary.php';
274 require_once 'inc/config.php';
275 require_once 'inc/install.php';
276 renderInstallerHTML();
277 break;
278
279 default:
280 throw new InvalidRequestArgException ('module', $requestedModule);
281 }
282 ob_end_flush();
283 }
284 catch (Exception $e)
285 {
286 ob_end_clean();
287 printException ($e);
288 }
289 ?>