1 /* passwd - change a passwd Author: Adri Koppes */
3 /* chfn, chsh - change full name, shell Added by: Kees J. Bot */
15 #include <minix/minlib.h>
18 _PROTOTYPE(void report
, (char *label
));
19 _PROTOTYPE(void quit
, (int ex_stat
));
20 _PROTOTYPE(void fatal
, (char *label
));
21 _PROTOTYPE(void usage
, (void));
22 _PROTOTYPE(int goodchars
, (char *s
));
23 _PROTOTYPE(int main
, (int argc
, char **argv
));
25 char pw_file
[] = "/etc/passwd";
26 char sh_file
[] = "/etc/shadow";
27 char pw_tmp
[] = "/etc/ptmp";
28 char bad
[] = "Permission denied\n";
41 fprintf(stderr
, "%s: ", arg0
);
50 if (unlink(pw_tmp
) < 0 && errno
!= ENOENT
) {
66 static char *usages
[] = {
68 "chfn [user] fullname\n",
71 std_err(usages
[(int) action
]);
80 while ((c
= *s
++) != 0) {
81 if (c
== ':' || c
< ' ' || c
>= 127) return(0);
95 char *name
, pwname
[9], oldpwd
[9], newpwd
[9], newcrypted
[14], sl
[2];
99 if ((arg0
= strrchr(argv
[0], '/')) != 0)
104 if (strcmp(arg0
, "chfn") == 0)
106 else if (strcmp(arg0
, "chsh") == 0)
111 n
= action
== PASSWD
? 1 : 2;
113 if (argc
!= n
&& argc
!= n
+ 1) usage();
117 strcpy(pwname
, pwd
->pw_name
);
121 pwd
= getpwnam(name
);
123 if (pwd
== NULL
|| ((uid
!= pwd
->pw_uid
) && uid
!= 0)) {
130 if (pwd
->pw_passwd
[0] == '#' && pwd
->pw_passwd
[1] == '#') {
131 /* The password is found in the shadow password file. */
133 strncpy(pwname
, pwd
->pw_passwd
+ 2, 8);
137 if ((pwd
= getpwnam(name
)) == NULL
) {
141 printf("Changing the shadow password of %s\n", name
);
143 printf("Changing the password of %s\n", name
);
147 if (pwd
->pw_passwd
[0] != '\0' && uid
!= 0) {
148 strcpy(oldpwd
, getpass("Old password:"));
149 if (strcmp(pwd
->pw_passwd
, crypt(oldpwd
, pwd
->pw_passwd
)) != 0)
156 strcpy(newpwd
, getpass("New password:"));
158 if (newpwd
[0] == '\0')
159 std_err("Password cannot be null");
160 else if (strcmp(newpwd
, getpass("Retype password:")) != 0)
161 std_err("Passwords don't match");
165 std_err(", try again\n");
168 sl
[0] = (salt
& 077) + '.';
169 sl
[1] = ((salt
>> 6) & 077) + '.';
170 for (cn
= 0; cn
< 2; cn
++) {
171 if (sl
[cn
] > '9') sl
[cn
] += 7;
172 if (sl
[cn
] > 'Z') sl
[cn
] += 6;
174 strcpy(newcrypted
, crypt(newpwd
, sl
));
179 argn
= argv
[argc
- 1];
181 if (strlen(argn
) > (action
== CHFN
? 80 : 60) || !goodchars(argn
)) {
187 signal(SIGHUP
, SIG_IGN
);
188 signal(SIGINT
, SIG_IGN
);
189 signal(SIGQUIT
, SIG_IGN
);
190 signal(SIGTERM
, SIG_IGN
);
194 while ((fd_tmp
= open(pw_tmp
, O_RDWR
| O_CREAT
| O_EXCL
, 0400)) < 0) {
195 if (errno
!= EEXIST
) fatal("Can't create temporary file");
200 fprintf(stderr
, "Password file busy, try again later.\n");
205 if ((fp_tmp
= fdopen(fd_tmp
, "w+")) == NULL
) fatal(pw_tmp
);
208 while ((pwd
= getpwent()) != 0) {
209 if (strcmp(name
, pwd
->pw_name
) == 0) {
212 pwd
->pw_passwd
= newcrypted
;
215 pwd
->pw_gecos
= argn
;
218 pwd
->pw_shell
= argn
;
222 if (strcmp(pwd
->pw_shell
, "/bin/sh") == 0
223 || strcmp(pwd
->pw_shell
, "/usr/bin/sh") == 0
227 fprintf(fp_tmp
, "%s:%s:%s:",
232 if (ferror(fp_tmp
)) fatal(pw_tmp
);
234 fprintf(fp_tmp
, "%s:%s:%s:%s\n",
240 if (ferror(fp_tmp
)) fatal(pw_tmp
);
243 if (fflush(fp_tmp
) == EOF
) fatal(pw_tmp
);
245 if (lseek(fd_tmp
, (off_t
) 0, SEEK_SET
) != 0)
246 fatal("Can't reread temp file");
248 if ((fd_pwd
= open(shadow
? sh_file
: pw_file
, O_WRONLY
| O_TRUNC
)) < 0)
249 fatal("Can't recreate password file");
251 while ((n
= read(fd_tmp
, buf
, sizeof(buf
))) != 0) {
252 if (n
< 0 || write(fd_pwd
, buf
, n
) != n
) {
253 report("Error rewriting password file, tell root!");