r4363 index.php: take care of "permission denied" in "ajax" module
[racktables] / wwwroot / index.php
CommitLineData
b325120a 1<?php
90a3d6d8 2ob_start();
91bd1d6e
DO
3# Neither "throw/catch" for custom exceptions nor printException() will
4# work without first loading exceptions.php.
5require_once 'inc/exceptions.php';
90a3d6d8 6try {
87c744a9
DO
7// Code block below is a module request dispatcher. Turning it into a
8// function will break things because of the way require() works.
c5dfde62 9 switch (TRUE)
36ef72d9 10 {
c5dfde62
DO
11 case ! array_key_exists ('module', $_REQUEST):
12 case 'interface' == $_REQUEST['module']:
13 require_once 'inc/interface.php';
14 // init.php has to be included after interface.php, otherwise the bits
15 // set by local.php get lost
16 require_once 'inc/init.php';
17 prepareNavigation();
18 // Security context is built on the requested page/tab/bypass data,
19 // do not override.
20 fixContext();
21 redirectIfNecessary();
3ec33017 22 assertPermission();
c5dfde62
DO
23 header ('Content-Type: text/html; charset=UTF-8');
24 // Only store the tab name after clearance is got. Any failure is unhandleable.
25 if (isset ($_REQUEST['tab']) and ! isset ($_SESSION['RTLT'][$pageno]['dont_remember']))
26 $_SESSION['RTLT'][$pageno] = array ('tabname' => $tabno, 'time' => time());
27 // call the main handler - page or tab handler.
28 if (isset ($tabhandler[$pageno][$tabno]))
29 call_user_func ($tabhandler[$pageno][$tabno], getBypassValue());
30 elseif (isset ($page[$pageno]['handler']))
31 $page[$pageno]['handler'] ($tabno);
32 else
33 throw new RackTablesError ("Failed to find handler for page '${pageno}', tab '${tabno}'", RackTablesError::INTERNAL);
34 // Embed the current text in OB into interface layout (the latter also
35 // empties color message buffer).
36 $contents = ob_get_contents();
37 ob_clean();
38 renderInterfaceHTML ($pageno, $tabno, $contents);
39 break;
19f22ad8 40 case 'chrome' == $_REQUEST['module']:
4afb4c10 41 require_once 'inc/init.php';
5c42f907 42 require_once 'inc/solutions.php';
36ef72d9
DO
43 genericAssertion ('uri', 'string');
44 proxyStaticURI ($_REQUEST['uri']);
45 break;
c5dfde62 46 case 'download' == $_REQUEST['module']:
4afb4c10 47 require_once 'inc/init.php';
0415b520
DO
48 $pageno = 'file';
49 $tabno = 'download';
50 fixContext();
3ec33017 51 assertPermission();
0415b520
DO
52 $file = getFile (getBypassValue());
53 header("Content-Type: {$file['type']}");
54 header("Content-Length: {$file['size']}");
39cfa9a7 55 if (! array_key_exists ('asattach', $_REQUEST) or $_REQUEST['asattach'] != 'no')
0415b520
DO
56 header("Content-Disposition: attachment; filename={$file['name']}");
57 echo $file['contents'];
58 break;
c5dfde62 59 case 'image' == $_REQUEST['module']:
b849b7e1
DO
60 # The difference between "image" and "download" ways to serve the same
61 # picture file is that the former is used in <IMG SRC=...> construct,
62 # and the latter is accessed as a standalone URL and can reply with any
63 # Content-type. Hence "image" module indicates failures with internally
64 # built images, and "download" can return a full-fledged "permission
65 # denied" or "exception" HTML page instead of the file requested.
8b912171 66 require_once 'inc/init.php'; // for authentication check
5c42f907 67 require_once 'inc/solutions.php';
4afb4c10
DO
68 try
69 {
70 dispatchImageRequest();
71 }
3ec33017
DO
72 catch (RTPermissionDenied $e)
73 {
74 ob_clean();
75 renderAccessDeniedImage();
76 }
4afb4c10
DO
77 catch (Exception $e)
78 {
87c744a9 79 ob_clean();
11566bd6 80 renderErrorImage();
4afb4c10
DO
81 }
82 break;
a069b30d
DO
83 case 'progressbar' == $_REQUEST['module']:
84 # Unlike images (and like static content), progress bars are processed
85 # without a permission check, but only for authenticated users.
86 require_once 'inc/init.php';
87 require_once 'inc/solutions.php';
88 genericAssertion ('done', 'uint0');
89 // 'progressbar's never change, make browser cache the result
90 if (checkCachedResponse (0, CACHE_DURATION))
91 break;
92 renderProgressBarImage ($_REQUEST['done']);
93 break;
c5dfde62 94 case 'ajax' == $_REQUEST['module']:
9f4f431c
DO
95 require_once 'inc/ajax-interface.php';
96 require_once 'inc/init.php';
97 try
98 {
99 dispatchAJAXRequest();
100 }
101 catch (InvalidRequestArgException $e)
102 {
103 ob_clean();
104 echo "NAK\nMalformed request";
105 }
fce31eff
DO
106 catch (RTPermissionDenied $e)
107 {
108 ob_clean();
109 # FIXME: the remote client could be expecting JSON data instead
110 echo "NAK\nPermission denied";
111 }
9f4f431c
DO
112 catch (Exception $e)
113 {
114 ob_clean();
115 echo "NAK\nRuntime exception: ". $e->getMessage();
116 }
117 break;
c5dfde62 118 case 'redirect' == $_REQUEST['module']:
87c744a9
DO
119 // Include init after ophandlers/snmp, not before, so local.php can redefine things.
120 require_once 'inc/ophandlers.php';
121 // snmp.php is an exception, it is treated by a special hack
122 if (isset ($_REQUEST['op']) and $_REQUEST['op'] == 'querySNMPData')
123 require_once 'inc/snmp.php';
124 require_once 'inc/init.php';
125 try
126 {
127 genericAssertion ('op', 'string');
128 $op = $_REQUEST['op'];
129 prepareNavigation();
130 $location = buildWideRedirectURL();
131 // FIXME: find a better way to handle this error
132 if ($op == 'addFile' && !isset($_FILES['file']['error']))
133 throw new RackTablesError ('File upload error, check upload_max_filesize in php.ini', RackTablesError::MISCONFIGURED);
134 fixContext();
135 if
136 (
137 !isset ($ophandler[$pageno][$tabno][$op]) or
138 !function_exists ($ophandler[$pageno][$tabno][$op])
139 )
140 throw new RackTablesError ("Invalid navigation data for '${pageno}-${tabno}-${op}'", RackTablesError::INTERNAL);
141 // We have a chance to handle an error before starting HTTP header.
3ec33017
DO
142 if (!isset ($delayauth[$pageno][$tabno][$op]))
143 assertPermission();
144 # Call below does the job of bypass argument assertion, if such is required,
145 # so the ophandler function doesn't have to re-assert this portion of its
146 # arguments. And it would be even better to pass returned value to ophandler,
147 # so it is not necessary to remember the name of bypass in it.
148 getBypassValue();
149 if (strlen ($redirect_to = call_user_func ($ophandler[$pageno][$tabno][$op])))
150 $location = $redirect_to;
87c744a9
DO
151 }
152 // known "soft" failures require a short error message
93c946ac 153 catch (InvalidRequestArgException $e)
87c744a9
DO
154 {
155 ob_clean();
156 showError ($e->getMessage());
87c744a9
DO
157 }
158 catch (RTDatabaseError $e)
159 {
160 ob_clean();
161 showError ('Database error: ' . $e->getMessage());
87c744a9 162 }
3ec33017
DO
163 catch (RTPermissionDenied $e)
164 {
165 ob_clean();
166 showError ('Operation not permitted');
167 }
168 header ('Location: ' . $location);
87c744a9
DO
169 // any other error requires no special handling and will be caught outside
170 break;
e0ce8064
DO
171 case 'popup' == $_REQUEST['module']:
172 require_once 'inc/popup.php';
e0ce8064
DO
173 require_once 'inc/init.php';
174 renderPopupHTML();
175 break;
964b0388
DO
176 case 'upgrade' == $_REQUEST['module']:
177 require_once 'inc/config.php'; // for CODE_VERSION
178 require_once 'inc/dictionary.php';
179 require_once 'inc/upgrade.php';
180 // Enforce default value for now, releases prior to 0.17.0 didn't support 'httpd' auth source.
181 $user_auth_src = 'database';
182 if (FALSE === @include_once 'inc/secret.php')
e37cfe5f 183 die ('<center>There is no working RackTables instance here, <a href="?module=installer">install</a>?</center>');
964b0388
DO
184 try
185 {
186 $dbxlink = new PDO ($pdo_dsn, $db_username, $db_password);
187 }
188 catch (PDOException $e)
189 {
190 die ("Database connection failed:\n\n" . $e->getMessage());
191 }
192 renderUpgraderHTML();
193 break;
91bd1d6e 194 case 'installer' == $_REQUEST['module']:
e37cfe5f
DO
195 require_once 'inc/dictionary.php';
196 require_once 'inc/install.php';
197 renderInstallerHTML();
198 break;
36ef72d9
DO
199 default:
200 throw new InvalidRequestArgException ('module', $_REQUEST['module']);
201 }
0415b520 202 ob_end_flush();
36ef72d9 203}
c5dfde62
DO
204catch (Exception $e)
205{
90a3d6d8 206 ob_end_clean();
91bd1d6e
DO
207 # prevent message appearing in foreign tab
208 if (isset ($_SESSION['log']))
209 unset ($_SESSION['log']);
c5dfde62 210 printException ($e);
90a3d6d8 211}
e410ebfc 212?>