Blame


1 6e527fbc 2005-02-13 devnull #include <u.h>
2 6e527fbc 2005-02-13 devnull #include <libc.h>
3 6e527fbc 2005-02-13 devnull #include <mp.h>
4 6e527fbc 2005-02-13 devnull #include <libsec.h>
5 6e527fbc 2005-02-13 devnull #include "SConn.h"
6 6e527fbc 2005-02-13 devnull #include "secstore.h"
7 6e527fbc 2005-02-13 devnull
8 6e527fbc 2005-02-13 devnull int verbose;
9 6e527fbc 2005-02-13 devnull
10 6e527fbc 2005-02-13 devnull static void userinput(char *, int);
11 6e527fbc 2005-02-13 devnull char *SECSTORE_DIR;
12 6e527fbc 2005-02-13 devnull
13 6e527fbc 2005-02-13 devnull static void
14 6e527fbc 2005-02-13 devnull ensure_exists(char *f, ulong perm)
15 6e527fbc 2005-02-13 devnull {
16 6e527fbc 2005-02-13 devnull int fd;
17 6e527fbc 2005-02-13 devnull
18 6e527fbc 2005-02-13 devnull if(access(f, AEXIST) >= 0)
19 6e527fbc 2005-02-13 devnull return;
20 6e527fbc 2005-02-13 devnull if(verbose)
21 6e527fbc 2005-02-13 devnull fprint(2,"first time setup for secstore: create %s %lo\n", f, perm);
22 6e527fbc 2005-02-13 devnull fd = create(f, OREAD, perm);
23 6e527fbc 2005-02-13 devnull if(fd < 0){
24 6e527fbc 2005-02-13 devnull fprint(2, "unable to create %s\n", f);
25 6e527fbc 2005-02-13 devnull exits("secstored directories");
26 6e527fbc 2005-02-13 devnull }
27 6e527fbc 2005-02-13 devnull close(fd);
28 6e527fbc 2005-02-13 devnull }
29 6e527fbc 2005-02-13 devnull
30 6e527fbc 2005-02-13 devnull
31 6e527fbc 2005-02-13 devnull int
32 6e527fbc 2005-02-13 devnull main(int argc, char **argv)
33 6e527fbc 2005-02-13 devnull {
34 6e527fbc 2005-02-13 devnull int isnew;
35 6e527fbc 2005-02-13 devnull char *id, buf[Maxmsg], home[Maxmsg], prompt[100], *hexHi;
36 6e527fbc 2005-02-13 devnull char *pass, *passck;
37 6e527fbc 2005-02-13 devnull long expsecs;
38 6e527fbc 2005-02-13 devnull mpint *H = mpnew(0), *Hi = mpnew(0);
39 6e527fbc 2005-02-13 devnull PW *pw;
40 6e527fbc 2005-02-13 devnull Tm *tm;
41 6e527fbc 2005-02-13 devnull
42 6e527fbc 2005-02-13 devnull SECSTORE_DIR = unsharp("#9/secstore");
43 6e527fbc 2005-02-13 devnull
44 6e527fbc 2005-02-13 devnull ARGBEGIN{
45 6e527fbc 2005-02-13 devnull case 'v':
46 6e527fbc 2005-02-13 devnull verbose++;
47 6e527fbc 2005-02-13 devnull break;
48 6e527fbc 2005-02-13 devnull }ARGEND;
49 6e527fbc 2005-02-13 devnull if(argc!=1){
50 6e527fbc 2005-02-13 devnull print("usage: secuser [-v] <user>\n");
51 6e527fbc 2005-02-13 devnull exits("usage");
52 6e527fbc 2005-02-13 devnull }
53 6e527fbc 2005-02-13 devnull
54 6e527fbc 2005-02-13 devnull ensure_exists(SECSTORE_DIR, DMDIR|0755L);
55 6e527fbc 2005-02-13 devnull snprint(home, sizeof(home), "%s/who", SECSTORE_DIR);
56 6e527fbc 2005-02-13 devnull ensure_exists(home, DMDIR|0755L);
57 6e527fbc 2005-02-13 devnull snprint(home, sizeof(home), "%s/store", SECSTORE_DIR);
58 6e527fbc 2005-02-13 devnull ensure_exists(home, DMDIR|0700L);
59 6e527fbc 2005-02-13 devnull
60 6e527fbc 2005-02-13 devnull id = argv[0];
61 6e527fbc 2005-02-13 devnull if(verbose)
62 6e527fbc 2005-02-13 devnull fprint(2,"secuser %s\n", id);
63 6e527fbc 2005-02-13 devnull if((pw = getPW(id,1)) == nil){
64 6e527fbc 2005-02-13 devnull isnew = 1;
65 6e527fbc 2005-02-13 devnull print("new account (because %s/%s %r)\n", SECSTORE_DIR, id);
66 6e527fbc 2005-02-13 devnull pw = emalloc(sizeof(*pw));
67 6e527fbc 2005-02-13 devnull pw->id = estrdup(id);
68 6e527fbc 2005-02-13 devnull snprint(home, sizeof(home), "%s/store/%s", SECSTORE_DIR, id);
69 6e527fbc 2005-02-13 devnull if(access(home, AEXIST) == 0){
70 6e527fbc 2005-02-13 devnull print("new user, but directory %s already exists\n", home);
71 6e527fbc 2005-02-13 devnull exits(home);
72 6e527fbc 2005-02-13 devnull }
73 6e527fbc 2005-02-13 devnull }else{
74 6e527fbc 2005-02-13 devnull isnew = 0;
75 6e527fbc 2005-02-13 devnull }
76 6e527fbc 2005-02-13 devnull
77 6e527fbc 2005-02-13 devnull /* get main password for id */
78 6e527fbc 2005-02-13 devnull for(;;){
79 6e527fbc 2005-02-13 devnull if(isnew)
80 6e527fbc 2005-02-13 devnull snprint(prompt, sizeof(prompt), "%s password", id);
81 6e527fbc 2005-02-13 devnull else
82 6e527fbc 2005-02-13 devnull snprint(prompt, sizeof(prompt), "%s password [default = don't change]", id);
83 6e527fbc 2005-02-13 devnull pass = readcons(prompt, nil, 1);
84 6e527fbc 2005-02-13 devnull if(pass == nil){
85 6e527fbc 2005-02-13 devnull print("getpass failed\n");
86 6e527fbc 2005-02-13 devnull exits("getpass failed");
87 6e527fbc 2005-02-13 devnull }
88 6e527fbc 2005-02-13 devnull if(verbose)
89 6e527fbc 2005-02-13 devnull print("%ld characters\n", strlen(pass));
90 6e527fbc 2005-02-13 devnull if(pass[0] == '\0' && isnew == 0)
91 6e527fbc 2005-02-13 devnull break;
92 6e527fbc 2005-02-13 devnull if(strlen(pass) >= 7)
93 6e527fbc 2005-02-13 devnull break;
94 6e527fbc 2005-02-13 devnull print("password must be at least 7 characters\n");
95 6e527fbc 2005-02-13 devnull }
96 6e527fbc 2005-02-13 devnull
97 6e527fbc 2005-02-13 devnull if(pass[0] != '\0'){
98 6e527fbc 2005-02-13 devnull snprint(prompt, sizeof(prompt), "retype password");
99 6e527fbc 2005-02-13 devnull if(verbose)
100 6e527fbc 2005-02-13 devnull print("confirming...\n");
101 6e527fbc 2005-02-13 devnull passck = readcons(prompt, nil, 1);
102 6e527fbc 2005-02-13 devnull if(passck == nil){
103 6e527fbc 2005-02-13 devnull print("getpass failed\n");
104 6e527fbc 2005-02-13 devnull exits("getpass failed");
105 6e527fbc 2005-02-13 devnull }
106 6e527fbc 2005-02-13 devnull if(strcmp(pass, passck) != 0){
107 6e527fbc 2005-02-13 devnull print("passwords didn't match\n");
108 6e527fbc 2005-02-13 devnull exits("no match");
109 6e527fbc 2005-02-13 devnull }
110 6e527fbc 2005-02-13 devnull memset(passck, 0, strlen(passck));
111 6e527fbc 2005-02-13 devnull free(passck);
112 6e527fbc 2005-02-13 devnull hexHi = PAK_Hi(id, pass, H, Hi);
113 6e527fbc 2005-02-13 devnull memset(pass, 0, strlen(pass));
114 6e527fbc 2005-02-13 devnull free(pass);
115 6e527fbc 2005-02-13 devnull free(hexHi);
116 6e527fbc 2005-02-13 devnull mpfree(H);
117 6e527fbc 2005-02-13 devnull pw->Hi = Hi;
118 6e527fbc 2005-02-13 devnull }
119 6e527fbc 2005-02-13 devnull
120 6e527fbc 2005-02-13 devnull /* get expiration time (midnight of date specified) */
121 6e527fbc 2005-02-13 devnull if(isnew)
122 6e527fbc 2005-02-13 devnull expsecs = time(0) + 365*24*60*60;
123 6e527fbc 2005-02-13 devnull else
124 6e527fbc 2005-02-13 devnull expsecs = pw->expire;
125 6e527fbc 2005-02-13 devnull
126 6e527fbc 2005-02-13 devnull for(;;){
127 6e527fbc 2005-02-13 devnull tm = localtime(expsecs);
128 6e527fbc 2005-02-13 devnull print("expires [DDMMYYYY, default = %2.2d%2.2d%4.4d]: ",
129 6e527fbc 2005-02-13 devnull tm->mday, tm->mon, tm->year+1900);
130 6e527fbc 2005-02-13 devnull userinput(buf, sizeof(buf));
131 6e527fbc 2005-02-13 devnull if(strlen(buf) == 0)
132 6e527fbc 2005-02-13 devnull break;
133 6e527fbc 2005-02-13 devnull if(strlen(buf) != 8){
134 6e527fbc 2005-02-13 devnull print("!bad date format: %s\n", buf);
135 6e527fbc 2005-02-13 devnull continue;
136 6e527fbc 2005-02-13 devnull }
137 6e527fbc 2005-02-13 devnull tm->mday = (buf[0]-'0')*10 + (buf[1]-'0');
138 6e527fbc 2005-02-13 devnull if(tm->mday > 31 || tm->mday < 1){
139 6e527fbc 2005-02-13 devnull print("!bad day of month: %d\n", tm->mday);
140 6e527fbc 2005-02-13 devnull continue;
141 6e527fbc 2005-02-13 devnull }
142 6e527fbc 2005-02-13 devnull tm->mon = (buf[2]-'0')*10 + (buf[3]-'0') - 1;
143 6e527fbc 2005-02-13 devnull if(tm->mon > 11 || tm->mday < 0){
144 6e527fbc 2005-02-13 devnull print("!bad month: %d\n", tm->mon + 1);
145 6e527fbc 2005-02-13 devnull continue;
146 6e527fbc 2005-02-13 devnull }
147 6e527fbc 2005-02-13 devnull tm->year = atoi(buf+4) - 1900;
148 6e527fbc 2005-02-13 devnull if(tm->year < 70){
149 6e527fbc 2005-02-13 devnull print("!bad year: %d\n", tm->year + 1900);
150 6e527fbc 2005-02-13 devnull continue;
151 6e527fbc 2005-02-13 devnull }
152 6e527fbc 2005-02-13 devnull tm->sec = 59;
153 6e527fbc 2005-02-13 devnull tm->min = 59;
154 6e527fbc 2005-02-13 devnull tm->hour = 23;
155 6e527fbc 2005-02-13 devnull tm->yday = 0;
156 6e527fbc 2005-02-13 devnull expsecs = tm2sec(tm);
157 6e527fbc 2005-02-13 devnull break;
158 6e527fbc 2005-02-13 devnull }
159 6e527fbc 2005-02-13 devnull pw->expire = expsecs;
160 6e527fbc 2005-02-13 devnull
161 6e527fbc 2005-02-13 devnull /* failed logins */
162 6e527fbc 2005-02-13 devnull if(pw->failed != 0 )
163 6e527fbc 2005-02-13 devnull print("clearing %d failed login attempts\n", pw->failed);
164 6e527fbc 2005-02-13 devnull pw->failed = 0;
165 6e527fbc 2005-02-13 devnull
166 6e527fbc 2005-02-13 devnull /* status bits */
167 6e527fbc 2005-02-13 devnull if(isnew)
168 6e527fbc 2005-02-13 devnull pw->status = Enabled;
169 6e527fbc 2005-02-13 devnull for(;;){
170 6e527fbc 2005-02-13 devnull print("Enabled or Disabled [default %s]: ",
171 6e527fbc 2005-02-13 devnull (pw->status & Enabled) ? "Enabled" : "Disabled" );
172 6e527fbc 2005-02-13 devnull userinput(buf, sizeof(buf));
173 6e527fbc 2005-02-13 devnull if(strlen(buf) == 0)
174 6e527fbc 2005-02-13 devnull break;
175 6e527fbc 2005-02-13 devnull if(buf[0]=='E' || buf[0]=='e'){
176 6e527fbc 2005-02-13 devnull pw->status |= Enabled;
177 6e527fbc 2005-02-13 devnull break;
178 6e527fbc 2005-02-13 devnull }
179 6e527fbc 2005-02-13 devnull if(buf[0]=='D' || buf[0]=='d'){
180 6e527fbc 2005-02-13 devnull pw->status = pw->status & ~Enabled;
181 6e527fbc 2005-02-13 devnull break;
182 6e527fbc 2005-02-13 devnull }
183 6e527fbc 2005-02-13 devnull }
184 6e527fbc 2005-02-13 devnull for(;;){
185 6e527fbc 2005-02-13 devnull print("require STA? [default %s]: ",
186 6e527fbc 2005-02-13 devnull (pw->status & STA) ? "yes" : "no" );
187 6e527fbc 2005-02-13 devnull userinput(buf, sizeof(buf));
188 6e527fbc 2005-02-13 devnull if(strlen(buf) == 0)
189 6e527fbc 2005-02-13 devnull break;
190 6e527fbc 2005-02-13 devnull if(buf[0]=='Y' || buf[0]=='y'){
191 6e527fbc 2005-02-13 devnull pw->status |= STA;
192 6e527fbc 2005-02-13 devnull break;
193 6e527fbc 2005-02-13 devnull }
194 6e527fbc 2005-02-13 devnull if(buf[0]=='N' || buf[0]=='n'){
195 6e527fbc 2005-02-13 devnull pw->status = pw->status & ~STA;
196 6e527fbc 2005-02-13 devnull break;
197 6e527fbc 2005-02-13 devnull }
198 6e527fbc 2005-02-13 devnull }
199 6e527fbc 2005-02-13 devnull
200 6e527fbc 2005-02-13 devnull /* free form field */
201 6e527fbc 2005-02-13 devnull if(isnew)
202 6e527fbc 2005-02-13 devnull pw->other = nil;
203 6e527fbc 2005-02-13 devnull print("comments [default = %s]: ", (pw->other == nil) ? "" : pw->other);
204 6e527fbc 2005-02-13 devnull userinput(buf, 72); /* 72 comes from password.h */
205 6e527fbc 2005-02-13 devnull if(buf[0])
206 6e527fbc 2005-02-13 devnull if((pw->other = strdup(buf)) == nil)
207 6e527fbc 2005-02-13 devnull sysfatal("strdup");
208 6e527fbc 2005-02-13 devnull
209 6e527fbc 2005-02-13 devnull syslog(0, LOG, "CHANGELOGIN for '%s'", pw->id);
210 6e527fbc 2005-02-13 devnull if(putPW(pw) < 0){
211 6e527fbc 2005-02-13 devnull print("error writing entry: %r\n");
212 6e527fbc 2005-02-13 devnull exits("can't write password file");
213 6e527fbc 2005-02-13 devnull }else{
214 6e527fbc 2005-02-13 devnull print("change written\n");
215 6e527fbc 2005-02-13 devnull if(isnew && create(home, OREAD, DMDIR | 0775L) < 0){
216 6e527fbc 2005-02-13 devnull print("unable to create %s: %r\n", home);
217 6e527fbc 2005-02-13 devnull exits(home);
218 6e527fbc 2005-02-13 devnull }
219 6e527fbc 2005-02-13 devnull }
220 6e527fbc 2005-02-13 devnull
221 6e527fbc 2005-02-13 devnull exits("");
222 6e527fbc 2005-02-13 devnull return 1; /* keep other compilers happy */
223 6e527fbc 2005-02-13 devnull }
224 6e527fbc 2005-02-13 devnull
225 6e527fbc 2005-02-13 devnull
226 6e527fbc 2005-02-13 devnull static void
227 6e527fbc 2005-02-13 devnull userinput(char *buf, int blen)
228 6e527fbc 2005-02-13 devnull {
229 6e527fbc 2005-02-13 devnull int n;
230 6e527fbc 2005-02-13 devnull
231 6e527fbc 2005-02-13 devnull while(1){
232 6e527fbc 2005-02-13 devnull n = read(0, buf, blen);
233 6e527fbc 2005-02-13 devnull if(n<=0)
234 6e527fbc 2005-02-13 devnull exits("read error");
235 6e527fbc 2005-02-13 devnull if(buf[n-1]=='\n'){
236 6e527fbc 2005-02-13 devnull buf[n-1] = '\0';
237 6e527fbc 2005-02-13 devnull return;
238 6e527fbc 2005-02-13 devnull }
239 6e527fbc 2005-02-13 devnull buf += n; blen -= n;
240 6e527fbc 2005-02-13 devnull if(blen<=0)
241 6e527fbc 2005-02-13 devnull exits("input too large");
242 6e527fbc 2005-02-13 devnull }
243 6e527fbc 2005-02-13 devnull }
244 6e527fbc 2005-02-13 devnull