auth/newns: add chdev command

This commit is contained in:
Jacob Moody 2022-05-28 02:27:59 +00:00 committed by xfnw
parent e6c589312e
commit 449fe7d8ed
2 changed files with 43 additions and 9 deletions

View file

@ -59,6 +59,12 @@ if
.I new .I new
is missing. is missing.
.TP .TP
.BR chdev \ [ -nr "] \fIdevmask
.I Devmask
defines a string of driver characters to restrict
the current namespace to. Existing binds
of drivers are left unaffected.
.TP
.BR clear .BR clear
Clear the name space with Clear the name space with
.BR rfork(RFCNAMEG) . .BR rfork(RFCNAMEG) .
@ -80,4 +86,5 @@ are interpreted as in
.SH "SEE ALSO" .SH "SEE ALSO"
.IR bind (1), .IR bind (1),
.IR namespace (4), .IR namespace (4),
.IR init (8) .IR init (8),
.IR chdev (1)

View file

@ -14,8 +14,8 @@ enum
static int setenv(char*, char*); static int setenv(char*, char*);
static char *expandarg(char*, char*); static char *expandarg(char*, char*);
static int splitargs(char*, char*[], char*, int); static int splitargs(char*, char*[], char*, int);
static int nsfile(char*, Biobuf *, AuthRpc *); static int nsfile(char*, Biobuf *, AuthRpc *, int);
static int nsop(char*, int, char*[], AuthRpc*); static int nsop(char*, int, char*[], AuthRpc*, int);
static int catch(void*, char*); static int catch(void*, char*);
int newnsdebug; int newnsdebug;
@ -35,7 +35,7 @@ buildns(int newns, char *user, char *file)
{ {
Biobuf *b; Biobuf *b;
char home[4*ANAMELEN]; char home[4*ANAMELEN];
int afd, cdroot; int afd, cdroot, dfd;
char *path; char *path;
AuthRpc *rpc; AuthRpc *rpc;
@ -51,8 +51,13 @@ buildns(int newns, char *user, char *file)
} }
/* rpc != nil iff afd >= 0 */ /* rpc != nil iff afd >= 0 */
dfd = open("#c/drivers", OWRITE|OCEXEC);
if(dfd < 0 && newnsdebug)
fprint(2, "open #c/drivers: %r\n");
if(file == nil){ if(file == nil){
if(!newns){ if(!newns){
close(dfd);
werrstr("no namespace file specified"); werrstr("no namespace file specified");
return freecloserpc(rpc); return freecloserpc(rpc);
} }
@ -60,6 +65,7 @@ buildns(int newns, char *user, char *file)
} }
b = Bopen(file, OREAD|OCEXEC); b = Bopen(file, OREAD|OCEXEC);
if(b == nil){ if(b == nil){
close(dfd);
werrstr("can't open %s: %r", file); werrstr("can't open %s: %r", file);
return freecloserpc(rpc); return freecloserpc(rpc);
} }
@ -70,7 +76,8 @@ buildns(int newns, char *user, char *file)
setenv("home", home); setenv("home", home);
} }
cdroot = nsfile(newns ? "newns" : "addns", b, rpc); cdroot = nsfile(newns ? "newns" : "addns", b, rpc, dfd);
close(dfd);
Bterm(b); Bterm(b);
freecloserpc(rpc); freecloserpc(rpc);
@ -87,7 +94,7 @@ buildns(int newns, char *user, char *file)
} }
static int static int
nsfile(char *fn, Biobuf *b, AuthRpc *rpc) nsfile(char *fn, Biobuf *b, AuthRpc *rpc, int dfd)
{ {
int argc; int argc;
char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG]; char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG];
@ -103,7 +110,7 @@ nsfile(char *fn, Biobuf *b, AuthRpc *rpc)
continue; continue;
argc = splitargs(cmd, argv, argbuf, NARG); argc = splitargs(cmd, argv, argbuf, NARG);
if(argc) if(argc)
cdroot |= nsop(fn, argc, argv, rpc); cdroot |= nsop(fn, argc, argv, rpc, dfd);
} }
atnotify(catch, 0); atnotify(catch, 0);
return cdroot; return cdroot;
@ -143,16 +150,18 @@ famount(int fd, AuthRpc *rpc, char *mntpt, int flags, char *aname)
} }
static int static int
nsop(char *fn, int argc, char *argv[], AuthRpc *rpc) nsop(char *fn, int argc, char *argv[], AuthRpc *rpc, int dfd)
{ {
char *argv0; char *argv0;
ulong flags; ulong flags;
char *devop;
int fd, i; int fd, i;
Biobuf *b; Biobuf *b;
int cdroot; int cdroot;
cdroot = 0; cdroot = 0;
flags = 0; flags = 0;
devop = "&";
argv0 = nil; argv0 = nil;
if(newnsdebug){ if(newnsdebug){
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
@ -172,6 +181,12 @@ nsop(char *fn, int argc, char *argv[], AuthRpc *rpc)
case 'C': case 'C':
flags |= MCACHE; flags |= MCACHE;
break; break;
case 'r':
devop = "&~";
break;
case 'n':
devop = "~";
break;
}ARGEND }ARGEND
if(!(flags & (MAFTER|MBEFORE))) if(!(flags & (MAFTER|MBEFORE)))
@ -181,7 +196,7 @@ nsop(char *fn, int argc, char *argv[], AuthRpc *rpc)
b = Bopen(argv[0], OREAD|OCEXEC); b = Bopen(argv[0], OREAD|OCEXEC);
if(b == nil) if(b == nil)
return 0; return 0;
cdroot |= nsfile(fn, b, rpc); cdroot |= nsfile(fn, b, rpc, dfd);
Bterm(b); Bterm(b);
}else if(strcmp(argv0, "clear") == 0 && argc == 0){ }else if(strcmp(argv0, "clear") == 0 && argc == 0){
rfork(RFCNAMEG); rfork(RFCNAMEG);
@ -212,6 +227,18 @@ nsop(char *fn, int argc, char *argv[], AuthRpc *rpc)
}else if(strcmp(argv0, "cd") == 0 && argc == 1){ }else if(strcmp(argv0, "cd") == 0 && argc == 1){
if(chdir(argv[0]) == 0 && *argv[0] == '/') if(chdir(argv[0]) == 0 && *argv[0] == '/')
cdroot = 1; cdroot = 1;
}else if(strcmp(argv0, "chdev") == 0){
//We should not silently fail if we can not honor a chdev
//due to the parent namespace missing #c/drivers.
if(dfd <= 0)
sysfatal("chdev requested, but could not open #c/drivers");
if(argc == 0 && devop[0] == '~'){
if(fprint(dfd, "chdev ~") < 0 && newnsdebug)
fprint(2, "%s: chdev ~: %r\n", fn);
}else if(argc == 1){
if(fprint(dfd, "chdev %s %s", devop, argv[0]) < 0 && newnsdebug)
fprint(2, "%s: chdev %s %s: %r\n", fn, devop, argv[0]);
}
} }
return cdroot; return cdroot;
} }