date and time created 83/07/03 01:53:35 by sam
[unix-history] / usr / src / usr.sbin / vipw / vipw.c
CommitLineData
4c6b79b5
SL
1#ifndef lint
2static char sccsid[] = "@(#)vipw.c 4.1 (Berkeley) %G%";
3#endif
4
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <sys/file.h>
8
9#include <stdio.h>
10#include <errno.h>
11#include <signal.h>
12
13/*
14 * Password file editor with locking.
15 */
16char *temp = "/etc/ptmp";
17char *passwd = "/etc/passwd";
18char buf[BUFSIZ];
19char *getenv();
20char *index();
21extern int errno;
22
23main(argc, argv)
24 char *argv[];
25{
26 int fd;
27 FILE *ft, *fp;
28 char *editor;
29
30 signal(SIGINT, SIG_IGN);
31 signal(SIGQUIT, SIG_IGN);
32 signal(SIGHUP, SIG_IGN);
33 setbuf(stderr, NULL);
34 fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
35 if (fd < 0) {
36 if (errno == EEXIST) {
37 fprintf(stderr, "vipw: password file busy\n");
38 exit(1);
39 }
40 fprintf(stderr, "vipw: "); perror(temp);
41 exit(1);
42 }
43 ft = fdopen(fd, "w");
44 if (ft == NULL) {
45 fprintf(stderr, "vipw: "); perror(temp);
46 goto bad;
47 }
48 fp = fopen(passwd, "r");
49 if (fp == NULL) {
50 fprintf(stderr, "vipw: "); perror(passwd);
51 goto bad;
52 }
53 while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
54 fputs(buf, ft);
55 fclose(ft); fclose(fp);
56 editor = getenv("EDITOR");
57 if (editor == 0)
58 editor = "vi";
59 sprintf(buf, "%s %s", editor, temp);
60 if (system(buf) == 0) {
61 struct stat sbuf;
62 int ok;
63
64 /* sanity checks */
65 if (stat(temp, &sbuf) < 0) {
66 fprintf(stderr,
67 "vipw: can't stat temp file, %s unchanged\n",
68 passwd);
69 goto bad;
70 }
71 if (sbuf.st_size == 0) {
72 fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
73 passwd);
74 goto bad;
75 }
76 ft = fopen(temp, "r");
77 if (ft == NULL) {
78 fprintf(stderr,
79 "vipw: can't reopen temp file, %s unchanged\n",
80 passwd);
81 goto bad;
82 }
83 ok = 0;
84 while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
85 register char *cp;
86
87 cp = index(buf, '\n');
88 if (cp == 0)
89 continue;
90 *cp = '\0';
91 cp = index(buf, ':');
92 if (cp == 0)
93 continue;
94 *cp = '\0';
95 if (strcmp(buf, "root"))
96 continue;
97 /* password */
98 cp = index(cp + 1, ':');
99 if (cp == 0)
100 break;
101 /* uid */
102 if (atoi(cp + 1) != 0)
103 break;
104 cp = index(cp + 1, ':');
105 if (cp == 0)
106 break;
107 /* gid */
108 cp = index(cp + 1, ':');
109 if (cp == 0)
110 break;
111 /* gecos */
112 cp = index(cp + 1, ':');
113 if (cp == 0)
114 break;
115 /* login directory */
116 if (strncmp(++cp, "/:"))
117 break;
118 cp += 2;
119 if (*cp && strcmp(cp, "/bin/sh") &&
120 strcmp(cp, "/bin/csh"))
121 break;
122 ok++;
123 }
124 fclose(ft);
125 if (ok) {
126 if (rename(temp, passwd) < 0)
127 fprintf(stderr, "vipw: "), perror("rename");
128 } else
129 fprintf(stderr,
130 "vipw: you mangled the temp file, %s unchanged\n",
131 passwd);
132 }
133bad:
134 unlink(temp);
135}