auth/as, auth/none, auth/newns: consistent handling of command arguments, cleanup

This commit is contained in:
cinap_lenrek 2016-12-22 21:39:59 +01:00
parent 640adc8f82
commit 82bf19941e
4 changed files with 106 additions and 120 deletions

View file

@ -50,6 +50,8 @@ changeuser, convkeys, printnetkey, status, enable, disable, authsrv, guard.srv,
.PP .PP
.B auth/none .B auth/none
[ [
.B -d
] [
.B -n .B -n
.I namespace .I namespace
] ]
@ -58,8 +60,16 @@ changeuser, convkeys, printnetkey, status, enable, disable, authsrv, guard.srv,
\&... \&...
.PP .PP
.B auth/as .B auth/as
[
.B -d
] [
.B -n
.I namespace
]
.I user .I user
.I command .I command
.I arg
\&...
.SH DESCRIPTION .SH DESCRIPTION
These administrative commands run only on the authentication server. These administrative commands run only on the authentication server.
.IR Changeuser .IR Changeuser

View file

@ -11,88 +11,62 @@
#include <authsrv.h> #include <authsrv.h>
#include "authcmdlib.h" #include "authcmdlib.h"
int debug; extern int newnsdebug;
char *defargv[] = { "/bin/rc", "-i", nil };
char *namespace = nil;
int becomeuser(char*); int becomeuser(char*);
void createuser(void);
void *emalloc(ulong);
void *erealloc(void*, ulong);
void initcap(void); void initcap(void);
int mkcmd(char*, char*, int);
int myauth(int, char*);
int qidcmp(Qid, Qid);
void runas(char *, char *);
void usage(void);
#pragma varargck argpos clog 1 void
#pragma varargck argpos fatal 1 usage(void)
static void
fatal(char *fmt, ...)
{ {
char msg[256]; fprint(2, "usage: %s [-d] [-n namespace] user [cmd [args...]]\n", argv0);
va_list arg; exits("usage");
}
va_start(arg, fmt); void
vseprint(msg, msg + sizeof msg, fmt, arg); run(char **a)
va_end(arg); {
error("%s", msg); exec(a[0], a);
if(a[0][0] != '/' && a[0][0] != '#' &&
(a[0][0] != '.' || (a[0][1] != '/' &&
(a[0][1] != '.' || a[0][2] != '/'))))
exec(smprint("/bin/%s", a[0]), a);
sysfatal("exec: %s: %r", a[0]);
} }
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
debug = 0;
ARGBEGIN{ ARGBEGIN{
case 'd': case 'd':
debug = 1; newnsdebug = 1;
break;
case 'n':
namespace = EARGF(usage());
break; break;
default: default:
usage(); usage();
}ARGEND }ARGEND
initcap(); if(argc == 0)
if(argc >= 2)
runas(argv[0], argv[1]);
else
usage(); usage();
}
void initcap();
runas(char *user, char *cmd) if(becomeuser(argv[0]) < 0)
{ sysfatal("can't change uid for %s: %r", argv[0]);
if(becomeuser(user) < 0) if(newns(argv[0], namespace) < 0)
sysfatal("can't change uid for %s: %r", user); sysfatal("can't build namespace: %r");
putenv("service", "rx");
execl("/bin/rc", "rc", "-lc", cmd, nil);
sysfatal("exec /bin/rc: %r");
}
void * argv++;
emalloc(ulong n) if(--argc == 0)
{ argv = defargv;
void *p;
if(p = mallocz(n, 1)) run(argv);
return p;
fatal("out of memory");
return 0;
}
void *
erealloc(void *p, ulong n)
{
if(p = realloc(p, n))
return p;
fatal("out of memory");
return 0;
}
void
usage(void)
{
fprint(2, "usage: %s [-c] [user] [command]\n", argv0);
exits("usage");
} }
/* /*
@ -105,7 +79,7 @@ initcap(void)
{ {
caphashfd = open("#¤/caphash", OCEXEC|OWRITE); caphashfd = open("#¤/caphash", OCEXEC|OWRITE);
if(caphashfd < 0) if(caphashfd < 0)
fprint(2, "%s: opening #¤/caphash: %r\n", argv0); fprint(2, "%s: opening #¤/caphash: %r", argv0);
} }
/* /*
@ -126,7 +100,9 @@ mkcap(char *from, char *to)
/* create the capability */ /* create the capability */
nto = strlen(to); nto = strlen(to);
nfrom = strlen(from); nfrom = strlen(from);
cap = emalloc(nfrom+1+nto+1+sizeof(rand)*3+1); cap = malloc(nfrom+1+nto+1+sizeof(rand)*3+1);
if(cap == nil)
sysfatal("malloc: %r");
sprint(cap, "%s@%s", from, to); sprint(cap, "%s@%s", from, to);
genrandom(rand, sizeof(rand)); genrandom(rand, sizeof(rand));
key = cap+nfrom+1+nto+1; key = cap+nfrom+1+nto+1;
@ -169,7 +145,5 @@ becomeuser(char *new)
return -1; return -1;
rv = usecap(cap); rv = usecap(cap);
free(cap); free(cap);
newns(new, nil);
return rv; return rv;
} }

View file

@ -2,36 +2,35 @@
#include <libc.h> #include <libc.h>
#include <auth.h> #include <auth.h>
extern int newnsdebug;
char *defargv[] = { "/bin/rc", "-i", nil };
char *namespace = "/lib/namespace";
int add = 0;
void void
usage(void) usage(void)
{ {
fprint(2, "usage: newns [-ad] [-n namespace] [cmd [args...]]\n"); fprint(2, "usage: %s [-ad] [-n namespace] [cmd [args...]]\n", argv0);
exits("usage"); exits("usage");
} }
static int void
rooted(char *s) run(char **a)
{ {
if(s[0] == '/') exec(a[0], a);
return 1;
if(s[0] == '.' && s[1] == '/') if(a[0][0] != '/' && a[0][0] != '#' &&
return 1; (a[0][0] != '.' || (a[0][1] != '/' &&
if(s[0] == '.' && s[1] == '.' && s[2] == '/') (a[0][1] != '.' || a[0][2] != '/'))))
return 1; exec(smprint("/bin/%s", a[0]), a);
return 0;
sysfatal("exec: %s: %r", a[0]);
} }
void void
main(int argc, char **argv) main(int argc, char **argv)
{ {
extern int newnsdebug;
char *defargv[] = { "/bin/rc", "-i", nil };
char *nsfile, err[ERRMAX];
int add;
rfork(RFNAMEG);
add = 0;
nsfile = "/lib/namespace";
ARGBEGIN{ ARGBEGIN{
case 'a': case 'a':
add = 1; add = 1;
@ -40,23 +39,21 @@ main(int argc, char **argv)
newnsdebug = 1; newnsdebug = 1;
break; break;
case 'n': case 'n':
nsfile = ARGF(); namespace = EARGF(usage());
break; break;
default: default:
usage(); usage();
break; break;
}ARGEND }ARGEND
if(add){
rfork(RFNAMEG);
addns(getuser(), namespace);
}else
newns(getuser(), namespace);
if(argc == 0) if(argc == 0)
argv = defargv; argv = defargv;
if (add)
addns(getuser(), nsfile); run(argv);
else
newns(getuser(), nsfile);
exec(argv[0], argv);
if(!rooted(argv[0])){
rerrstr(err, sizeof err);
exec(smprint("/bin/%s", argv[0]), argv);
errstr(err, sizeof err);
}
sysfatal("exec: %s: %r", argv[0]);
} }

View file

@ -2,22 +2,40 @@
#include <libc.h> #include <libc.h>
#include <auth.h> #include <auth.h>
char *namespace; extern int newnsdebug;
char *defargv[] = { "/bin/rc", "-i", nil };
char *namespace = nil;
void void
usage(void) usage(void)
{ {
fprint(2, "usage: auth/none [-n namespace] [cmd ...]\n"); fprint(2, "usage: %s [-d] [-n namespace] [cmd [args...]]\n", argv0);
exits("usage"); exits("usage");
} }
void
run(char **a)
{
exec(a[0], a);
if(a[0][0] != '/' && a[0][0] != '#' &&
(a[0][0] != '.' || (a[0][1] != '/' &&
(a[0][1] != '.' || a[0][2] != '/'))))
exec(smprint("/bin/%s", a[0]), a);
sysfatal("exec: %s: %r", a[0]);
}
void void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char cmd[256];
int fd; int fd;
ARGBEGIN{ ARGBEGIN{
case 'd':
newnsdebug = 1;
break;
case 'n': case 'n':
namespace = EARGF(usage()); namespace = EARGF(usage());
break; break;
@ -25,31 +43,18 @@ main(int argc, char *argv[])
usage(); usage();
}ARGEND }ARGEND
if (rfork(RFENVG|RFNAMEG) < 0)
sysfatal("can't make new pgrp");
fd = open("#c/user", OWRITE); fd = open("#c/user", OWRITE);
if (fd < 0) if(fd < 0)
sysfatal("can't open #c/user"); sysfatal("can't open #c/user: %r");
if (write(fd, "none", strlen("none")) < 0) if(write(fd, "none", strlen("none")) < 0)
sysfatal("can't become none"); sysfatal("can't become none: %r");
close(fd); close(fd);
if (newns("none", namespace) < 0) if(newns("none", namespace) < 0)
sysfatal("can't build namespace"); sysfatal("can't build namespace: %r");
if (argc > 0) { if(argc == 0)
strecpy(cmd, cmd+sizeof cmd, argv[0]); argv = defargv;
exec(cmd, &argv[0]);
if (strncmp(cmd, "/", 1) != 0 run(argv);
&& strncmp(cmd, "./", 2) != 0
&& strncmp(cmd, "../", 3) != 0) {
snprint(cmd, sizeof cmd, "/bin/%s", argv[0]);
exec(cmd, &argv[0]);
}
} else {
strcpy(cmd, "/bin/rc");
execl(cmd, cmd, nil);
}
sysfatal(cmd);
} }