pg_passwd.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:7k
源码类别:

数据库系统

开发平台:

Unix_Linux

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