Skip to content

Commit

Permalink
Merge remote-tracking branch 'kiszka/queues/slirp' into staging
Browse files Browse the repository at this point in the history
* kiszka/queues/slirp:
  slirp: Improve error reporting of inaccessible smb directories
  slirp: Ensure smbd and shared directory exist when enable smb
  slirp: add 'cmd:' target for guestfwd
  slirp: Enforce host-side user of smb share
  • Loading branch information
Anthony Liguori committed Jul 9, 2012
2 parents 715cc00 + 22a61f3 commit 537cf40
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 20 deletions.
70 changes: 51 additions & 19 deletions net/slirp.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "config-host.h"

#ifndef _WIN32
#include <pwd.h>
#include <sys/wait.h>
#endif
#include "net.h"
Expand Down Expand Up @@ -487,8 +488,27 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
static int instance;
char smb_conf[128];
char smb_cmdline[128];
struct passwd *passwd;
FILE *f;

passwd = getpwuid(geteuid());
if (!passwd) {
error_report("failed to retrieve user name");
return -1;
}

if (access(CONFIG_SMBD_COMMAND, F_OK)) {
error_report("could not find '%s', please install it",
CONFIG_SMBD_COMMAND);
return -1;
}

if (access(exported_dir, R_OK | X_OK)) {
error_report("error accessing shared directory '%s': %s",
exported_dir, strerror(errno));
return -1;
}

snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.%ld-%d",
(long)getpid(), instance++);
if (mkdir(s->smb_dir, 0700) < 0) {
Expand Down Expand Up @@ -517,14 +537,16 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
"[qemu]\n"
"path=%s\n"
"read only=no\n"
"guest ok=yes\n",
"guest ok=yes\n"
"force user=%s\n",
s->smb_dir,
s->smb_dir,
s->smb_dir,
s->smb_dir,
s->smb_dir,
s->smb_dir,
exported_dir
exported_dir,
passwd->pw_name
);
fclose(f);

Expand Down Expand Up @@ -616,25 +638,35 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,

fwd = g_malloc(sizeof(struct GuestFwd));
snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
fwd->hd = qemu_chr_new(buf, p, NULL);
if (!fwd->hd) {
error_report("could not open guest forwarding device '%s'", buf);
g_free(fwd);
return -1;
}

if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
error_report("conflicting/invalid host:port in guest forwarding "
"rule '%s'", config_str);
g_free(fwd);
return -1;
}
fwd->server = server;
fwd->port = port;
fwd->slirp = s->slirp;
if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
if (slirp_add_exec(s->slirp, 0, &p[4], &server, port) < 0) {
error_report("conflicting/invalid host:port in guest forwarding "
"rule '%s'", config_str);
g_free(fwd);
return -1;
}
} else {
fwd->hd = qemu_chr_new(buf, p, NULL);
if (!fwd->hd) {
error_report("could not open guest forwarding device '%s'", buf);
g_free(fwd);
return -1;
}

qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
NULL, fwd);
if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
error_report("conflicting/invalid host:port in guest forwarding "
"rule '%s'", config_str);
g_free(fwd);
return -1;
}
fwd->server = server;
fwd->port = port;
fwd->slirp = s->slirp;

qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
NULL, fwd);
}
return 0;

fail_syntax:
Expand Down
22 changes: 21 additions & 1 deletion qemu-options.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1421,8 +1421,28 @@ Then when you use on the host @code{telnet localhost 5555}, you
connect to the guest telnet server.
@item guestfwd=[tcp]:@var{server}:@var{port}-@var{dev}
@item guestfwd=[tcp]:@var{server}:@var{port}-@var{cmd:command}
Forward guest TCP connections to the IP address @var{server} on port @var{port}
to the character device @var{dev}. This option can be given multiple times.
to the character device @var{dev} or to a program executed by @var{cmd:command}
which gets spawned for each connection. This option can be given multiple times.
You can either use a chardev directly and have that one used throughout Qemu's
lifetime, like in the following example:
@example
# open 10.10.1.1:4321 on bootup, connect 10.0.2.100:1234 to it whenever
# the guest accesses it
qemu -net user,guestfwd=tcp:10.0.2.100:1234-tcp:10.10.1.1:4321 [...]
@end example
Or you can execute a command on every TCP connection established by the guest,
so that Qemu behaves similar to an inetd process for that virtual server:
@example
# call "netcat 10.10.1.1 4321" on every TCP connection to 10.0.2.100:1234
# and connect the TCP stream to its stdin/stdout
qemu -net 'user,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10.1.1 4321'
@end example
@end table
Expand Down

0 comments on commit 537cf40

Please sign in to comment.