2 * as user cmd [arg...] - run cmd with args as user on this cpu server.
3 * must be hostowner for this to work.
4 * needs #¤/caphash and #¤/capuse.
11 #include "authcmdlib.h"
15 int becomeuser(char*);
16 void createuser(void);
18 void *erealloc(void*, ulong);
20 int mkcmd(char*, char*, int);
21 int myauth(int, char*);
23 void runas(char *, char *);
26 #pragma varargck argpos clog 1
27 #pragma varargck argpos fatal 1
36 vseprint(msg, msg + sizeof msg, fmt, arg);
42 main(int argc, char *argv[])
54 srand(getpid()*time(0));
55 runas(argv[0], argv[1]);
59 runas(char *user, char *cmd)
61 if(becomeuser(user) < 0)
62 sysfatal("can't change uid for %s: %r", user);
63 putenv("service", "rx");
64 execl("/bin/rc", "rc", "-lc", cmd, nil);
65 sysfatal("exec /bin/rc: %r");
75 fatal("out of memory");
80 erealloc(void *p, ulong n)
84 fatal("out of memory");
91 fprint(2, "usage: %s [-c]\n", argv0);
96 memrandom(void *p, int n)
100 for(cp = (uchar*)p; n > 0; n--)
105 * keep caphash fd open since opens of it could be disabled
107 static int caphashfd;
112 caphashfd = open("#¤/caphash", OCEXEC|OWRITE);
114 fprint(2, "%s: opening #¤/caphash: %r\n", argv0);
118 * create a change uid capability
121 mkcap(char *from, char *to)
127 uchar hash[SHA1dlen];
132 /* create the capability */
134 nfrom = strlen(from);
135 cap = emalloc(nfrom+1+nto+1+sizeof(rand)*3+1);
136 sprint(cap, "%s@%s", from, to);
137 memrandom(rand, sizeof(rand));
138 key = cap+nfrom+1+nto+1;
139 enc64(key, sizeof(rand)*3, rand, sizeof(rand));
141 /* hash the capability */
142 hmac_sha1((uchar*)cap, strlen(cap), (uchar*)key, strlen(key), hash, nil);
144 /* give the kernel the hash */
146 if(write(caphashfd, hash, SHA1dlen) < 0){
159 fd = open("#¤/capuse", OWRITE);
162 rv = write(fd, cap, strlen(cap));
168 becomeuser(char *new)
173 cap = mkcap(getuser(), new);