1 #include <u.h>
2 #include <libc.h>
3 #include <authsrv.h>
4 #include <ctype.h>
5 #include <bio.h>
6 #include "authcmdlib.h"
7
8 void install(char*, char*, char*, long, int);
9 int exists (char*, char*);
10
11 void
usage(void)12 usage(void)
13 {
14 fprint(2, "usage: changeuser [-pn] user\n");
15 exits("usage");
16 }
17
18 void
main(int argc,char * argv[])19 main(int argc, char *argv[])
20 {
21 char *u, key[DESKEYLEN], answer[32], p9pass[32];
22 int which, i, newkey, newbio, dosecret;
23 long t;
24 Acctbio a;
25 Fs *f;
26
27 srand(getpid()*time(0));
28 fmtinstall('K', keyfmt);
29
30 which = 0;
31 ARGBEGIN{
32 case 'p':
33 which |= Plan9;
34 break;
35 case 'n':
36 which |= Securenet;
37 break;
38 default:
39 usage();
40 }ARGEND
41 argv0 = "changeuser";
42
43 if(argc != 1)
44 usage();
45 u = *argv;
46 if(memchr(u, '\0', ANAMELEN) == 0)
47 error("bad user name");
48
49 if(!which)
50 which = Plan9;
51
52 newbio = 0;
53 t = 0;
54 a.user = 0;
55 if(which & Plan9){
56 f = &fs[Plan9];
57 newkey = 1;
58 if(exists(f->keys, u)){
59 readln("assign new password? [y/n]: ", answer, sizeof answer, 0);
60 if(answer[0] != 'y' && answer[0] != 'Y')
61 newkey = 0;
62 }
63 if(newkey)
64 getpass(key, p9pass, 1, 1);
65 dosecret = getsecret(newkey, p9pass);
66 t = getexpiration(f->keys, u);
67 install(f->keys, u, key, t, newkey);
68 if(dosecret && setsecret(KEYDB, u, p9pass) == 0)
69 error("error writing Inferno/pop secret");
70 newbio = querybio(f->who, u, &a);
71 if(newbio)
72 wrbio(f->who, &a);
73 print("user %s installed for Plan 9\n", u);
74 syslog(0, AUTHLOG, "user %s installed for plan 9", u);
75 }
76 if(which & Securenet){
77 f = &fs[Securenet];
78 newkey = 1;
79 if(exists(f->keys, u)){
80 readln("assign new key? [y/n]: ", answer, sizeof answer, 0);
81 if(answer[0] != 'y' && answer[0] != 'Y')
82 newkey = 0;
83 }
84 if(newkey)
85 for(i=0; i<DESKEYLEN; i++)
86 key[i] = nrand(256);
87 if(a.user == 0){
88 t = getexpiration(f->keys, u);
89 newbio = querybio(f->who, u, &a);
90 }
91 install(f->keys, u, key, t, newkey);
92 if(newbio)
93 wrbio(f->who, &a);
94 findkey(f->keys, u, key);
95 print("user %s: SecureNet key: %K\n", u, key);
96 checksum(key, answer);
97 print("verify with checksum %s\n", answer);
98 print("user %s installed for SecureNet\n", u);
99 syslog(0, AUTHLOG, "user %s installed for securenet", u);
100 }
101 exits(0);
102 }
103
104 void
install(char * db,char * u,char * key,long t,int newkey)105 install(char *db, char *u, char *key, long t, int newkey)
106 {
107 char buf[KEYDBBUF+ANAMELEN+20];
108 int fd;
109
110 if(!exists(db, u)){
111 snprint(buf, sizeof buf, "%s/%s", db, u);
112 fd = create(buf, OREAD, 0777|DMDIR);
113 if(fd < 0)
114 error("can't create user %s: %r", u);
115 close(fd);
116 }
117
118 if(newkey){
119 snprint(buf, sizeof buf, "%s/%s/key", db, u);
120 fd = open(buf, OWRITE);
121 if(fd < 0 || write(fd, key, DESKEYLEN) != DESKEYLEN)
122 error("can't set key: %r");
123 close(fd);
124 }
125
126 if(t == -1)
127 return;
128 snprint(buf, sizeof buf, "%s/%s/expire", db, u);
129 fd = open(buf, OWRITE);
130 if(fd < 0 || fprint(fd, "%ld", t) < 0)
131 error("can't write expiration time");
132 close(fd);
133 }
134
135 int
exists(char * db,char * u)136 exists(char *db, char *u)
137 {
138 char buf[KEYDBBUF+ANAMELEN+6];
139
140 snprint(buf, sizeof buf, "%s/%s/expire", db, u);
141 if(access(buf, 0) < 0)
142 return 0;
143 return 1;
144 }
145