This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace SilverStripe\MSSQL; |
||
4 | |||
5 | use SilverStripe\Dev\Install\DatabaseAdapterRegistry; |
||
6 | use SilverStripe\Dev\Install\DatabaseConfigurationHelper; |
||
7 | use PDO; |
||
8 | use Exception; |
||
9 | |||
10 | /** |
||
11 | * This is a helper class for the SS installer. |
||
12 | * |
||
13 | * It does all the specific checking for MSSQLDatabase |
||
14 | * to ensure that the configuration is setup correctly. |
||
15 | */ |
||
16 | class MSSQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper |
||
17 | { |
||
18 | |||
19 | protected function isAzure($databaseConfig) |
||
20 | { |
||
21 | /** @skipUpgrade */ |
||
22 | return $databaseConfig['type'] === 'MSSQLAzureDatabase'; |
||
23 | } |
||
24 | |||
25 | /** |
||
26 | * Create a connection of the appropriate type |
||
27 | * |
||
28 | * @skipUpgrade |
||
29 | * @param array $databaseConfig |
||
30 | * @param string $error Error message passed by value |
||
31 | * @return mixed|null Either the connection object, or null if error |
||
32 | */ |
||
33 | protected function createConnection($databaseConfig, &$error) |
||
34 | { |
||
35 | $error = null; |
||
36 | try { |
||
37 | switch ($databaseConfig['type']) { |
||
38 | case 'MSSQLDatabase': |
||
39 | case 'MSSQLAzureDatabase': |
||
40 | $parameters = array( |
||
41 | 'UID' => $databaseConfig['username'], |
||
42 | 'PWD' => $databaseConfig['password'] |
||
43 | ); |
||
44 | |||
45 | // Azure has additional parameter requirements |
||
46 | if ($this->isAzure($databaseConfig)) { |
||
47 | $parameters['database'] = $databaseConfig['database']; |
||
48 | $parameters['multipleactiveresultsets'] = 0; |
||
49 | } |
||
50 | $conn = @sqlsrv_connect($databaseConfig['server'], $parameters); |
||
51 | if ($conn) { |
||
52 | return $conn; |
||
53 | } |
||
54 | |||
55 | // Get error |
||
56 | if ($errors = sqlsrv_errors()) { |
||
57 | $error = ''; |
||
58 | foreach ($errors as $detail) { |
||
59 | $error .= "{$detail['message']}\n"; |
||
60 | } |
||
61 | } else { |
||
62 | $error = 'Unknown connection error'; |
||
63 | } |
||
64 | return null; |
||
65 | case 'MSSQLPDODatabase': |
||
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
66 | $driver = $this->getPDODriver(); |
||
67 | if (!$driver) { |
||
68 | $error = 'No supported PDO driver'; |
||
69 | return null; |
||
70 | } |
||
71 | |||
72 | // May throw a PDOException if fails |
||
73 | $conn = @new PDO($driver.':Server='.$databaseConfig['server'], $databaseConfig['username'], $databaseConfig['password']); |
||
74 | if ($conn) { |
||
75 | return $conn; |
||
76 | } else { |
||
77 | $error = 'Unknown connection error'; |
||
78 | return null; |
||
79 | } |
||
80 | default: |
||
81 | $error = 'Invalid connection type: ' . $databaseConfig['type']; |
||
82 | return null; |
||
83 | } |
||
84 | } catch (Exception $ex) { |
||
85 | $error = $ex->getMessage(); |
||
86 | return null; |
||
87 | } |
||
88 | } |
||
89 | |||
90 | /** |
||
91 | * Get supported PDO driver |
||
92 | * |
||
93 | * @return null |
||
94 | */ |
||
95 | public static function getPDODriver() { |
||
96 | if (!class_exists('PDO')) { |
||
97 | return null; |
||
98 | } |
||
99 | foreach(PDO::getAvailableDrivers() as $driver) { |
||
100 | if(in_array($driver, array('sqlsrv', 'dblib'))) { |
||
101 | return $driver; |
||
102 | } |
||
103 | } |
||
104 | return null; |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Helper function to quote a string value |
||
109 | * |
||
110 | * @param mixed $conn Connection object/resource |
||
111 | * @param string $value Value to quote |
||
112 | * @return string Quoted string |
||
113 | */ |
||
114 | protected function quote($conn, $value) |
||
115 | { |
||
116 | if ($conn instanceof PDO) { |
||
117 | return $conn->quote($value); |
||
118 | } elseif (is_resource($conn)) { |
||
119 | $value = str_replace("'", "''", $value); |
||
120 | $value = str_replace("\0", "[NULL]", $value); |
||
121 | return "N'$value'"; |
||
122 | } else { |
||
123 | user_error('Invalid database connection', E_USER_ERROR); |
||
124 | } |
||
125 | return null; |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * Helper function to execute a query |
||
130 | * |
||
131 | * @param mixed $conn Connection object/resource |
||
132 | * @param string $sql SQL string to execute |
||
133 | * @return array List of first value from each resulting row |
||
134 | */ |
||
135 | protected function query($conn, $sql) |
||
136 | { |
||
137 | $items = array(); |
||
138 | if ($conn instanceof PDO) { |
||
139 | $result = $conn->query($sql); |
||
140 | if ($result) { |
||
141 | foreach ($result as $row) { |
||
142 | $items[] = $row[0]; |
||
143 | } |
||
144 | } |
||
145 | } elseif (is_resource($conn)) { |
||
146 | $result = sqlsrv_query($conn, $sql); |
||
147 | if ($result) { |
||
148 | while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_NUMERIC)) { |
||
149 | $items[] = $row[0]; |
||
150 | } |
||
151 | } |
||
152 | } |
||
153 | return $items; |
||
154 | } |
||
155 | |||
156 | public function requireDatabaseFunctions($databaseConfig) |
||
157 | { |
||
158 | $data = DatabaseAdapterRegistry::get_adapter($databaseConfig['type']); |
||
159 | return !empty($data['supported']); |
||
160 | } |
||
161 | |||
162 | View Code Duplication | public function requireDatabaseServer($databaseConfig) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
163 | { |
||
164 | $conn = $this->createConnection($databaseConfig, $error); |
||
165 | $success = !empty($conn); |
||
166 | |||
167 | return array( |
||
168 | 'success' => $success, |
||
169 | 'error' => $error |
||
170 | ); |
||
171 | } |
||
172 | |||
173 | View Code Duplication | public function requireDatabaseConnection($databaseConfig) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
174 | { |
||
175 | $conn = $this->createConnection($databaseConfig, $error); |
||
176 | $success = !empty($conn); |
||
177 | |||
178 | return array( |
||
179 | 'success' => $success, |
||
180 | 'connection' => $conn, |
||
181 | 'error' => $error |
||
182 | ); |
||
183 | } |
||
184 | |||
185 | public function getDatabaseVersion($databaseConfig) |
||
186 | { |
||
187 | $conn = $this->createConnection($databaseConfig, $error); |
||
188 | $result = $this->query($conn, "SELECT CONVERT(char(15), SERVERPROPERTY('ProductVersion'))"); |
||
189 | return empty($result) ? 0 : reset($result); |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Ensure that the SQL Server version is at least 10.00.2531 (SQL Server 2008 SP1). |
||
194 | * |
||
195 | * @see http://www.sqlteam.com/article/sql-server-versions |
||
196 | * @param array $databaseConfig Associative array of db configuration, e.g. "server", "username" etc |
||
197 | * @return array Result - e.g. array('success' => true, 'error' => 'details of error') |
||
198 | */ |
||
199 | public function requireDatabaseVersion($databaseConfig) |
||
200 | { |
||
201 | $success = false; |
||
202 | $error = ''; |
||
203 | $version = $this->getDatabaseVersion($databaseConfig); |
||
204 | |||
205 | if ($version) { |
||
206 | $success = version_compare($version, '10.00.2531', '>='); |
||
207 | if (!$success) { |
||
208 | $error = "Your SQL Server version is $version. It's recommended you use at least 10.00.2531 (SQL Server 2008 SP1)."; |
||
209 | } |
||
210 | } else { |
||
211 | $error = "Your SQL Server version could not be determined."; |
||
212 | } |
||
213 | |||
214 | return array( |
||
215 | 'success' => $success, |
||
216 | 'error' => $error |
||
217 | ); |
||
218 | } |
||
219 | |||
220 | public function requireDatabaseOrCreatePermissions($databaseConfig) |
||
221 | { |
||
222 | $conn = $this->createConnection($databaseConfig, $error); |
||
223 | /** @skipUpgrade */ |
||
224 | if (empty($conn)) { |
||
225 | $success = false; |
||
226 | $alreadyExists = false; |
||
227 | } elseif ($databaseConfig['type'] == 'MSSQLAzureDatabase') { |
||
228 | // Don't bother with DB selection for azure, as it's not supported |
||
229 | $success = true; |
||
230 | $alreadyExists = true; |
||
231 | } else { |
||
232 | // does this database exist already? |
||
233 | $list = $this->query($conn, 'SELECT NAME FROM sys.sysdatabases'); |
||
234 | if (in_array($databaseConfig['database'], $list)) { |
||
235 | $success = true; |
||
236 | $alreadyExists = true; |
||
237 | } else { |
||
238 | $permissions = $this->query($conn, "select COUNT(*) from sys.fn_my_permissions('','') where permission_name like 'CREATE ANY DATABASE' or permission_name like 'CREATE DATABASE';"); |
||
239 | $success = $permissions[0] > 0; |
||
240 | $alreadyExists = false; |
||
241 | } |
||
242 | } |
||
243 | |||
244 | return array( |
||
245 | 'success' => $success, |
||
246 | 'alreadyExists' => $alreadyExists |
||
247 | ); |
||
248 | } |
||
249 | |||
250 | public function requireDatabaseAlterPermissions($databaseConfig) |
||
251 | { |
||
252 | $success = false; |
||
253 | $conn = $this->createConnection($databaseConfig, $error); |
||
254 | if (!empty($conn)) { |
||
255 | if (!$this->isAzure($databaseConfig)) { |
||
256 | // Make sure to select the current database when checking permission against this database |
||
257 | $this->query($conn, "USE \"{$databaseConfig['database']}\""); |
||
258 | } |
||
259 | $permissions = $this->query($conn, "select COUNT(*) from sys.fn_my_permissions(NULL,'DATABASE') WHERE permission_name like 'create table';"); |
||
260 | $success = $permissions[0] > 0; |
||
261 | } |
||
262 | |||
263 | return array( |
||
264 | 'success' => $success, |
||
265 | 'applies' => true |
||
266 | ); |
||
267 | } |
||
268 | } |
||
269 |