1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <ctype.h> 5 #include "authsrv.h" 6 7 8 void install(char*, char*, char*, long, int); 9 int exists (char*, char*); 10 long getexpiration(char *db, char *u); 11 Tm getdate(char*); 12 13 void 14 usage(void) 15 { 16 fprint(2, "usage: changeuser [-hpn] user\n"); 17 exits("usage"); 18 } 19 20 void 21 main(int argc, char *argv[]) 22 { 23 char *u, key[DESKEYLEN], answer[32]; 24 int which, i, newkey, newbio; 25 long t; 26 Acctbio a; 27 Fs *f; 28 29 srand(getpid()*time(0)); 30 fmtinstall('K', keyconv); 31 32 which = 0; 33 ARGBEGIN{ 34 case 'p': 35 which |= Plan9; 36 break; 37 case 'n': 38 which |= Securenet; 39 break; 40 default: 41 usage(); 42 }ARGEND 43 argv0 = "changeuser"; 44 45 if(argc != 1) 46 usage(); 47 u = *argv; 48 if(memchr(u, '\0', NAMELEN) == 0) 49 error("bad user name"); 50 51 if(!which) 52 which = Plan9; 53 54 newbio = 0; 55 t = 0; 56 a.user = 0; 57 if(which & Plan9){ 58 f = &fs[Plan9]; 59 newkey = 1; 60 if(exists(f->keys, u)){ 61 readln("assign new password? [y/n]: ", answer, sizeof answer, 0); 62 if(answer[0] != 'y' && answer[0] != 'Y') 63 newkey = 0; 64 } 65 if(newkey) 66 getpass(key, 1); 67 t = getexpiration(f->keys, u); 68 install(f->keys, u, key, t, newkey); 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+NAMELEN+6]; 107 int fd; 108 109 if(!exists(db, u)){ 110 sprint(buf, "%s/%s", db, u); 111 fd = create(buf, OREAD, 0777|CHDIR); 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 == 0) 126 return; 127 sprint(buf, "%s/%s/expire", db, u); 128 fd = open(buf, OWRITE); 129 if(fd < 0 || fprint(fd, "%d", 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+NAMELEN+6]; 138 139 sprint(buf, "%s/%s/expire", db, u); 140 if(access(buf, OREAD) < 0) 141 return 0; 142 return 1; 143 } 144 145 /* 146 * get the date in the format yyyymmdd 147 */ 148 Tm 149 getdate(char *d) 150 { 151 Tm date; 152 int i; 153 154 date.year = date.mon = date.mday = 0; 155 date.hour = date.min = date.sec = 0; 156 for(i = 0; i < 8; i++) 157 if(!isdigit(d[i])) 158 return date; 159 date.year = (d[0]-'0')*1000 + (d[1]-'0')*100 + (d[2]-'0')*10 + d[3]-'0'; 160 date.year -= 1900; 161 d += 4; 162 date.mon = (d[0]-'0')*10 + d[1]-'0'; 163 d += 2; 164 date.mday = (d[0]-'0')*10 + d[1]-'0'; 165 return date; 166 } 167 168 long 169 getexpiration(char *db, char *u) 170 { 171 char buf[32]; 172 char prompt[128]; 173 char cdate[32]; 174 Tm date; 175 ulong secs, now, fd; 176 int n; 177 178 /* read current expiration (if any) */ 179 sprint(buf, "%s/%s/expire", db, u); 180 fd = open(buf, OREAD); 181 buf[0] = 0; 182 if(fd >= 0){ 183 n = read(fd, buf, sizeof(buf)-1); 184 if(n > 0) 185 buf[n-1] = 0; 186 close(fd); 187 } 188 secs = 0; 189 if(buf[0]){ 190 if(strncmp(buf, "never", 5)){ 191 secs = atoi(buf); 192 memmove(&date, localtime(secs), sizeof(date)); 193 sprint(buf, "%4.4d%2.2d%2.2d", date.year+1900, date.mon, date.mday); 194 } else 195 buf[5] = 0; 196 } else 197 strcpy(buf, "never"); 198 sprint(prompt, "Expiration date (YYYYMMDD or never)[return = %s]: ", buf); 199 200 now = time(0); 201 for(;;){ 202 readln(prompt, cdate, sizeof cdate, 0); 203 if(*cdate == 0) 204 return secs; 205 if(strcmp(cdate, "never") == 0) 206 return 0; 207 date = getdate(cdate); 208 secs = tm2sec(date); 209 if(secs > now && secs < now + 2*365*24*60*60) 210 break; 211 print("expiration time must fall between now and 2 years from now\n"); 212 } 213 return secs; 214 } 215