]> git.proxmox.com Git - mirror_qemu.git/blob - hw/virtio-9p-local.c
virtio-9p: Add minimal set of FileOperations
[mirror_qemu.git] / hw / virtio-9p-local.c
1 /*
2 * Virtio 9p Posix callback
3 *
4 * Copyright IBM, Corp. 2010
5 *
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
11 *
12 */
13 #include "virtio.h"
14 #include "virtio-9p.h"
15 #include <pwd.h>
16 #include <grp.h>
17
18 static const char *rpath(FsContext *ctx, const char *path)
19 {
20 /* FIXME: so wrong... */
21 static char buffer[4096];
22 snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
23 return buffer;
24 }
25
26 static int local_lstat(FsContext *ctx, const char *path, struct stat *stbuf)
27 {
28 return lstat(rpath(ctx, path), stbuf);
29 }
30
31 static int local_setuid(FsContext *ctx, uid_t uid)
32 {
33 struct passwd *pw;
34 gid_t groups[33];
35 int ngroups;
36 static uid_t cur_uid = -1;
37
38 if (cur_uid == uid) {
39 return 0;
40 }
41
42 if (setreuid(0, 0)) {
43 return -1;
44 }
45
46 pw = getpwuid(uid);
47 if (pw == NULL) {
48 return -1;
49 }
50
51 ngroups = 33;
52 if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups) == -1) {
53 return -1;
54 }
55
56 if (setgroups(ngroups, groups)) {
57 return -1;
58 }
59
60 if (setregid(-1, pw->pw_gid)) {
61 return -1;
62 }
63
64 if (setreuid(-1, uid)) {
65 return -1;
66 }
67
68 cur_uid = uid;
69
70 return 0;
71 }
72
73 static ssize_t local_readlink(FsContext *ctx, const char *path,
74 char *buf, size_t bufsz)
75 {
76 return readlink(rpath(ctx, path), buf, bufsz);
77 }
78
79 static int local_close(FsContext *ctx, int fd)
80 {
81 return close(fd);
82 }
83
84 static int local_closedir(FsContext *ctx, DIR *dir)
85 {
86 return closedir(dir);
87 }
88
89 FileOperations local_ops = {
90 .lstat = local_lstat,
91 .setuid = local_setuid,
92 .readlink = local_readlink,
93 .close = local_close,
94 .closedir = local_closedir,
95 };