3 # Handles remote_foreign_require and remote_foreign_call requests from
4 # other webmin servers. State is preserved by starting a process for each
5 # session that listens for requests on a named pipe (and dies after a few
6 # seconds of inactivity)
7 # access{'rpc'} 0=not allowed 1=allowed 2=allowed if root or admin
9 BEGIN { push(@INC, ".."); };
14 if ($ENV{'REQUEST_METHOD'} eq 'POST') {
16 while(length($rawarg) < $ENV{'CONTENT_LENGTH'}) {
17 read(STDIN, $got, $ENV{'CONTENT_LENGTH'}) > 0 || last;
22 $rawarg = $ENV{'QUERY_STRING'};
24 $arg = &unserialise_variable($rawarg);
26 print "Content-type: text/plain\n\n";
28 # Can this user make remote calls?
29 %access = &get_module_acl();
30 if ($access{'rpc'} == 0 || $access{'rpc'} == 2 &&
31 $base_remote_user ne 'admin' && $base_remote_user ne 'root' &&
32 $base_remote_user ne 'sysadm') {
33 print &serialise_variable( { 'status' => 0 } );
37 if ($arg->{'newsession'}) {
38 # Need to fork a new session-handler process
44 # This is the subprocess where execution really happens
45 $SIG{'ALRM'} = "fifo_timeout";
50 close(miniserv::SOCK);
51 local $stime = time();
53 local ($rawcmd, $cmd, @rv);
55 open(FIFO, $fifo1) || last;
61 $cmd = &unserialise_variable($rawcmd);
62 if ($cmd->{'action'} eq 'quit') {
63 # time to end this session (after the reply)
64 @rv = ( { 'time' => time() - $stime } );
66 elsif ($cmd->{'action'} eq 'require') {
68 &foreign_require($cmd->{'module'},
70 @rv = ( { 'session' => [ $fifo1, $fifo2 ] } );
72 elsif ($cmd->{'action'} eq 'call') {
74 @rv = &foreign_call($cmd->{'module'},
78 elsif ($cmd->{'action'} eq 'eval') {
80 if ($cmd->{'module'}) {
82 package $cmd->{'module'};
87 @rv = eval $cmd->{'code'};
90 open(FIFO, ">$fifo2");
92 print FIFO &serialise_variable(
93 { 'status' => 1, 'rv' => $rv[0] } );
96 print FIFO &serialise_variable(
97 { 'status' => 1, 'arv' => \@rv } );
100 last if ($cmd->{'action'} eq 'quit');
106 $session = [ $fifo1, $fifo2 ];
109 # Use the provided session id
110 $session = $arg->{'session'};
113 if ($arg->{'action'} eq 'ping') {
114 # Just respond with an OK
115 print &serialise_variable( { 'status' => 1 } );
117 elsif ($arg->{'action'} eq 'check') {
118 # Check if some module is supported
119 print &serialise_variable(
121 'rv' => &foreign_check($arg->{'module'}, undef, undef,
124 elsif ($arg->{'action'} eq 'config') {
125 # Get the config for some module
126 local %config = &foreign_config($arg->{'module'});
127 print &serialise_variable(
128 { 'status' => 1, 'rv' => \%config } );
130 elsif ($arg->{'action'} eq 'write') {
131 # Transfer data to a local temp file
132 local $file = $arg->{'file'} ? $arg->{'file'} :
133 $arg->{'name'} ? &tempname($arg->{'name'}) :
135 open(FILE, ">$file");
136 print FILE $arg->{'data'};
138 print &serialise_variable(
139 { 'status' => 1, 'rv' => $file } );
141 elsif ($arg->{'action'} eq 'read') {
142 # Transfer data from a file
144 open(FILE, $arg->{'file'});
145 while(read(FILE, $got, 1024) > 0) {
149 print &serialise_variable(
150 { 'status' => 1, 'rv' => $data } );
153 # Pass the request on to the subprocess
154 open(FIFO, ">$session->[0]");
157 open(FIFO, $session->[1]);