xref: /plan9/sys/src/cmd/auth/changeuser.c (revision f54edc786b9c49b2c7ab1c0695cdc8c698b11f4d)
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