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/*
8*
9* This file performs RackTables initialisation. After you include it
10* from 1st-level page, don't forget to call fixContext(). This is done
11* to enable override of of pageno and tabno variables. pageno and tabno
12* together participate in forming security context by generating
13* related autotags.
14*
15*/
16
17require_once 'pre-init.php';
18require_once 'config.php';
19require_once 'functions.php';
20require_once 'database.php';
21require_once 'auth.php';
22require_once 'navigation.php';
23require_once 'triggers.php';
24require_once 'remote.php';
25require_once 'caching.php';
26require_once 'slb.php';
27require_once 'slbv2.php';
28
29// secret.php may be missing, in which case this is a special fatal error
30if (! fileSearchExists ($path_to_secret_php))
31	throw new RackTablesError
32	(
33		"This instance of RackTables misses a configuration file " .
34		"(<code>${path_to_secret_php}</code>).<br>" .
35		"The configuration file is usually generated by RackTables installer, which " .
36		"can be launched <a href='?module=installer'>here</a>.",
37		RackTablesError::MISCONFIGURED
38	);
39
40connectDB();
41transformRequestData();
42$configCache = loadConfigDefaults();
43
44if (getConfigVar ('DB_VERSION') != CODE_VERSION)
45{
46	echo '<p align=justify>This Racktables installation seems to be ' .
47		'just upgraded to version ' . CODE_VERSION . ', while the '.
48		'database version is ' . getConfigVar ('DB_VERSION') . '.<br>No user will be ' .
49		'either authenticated or shown any page until the upgrade is ' .
50		"finished.<br>Follow <a href='?module=upgrade'>this link</a> and " .
51		'authenticate as administrator to finish the upgrade.</p>';
52	exit (1);
53}
54
55if (!mb_internal_encoding ('UTF-8'))
56	throw new RackTablesError ('Failed setting multibyte string encoding to UTF-8', RackTablesError::INTERNAL);
57
58$rackCodeCache = loadScript ('RackCodeCache');
59if ($rackCodeCache == NULL || $rackCodeCache == '')
60{
61	$rackCode = getRackCode (loadScript ('RackCode'));
62	saveScript ('RackCodeCache', base64_encode (serialize ($rackCode)));
63}
64else
65{
66	$rackCode = unserialize (base64_decode ($rackCodeCache));
67	if ($rackCode === FALSE) // invalid cache
68	{
69		saveScript ('RackCodeCache', '');
70		$rackCode = getRackCode (loadScript ('RackCode'));
71	}
72	elseif (! isset ($rackCode['ABI_ver']) || $rackCode['ABI_ver'] != PARSER_ABI_VER)
73	{
74		// Re-calculate rackCode locally, keep unsupported cache in place.
75		// This helps transition between version on master-slave installations.
76		$rackCode = getRackCode (loadScript ('RackCode'));
77	}
78}
79
80// avoid notices being thrown
81date_default_timezone_set (getConfigVar ('DATETIME_ZONE'));
82
83// Depending on the 'result' value the 'load' carries either the
84// parse tree or error message. The latter case is a bug, because
85// RackCode saving function was supposed to validate its input.
86if ($rackCode['result'] != 'ACK')
87	throw new RackTablesError ($rackCode['load'], RackTablesError::INTERNAL);
88$rackCode = $rackCode['load'];
89// Only call buildPredicateTable() once and save the result, because it will remain
90// constant during one execution for constraints processing.
91$pTable = buildPredicateTable ($rackCode);
92// Constraints parse trees aren't cached in the database, so the least to keep
93// things running is to maintain application cache for them.
94$entityCache = array();
95// used by getExplicitTagsOnly()
96$tagRelCache = array();
97
98$taglist = addTraceToNodes (getTagList());
99
100$auto_tags = array();
101if (! isCLIMode() && isset ($_SERVER['REMOTE_ADDR']))
102	$auto_tags[] = array ('tag' => '$client_' . $_SERVER['REMOTE_ADDR']);
103
104// Initial chain for the current user.
105$user_given_tags = array();
106
107// List of additional regexps for checkAutotagName(). Add your site-local regexps
108// here to manage false positive 'Martian autotag' warnings about the permissions
109// text that uses autotags generated by local plugins.
110$user_defined_atags = array();
111
112// Initial the HTML header array used by addJSxxx() and addCSSxxx() functions
113// FIXME: For some reason without this global declaration this variable does
114// not exist for addPageHeader() in PHPUnit.
115global $html_headers;
116$html_headers = array();
117
118// This also can be modified in local.php.
119$pageheaders = array
120(
121	100 => "<link rel='ICON' type='image/x-icon' href='?module=chrome&uri=pix/favicon.ico' />",
122);
123addCSSInternal ('css/pi.css');
124
125if (! isset ($script_mode) || $script_mode !== TRUE)
126{
127	// A successful call to authenticate() always generates autotags and somethimes
128	// even given/implicit tags. It also sets remote_username and remote_displayname.
129	authenticate();
130	// Authentication passed.
131	// Note that authorization does not happen here as every CLI script, HTTP module and
132	// page does it differently, e.g. by calling authorize() after fixContext().
133}
134elseif (! isset ($remote_username))
135{
136	// Some functions require remote_username to be set to something to act correctly,
137	// even though they don't use the value itself.
138	$admin_account = spotEntity ('user', 1);
139	if (isCLIMode() && FALSE !== $env_user = getenv('USER'))
140		// use USER env var if running in CLI mode
141		$remote_username = $env_user;
142	else
143		$remote_username = $admin_account['user_name'];
144	unset ($env_user);
145	unset ($admin_account);
146}
147
148$virtual_obj_types = explode (',', getConfigVar ('VIRTUAL_OBJ_CSV'));
149
150alterConfigWithUserPreferences();
151$op = '';
152
153// load v1 plugins
154ob_start();
155if (FALSE !== $plugin_files = glob ("${racktables_plugins_dir}/*.php"))
156	foreach ($plugin_files as $plugin_file)
157		 require_once $plugin_file;
158// display plugins output if it contains something but newlines
159$tmp = ob_get_clean();
160if ($tmp != '' && ! preg_match ("/^\n+$/D", $tmp))
161	echo $tmp;
162unset ($tmp);
163
164// load v2 plugins that are enabled
165$plugins = getPlugins ('enabled');
166foreach (array_keys ($plugins) as $plugin)
167	if (function_exists ("plugin_${plugin}_init"))
168		call_user_func ("plugin_${plugin}_init");
169
170// These will be filled in by fixContext()
171$expl_tags = array();
172$impl_tags = array();
173// Initial chain for the current target.
174$target_given_tags = array();
175
176// Now we've finished let plugins know
177callHook ('initFinished');
178