BSD 1 development
[unix-history] / s1 / passwd.c
CommitLineData
fde98a2d
BJ
1/*
2 * enter a password in the password file
3 * this program should be suid with owner
4 * with an owner with write permission on /etc/passwd
5 */
6char *tfile { "/usr/adm/ptmp" };
7char *pfile { "/etc/passwd" };
8char *pw;
9char pwbuf[10];
10int ttybuf[3];
11int tbuf[259];
12int pbuf[259];
13
14main(argc, argv)
15char *argv[];
16{
17 register u, c;
18 register char *p;
19 int exitt();
20 int v;
21 char x;
22
23 if(argc < 2) {
24 write(2, "Usage: passwd user [ password ]\n", 32);
25 goto bex;
26 }
27 if(argc == 2) {
28 signal(1, &exitt);
29 signal(2, &exitt);
30 signal(3, &exitt);
31 gtty(0, ttybuf);
32 ttybuf[2] =& ~010;
33 stty(0, ttybuf);
34again:
35 write(2, "Password: ", 10);
36 p = pwbuf;
37 for(;;) {
38 if(read(0, p, 1) != 1)
39 break;
40 if(*p == '\n')
41 break;
42 if(p < pwbuf+9)
43 p++;
44 }
45 *p = 0;
46 write(2, "\nAgain: ", 8);
47 p = pwbuf;
48 for (;;) {
49 if (read(0, &x, 1) != 1 || x == '\n')
50 break;
51 if (*p++ != x) {
52xxx:
53 while (read(0, &x, 1) == 1 && x != '\n')
54 continue;
55 write(2, "\nThose weren't the same\n", 24);
56 goto again;
57 }
58 }
59 if (*p != 0)
60 goto xxx;
61 ttybuf[2] =| 010;
62 stty(0, ttybuf);
63 write(2, "\n", 1);
64 pw = pwbuf;
65 } else
66 pw = argv[2];
67 signal(1, 1);
68 signal(2, 1);
69 signal(3, 1);
70
71 if(stat(tfile, tbuf+20) >= 0) {
72 write(2, "Temporary file busy -- try again\n", 33);
73 goto bex;
74 }
75 tbuf[0] = creat(tfile, 0600);
76 if(tbuf[0] < 0) {
77 write(2, "Cannot create temporary file\n", 29);
78 goto bex;
79 }
80 pbuf[0] = open(pfile, 0);
81 if(pbuf[0] < 0) {
82 write(2, "Cannot open /etc/passwd\n", 25);
83 goto out;
84 }
85 goto l1;
86
87/*
88 * skip to beginning of next line
89 */
90
91skip:
92 while(c != '\n') {
93 if(c < 0)
94 goto ill;
95 c = getc(pbuf);
96 putc(c, tbuf);
97 }
98
99/*
100 * compare user names
101 */
102
103l1:
104 c = getc(pbuf);
105 putc(c, tbuf);
106 if(c < 0) {
107 write(2, "User name not found in password file\n", 37);
108 goto out;
109 }
110 p = argv[1];
111 while(c != ':') {
112 if(*p++ != c)
113 goto skip;
114 c = getc(pbuf);
115 putc(c, tbuf);
116 }
117 if(*p)
118 goto skip;
119/*
120 * skip old password
121 */
122 do {
123 c = getc(pbuf);
124 if(c < 0)
125 goto ill;
126 } while(c != ':');
127
128/*
129 * copy in new password
130 */
131 p = pw;
132 for(c=0; c<9; c++)
133 if(*p++ == 0)
134 break;
135 *--p = 0;
136 if(p != pw)
137 p = crypt(pw);
138 while(*p)
139 putc(*p++, tbuf);
140 putc(':', tbuf);
141
142/*
143 * validate uid and gid
144 */
145
146 u = 0;
147 do {
148 c = getc(pbuf);
149 putc(c, tbuf);
150 if(c >= '0' && c <= '9')
151 u = u*10 + c-'0';
152 if(c < 0)
153 goto ill;
154 } while(c != ':');
155 v = 0;
156 do {
157 c = getc(pbuf);
158 putc(c, tbuf);
159 if(c >= '0' && c <= '9')
160 v = v*10 + c-'0';
161 if(c < 0)
162 goto ill;
163 } while(c != ':');
164 c = getuid();
165 if(c == 0)
166 goto ok;
167 if(c == ((v<<8) | u))
168 goto ok;
169 if((c&0377) == 0 && ((c>>8)&0377) == v)
170 goto ok;
171 write(2, "Permission denied\n", 18);
172 goto out;
173ok:
174
175/*
176 * copy out and back
177 */
178
179 for(;;) {
180 c = getc(pbuf);
181 if(c < 0) {
182 fflush(tbuf);
183 close(pbuf[0]);
184 close(tbuf[0]);
185 tbuf[0] = open(tfile, 0);
186 if(tbuf[0] < 0) {
187 write(2, "Urk\n", 4);
188 goto out;
189 }
190 pbuf[0] = creat(pfile, 0644);
191 if(pbuf[0] < 0) {
192 write(2, "Cannot create /etc/passwd\n", 27);
193 goto out;
194 }
195 while((c = read(tbuf[0], tbuf+1, 512)) > 0)
196 write(pbuf[0], tbuf+1, c);
197 unlink(tfile);
198 exit(0);
199 }
200 putc(c, tbuf);
201 }
202
203ill:
204 write(2, "Password file illformed\n", 24);
205
206out:
207 unlink(tfile);
208
209bex:
210 exit(1);
211}
212
213exitt()
214{
215 ttybuf[2] =| 010;
216 stty(0, ttybuf);
217 write(2, "\n", 1);
218 exit(1);
219}