626
|
1 /* vi: set sw=4 ts=4 :
|
|
2 * pwdutils.c - password read/update helper functions.
|
|
3 *
|
|
4 * Copyright 2012 Ashwini Kumar <ak.ashwini@gmail.com>
|
|
5 */
|
|
6
|
|
7 #include "toys.h"
|
|
8 #include <time.h>
|
|
9
|
|
10
|
|
11 int read_passwd(char * buff, int buflen, char* mesg)
|
|
12 {
|
|
13 int i = 0;
|
|
14 struct termios termio, oldtermio;
|
|
15 tcgetattr(0, &oldtermio);
|
|
16 tcflush(0, TCIFLUSH);
|
|
17 termio = oldtermio;
|
|
18
|
|
19 termio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
|
|
20 termio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
|
|
21 tcsetattr(0, TCSANOW, &termio);
|
|
22
|
|
23 fputs(mesg, stdout);
|
|
24 fflush(stdout);
|
|
25
|
|
26 while (1) {
|
|
27 int ret = read(0, &buff[i], 1);
|
|
28 if ( ret < 0 ) {
|
|
29 buff[0] = 0;
|
|
30 tcsetattr(0, TCSANOW, &oldtermio);
|
|
31 return 1;
|
|
32 }
|
|
33 else if ( ret == 0 || buff[i] == '\n' ||
|
|
34 buff[i] == '\r' || buflen == i+1) {
|
|
35 buff[i] = '\0';
|
|
36 break;
|
|
37 }
|
|
38 i++;
|
|
39 }
|
|
40
|
|
41 tcsetattr(0, TCSANOW, &oldtermio);
|
|
42 puts("");
|
|
43 fflush(stdout);
|
|
44 return 0;
|
|
45 }
|
|
46
|
|
47 static char *get_nextcolon(const char *line, char delim)
|
|
48 {
|
|
49 char *current_ptr = NULL;
|
|
50 if((current_ptr = strchr(line, ':')) == NULL)
|
|
51 error_exit("Invalid Entry\n");
|
|
52 return current_ptr;
|
|
53 }
|
|
54
|
|
55 int update_passwd(char *filename, char* username, char* encrypted)
|
|
56 {
|
|
57 char *filenamesfx = NULL, *namesfx = NULL;
|
|
58 char *shadow = NULL, *sfx = NULL;
|
|
59 FILE *exfp, *newfp;
|
|
60 int ret = -1; //fail
|
|
61 struct flock lock;
|
|
62 char *line = NULL;
|
|
63
|
|
64 shadow = strstr(filename, "shadow");
|
|
65 filenamesfx = xmsprintf("%s+", filename);
|
|
66 sfx = strchr(filenamesfx, '+');
|
|
67
|
|
68 exfp = fopen(filename, "r+");
|
|
69 if(!exfp) {
|
|
70 perror_msg("Couldn't open file %s",filename);
|
|
71 goto free_storage;
|
|
72 }
|
|
73
|
|
74 *sfx = '-';
|
|
75 ret = unlink(filenamesfx);
|
|
76 ret = link(filename, filenamesfx);
|
|
77 if(ret < 0) error_msg("can't create backup file");
|
|
78
|
|
79 *sfx = '+';
|
|
80 lock.l_type = F_WRLCK;
|
|
81 lock.l_whence = SEEK_SET;
|
|
82 lock.l_start = 0;
|
|
83 lock.l_len = 0;
|
|
84
|
|
85 ret = fcntl(fileno(exfp), F_SETLK, &lock);
|
|
86 if(ret < 0) perror_msg("Couldn't lock file %s",filename);
|
|
87
|
|
88 lock.l_type = F_UNLCK; //unlocking at a later stage
|
|
89
|
|
90 newfp = fopen(filenamesfx, "w+");
|
|
91 if(!newfp) {
|
|
92 error_msg("couldn't open file for writing");
|
|
93 ret = -1;
|
|
94 fclose(exfp);
|
|
95 goto free_storage;
|
|
96 }
|
|
97
|
|
98 ret = 0;
|
|
99 namesfx = xmsprintf("%s:",username);
|
|
100 while((line = get_line(fileno(exfp))) != NULL)
|
|
101 {
|
|
102 if(strncmp(line, namesfx, strlen(namesfx)) != 0)
|
|
103 fprintf(newfp, "%s\n", line);
|
|
104 else {
|
|
105 char *current_ptr = NULL;
|
|
106 fprintf(newfp, "%s%s:",namesfx,encrypted);
|
|
107 current_ptr = get_nextcolon(line, ':'); //past username
|
|
108 current_ptr++; //past colon ':' after username
|
|
109 current_ptr = get_nextcolon(current_ptr, ':'); //past passwd
|
|
110 current_ptr++; //past colon ':' after passwd
|
|
111 if(shadow) {
|
|
112 fprintf(newfp, "%u:",(unsigned)(time(NULL))/(24*60*60));
|
|
113 current_ptr = get_nextcolon(current_ptr, ':');
|
|
114 current_ptr++; //past time stamp colon.
|
|
115 fprintf(newfp, "%s\n",current_ptr);
|
|
116 }
|
|
117 else {
|
|
118 fprintf(newfp, "%s\n",current_ptr);
|
|
119 }
|
|
120 }
|
|
121
|
|
122 free(line);
|
|
123 }
|
|
124 free(namesfx);
|
|
125 fcntl(fileno(exfp), F_SETLK, &lock);
|
|
126 fclose(exfp);
|
|
127
|
|
128 errno = 0;
|
|
129 fflush(newfp);
|
|
130 fsync(fileno(newfp));
|
|
131 fclose(newfp);
|
|
132 rename(filenamesfx, filename);
|
|
133 if(errno) {
|
|
134 perror_msg("File Writing/Saving failed: ");
|
|
135 unlink(filenamesfx);
|
|
136 ret = -1;
|
|
137 }
|
|
138
|
|
139 free_storage:
|
|
140 free(filenamesfx);
|
|
141 return ret;
|
|
142 }
|