Blame


1 be8b315d 2004-06-17 devnull #include <u.h>
2 be8b315d 2004-06-17 devnull #include <libc.h>
3 be8b315d 2004-06-17 devnull #include <bio.h>
4 be8b315d 2004-06-17 devnull #include <auth.h>
5 be8b315d 2004-06-17 devnull #include <authsrv.h>
6 be8b315d 2004-06-17 devnull #include "authlocal.h"
7 be8b315d 2004-06-17 devnull
8 be8b315d 2004-06-17 devnull enum
9 be8b315d 2004-06-17 devnull {
10 be8b315d 2004-06-17 devnull NARG = 15, /* max number of arguments */
11 be8b315d 2004-06-17 devnull MAXARG = 10*ANAMELEN, /* max length of an argument */
12 be8b315d 2004-06-17 devnull };
13 be8b315d 2004-06-17 devnull
14 be8b315d 2004-06-17 devnull static int setenv(char*, char*);
15 be8b315d 2004-06-17 devnull static char *expandarg(char*, char*);
16 be8b315d 2004-06-17 devnull static int splitargs(char*, char*[], char*, int);
17 be8b315d 2004-06-17 devnull static int nsfile(Biobuf *, AuthRpc *);
18 be8b315d 2004-06-17 devnull static int nsop(int, char*[], AuthRpc*);
19 be8b315d 2004-06-17 devnull static int callexport(char*, char*);
20 be8b315d 2004-06-17 devnull static int catch(void*, char*);
21 be8b315d 2004-06-17 devnull
22 be8b315d 2004-06-17 devnull static int
23 be8b315d 2004-06-17 devnull buildns(int newns, char *user, char *file)
24 be8b315d 2004-06-17 devnull {
25 be8b315d 2004-06-17 devnull Biobuf *b;
26 be8b315d 2004-06-17 devnull char home[4*ANAMELEN];
27 be8b315d 2004-06-17 devnull int afd;
28 be8b315d 2004-06-17 devnull AuthRpc *rpc;
29 be8b315d 2004-06-17 devnull int cdroot;
30 be8b315d 2004-06-17 devnull char *path;
31 be8b315d 2004-06-17 devnull
32 be8b315d 2004-06-17 devnull rpc = nil;
33 be8b315d 2004-06-17 devnull /* try for factotum now because later is impossible */
34 be8b315d 2004-06-17 devnull afd = open("/mnt/factotum/rpc", ORDWR);
35 be8b315d 2004-06-17 devnull if(afd >= 0){
36 be8b315d 2004-06-17 devnull rpc = auth_allocrpc(afd);
37 be8b315d 2004-06-17 devnull if(rpc == nil){
38 be8b315d 2004-06-17 devnull close(afd);
39 be8b315d 2004-06-17 devnull afd = -1;
40 be8b315d 2004-06-17 devnull }
41 be8b315d 2004-06-17 devnull }
42 be8b315d 2004-06-17 devnull if(file == nil){
43 be8b315d 2004-06-17 devnull if(!newns){
44 be8b315d 2004-06-17 devnull werrstr("no namespace file specified");
45 be8b315d 2004-06-17 devnull return -1;
46 be8b315d 2004-06-17 devnull }
47 be8b315d 2004-06-17 devnull file = "/lib/namespace";
48 be8b315d 2004-06-17 devnull }
49 be8b315d 2004-06-17 devnull b = Bopen(file, OREAD);
50 be8b315d 2004-06-17 devnull if(b == 0){
51 be8b315d 2004-06-17 devnull werrstr("can't open %s: %r", file);
52 be8b315d 2004-06-17 devnull close(afd);
53 be8b315d 2004-06-17 devnull auth_freerpc(rpc);
54 be8b315d 2004-06-17 devnull return -1;
55 be8b315d 2004-06-17 devnull }
56 be8b315d 2004-06-17 devnull if(newns){
57 be8b315d 2004-06-17 devnull rfork(RFENVG|RFCNAMEG);
58 be8b315d 2004-06-17 devnull setenv("user", user);
59 be8b315d 2004-06-17 devnull snprint(home, 2*ANAMELEN, "/usr/%s", user);
60 be8b315d 2004-06-17 devnull setenv("home", home);
61 be8b315d 2004-06-17 devnull }
62 be8b315d 2004-06-17 devnull cdroot = nsfile(b, rpc);
63 be8b315d 2004-06-17 devnull Bterm(b);
64 be8b315d 2004-06-17 devnull if(rpc){
65 be8b315d 2004-06-17 devnull close(rpc->afd);
66 be8b315d 2004-06-17 devnull auth_freerpc(rpc);
67 be8b315d 2004-06-17 devnull }
68 be8b315d 2004-06-17 devnull
69 be8b315d 2004-06-17 devnull /* make sure we managed to cd into the new name space */
70 be8b315d 2004-06-17 devnull if(newns && !cdroot){
71 be8b315d 2004-06-17 devnull path = malloc(1024);
72 be8b315d 2004-06-17 devnull if(path == nil || getwd(path, 1024) == 0 || chdir(path) < 0)
73 be8b315d 2004-06-17 devnull chdir("/");
74 be8b315d 2004-06-17 devnull if(path != nil)
75 be8b315d 2004-06-17 devnull free(path);
76 be8b315d 2004-06-17 devnull }
77 be8b315d 2004-06-17 devnull
78 be8b315d 2004-06-17 devnull return 0;
79 be8b315d 2004-06-17 devnull }
80 be8b315d 2004-06-17 devnull
81 be8b315d 2004-06-17 devnull static int
82 be8b315d 2004-06-17 devnull nsfile(Biobuf *b, AuthRpc *rpc)
83 be8b315d 2004-06-17 devnull {
84 be8b315d 2004-06-17 devnull int argc;
85 be8b315d 2004-06-17 devnull char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG];
86 be8b315d 2004-06-17 devnull int cdroot = 0;
87 be8b315d 2004-06-17 devnull
88 be8b315d 2004-06-17 devnull atnotify(catch, 1);
89 be8b315d 2004-06-17 devnull while(cmd = Brdline(b, '\n')){
90 be8b315d 2004-06-17 devnull cmd[Blinelen(b)-1] = '\0';
91 be8b315d 2004-06-17 devnull while(*cmd==' ' || *cmd=='\t')
92 be8b315d 2004-06-17 devnull cmd++;
93 be8b315d 2004-06-17 devnull if(*cmd == '#')
94 be8b315d 2004-06-17 devnull continue;
95 be8b315d 2004-06-17 devnull argc = splitargs(cmd, argv, argbuf, NARG);
96 be8b315d 2004-06-17 devnull if(argc)
97 be8b315d 2004-06-17 devnull cdroot |= nsop(argc, argv, rpc);
98 be8b315d 2004-06-17 devnull }
99 be8b315d 2004-06-17 devnull atnotify(catch, 0);
100 be8b315d 2004-06-17 devnull return cdroot;
101 be8b315d 2004-06-17 devnull }
102 be8b315d 2004-06-17 devnull
103 be8b315d 2004-06-17 devnull int
104 be8b315d 2004-06-17 devnull newns(char *user, char *file)
105 be8b315d 2004-06-17 devnull {
106 be8b315d 2004-06-17 devnull return buildns(1, user, file);
107 be8b315d 2004-06-17 devnull }
108 be8b315d 2004-06-17 devnull
109 be8b315d 2004-06-17 devnull int
110 be8b315d 2004-06-17 devnull addns(char *user, char *file)
111 be8b315d 2004-06-17 devnull {
112 be8b315d 2004-06-17 devnull return buildns(0, user, file);
113 be8b315d 2004-06-17 devnull }
114 be8b315d 2004-06-17 devnull
115 be8b315d 2004-06-17 devnull static int
116 be8b315d 2004-06-17 devnull famount(int fd, AuthRpc *rpc, char *mntpt, int flags, char *aname)
117 be8b315d 2004-06-17 devnull {
118 be8b315d 2004-06-17 devnull int afd;
119 be8b315d 2004-06-17 devnull AuthInfo *ai;
120 be8b315d 2004-06-17 devnull
121 be8b315d 2004-06-17 devnull afd = fauth(fd, aname);
122 be8b315d 2004-06-17 devnull if(afd >= 0){
123 be8b315d 2004-06-17 devnull ai = fauth_proxy(afd, rpc, amount_getkey, "proto=p9any role=client");
124 be8b315d 2004-06-17 devnull if(ai != nil)
125 be8b315d 2004-06-17 devnull auth_freeAI(ai);
126 be8b315d 2004-06-17 devnull }
127 be8b315d 2004-06-17 devnull return mount(fd, afd, mntpt, flags, aname);
128 be8b315d 2004-06-17 devnull }
129 be8b315d 2004-06-17 devnull
130 be8b315d 2004-06-17 devnull static int
131 be8b315d 2004-06-17 devnull nsop(int argc, char *argv[], AuthRpc *rpc)
132 be8b315d 2004-06-17 devnull {
133 be8b315d 2004-06-17 devnull char *argv0;
134 be8b315d 2004-06-17 devnull ulong flags;
135 be8b315d 2004-06-17 devnull int fd;
136 be8b315d 2004-06-17 devnull Biobuf *b;
137 be8b315d 2004-06-17 devnull int cdroot = 0;
138 be8b315d 2004-06-17 devnull
139 be8b315d 2004-06-17 devnull flags = 0;
140 be8b315d 2004-06-17 devnull argv0 = 0;
141 be8b315d 2004-06-17 devnull ARGBEGIN{
142 be8b315d 2004-06-17 devnull case 'a':
143 be8b315d 2004-06-17 devnull flags |= MAFTER;
144 be8b315d 2004-06-17 devnull break;
145 be8b315d 2004-06-17 devnull case 'b':
146 be8b315d 2004-06-17 devnull flags |= MBEFORE;
147 be8b315d 2004-06-17 devnull break;
148 be8b315d 2004-06-17 devnull case 'c':
149 be8b315d 2004-06-17 devnull flags |= MCREATE;
150 be8b315d 2004-06-17 devnull break;
151 be8b315d 2004-06-17 devnull case 'C':
152 be8b315d 2004-06-17 devnull flags |= MCACHE;
153 be8b315d 2004-06-17 devnull break;
154 be8b315d 2004-06-17 devnull }ARGEND
155 be8b315d 2004-06-17 devnull
156 be8b315d 2004-06-17 devnull if(!(flags & (MAFTER|MBEFORE)))
157 be8b315d 2004-06-17 devnull flags |= MREPL;
158 be8b315d 2004-06-17 devnull
159 be8b315d 2004-06-17 devnull if(strcmp(argv0, ".") == 0 && argc == 1){
160 be8b315d 2004-06-17 devnull b = Bopen(argv[0], OREAD);
161 be8b315d 2004-06-17 devnull if(b == nil)
162 be8b315d 2004-06-17 devnull return 0;
163 be8b315d 2004-06-17 devnull cdroot |= nsfile(b, rpc);
164 be8b315d 2004-06-17 devnull Bterm(b);
165 be8b315d 2004-06-17 devnull } else if(strcmp(argv0, "clear") == 0 && argc == 0)
166 be8b315d 2004-06-17 devnull rfork(RFCNAMEG);
167 be8b315d 2004-06-17 devnull else if(strcmp(argv0, "bind") == 0 && argc == 2)
168 be8b315d 2004-06-17 devnull bind(argv[0], argv[1], flags);
169 be8b315d 2004-06-17 devnull else if(strcmp(argv0, "unmount") == 0){
170 be8b315d 2004-06-17 devnull if(argc == 1)
171 be8b315d 2004-06-17 devnull unmount(nil, argv[0]);
172 be8b315d 2004-06-17 devnull else if(argc == 2)
173 be8b315d 2004-06-17 devnull unmount(argv[0], argv[1]);
174 be8b315d 2004-06-17 devnull } else if(strcmp(argv0, "mount") == 0){
175 be8b315d 2004-06-17 devnull fd = open(argv[0], ORDWR);
176 be8b315d 2004-06-17 devnull if(argc == 2)
177 be8b315d 2004-06-17 devnull famount(fd, rpc, argv[1], flags, "");
178 be8b315d 2004-06-17 devnull else if(argc == 3)
179 be8b315d 2004-06-17 devnull famount(fd, rpc, argv[1], flags, argv[2]);
180 be8b315d 2004-06-17 devnull close(fd);
181 be8b315d 2004-06-17 devnull } else if(strcmp(argv0, "import") == 0){
182 be8b315d 2004-06-17 devnull fd = callexport(argv[0], argv[1]);
183 be8b315d 2004-06-17 devnull if(argc == 2)
184 be8b315d 2004-06-17 devnull famount(fd, rpc, argv[1], flags, "");
185 be8b315d 2004-06-17 devnull else if(argc == 3)
186 be8b315d 2004-06-17 devnull famount(fd, rpc, argv[2], flags, "");
187 be8b315d 2004-06-17 devnull close(fd);
188 be8b315d 2004-06-17 devnull } else if(strcmp(argv0, "cd") == 0 && argc == 1)
189 be8b315d 2004-06-17 devnull if(chdir(argv[0]) == 0 && *argv[0] == '/')
190 be8b315d 2004-06-17 devnull cdroot = 1;
191 be8b315d 2004-06-17 devnull return cdroot;
192 be8b315d 2004-06-17 devnull }
193 be8b315d 2004-06-17 devnull
194 be8b315d 2004-06-17 devnull static char *wocp = "sys: write on closed pipe";
195 be8b315d 2004-06-17 devnull
196 be8b315d 2004-06-17 devnull static int
197 be8b315d 2004-06-17 devnull catch(void *x, char *m)
198 be8b315d 2004-06-17 devnull {
199 be8b315d 2004-06-17 devnull USED(x);
200 be8b315d 2004-06-17 devnull return strncmp(m, wocp, strlen(wocp)) == 0;
201 be8b315d 2004-06-17 devnull }
202 be8b315d 2004-06-17 devnull
203 be8b315d 2004-06-17 devnull static int
204 be8b315d 2004-06-17 devnull callexport(char *sys, char *tree)
205 be8b315d 2004-06-17 devnull {
206 be8b315d 2004-06-17 devnull char *na, buf[3];
207 be8b315d 2004-06-17 devnull int fd;
208 be8b315d 2004-06-17 devnull AuthInfo *ai;
209 be8b315d 2004-06-17 devnull
210 be8b315d 2004-06-17 devnull na = netmkaddr(sys, 0, "exportfs");
211 be8b315d 2004-06-17 devnull if((fd = dial(na, 0, 0, 0)) < 0)
212 be8b315d 2004-06-17 devnull return -1;
213 be8b315d 2004-06-17 devnull if((ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client")) == nil
214 be8b315d 2004-06-17 devnull || write(fd, tree, strlen(tree)) < 0
215 be8b315d 2004-06-17 devnull || read(fd, buf, 3) != 2 || buf[0]!='O' || buf[1]!= 'K'){
216 be8b315d 2004-06-17 devnull close(fd);
217 be8b315d 2004-06-17 devnull auth_freeAI(ai);
218 be8b315d 2004-06-17 devnull return -1;
219 be8b315d 2004-06-17 devnull }
220 be8b315d 2004-06-17 devnull auth_freeAI(ai);
221 be8b315d 2004-06-17 devnull return fd;
222 be8b315d 2004-06-17 devnull }
223 be8b315d 2004-06-17 devnull
224 be8b315d 2004-06-17 devnull static int
225 be8b315d 2004-06-17 devnull splitargs(char *p, char *argv[], char *argbuf, int nargv)
226 be8b315d 2004-06-17 devnull {
227 be8b315d 2004-06-17 devnull char *q;
228 be8b315d 2004-06-17 devnull int i, n;
229 be8b315d 2004-06-17 devnull
230 be8b315d 2004-06-17 devnull n = gettokens(p, argv, nargv, " \t'\r");
231 be8b315d 2004-06-17 devnull if(n == nargv)
232 be8b315d 2004-06-17 devnull return 0;
233 be8b315d 2004-06-17 devnull for(i = 0; i < n; i++){
234 be8b315d 2004-06-17 devnull q = argv[i];
235 be8b315d 2004-06-17 devnull argv[i] = argbuf;
236 be8b315d 2004-06-17 devnull argbuf = expandarg(q, argbuf);
237 be8b315d 2004-06-17 devnull if(!argbuf)
238 be8b315d 2004-06-17 devnull return 0;
239 be8b315d 2004-06-17 devnull }
240 be8b315d 2004-06-17 devnull return n;
241 be8b315d 2004-06-17 devnull }
242 be8b315d 2004-06-17 devnull
243 be8b315d 2004-06-17 devnull /*
244 be8b315d 2004-06-17 devnull * copy the arg into the buffer,
245 be8b315d 2004-06-17 devnull * expanding any environment variables.
246 be8b315d 2004-06-17 devnull * environment variables are assumed to be
247 be8b315d 2004-06-17 devnull * names (ie. < ANAMELEN long)
248 be8b315d 2004-06-17 devnull * the entire argument is expanded to be at
249 be8b315d 2004-06-17 devnull * most MAXARG long and null terminated
250 be8b315d 2004-06-17 devnull * the address of the byte after the terminating null is returned
251 be8b315d 2004-06-17 devnull * any problems cause a 0 return;
252 be8b315d 2004-06-17 devnull */
253 be8b315d 2004-06-17 devnull static char *
254 be8b315d 2004-06-17 devnull expandarg(char *arg, char *buf)
255 be8b315d 2004-06-17 devnull {
256 be8b315d 2004-06-17 devnull char env[3+ANAMELEN], *p, *q, *x;
257 be8b315d 2004-06-17 devnull int fd, n, len;
258 be8b315d 2004-06-17 devnull
259 be8b315d 2004-06-17 devnull n = 0;
260 be8b315d 2004-06-17 devnull while(p = utfrune(arg, L'$')){
261 be8b315d 2004-06-17 devnull len = p - arg;
262 be8b315d 2004-06-17 devnull if(n + len + ANAMELEN >= MAXARG-1)
263 be8b315d 2004-06-17 devnull return 0;
264 be8b315d 2004-06-17 devnull memmove(&buf[n], arg, len);
265 be8b315d 2004-06-17 devnull n += len;
266 be8b315d 2004-06-17 devnull p++;
267 be8b315d 2004-06-17 devnull arg = utfrune(p, L'\0');
268 be8b315d 2004-06-17 devnull q = utfrune(p, L'/');
269 be8b315d 2004-06-17 devnull if(q && q < arg)
270 be8b315d 2004-06-17 devnull arg = q;
271 be8b315d 2004-06-17 devnull q = utfrune(p, L'.');
272 be8b315d 2004-06-17 devnull if(q && q < arg)
273 be8b315d 2004-06-17 devnull arg = q;
274 be8b315d 2004-06-17 devnull q = utfrune(p, L'$');
275 be8b315d 2004-06-17 devnull if(q && q < arg)
276 be8b315d 2004-06-17 devnull arg = q;
277 be8b315d 2004-06-17 devnull len = arg - p;
278 be8b315d 2004-06-17 devnull if(len >= ANAMELEN)
279 be8b315d 2004-06-17 devnull continue;
280 be8b315d 2004-06-17 devnull strcpy(env, "#e/");
281 be8b315d 2004-06-17 devnull strncpy(env+3, p, len);
282 be8b315d 2004-06-17 devnull env[3+len] = '\0';
283 be8b315d 2004-06-17 devnull fd = open(env, OREAD);
284 be8b315d 2004-06-17 devnull if(fd >= 0){
285 be8b315d 2004-06-17 devnull len = read(fd, &buf[n], ANAMELEN - 1);
286 be8b315d 2004-06-17 devnull /* some singleton environment variables have trailing NULs */
287 be8b315d 2004-06-17 devnull /* lists separate entries with NULs; we arbitrarily take the first element */
288 be8b315d 2004-06-17 devnull if(len > 0){
289 be8b315d 2004-06-17 devnull x = memchr(&buf[n], 0, len);
290 be8b315d 2004-06-17 devnull if(x != nil)
291 be8b315d 2004-06-17 devnull len = x - &buf[n];
292 be8b315d 2004-06-17 devnull n += len;
293 be8b315d 2004-06-17 devnull }
294 be8b315d 2004-06-17 devnull close(fd);
295 be8b315d 2004-06-17 devnull }
296 be8b315d 2004-06-17 devnull }
297 be8b315d 2004-06-17 devnull len = strlen(arg);
298 be8b315d 2004-06-17 devnull if(n + len >= MAXARG - 1)
299 be8b315d 2004-06-17 devnull return 0;
300 be8b315d 2004-06-17 devnull strcpy(&buf[n], arg);
301 be8b315d 2004-06-17 devnull return &buf[n+len+1];
302 be8b315d 2004-06-17 devnull }
303 be8b315d 2004-06-17 devnull
304 be8b315d 2004-06-17 devnull static int
305 be8b315d 2004-06-17 devnull setenv(char *name, char *val)
306 be8b315d 2004-06-17 devnull {
307 be8b315d 2004-06-17 devnull int f;
308 be8b315d 2004-06-17 devnull char ename[ANAMELEN+6];
309 be8b315d 2004-06-17 devnull long s;
310 be8b315d 2004-06-17 devnull
311 be8b315d 2004-06-17 devnull sprint(ename, "#e/%s", name);
312 be8b315d 2004-06-17 devnull f = create(ename, OWRITE, 0664);
313 be8b315d 2004-06-17 devnull if(f < 0)
314 be8b315d 2004-06-17 devnull return -1;
315 be8b315d 2004-06-17 devnull s = strlen(val);
316 be8b315d 2004-06-17 devnull if(write(f, val, s) != s){
317 be8b315d 2004-06-17 devnull close(f);
318 be8b315d 2004-06-17 devnull return -1;
319 be8b315d 2004-06-17 devnull }
320 be8b315d 2004-06-17 devnull close(f);
321 be8b315d 2004-06-17 devnull return 0;
322 be8b315d 2004-06-17 devnull }