xmlrpcpipe.php3.in 3.9 KB
Newer Older
Timothy Stack's avatar
Timothy Stack committed
1 2
<?php
#
3
# Copyright (c) 2004-2010 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Timothy Stack's avatar
Timothy Stack committed
23 24 25 26 27 28 29 30 31 32
#
# This is an included file. No headers or footers.
#
# Stuff to use the xmlrpc client/server. This is functionally equivalent
# to the perl stuff I wrote in xmlrpc/libxmlrpc.pm.in.
#
include("defs.php3");

$RPCSERVER  = "@BOSSNODE@";
$RPCPORT    = "@OUTERBOSS_XMLRPCPORT@";
33
$FSDIR_USERS = "@USERSROOT_DIR@";
Timothy Stack's avatar
Timothy Stack committed
34

35 36 37
# So errors are sent back in short form.
$session_interactive = 0;

Timothy Stack's avatar
Timothy Stack committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#
# Emulab XMLRPC defs.
#
# WARNING: If you change this stuff, also change defs in xmlrpc directory.
#
define("XMLRPC_RESPONSE_SUCCESS",	0);
define("XMLRPC_RESPONSE_BADARGS",	1);
define("XMLRPC_RESPONSE_ERROR",		2);
define("XMLRPC_RESPONSE_FORBIDDEN",	3);
define("XMLRPC_RESPONSE_BADVERSION",	4);
define("XMLRPC_RESPONSE_SERVERERROR",	5);
define("XMLRPC_RESPONSE_TOOBIG",	6);
define("XMLRPC_RESPONSE_REFUSED",	7);
define("XMLRPC_RESPONSE_TIMEDOUT",	8);

##
# The package version number
#
define("XMLRPC_PACKAGE_VERSION",	0.1);

58 59 60
$this_user = CheckLoginOrDie();
$uid       = $this_user->uid();
$isadmin   = ISADMIN();
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#
# Check the XML to make sure it is well formed.
#
$all_data = file_get_contents("php://input");

if (!isset($all_data) || $all_data == "") {
    USERERROR("Where is the XML?", 1);
}
$mypipe = popen("/usr/local/bin/xmllint --noout - 2>&1", "w");
if ($mypipe == false) {
    TBERROR("Could not start xmllint", 1);
}
fwrite($mypipe, $all_data);
fflush($mypipe);
$return_value = pclose($mypipe);
if ($return_value) {
    USERERROR("Invalid XML", 1);
}
Timothy Stack's avatar
Timothy Stack committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

#
# Invoke the ssl xmlrpc client in raw mode, passing it an encoded XMLRPC
# string, reading back an XMLRPC encoded response, which is converted to
# a PHP datatype with the ParseResponse() function above. In other words,
# we invoke a method on a remote xmlrpc server, and get back a response.
# Invoked as the current user, but the actual uid of the caller is contained
# in the ssl certificate we use, which for now is the elabinelab certificate
# of the creator (since that is the only place this code is being used).
#

$descriptorspec = array(0 => array("pipe", "r"),
		        1 => array("pipe", "w"));

$process = proc_open("$TBSUEXEC_PATH $uid nobody webxmlrpc -r ".
		     "-s $RPCSERVER -p $RPCPORT ".
		     "--cert $FSDIR_USERS/$uid/.ssl/emulab.pem",
		     $descriptorspec, $pipes);

if (! is_resource($process)) {
99 100 101 102
    TBERROR("Could not invoke XMLRPC backend!\n".
	    "Invoked as $uid,nobody\n".
	    "XML:\n" .
	    "$all_data\n\n", 1);
Timothy Stack's avatar
Timothy Stack committed
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
}

# $pipes now looks like this:
# 0 => writeable handle connected to child stdin
# 1 => readable handle connected to child stdout

fwrite($pipes[0], $all_data);
fflush($pipes[0]);

fclose($pipes[0]);

$output = "";
#
# Now read back the results.
while(!feof($pipes[1])) {
    $output .= fread($pipes[1], 1024); # XXX do this better
}
fclose($pipes[1]);

# It is important that you close any pipes before calling
# proc_close in order to avoid a deadlock.
$return_value = proc_close($process);

if ($return_value || $output == "") {
127 128 129 130 131 132
    TBERROR("XMLRPC backend failure!\n".
	    "Invoked as $uid,nobody. Returned $return_value\n".
	    "XML:\n" .
	    "$all_data\n\n" .
	    "Output:\n" .
	    "$output\n", 1);
Timothy Stack's avatar
Timothy Stack committed
133 134 135 136 137
}

header("content-length: " . strlen($output));

echo $output;