function AJconnectRequest() { global $remoteIP, $user; $requestid = getContinuationVar('requestid'); $requestData = getRequestInfo($requestid, 1); if (is_null($requestData)) { $h = i("This reservation is no longer available."); sendJSON(array('html' => $h, 'refresh' => 1)); return; } if ($requestData['stateid'] == 11 || $requestData['stateid'] == 12 || $requestData['stateid'] == 14 && ($requestData['laststateid'] == 11 || $requestData['laststateid'] == 12)) { $h = i("This reservation has timed out due to lack of user activity and is no longer available."); sendJSON(array('html' => $h, 'refresh' => 1)); return; } $h = ''; $now = time(); if ($requestData['reservations'][0]['remoteIP'] != $remoteIP) { $query = "UPDATE reservation " . "SET remoteIP = '{$remoteIP}' " . "WHERE requestid = {$requestid}"; $qh = doQuery($query, 226); addChangeLogEntry($requestData["logid"], $remoteIP); if ($requestData['reservations'][0]['remoteIP'] == '') { addConnectTimeout($requestData['reservations'][0]['reservationid'], $requestData['reservations'][0]['computerid']); } } $timeout = getReservationNextTimeout($requestData['reservations'][0]['reservationid']); if (!is_null($timeout)) { $h .= "<input type=\"hidden\" id=\"connecttimeout\" value=\"{$timeout}\">\n"; } if ($requestData['forimaging']) { $h .= "<font color=red><big>"; $m = "<strong>" . i("NOTICE:") . "</strong> "; $m .= i("Later in this process, you must accept a <a>click-through agreement</a> about software licensing."); $h .= preg_replace('|<a>(.+)</a>|', '<a href="' . BASEURL . SCRIPT . '?mode=viewRequests#" onClick="previewClickThrough();">\\1</a>', $m); $h .= "</big></font><br><br>\n"; } $imagenotes = getImageNotes($requestData['reservations'][0]['imageid']); if (!preg_match('/^\\s*$/', $imagenotes['usage'])) { $h .= "<h3>" . i("Notes on using this environment:") . "</h3>\n"; $h .= "{$imagenotes['usage']}<br><br><br>\n"; } if (count($requestData["reservations"]) > 1) { $cluster = 1; } else { $cluster = 0; } if ($cluster) { $h .= "<h2>" . i("Cluster Reservation") . "</h2>\n"; $h .= i("This is a cluster reservation. Depending on the makeup of the cluster, you may need to use different methods to connect to the different environments in your cluster."); $h .= "<br><br>\n"; } foreach ($requestData["reservations"] as $key => $res) { $osname = $res["OS"]; if (array_key_exists($user['id'], $requestData['passwds'][$res['reservationid']])) { $passwd = $requestData['passwds'][$res['reservationid']][$user['id']]; } else { $passwd = ''; } $connectData = getImageConnectMethodTexts($res['imageid'], $res['imagerevisionid']); $natports = getNATports($res['reservationid']); $usenat = 0; if (count($natports)) { $usenat = 1; } $first = 1; if ($cluster) { $h .= "<fieldset>\n"; $h .= "<legend><big><b>{$res['prettyimage']}</b></big></legend>\n"; } foreach ($connectData as $cmid => $method) { if ($first) { $first = 0; } else { $h .= "<hr>\n"; } if ($requestData['forimaging'] && $res['OStype'] == 'windows') { $conuser = '******'; } elseif (preg_match('/(.*)@(.*)/', $user['unityid'], $matches)) { $conuser = $matches[1]; } else { $conuser = $user['unityid']; } if (!strlen($passwd)) { $passwd = i('(use your campus password)'); } if ($cluster) { $h .= "<h4>" . i("Connect to reservation using") . " {$method['description']}</h4>\n"; } else { $h .= "<h3>" . i("Connect to reservation using") . " {$method['description']}</h3>\n"; } $froms = array('/#userid#/', '/#password#/', '/#connectIP#/'); # check that connecttext includes port if nat is being used if ($usenat) { $found = 0; foreach ($method['ports'] as $port) { if (preg_match("/{$port['key']}/", $method['connecttext'])) { $found = 1; break; } } if (!$found) { # no port in connect text, assume first port will work $method['connecttext'] = preg_replace("/#connectIP#/", "#connectIP#:{$method['ports'][0]['key']}", $method['connecttext']); } } $tos = array($conuser, $passwd, $res['connectIP']); $msg = preg_replace($froms, $tos, $method['connecttext']); foreach ($method['ports'] as $port) { if ($usenat && array_key_exists($port['key'], $natports[$cmid])) { $msg = preg_replace("/{$port['key']}/", $natports[$cmid][$port['key']]['publicport'], $msg); } else { if ((preg_match('/remote desktop/i', $method['description']) || preg_match('/RDP/i', $method['description'])) && $port['key'] == '#Port-TCP-3389#') { $msg = preg_replace("/{$port['key']}/", $user['rdpport'], $msg); } else { $msg = preg_replace("/{$port['key']}/", $port['port'], $msg); } } } #$h .= preg_replace("/(.{1,120}([ ]|$))/", '\1<br>', $msg); $h .= $msg; if (preg_match('/remote desktop/i', $method['description']) || preg_match('/RDP/i', $method['description'])) { #$h .= "<div id=\"counterdiv\" class=\"hidden\"></div>\n"; #$h .= "<div id=\"connectdiv\">\n"; $h .= "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; $cdata = array('requestid' => $requestid, 'resid' => $res['reservationid']); $expire = datetimeToUnix($requestData['end']) - $now + 1800; # remaining reservation time plus 30 min $cont = addContinuationsEntry('sendRDPfile', $cdata, $expire); $h .= "<INPUT type=hidden name=continuation value=\"{$cont}\">\n"; $h .= "<INPUT type=submit value=\"" . i("Get RDP File") . "\">\n"; $h .= "</FORM>\n"; #$h .= "</div>\n"; } } if ($cluster) { $h .= "</fieldset><br>\n"; } } $cdata = array('requestid' => $requestid); $cont = addContinuationsEntry('AJcheckConnectTimeout', $cdata, SECINDAY); $h .= "<input type=\"hidden\" id=\"refreshcont\" value=\"{$cont}\">\n"; $return = array('html' => $h); if (!is_null($timeout)) { $return['timeoutid'] = "timeoutvalue|{$requestid}"; $return['timeout'] = $timeout; } sendJSON($return); }
function connectRequest() { global $remoteIP, $user, $inContinuation; if ($inContinuation) { $requestid = getContinuationVar('requestid', 0); } else { $requestid = processInputVar("requestid", ARG_NUMERIC); } $requestData = getRequestInfo($requestid); if ($requestData['reservations'][0]['remoteIP'] != $remoteIP) { $setback = unixToDatetime(time() - 600); $query = "UPDATE reservation " . "SET remoteIP = '{$remoteIP}', " . "lastcheck = '{$setback}' " . "WHERE requestid = {$requestid}"; $qh = doQuery($query, 226); addChangeLogEntry($requestData["logid"], $remoteIP); } print "<H2 align=center>Connect!</H2>\n"; if ($requestData['forimaging']) { print "<font color=red><big><strong>NOTICE:</strong> Later in this process, you must accept a\n\t\t<a href=\"" . BASEURL . SCRIPT . "?mode=imageClickThrough\">click-through agreement</a> about software licensing.</big></font><br><br>\n"; } if (count($requestData["reservations"]) == 1) { $serverIP = $requestData["reservations"][0]["reservedIP"]; $osname = $requestData["reservations"][0]["OS"]; $passwd = $requestData["reservations"][0]["password"]; if (eregi("windows", $osname)) { print "You will need to use a "; print "Remote Desktop program to connect to the "; print "system. If you did not click on the <b>Connect!</b> button from "; print "the computer you will be using to access the VCL system, you "; print "will need to cancel this reservation, request a new one, and "; print "make sure you click the <strong>Connect!</strong> button in "; print "a web browser running on the same computer from which you will "; print "be connecting to the VCL system. Otherwise, you may be denied "; print "access to the remote computer.<br><br>\n"; print "Use the following information when you are ready to connect:<br>\n"; print "<UL>\n"; print "<LI><b>Remote Computer</b>: {$serverIP}</LI>\n"; if ($requestData["forimaging"]) { print "<LI><b>User ID</b>: Administrator</LI>\n"; } else { if (preg_match('/(.*)@(.*)/', $user['unityid'], $matches)) { print "<LI><b>User ID</b>: " . $matches[1] . "</LI>\n"; } else { print "<LI><b>User ID</b>: " . $user['unityid'] . "</LI>\n"; } } if (strlen($passwd)) { print "<LI><b>Password</b>: {$passwd}<br></LI>\n"; print "</UL>\n"; print "<b>NOTE</b>: The given password is for <i>this reservation "; print "only</i>. You will be given a different password for any other "; print "reservations.<br>\n"; } else { print "<LI><b>Password</b>: (use your campus password)</LI>\n"; print "</UL>\n"; } /*print "<br>\n"; print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; print "<h3>NEW!</h3>\n"; print "Connect to the server using a java applet:<br>\n"; print "<INPUT type=submit value=\"Connect with Applet\">\n"; print "<INPUT type=hidden name=mode value=connectRDPapplet>\n"; print "<INPUT type=hidden name=requestid value=$requestid>\n"; print "</FORM><br>\n";*/ print "For automatic connection, you can download an RDP file that can "; print "be opened by the Remote Desktop Connection program.<br><br>\n"; print "<table summary=\"\">\n"; print " <TR>\n"; print " <TD>\n"; print " <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; $cdata = array('requestid' => $requestid); $expire = datetimeToUnix($requestData['end']) - datetimeToUnix($requestData['start']) + 1800; # reservation time plus 30 min $cont = addContinuationsEntry('sendRDPfile', $cdata, $expire); print " <INPUT type=hidden name=continuation value=\"{$cont}\">\n"; print " <INPUT type=submit value=\"Get RDP File\">\n"; print " </FORM>\n"; print " </TD>\n"; print " </TR>\n"; print "</table>\n"; } else { print "You will need to have an "; print "X server running on your local computer and use an "; print "ssh client to connect to the system. If you did not "; print "click on the <b>Connect!</b> button from the computer you will "; print "need to cancel this reservation, request a new one, and "; print "make sure you click the <strong>Connect!</strong> button in "; print "a web browser running on the same computer from which you will "; print "be connecting to the VCL system. Otherwise, you may be denied "; print "access to the remote computer.<br><br>\n"; print "Use the following information when you are ready to connect:<br>\n"; print "<UL>\n"; print "<LI><b>Remote Computer</b>: {$serverIP}</LI>\n"; if (preg_match('/(.*)@(.*)/', $user['unityid'], $matches)) { print "<LI><b>User ID</b>: " . $matches[1] . "</LI>\n"; } else { print "<LI><b>User ID</b>: " . $user['unityid'] . "</LI>\n"; } if (strlen($passwd)) { print "<LI><b>Password</b>: {$passwd}<br></LI>\n"; print "</UL>\n"; print "<b>NOTE</b>: The given password is for <i>this reservation "; print "only</i>. You will be given a different password for any other "; print "reservations.<br>\n"; } else { print "<LI><b>Password</b>: (use your campus password)</LI>\n"; print "</UL>\n"; } print "<strong><big>NOTE:</big> You cannot use the Windows Remote "; print "Desktop Connection to connect to this computer. You must use an "; print "ssh client.</strong>\n"; /*if(eregi("windows", $_SERVER["HTTP_USER_AGENT"])) { print "<br><br><h3>NEW!</h3>\n"; print "Connect to the server using a java applet:<br>\n"; print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; print "<INPUT type=submit value=\"Connect with Applet\">\n"; print "<INPUT type=hidden name=mode value=connectMindterm>\n"; print "<INPUT type=hidden name=serverip value=\"$serverIP\">\n"; print "</FORM>\n"; }*/ } } else { print "You will need an "; print "ssh client to connect to any unix systems.<br>\n"; print "You will need a "; print "Remote Desktop program</a> to connect to any windows systems.<br><br>\n"; print "Use the following information when you are ready to connect:<br>\n"; $total = count($requestData["reservations"]); $count = 0; foreach ($requestData["reservations"] as $key => $res) { $count++; print "<h3>{$res["prettyimage"]}</h3>\n"; print "<UL>\n"; print "<LI><b>Platform</b>: {$res["OS"]}</LI>\n"; print "<LI><b>Remote Computer</b>: {$res["reservedIP"]}</LI>\n"; print "<LI><b>User ID</b>: " . $user['unityid'] . "</LI>\n"; if (eregi("windows", $res["OS"])) { if (strlen($res['password'])) { print "<LI><b>Password</b>: {$res['password']}<br></LI>\n"; print "</UL>\n"; print "<b>NOTE</b>: The given password is for <i>this reservation "; print "only</i>. You will be given a different password for any other "; print "reservations.<br>\n"; } else { print "<LI><b>Password</b>: (use your campus password)</LI>\n"; print "</UL>\n"; } /*print "Connect to the server using a java applet:<br>\n"; print "<INPUT type=submit value=\"Connect with Applet\">\n"; print "<INPUT type=hidden name=mode value=connectRDPapplet>\n"; print "<INPUT type=hidden name=requestid value=$requestid>\n"; print "<INPUT type=hidden name=reservedIP value=\"{$res["reservedIP"]}\">\n"; print "</FORM><br><br>\n";*/ print "Automatic connection using an RDP file:<br>\n"; print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; $cdata = array('requestid' => $requestid, 'reservedIP' => $res['reservedIP']); $expire = datetimeToUnix($requestData['end']) - datetimeToUnix($requestData['start']) + 1800; # reservation time plus 30 min $cont = addContinuationsEntry('sendRDPfile', $cdata, $expire); print "<INPUT type=hidden name=continuation value=\"{$cont}\">\n"; print "<INPUT type=submit value=\"Get RDP File\">\n"; print "</FORM>\n"; } else { if (strlen($res['password'])) { print "<LI><b>Password</b>: {$res['password']}<br></LI>\n"; print "</UL>\n"; print "<b>NOTE</b>: The given password is for <i>this reservation "; print "only</i>. You will be given a different password for any other "; print "reservations.<br>\n"; } else { print "<LI><b>Password</b>: (use your campus password)</LI>\n"; print "</UL>\n"; } /*if(eregi("windows", $_SERVER["HTTP_USER_AGENT"])) { print "Connect to the server using a java applet:<br>\n"; print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; print "<INPUT type=submit value=\"Connect with Applet\">\n"; print "<INPUT type=hidden name=mode value=connectMindterm>\n"; print "<INPUT type=hidden name=requestid value=$requestid>\n"; print "<INPUT type=hidden name=serverip value=\"{$res["reservedIP"]}\">\n"; print "</FORM>\n"; }*/ } if ($count < $total) { print "<hr>\n"; } } } foreach ($requestData["reservations"] as $res) { if ($res["forcheckout"]) { $imageid = $res["imageid"]; break; } } $imagenotes = getImageNotes($imageid); if (preg_match('/\\w/', $imagenotes['usage'])) { print "<h3>Notes on using this environment:</h3>\n"; print "{$imagenotes['usage']}<br><br><br>\n"; } }
function XMLRPCgetRequestConnectData($requestid, $remoteIP) { global $user; $requestid = processInputData($requestid, ARG_NUMERIC); $remoteIP = processInputData($remoteIP, ARG_STRING, 1); if (!preg_match('/^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$/', $remoteIP, $matches) || $matches[1] < 1 || $matches[1] > 223 || $matches[2] > 255 || $matches[3] > 255 || $matches[4] > 255) { return array('status' => 'error', 'errorcode' => 2, 'errormsg' => 'invalid IP address'); } $userRequests = getUserRequests('all', $user['id']); $found = 0; foreach ($userRequests as $req) { if ($req['id'] == $requestid) { $request = $req; $found = 1; break; } } if (!$found) { return array('status' => 'error', 'errorcode' => 1, 'errormsg' => 'unknown requestid'); } // FIXME - add support for cluster requests if (requestIsReady($request)) { $requestData = getRequestInfo($requestid); $query = "UPDATE reservation " . "SET remoteIP = '{$remoteIP}' " . "WHERE requestid = {$requestid}"; $qh = doQuery($query, 101); addChangeLogEntry($requestData["logid"], $remoteIP); $serverIP = $requestData["reservations"][0]["reservedIP"]; $passwd = $requestData["reservations"][0]["password"]; if ($requestData["forimaging"]) { $thisuser = '******'; } else { if (preg_match('/(.*)@(.*)/', $user['unityid'], $matches)) { $thisuser = $matches[1]; } else { $thisuser = $user['unityid']; } } return array('status' => 'ready', 'serverIP' => $serverIP, 'user' => $thisuser, 'password' => $passwd); } return array('status' => 'notready'); }
function moveReservationsOffComputer($compid = 0, $count = 0) { global $requestInfo, $user; $resInfo = array(); $checkstart = unixToDatetime(time() + 180); if ($compid == 0) { $resources = getUserResources(array("imageAdmin", "imageCheckOut"), array("available"), 0, 0); $computers = implode("','", array_keys($resources["computer"])); $computers = "'{$computers}'"; $query = "SELECT DISTINCT COUNT(rs.id) AS reservations, " . "rs.computerid " . "FROM reservation rs, " . "request rq " . "WHERE rq.start > '{$checkstart}' AND " . "rs.computerid IN ({$computers}) " . "GROUP BY computerid " . "ORDER BY reservations " . "LIMIT 1"; $qh = doQuery($query, 101); if ($row = mysql_fetch_assoc($qh)) { $compid = $row["computerid"]; } else { return -1; } } # get all reservation info for $compid $query = "SELECT rs.id, " . "rs.requestid, " . "rs.imageid, " . "rq.logid, " . "rq.userid, " . "rq.start, " . "rq.end " . "FROM reservation rs, " . "request rq " . "WHERE rs.computerid = {$compid} AND " . "rs.requestid = rq.id AND " . "rq.start > '{$checkstart}' AND " . "rq.stateid NOT IN (1, 5, 11, 12) " . "ORDER BY rq.start"; if ($count) { $query .= " LIMIT {$count}"; } $qh = doQuery($query, 101); while ($row = mysql_fetch_assoc($qh)) { $resInfo[$row["id"]] = $row; } if (!count($resInfo)) { return -1; } $images = getImages(); $allmovable = 1; foreach ($resInfo as $res) { $rc = isAvailable($images, $res["imageid"], datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), "dummy", 0, $res["userid"]); if ($rc < 1) { $allmovable = 0; break; } } if (!$allmovable) { return 0; } foreach ($resInfo as $res) { $rc = isAvailable($images, $res["imageid"], datetimeToUnix($res["start"]), datetimeToUnix($res["end"]), "dummy", 0, $res["userid"]); if ($rc > 0) { $newcompid = array_shift($requestInfo["computers"]); # get mgmt node for computer $mgmtnodeid = findManagementNode($newcompid, $res['start'], 'future'); # update mgmt node and computer in reservation table $query = "UPDATE reservation " . "SET computerid = {$newcompid}, " . "managementnodeid = {$mgmtnodeid} " . "WHERE id = {$res["id"]}"; doQuery($query, 101); # add changelog entry addChangeLogEntry($res['logid'], NULL, NULL, NULL, $newcompid); # update sublog entry $query = "UPDATE sublog " . "SET computerid = {$newcompid} " . "WHERE logid = {$res['logid']} AND " . "computerid = {$compid}"; doQuery($query, 101); } else { return 0; } } return 1; }
function XMLRPCsetRequestEnding($requestid, $end) { global $user; $requestid = processInputData($requestid, ARG_NUMERIC); $userRequests = getUserRequests('all', $user['id']); $found = 0; foreach ($userRequests as $req) { if ($req['id'] == $requestid) { $request = getRequestInfo($requestid); $found = 1; break; } } if (!$found) { return array('status' => 'error', 'errorcode' => 1, 'errormsg' => 'unknown requestid'); } // make sure user is a member of the 'Specify End Time' group $groupid = getUserGroupID('Specify End Time'); $members = getUserGroupMembers($groupid); if (!$request['serverrequest'] && !array_key_exists($user['id'], $members)) { return array('status' => 'error', 'errorcode' => 35, 'errormsg' => "access denied to specify end time"); } $end = processInputData($end, ARG_NUMERIC); $maxend = datetimeToUnix("2038-01-01 00:00:00"); if ($end < 0 || $end > $maxend) { return array('status' => 'error', 'errorcode' => 36, 'errormsg' => "received invalid input for end"); } $startts = datetimeToUnix($request['start']); if ($end % (15 * 60)) { $end = unixFloor15($end) + 15 * 60; } // check that reservation has started if ($startts > time()) { return array('status' => 'error', 'errorcode' => 38, 'errormsg' => 'reservation has not started'); } // check for overlap $max = getMaxOverlap($user['id']); if (checkOverlap($startts, $end, $max, $requestid)) { return array('status' => 'error', 'errorcode' => 41, 'errormsg' => 'overlapping reservation restriction', 'maxoverlap' => $max); } // check for computer being available for extended time? $timeToNext = timeToNextReservation($request); $movedall = 1; if ($timeToNext > -1) { $lockedall = 1; if (count($request['reservations']) > 1) { # get semaphore on each existing node in cluster so that nothing # can get moved to the nodes during this process $unixend = datetimeToUnix($request['end']); $checkend = unixToDatetime($unixend + 900); $resources = getUserResources(array("imageAdmin", "imageCheckOut")); $tmp = array_keys($resources['image']); $semimageid = $tmp[0]; $semrevid = getProductionRevisionid($semimageid); foreach ($request["reservations"] as $res) { if (!retryGetSemaphore($semimageid, $semrevid, $res['managementnodeid'], $res['computerid'], $request['start'], $checkend, $requestid)) { $lockedall = 0; break; } } } if ($lockedall) { foreach ($request["reservations"] as $res) { if (!moveReservationsOffComputer($res["computerid"])) { $movedall = 0; break; } } } else { cleanSemaphore(); return array('status' => 'error', 'errorcode' => 42, 'errormsg' => 'cannot extend due to another reservation immediately after this one'); } cleanSemaphore(); } if (!$movedall) { $timeToNext = timeToNextReservation($request); if ($timeToNext >= 15) { $timeToNext -= 15; } $oldendts = datetimeToUnix($request['end']); // reservation immediately after this one, cannot extend if ($timeToNext < 15) { return array('status' => 'error', 'errorcode' => 42, 'errormsg' => 'cannot extend due to another reservation immediately after this one'); } elseif (($end - $oldendts) / 60 > $timeToNext) { $maxend = $oldendts + $timeToNext * 60; return array('status' => 'error', 'errorcode' => 43, 'errormsg' => 'cannot extend by requested amount due to another reservation', 'maxend' => $maxend); } } $rc = isAvailable(getImages(), $request['reservations'][0]["imageid"], $request['reservations'][0]['imagerevisionid'], $startts, $end, 1, $requestid); // conflicts with scheduled maintenance if ($rc == -2) { addChangeLogEntry($request["logid"], NULL, unixToDatetime($end), $request['start'], NULL, NULL, 0); return array('status' => 'error', 'errorcode' => 46, 'errormsg' => 'requested time is during a maintenance window'); } elseif ($rc == -1) { addChangeLogEntry($request["logid"], NULL, unixToDatetime($end), $request['start'], NULL, NULL, 0); return array('status' => 'error', 'errorcode' => 44, 'errormsg' => 'concurrent license restriction'); } elseif ($rc == 0) { addChangeLogEntry($request["logid"], NULL, unixToDatetime($end), $request['start'], NULL, NULL, 0); return array('status' => 'error', 'errorcode' => 45, 'errormsg' => 'cannot extend at this time'); } // success updateRequest($requestid); cleanSemaphore(); return array('status' => 'success'); }