PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/xCAT-UI/lib/functions.php

https://gitlab.com/qisback/xcat-core
PHP | 367 lines | 226 code | 43 blank | 98 comment | 56 complexity | 955450970cefc1467d4db7c4d982f2ee MD5 | raw file
Possible License(s): EPL-1.0
  1. <?php
  2. /**
  3. * Contains all common PHP functions needed by most pages
  4. */
  5. // Retain session variables across page requests
  6. session_start();
  7. session_write_close(); // Do not block other HTTP requests
  8. // The settings below display error on the screen, instead of giving blank pages.
  9. error_reporting(E_ALL);
  10. ini_set('display_errors', true);
  11. /**
  12. * Run a command using the xCAT client/server protocol
  13. *
  14. * @param $cmd The xCAT command
  15. * @param $nr Node range or group
  16. * @param $args_array Command arguments
  17. * @param $opts_array Command options
  18. * @return A tree of SimpleXML objects.
  19. * See perl-xCAT/xCAT/Client.pm for the format
  20. */
  21. function docmd($cmd, $nr, $args_array, $opts_array){
  22. // If we are not logged in,
  23. // do not try to communicate with xcatd
  24. if (!is_logged()) {
  25. echo "<p>You are not logged in! Failed to run command.</p>";
  26. return simplexml_load_string('<xcat></xcat>', 'SimpleXMLElement', LIBXML_NOCDATA);
  27. }
  28. // Create xCAT request
  29. // Add command, node range, and arguments to request
  30. $request = simplexml_load_string('<xcatrequest></xcatrequest>');
  31. $request->addChild('command', $cmd);
  32. if (!empty($nr)) {
  33. $request->addChild('noderange', $nr);
  34. }
  35. if (!empty($args_array)) {
  36. foreach ($args_array as $a) {
  37. $request->addChild('arg',$a);
  38. }
  39. }
  40. // Add user and password to request
  41. $usernode=$request->addChild('becomeuser');
  42. $usernode->addChild('username',$_SESSION["username"]);
  43. $usernode->addChild('password',getpassword());
  44. $xml = submit_request($request, 0, $opts_array);
  45. return $xml;
  46. }
  47. /**
  48. * Used by docmd() to submit request to xCAT
  49. *
  50. * @param $req Tree of SimpleXML objects
  51. * @param $opts_array Request options
  52. * @return A tree of SimpleXML objects
  53. */
  54. function submit_request($req, $skipVerify, $opts_array){
  55. $xcathost = "localhost";
  56. $port = "3001";
  57. $rsp = FALSE;
  58. $response = '';
  59. $cleanexit = 0;
  60. $flushtail = '';
  61. // Determine whether to flush output or not
  62. $flush = false;
  63. if ($opts_array && in_array("flush", $opts_array)) {
  64. $flush = true;
  65. }
  66. // Determine how to handle the flush output
  67. // You can specify a function name, in place of TBD, to handle the flush output
  68. $flush_format = "";
  69. if ($opts_array && in_array("flush-format=TBD", $opts_array)) {
  70. $flush_format = "TBD";
  71. }
  72. // Open syslog, include the process ID and also send the log to standard error,
  73. // and use a user defined logging mechanism
  74. openlog("xcat", LOG_PID | LOG_PERROR, LOG_LOCAL0);
  75. // Open a socket to xcatd
  76. syslog(LOG_INFO, "Opening socket to xcatd...");
  77. if ($fp = stream_socket_client('ssl://'.$xcathost.':'.$port, $errno, $errstr, 30, STREAM_CLIENT_CONNECT)){
  78. $reqXML = $req->asXML();
  79. $nr = $req->noderange;
  80. $cmd = $req->command;
  81. syslog(LOG_INFO, "Sending request: $cmd $nr");
  82. stream_set_blocking($fp, 0); // Set as non-blocking
  83. fwrite($fp,$req->asXML()); // Send XML to xcatd
  84. set_time_limit(3600); // Set 15 minutes timeout (for long running requests)
  85. // The default is 30 seconds which is too short for some requests
  86. // Turn on output buffering
  87. ob_start();
  88. if ($flush){
  89. echo str_pad('',1024)."\n";
  90. }
  91. while (!feof($fp)) {
  92. // Read until there is no more
  93. // Remove newlines and add it to the response
  94. $str = fread($fp, 8192);
  95. if ($str) {
  96. $response .= preg_replace('/>\n\s*</', '><', $str);
  97. // Flush output to browser
  98. if ($flush) {
  99. $str = $flushtail . $str;
  100. if (preg_match('/[^>]+$/', $str, $matches)){
  101. $flushtail = $matches[0];
  102. $str = preg_replace('/[^>]+$/', '', $str);
  103. } else {
  104. $flushtail = '';
  105. }
  106. $str = preg_replace('/<errorcode>.*<\/errorcode>/', '', $str);
  107. // Strip HTML tags from output
  108. if ($tmp = trim(strip_tags($str))) {
  109. // Format the output based on what was given for $flush_format
  110. if ($flush_format == "TDB") {
  111. format_TBD($tmp);
  112. } else {
  113. $tmp = preg_replace('/\n\s*/', "\n", $tmp);
  114. // Print out output by default
  115. echo '<pre style="font-size: 10px;">' . $tmp . '</pre>';
  116. ob_flush();
  117. flush();
  118. }
  119. }
  120. }
  121. }
  122. // Look for serverdone response
  123. $fullpattern = '/<xcatresponse>\s*<serverdone>\s*<\/serverdone>\s*<\/xcatresponse>/';
  124. $mixedpattern = '/<serverdone>\s*<\/serverdone>.*<\/xcatresponse>/';
  125. $recentpattern = '/<\/xcatresponse>/';
  126. if (preg_match($recentpattern,$str) && preg_match($mixedpattern,$response)) {
  127. // Transaction is done, package up XML and return it
  128. // Remove the serverdone response and put an xcat tag around the rest
  129. $count = 0;
  130. $response = preg_replace($fullpattern,'', $response, -1, $count); // 1st try to remove the long pattern
  131. if (!$count) {
  132. $response = preg_replace($mixedpattern,'', $response) . '</xcatresponse>/';
  133. }
  134. $response = "<xcat>$response</xcat>";
  135. $response = preg_replace('/>\n\s*</', '><', $response);
  136. $response = preg_replace('/\n/', ':|:', $response);
  137. $rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
  138. $cleanexit = 1;
  139. break;
  140. }
  141. } // End of while(!feof($fp))
  142. syslog(LOG_INFO, "($cmd $nr) Sending response");
  143. fclose($fp);
  144. } else {
  145. echo "<p>xCAT submit request socket error: $errno - $errstr</p>";
  146. }
  147. // Flush (send) the output buffer and turn off output buffering
  148. ob_end_flush();
  149. // Close syslog
  150. closelog();
  151. if (!$cleanexit) {
  152. if (preg_match('/^\s*<xcatresponse>.*<\/xcatresponse>\s*$/',$response)) {
  153. // Probably an error message
  154. $response = "<xcat>$response</xcat>";
  155. $rsp = simplexml_load_string($response,'SimpleXMLElement', LIBXML_NOCDATA);
  156. } else if (!$skipVerify) {
  157. echo "<p>(Error) xCAT response ended prematurely: ", htmlentities($response), "</p>";
  158. $rsp = FALSE;
  159. }
  160. }
  161. return $rsp;
  162. }
  163. /**
  164. * Enable password storage to split between cookie and session variable
  165. */
  166. function xorcrypt($data, $key) {
  167. $datalen = strlen($data);
  168. $keylen = strlen($key);
  169. for ($i=0;$i<$datalen;$i++) {
  170. $data[$i] = chr(ord($data[$i])^ord($key[$i]));
  171. }
  172. return $data;
  173. }
  174. /**
  175. * Get password
  176. */
  177. function getpassword() {
  178. if (isset($GLOBALS['xcatauthsecret'])) {
  179. $cryptext = $GLOBALS['xcatauthsecret'];
  180. } else if (isset($_COOKIE["xcatauthsecret"])) {
  181. $cryptext = $_COOKIE["xcatauthsecret"];
  182. } else {
  183. return false;
  184. }
  185. return xorcrypt($_SESSION["secretkey"], base64_decode($cryptext));
  186. }
  187. /**
  188. * Get the password splitting knowledge between server and client side persistant storage.
  189. * Caller should regenerate session ID when contemplating a new user/password,
  190. * to preclude session fixation, though fixation is limited without the secret.
  191. *
  192. * @param $password Password
  193. */
  194. function setpassword($password) {
  195. $randlen = strlen($password);
  196. $key = getrandchars($randlen);
  197. $cryptext = xorcrypt($password,$key);
  198. // Non-ascii characters, encode it in base64
  199. $cryptext = base64_encode($cryptext);
  200. setcookie("xcatauthsecret",$cryptext,0,'/');
  201. $GLOBALS["xcatauthsecret"] = $cryptext;
  202. $_SESSION["secretkey"] = $key;
  203. }
  204. /**
  205. * Get RAND characters
  206. *
  207. * @param $length Length of characters
  208. * @return RAND characters
  209. */
  210. function getrandchars($length) {
  211. $charset = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*';
  212. $charsize = strlen($charset);
  213. srand();
  214. $chars = '';
  215. for ($i=0;$i<$length;$i++) {
  216. $num=rand()%$charsize;
  217. $chars=$chars.substr($charset,$num,1);
  218. }
  219. return $chars;
  220. }
  221. /**
  222. * Determine if a user/password session exists
  223. *
  224. * @return True if user has a session, false otherwise
  225. */
  226. function is_logged() {
  227. if (isset($_SESSION["username"]) and !is_bool(getpassword())) {
  228. return true;
  229. } else {
  230. return false;
  231. }
  232. }
  233. /**
  234. * Determine if a user is currently logged in successfully
  235. *
  236. * @return True if the user is currently logged in successfully, false otherwise
  237. */
  238. function isAuthenticated() {
  239. if (is_logged()) {
  240. if ($_SESSION["xcatpassvalid"] != 1) {
  241. $testcred = docmd("authcheck", "", NULL, NULL);
  242. if (isset($testcred->{'xcatresponse'}->{'data'})) {
  243. $result = "".$testcred->{'xcatresponse'}->{'data'};
  244. if (is_numeric(strpos("Authenticated",$result))) {
  245. // Logged in successfully
  246. $_SESSION["xcatpassvalid"] = 1;
  247. } else {
  248. // Not logged in
  249. $_SESSION["xcatpassvalid"] = 0;
  250. }
  251. }
  252. }
  253. }
  254. if (isset($_SESSION["xcatpassvalid"]) and $_SESSION["xcatpassvalid"]==1) {
  255. return true;
  256. } else {
  257. return false;
  258. }
  259. }
  260. /**
  261. * Determine if a user has root access
  262. *
  263. * @return True if the user has root access, false otherwise
  264. */
  265. function isRootAcess() {
  266. if (is_logged() && $_SESSION["xcatpassvalid"]) {
  267. $testacc = docmd('tabdump', '', array('policy', '-w', "name==" . $_SESSION["username"]), array());
  268. if (isset($testacc->{'xcatresponse'}->{'data'}->{1})) {
  269. $result = $testacc->{'xcatresponse'}->{'data'}->{1};
  270. $result = str_replace('"', '', $result);
  271. $args = array();
  272. $args = explode(",", $result);
  273. // Get the comments which contains the privilege
  274. $comments = $args[8];
  275. $args = explode(";", $comments);
  276. // Default privilege is guest
  277. $privilege = 'guest';
  278. $_SESSION["xcatpassvalid"] = 0;
  279. foreach ($args as $arg) {
  280. // Get user privilege
  281. if ($arg && is_numeric(strpos($arg, "privilege"))) {
  282. if (is_numeric(strpos($arg, "root"))) {
  283. // Set privilege to root
  284. $privilege = 'root';
  285. $_SESSION["xcatpassvalid"] = 1;
  286. }
  287. break;
  288. }
  289. }
  290. }
  291. }
  292. if (strcmp($_SESSION["username"], 'root') == 0 || strcmp($_SESSION["username"], 'admin') == 0) {
  293. $_SESSION["xcatpassvalid"] = 1;
  294. }
  295. if (isset($_SESSION["xcatpassvalid"]) and $_SESSION["xcatpassvalid"]==1) {
  296. return true;
  297. } else {
  298. return false;
  299. }
  300. }
  301. /**
  302. * Log out of current user session
  303. */
  304. function logout() {
  305. // Clear the secret cookie from browser
  306. if (isset($_COOKIE["xcatauthsecret"])) {
  307. setcookie("xcatauthsecret",'',time()-86400*7,'/');
  308. }
  309. // Expire session cookie
  310. if (isset($_COOKIE[session_name()])) {
  311. setcookie(session_name(),"",time()-86400*7,"/");
  312. }
  313. // Clear server store of data
  314. $_SESSION=array();
  315. }
  316. /**
  317. * Format a given string and echo it back to the browser
  318. */
  319. function format_TBD($str) {
  320. // Format a given string however you want it
  321. echo $tmp . '<br/>';
  322. flush();
  323. }
  324. ?>