xref: /plan9/sys/src/cmd/auth/changeuser.c (revision f54edc786b9c49b2c7ab1c0695cdc8c698b11f4d)
1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <authsrv.h>
4219b2ee8SDavid du Colombier #include <ctype.h>
55979f962SDavid du Colombier #include <bio.h>
69a747e4fSDavid du Colombier #include "authcmdlib.h"
7219b2ee8SDavid du Colombier 
8219b2ee8SDavid du Colombier void	install(char*, char*, char*, long, int);
9219b2ee8SDavid du Colombier int	exists (char*, char*);
10219b2ee8SDavid du Colombier 
11219b2ee8SDavid du Colombier void
usage(void)12219b2ee8SDavid du Colombier usage(void)
13219b2ee8SDavid du Colombier {
1405406af2SDavid du Colombier 	fprint(2, "usage: changeuser [-pn] user\n");
15219b2ee8SDavid du Colombier 	exits("usage");
16219b2ee8SDavid du Colombier }
17219b2ee8SDavid du Colombier 
18219b2ee8SDavid du Colombier void
main(int argc,char * argv[])19219b2ee8SDavid du Colombier main(int argc, char *argv[])
20219b2ee8SDavid du Colombier {
217dd7cddfSDavid du Colombier 	char *u, key[DESKEYLEN], answer[32], p9pass[32];
227dd7cddfSDavid du Colombier 	int which, i, newkey, newbio, dosecret;
23219b2ee8SDavid du Colombier 	long t;
24219b2ee8SDavid du Colombier 	Acctbio a;
25219b2ee8SDavid du Colombier 	Fs *f;
26219b2ee8SDavid du Colombier 
27219b2ee8SDavid du Colombier 	srand(getpid()*time(0));
289a747e4fSDavid du Colombier 	fmtinstall('K', keyfmt);
29219b2ee8SDavid du Colombier 
30219b2ee8SDavid du Colombier 	which = 0;
31219b2ee8SDavid du Colombier 	ARGBEGIN{
32219b2ee8SDavid du Colombier 	case 'p':
33219b2ee8SDavid du Colombier 		which |= Plan9;
34219b2ee8SDavid du Colombier 		break;
35219b2ee8SDavid du Colombier 	case 'n':
36219b2ee8SDavid du Colombier 		which |= Securenet;
37219b2ee8SDavid du Colombier 		break;
38219b2ee8SDavid du Colombier 	default:
39219b2ee8SDavid du Colombier 		usage();
40219b2ee8SDavid du Colombier 	}ARGEND
41219b2ee8SDavid du Colombier 	argv0 = "changeuser";
42219b2ee8SDavid du Colombier 
43219b2ee8SDavid du Colombier 	if(argc != 1)
44219b2ee8SDavid du Colombier 		usage();
45219b2ee8SDavid du Colombier 	u = *argv;
469a747e4fSDavid du Colombier 	if(memchr(u, '\0', ANAMELEN) == 0)
47219b2ee8SDavid du Colombier 		error("bad user name");
48219b2ee8SDavid du Colombier 
49219b2ee8SDavid du Colombier 	if(!which)
50219b2ee8SDavid du Colombier 		which = Plan9;
51219b2ee8SDavid du Colombier 
52219b2ee8SDavid du Colombier 	newbio = 0;
53219b2ee8SDavid du Colombier 	t = 0;
54219b2ee8SDavid du Colombier 	a.user = 0;
55219b2ee8SDavid du Colombier 	if(which & Plan9){
56219b2ee8SDavid du Colombier 		f = &fs[Plan9];
57219b2ee8SDavid du Colombier 		newkey = 1;
58219b2ee8SDavid du Colombier 		if(exists(f->keys, u)){
59219b2ee8SDavid du Colombier 			readln("assign new password? [y/n]: ", answer, sizeof answer, 0);
60219b2ee8SDavid du Colombier 			if(answer[0] != 'y' && answer[0] != 'Y')
61219b2ee8SDavid du Colombier 				newkey = 0;
62219b2ee8SDavid du Colombier 		}
63219b2ee8SDavid du Colombier 		if(newkey)
6480ee5cbfSDavid du Colombier 			getpass(key, p9pass, 1, 1);
657dd7cddfSDavid du Colombier 		dosecret = getsecret(newkey, p9pass);
66219b2ee8SDavid du Colombier 		t = getexpiration(f->keys, u);
67219b2ee8SDavid du Colombier 		install(f->keys, u, key, t, newkey);
687dd7cddfSDavid du Colombier 		if(dosecret && setsecret(KEYDB, u, p9pass) == 0)
697dd7cddfSDavid du Colombier 			error("error writing Inferno/pop secret");
70219b2ee8SDavid du Colombier 		newbio = querybio(f->who, u, &a);
71219b2ee8SDavid du Colombier 		if(newbio)
72219b2ee8SDavid du Colombier 			wrbio(f->who, &a);
73219b2ee8SDavid du Colombier 		print("user %s installed for Plan 9\n", u);
74219b2ee8SDavid du Colombier 		syslog(0, AUTHLOG, "user %s installed for plan 9", u);
75219b2ee8SDavid du Colombier 	}
76219b2ee8SDavid du Colombier 	if(which & Securenet){
77219b2ee8SDavid du Colombier 		f = &fs[Securenet];
78219b2ee8SDavid du Colombier 		newkey = 1;
79219b2ee8SDavid du Colombier 		if(exists(f->keys, u)){
80219b2ee8SDavid du Colombier 			readln("assign new key? [y/n]: ", answer, sizeof answer, 0);
81219b2ee8SDavid du Colombier 			if(answer[0] != 'y' && answer[0] != 'Y')
82219b2ee8SDavid du Colombier 				newkey = 0;
83219b2ee8SDavid du Colombier 		}
84219b2ee8SDavid du Colombier 		if(newkey)
85219b2ee8SDavid du Colombier 			for(i=0; i<DESKEYLEN; i++)
86219b2ee8SDavid du Colombier 				key[i] = nrand(256);
87219b2ee8SDavid du Colombier 		if(a.user == 0){
88219b2ee8SDavid du Colombier 			t = getexpiration(f->keys, u);
89219b2ee8SDavid du Colombier 			newbio = querybio(f->who, u, &a);
90219b2ee8SDavid du Colombier 		}
91219b2ee8SDavid du Colombier 		install(f->keys, u, key, t, newkey);
92219b2ee8SDavid du Colombier 		if(newbio)
93219b2ee8SDavid du Colombier 			wrbio(f->who, &a);
94219b2ee8SDavid du Colombier 		findkey(f->keys, u, key);
95219b2ee8SDavid du Colombier 		print("user %s: SecureNet key: %K\n", u, key);
96219b2ee8SDavid du Colombier 		checksum(key, answer);
97219b2ee8SDavid du Colombier 		print("verify with checksum %s\n", answer);
98219b2ee8SDavid du Colombier 		print("user %s installed for SecureNet\n", u);
99219b2ee8SDavid du Colombier 		syslog(0, AUTHLOG, "user %s installed for securenet", u);
100219b2ee8SDavid du Colombier 	}
101219b2ee8SDavid du Colombier 	exits(0);
102219b2ee8SDavid du Colombier }
103219b2ee8SDavid du Colombier 
104219b2ee8SDavid du Colombier void
install(char * db,char * u,char * key,long t,int newkey)105219b2ee8SDavid du Colombier install(char *db, char *u, char *key, long t, int newkey)
106219b2ee8SDavid du Colombier {
1079a747e4fSDavid du Colombier 	char buf[KEYDBBUF+ANAMELEN+20];
108219b2ee8SDavid du Colombier 	int fd;
109219b2ee8SDavid du Colombier 
110219b2ee8SDavid du Colombier 	if(!exists(db, u)){
111*f54edc78SDavid du Colombier 		snprint(buf, sizeof buf, "%s/%s", db, u);
1129a747e4fSDavid du Colombier 		fd = create(buf, OREAD, 0777|DMDIR);
113219b2ee8SDavid du Colombier 		if(fd < 0)
114219b2ee8SDavid du Colombier 			error("can't create user %s: %r", u);
115219b2ee8SDavid du Colombier 		close(fd);
116219b2ee8SDavid du Colombier 	}
117219b2ee8SDavid du Colombier 
118219b2ee8SDavid du Colombier 	if(newkey){
119*f54edc78SDavid du Colombier 		snprint(buf, sizeof buf, "%s/%s/key", db, u);
120219b2ee8SDavid du Colombier 		fd = open(buf, OWRITE);
121219b2ee8SDavid du Colombier 		if(fd < 0 || write(fd, key, DESKEYLEN) != DESKEYLEN)
122219b2ee8SDavid du Colombier 			error("can't set key: %r");
123219b2ee8SDavid du Colombier 		close(fd);
124219b2ee8SDavid du Colombier 	}
125219b2ee8SDavid du Colombier 
1267dd7cddfSDavid du Colombier 	if(t == -1)
127219b2ee8SDavid du Colombier 		return;
128*f54edc78SDavid du Colombier 	snprint(buf, sizeof buf, "%s/%s/expire", db, u);
129219b2ee8SDavid du Colombier 	fd = open(buf, OWRITE);
1307dd7cddfSDavid du Colombier 	if(fd < 0 || fprint(fd, "%ld", t) < 0)
131219b2ee8SDavid du Colombier 		error("can't write expiration time");
132219b2ee8SDavid du Colombier 	close(fd);
133219b2ee8SDavid du Colombier }
134219b2ee8SDavid du Colombier 
135219b2ee8SDavid du Colombier int
exists(char * db,char * u)136219b2ee8SDavid du Colombier exists(char *db, char *u)
137219b2ee8SDavid du Colombier {
1389a747e4fSDavid du Colombier 	char buf[KEYDBBUF+ANAMELEN+6];
139219b2ee8SDavid du Colombier 
140*f54edc78SDavid du Colombier 	snprint(buf, sizeof buf, "%s/%s/expire", db, u);
1417dd7cddfSDavid du Colombier 	if(access(buf, 0) < 0)
142219b2ee8SDavid du Colombier 		return 0;
143219b2ee8SDavid du Colombier 	return 1;
144219b2ee8SDavid du Colombier }
145