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