|
1 | 1 | /*
|
2 |
| - * @(#) pg_passwd.c 1.8 09:13:16 97/07/02Y. Ichikawa |
| 2 | + * @(#) pg_passwd.c 1.8 09:13:16 97/07/02Y. Ichikawa |
3 | 3 | */
|
| 4 | + |
4 | 5 | #include<stdio.h>
|
5 | 6 | #include<stdlib.h>
|
6 | 7 | #include<string.h>
|
|
9 | 10 | #include<errno.h>
|
10 | 11 | #include<sys/time.h>
|
11 | 12 | #include<ctype.h>
|
12 |
| -#defineissaltchar(c) (isalnum(c) || (c) == '.' || (c) == '/') |
| 13 | +#defineissaltchar(c)(isalnum(c) || (c) == '.' || (c) == '/') |
| 14 | + |
13 | 15 | #include"postgres.h"
|
14 | 16 | #ifdefHAVE_TERMIOS_H
|
15 | 17 | #include<termios.h>
|
16 | 18 | #endif
|
17 | 19 | #ifdefHAVE_CRYPT_H
|
18 | 20 | #include<crypt.h>
|
19 | 21 | #else
|
20 |
| -externchar*crypt(constchar*,constchar*); |
| 22 | +externchar*crypt(constchar*,constchar*); |
21 | 23 | #endif
|
22 |
| -char*comname; |
| 24 | + |
| 25 | +char*comname; |
23 | 26 | voidusage(FILE*stream);
|
24 | 27 | voidread_pwd_file(char*filename);
|
25 | 28 | voidwrite_pwd_file(char*filename,char*bkname);
|
26 | 29 | voidencrypt_pwd(charkey[9],charsalt[3],charpasswd[14]);
|
27 | 30 | intcheck_pwd(charkey[9],charpasswd[14]);
|
28 | 31 | voidprompt_for_username(char*username);
|
29 | 32 | voidprompt_for_password(char*prompt,char*password);
|
| 33 | + |
30 | 34 | voidusage(FILE*stream)
|
31 | 35 | {
|
32 |
| -fprintf(stream,"Usage: %s <password file>\n",comname); |
| 36 | +fprintf(stream,"Usage: %s <password file>\n",comname); |
33 | 37 | }
|
| 38 | + |
34 | 39 | typedefstruct {
|
35 |
| -char*uname; |
36 |
| -char*pwd; |
37 |
| -char*rest; |
| 40 | +char*uname; |
| 41 | +char*pwd; |
| 42 | +char*rest; |
38 | 43 | }pg_pwd;
|
39 |
| -#defineMAXPWDS 1024 |
40 |
| -pg_pwdpwds[MAXPWDS]; |
41 |
| -intnpwds=0; |
| 44 | + |
| 45 | +#defineMAXPWDS1024 |
| 46 | + |
| 47 | +pg_pwdpwds[MAXPWDS]; |
| 48 | +intnpwds=0; |
| 49 | + |
| 50 | + |
42 | 51 | voidread_pwd_file(char*filename)
|
43 | 52 | {
|
44 |
| -FILE*fp; |
45 |
| -staticcharline[512]; |
| 53 | +FILE*fp; |
| 54 | +staticcharline[512]; |
46 | 55 | staticcharans[128];
|
47 |
| -inti; |
| 56 | +inti; |
| 57 | + |
48 | 58 | try_again:
|
49 | 59 | fp=fopen(filename,"r");
|
50 | 60 | if (fp==NULL) {
|
51 |
| -if (errno==ENOENT) { |
52 |
| -printf("File \"%s\" does not exist. Create? (y/n): ",filename); |
53 |
| -fflush(stdout); |
54 |
| -fgets(ans,128,stdin); |
55 |
| -switch (ans[0]) { |
56 |
| -case'y':case'Y': |
57 |
| -fp=fopen(filename,"w"); |
58 |
| -if (fp==NULL) { |
59 |
| -perror(filename); |
60 |
| -exit(1); |
61 |
| -} |
62 |
| -fclose(fp); |
63 |
| -gototry_again; |
64 |
| -default: |
65 |
| -/* cannot continue */ |
66 |
| -exit(1); |
67 |
| - } |
68 |
| -}else { |
69 |
| -perror(filename); |
70 |
| -exit(1); |
71 |
| -} |
| 61 | +if (errno==ENOENT) { |
| 62 | +printf("File \"%s\" does not exist. Create? (y/n): ",filename); |
| 63 | +fflush(stdout); |
| 64 | +fgets(ans,128,stdin); |
| 65 | +switch (ans[0]) { |
| 66 | +case'y':case'Y': |
| 67 | +fp=fopen(filename,"w"); |
| 68 | +if (fp==NULL) { |
| 69 | +perror(filename); |
| 70 | +exit(1); |
| 71 | +} |
| 72 | +fclose(fp); |
| 73 | +gototry_again; |
| 74 | +default: |
| 75 | +/* cannot continue */ |
| 76 | +exit(1); |
| 77 | + } |
| 78 | +}else { |
| 79 | +perror(filename); |
| 80 | +exit(1); |
| 81 | +} |
72 | 82 | }
|
| 83 | + |
73 | 84 | /* read all the entries */
|
74 |
| -for (npwds=0;npwds<MAXPWDS&&fgets(line,512,fp)!=NULL;++npwds) |
| 85 | +for (npwds=0;npwds<MAXPWDS&&fgets(line,512,fp)!=NULL;++npwds) { |
| 86 | +intl; |
| 87 | +char*p,*q; |
| 88 | +l=strlen(line); |
| 89 | +if (line[l-1]=='\n') |
| 90 | +line[l-1]='\0'; |
| 91 | +else {/* too long */ |
| 92 | +fprintf(stderr,"%s: line %d: line too long.\n", |
| 93 | +filename,npwds+1); |
| 94 | +exit(1); |
| 95 | +} |
| 96 | + |
| 97 | +/* get user name */ |
| 98 | +p=line; |
| 99 | +if ((q=index(p,':'))==NULL) { |
| 100 | +fprintf(stderr,"%s: line %d: illegal format.\n", |
| 101 | +filename,npwds+1); |
| 102 | +exit(1); |
| 103 | +} |
| 104 | +*(q++)='\0'; |
| 105 | +if (strlen(p)==0) { |
| 106 | +fprintf(stderr,"%s: line %d: null user name.\n", |
| 107 | +filename,npwds+1); |
| 108 | +exit(1); |
| 109 | +} |
| 110 | +pwds[npwds].uname=strdup(p); |
| 111 | + |
| 112 | +/* check duplicate */ |
| 113 | +for (i=0;i<npwds;++i) { |
| 114 | +if (strcmp(pwds[i].uname,pwds[npwds].uname)==0) { |
| 115 | +fprintf(stderr,"%s: duplicated entry.\n",pwds[npwds].uname); |
| 116 | +exit(1); |
| 117 | + } |
| 118 | +} |
| 119 | + |
| 120 | +/* get password field */ |
| 121 | +p=q; |
| 122 | +q=index(p,':'); |
| 123 | +/* |
| 124 | + * --- don't care ----- |
| 125 | +if ((q = index(p, ':')) == NULL) { |
| 126 | + fprintf(stderr, "%s: line %d: illegal format.\n", |
| 127 | +filename, npwds + 1); |
| 128 | + exit(1); |
| 129 | +} |
| 130 | +*/ |
| 131 | + |
| 132 | +if (q!=NULL)*(q++)='\0'; |
| 133 | +if (strlen(p)!=13) { |
| 134 | +fprintf(stderr,"WARNING: %s: line %d: illegal password length.\n", |
| 135 | +filename,npwds+1); |
| 136 | +} |
| 137 | +pwds[npwds].pwd=strdup(p); |
| 138 | + |
| 139 | +/* rest of the line is treated as is */ |
| 140 | +if (q==NULL) |
| 141 | +pwds[npwds].rest=NULL; |
| 142 | +else |
| 143 | +pwds[npwds].rest=strdup(q); |
| 144 | + } |
| 145 | + |
| 146 | +fclose(fp); |
| 147 | +} |
| 148 | + |
| 149 | +voidwrite_pwd_file(char*filename,char*bkname) |
| 150 | +{ |
| 151 | +FILE*fp; |
| 152 | +inti; |
| 153 | + |
| 154 | +/* make the backup file */ |
| 155 | +link_again: |
| 156 | +if (link(filename,bkname)) { |
| 157 | +if (errno==EEXIST) { |
| 158 | +unlink(bkname); |
| 159 | + gotolink_again; |
| 160 | +} |
| 161 | +perror(bkname); |
| 162 | +exit(1); |
| 163 | + } |
| 164 | +if (unlink(filename)) { |
| 165 | +perror(filename); |
| 166 | +exit(1); |
| 167 | + } |
| 168 | + |
| 169 | +/* open file */ |
| 170 | +if ((fp=fopen(filename,"w"))==NULL) { |
| 171 | +perror(filename); |
| 172 | +exit(1); |
| 173 | + } |
| 174 | + |
| 175 | +/* write file */ |
| 176 | +for (i=0;i<npwds;++i) { |
| 177 | +fprintf(fp,"%s:%s%s%s\n",pwds[i].uname,pwds[i].pwd, |
| 178 | +pwds[i].rest ?":" :"", |
| 179 | +pwds[i].rest ?pwds[i].rest :""); |
| 180 | + } |
| 181 | + |
| 182 | +fclose(fp); |
| 183 | +} |
| 184 | + |
| 185 | +voidencrypt_pwd(charkey[9],charsalt[3],charpasswd[14]) |
| 186 | +{ |
| 187 | +intn; |
| 188 | + |
| 189 | +/* get encrypted password */ |
| 190 | +if (salt[0]=='\0') { |
| 191 | +structtimevaltm; |
| 192 | +gettimeofday(&tm,NULL); |
| 193 | +srand(tm.tv_sec ?tm.tv_sec :1); |
| 194 | +do { |
| 195 | +n=rand() %256; |
| 196 | +}while (!issaltchar(n)); |
| 197 | +salt[0]=n; |
| 198 | +do { |
| 199 | +n=rand() %256; |
| 200 | +}while (!issaltchar(n)); |
| 201 | +salt[1]=n; |
| 202 | +salt[2]='\0'; |
| 203 | + } |
| 204 | +strcpy(passwd,crypt(key,salt)); |
| 205 | + |
| 206 | +/* show it */ |
| 207 | +/* fprintf(stderr, "key = %s, salt = %s, password = %s\n", |
| 208 | +key, salt, passwd); */ |
| 209 | +} |
| 210 | + |
| 211 | +intcheck_pwd(charkey[9],charpasswd[14]) |
| 212 | +{ |
| 213 | +charshouldbe[14]; |
| 214 | +charsalt[3]; |
| 215 | + |
| 216 | +salt[0]=passwd[0]; |
| 217 | +salt[1]=passwd[1]; |
| 218 | +salt[2]='\0'; |
| 219 | +encrypt_pwd(key,salt,shouldbe); |
| 220 | + |
| 221 | +returnstrncmp(shouldbe,passwd,13)==0 ?1 :0; |
| 222 | +} |
| 223 | + |
| 224 | +voidprompt_for_username(char*username) |
| 225 | +{ |
| 226 | +intlength; |
| 227 | + |
| 228 | +printf("Username: "); |
| 229 | +fgets(username,9,stdin); |
| 230 | +length=strlen(username); |
| 231 | + |
| 232 | +/* skip rest of the line */ |
| 233 | +if (length>0&&username[length-1]!='\n') { |
| 234 | +staticcharbuf[512]; |
| 235 | +do { |
| 236 | +fgets(buf,512,stdin); |
| 237 | +}while (buf[strlen(buf)-1]!='\n'); |
| 238 | + } |
| 239 | +if(length>0&&username[length-1]=='\n')username[length-1]='\0'; |
| 240 | +} |
| 241 | + |
| 242 | +voidprompt_for_password(char*prompt,char*password) |
| 243 | +{ |
| 244 | +intlength; |
| 245 | +#ifdefHAVE_TERMIOS_H |
| 246 | +structtermiost_orig,t; |
| 247 | +#endif |
| 248 | + |
| 249 | +printf(prompt); |
| 250 | +#ifdefHAVE_TERMIOS_H |
| 251 | +tcgetattr(0,&t); |
| 252 | +t_orig=t; |
| 253 | +t.c_lflag &= ~ECHO; |
| 254 | +tcsetattr(0,TCSADRAIN,&t); |
| 255 | +#endif |
| 256 | +fgets(password,9,stdin); |
| 257 | +#ifdefHAVE_TERMIOS_H |
| 258 | +tcsetattr(0,TCSADRAIN,&t_orig); |
| 259 | +#endif |
| 260 | + |
| 261 | +length=strlen(password); |
| 262 | +/* skip rest of the line */ |
| 263 | +if (length>0&&password[length-1]!='\n') { |
| 264 | +staticcharbuf[512]; |
| 265 | +do { |
| 266 | +fgets(buf,512,stdin); |
| 267 | +}while (buf[strlen(buf)-1]!='\n'); |
| 268 | + } |
| 269 | +if(length>0&&password[length-1]=='\n')password[length-1]='\0'; |
| 270 | +printf("\n"); |
| 271 | +} |
| 272 | + |
| 273 | + |
| 274 | +intmain(intargc,char*argv[]) |
| 275 | +{ |
| 276 | +staticcharbkname[512]; |
| 277 | +charusername[9]; |
| 278 | +charsalt[3]; |
| 279 | +charkey[9],key2[9]; |
| 280 | +chare_passwd[14]; |
| 281 | +inti; |
| 282 | + |
| 283 | +comname=argv[0]; |
| 284 | +if (argc!=2) { |
| 285 | +usage(stderr); |
| 286 | +exit(1); |
| 287 | + } |
| 288 | + |
| 289 | + |
| 290 | +/* open file */ |
| 291 | +read_pwd_file(argv[1]); |
| 292 | + |
| 293 | +/* ask for the user name and the password */ |
| 294 | +prompt_for_username(username); |
| 295 | +prompt_for_password("New password: ",key); |
| 296 | +prompt_for_password("Re-enter new password: ",key2); |
| 297 | +if (strncmp(key,key2,8)!=0) { |
| 298 | +fprintf(stderr,"Password mismatch.\n"); |
| 299 | +exit(1); |
| 300 | + } |
| 301 | +salt[0]='\0'; |
| 302 | +encrypt_pwd(key,salt,e_passwd); |
| 303 | + |
| 304 | +/* check password entry */ |
| 305 | +for (i=0;i<npwds;++i) { |
| 306 | +if (strcmp(pwds[i].uname,username)==0) {/* found */ |
| 307 | +pwds[i].pwd=strdup(e_passwd); |
| 308 | +break; |
| 309 | +} |
| 310 | + } |
| 311 | +if (i==npwds) {/* did not exist */ |
| 312 | +if (npwds==MAXPWDS) { |
| 313 | +fprintf(stderr,"%s: cannot handle so may entries.\n",comname); |
| 314 | +exit(1); |
| 315 | +} |
| 316 | +pwds[npwds].uname=strdup(username); |
| 317 | +pwds[npwds].pwd=strdup(e_passwd); |
| 318 | +pwds[npwds].rest=NULL; |
| 319 | +++npwds; |
| 320 | + } |
| 321 | + |
| 322 | +/* write back the file */ |
| 323 | +sprintf(bkname,"%s.bk",argv[1]); |
| 324 | +write_pwd_file(argv[1],bkname); |
| 325 | + |
| 326 | +return0; |
| 327 | +} |