made minimum granularity of vertical movement a parameter read from DESC file
[unix-history] / usr / src / usr.sbin / vipw / vipw.c
CommitLineData
4c6b79b5 1#ifndef lint
839955a4 2static char sccsid[] = "@(#)vipw.c 4.6 (Berkeley) %G%";
4c6b79b5
SL
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 */
c6ab0749
RC
16char temp[] = "/etc/ptmp";
17char temp_pag[] = "/etc/ptmp.pag";
18char temp_dir[] = "/etc/ptmp.dir";
19char passwd[] = "/etc/passwd";
20char passwd_pag[] = "/etc/passwd.pag";
21char passwd_dir[] = "/etc/passwd.dir";
4c6b79b5
SL
22char buf[BUFSIZ];
23char *getenv();
24char *index();
25extern int errno;
26
27main(argc, argv)
28 char *argv[];
29{
30 int fd;
31 FILE *ft, *fp;
32 char *editor;
33
c6ab0749 34 signal(SIGHUP, SIG_IGN);
4c6b79b5
SL
35 signal(SIGINT, SIG_IGN);
36 signal(SIGQUIT, SIG_IGN);
4c6b79b5 37 setbuf(stderr, NULL);
b2018160 38 umask(0);
4c6b79b5
SL
39 fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
40 if (fd < 0) {
41 if (errno == EEXIST) {
42 fprintf(stderr, "vipw: password file busy\n");
43 exit(1);
44 }
45 fprintf(stderr, "vipw: "); perror(temp);
46 exit(1);
47 }
48 ft = fdopen(fd, "w");
49 if (ft == NULL) {
50 fprintf(stderr, "vipw: "); perror(temp);
51 goto bad;
52 }
53 fp = fopen(passwd, "r");
54 if (fp == NULL) {
55 fprintf(stderr, "vipw: "); perror(passwd);
56 goto bad;
57 }
58 while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
59 fputs(buf, ft);
60 fclose(ft); fclose(fp);
61 editor = getenv("EDITOR");
62 if (editor == 0)
63 editor = "vi";
64 sprintf(buf, "%s %s", editor, temp);
65 if (system(buf) == 0) {
66 struct stat sbuf;
67 int ok;
68
69 /* sanity checks */
70 if (stat(temp, &sbuf) < 0) {
71 fprintf(stderr,
72 "vipw: can't stat temp file, %s unchanged\n",
73 passwd);
74 goto bad;
75 }
76 if (sbuf.st_size == 0) {
77 fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
78 passwd);
79 goto bad;
80 }
81 ft = fopen(temp, "r");
82 if (ft == NULL) {
83 fprintf(stderr,
84 "vipw: can't reopen temp file, %s unchanged\n",
85 passwd);
86 goto bad;
87 }
88 ok = 0;
89 while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
90 register char *cp;
91
92 cp = index(buf, '\n');
93 if (cp == 0)
94 continue;
95 *cp = '\0';
96 cp = index(buf, ':');
97 if (cp == 0)
98 continue;
99 *cp = '\0';
100 if (strcmp(buf, "root"))
101 continue;
102 /* password */
103 cp = index(cp + 1, ':');
104 if (cp == 0)
105 break;
106 /* uid */
107 if (atoi(cp + 1) != 0)
108 break;
109 cp = index(cp + 1, ':');
110 if (cp == 0)
111 break;
112 /* gid */
113 cp = index(cp + 1, ':');
114 if (cp == 0)
115 break;
116 /* gecos */
117 cp = index(cp + 1, ':');
118 if (cp == 0)
119 break;
120 /* login directory */
121 if (strncmp(++cp, "/:"))
122 break;
123 cp += 2;
124 if (*cp && strcmp(cp, "/bin/sh") &&
125 strcmp(cp, "/bin/csh"))
126 break;
127 ok++;
128 }
129 fclose(ft);
130 if (ok) {
ae41743d
RC
131 if (makedb(temp) < 0)
132 fprintf(stderr, "vipw: mkpasswd failed\n");
133 else if (rename(temp_pag, passwd_pag) < 0)
134 fprintf(stderr, "vipw: "), perror(temp_pag);
135 else if (rename(temp_dir, passwd_dir) < 0)
136 fprintf(stderr, "vipw: "), perror(temp_dir);
137 else if (rename(temp, passwd) < 0)
4c6b79b5 138 fprintf(stderr, "vipw: "), perror("rename");
6b52f313
RC
139 else
140 exit(0);
4c6b79b5
SL
141 } else
142 fprintf(stderr,
143 "vipw: you mangled the temp file, %s unchanged\n",
144 passwd);
145 }
146bad:
c6ab0749
RC
147 unlink(temp_pag);
148 unlink(temp_dir);
4c6b79b5 149 unlink(temp);
6b52f313 150 exit(1);
4c6b79b5 151}
ae41743d
RC
152
153makedb(file)
154 char *file;
155{
156 int status, pid, w;
157
158 if ((pid = vfork()) == 0) {
159 execl("/etc/mkpasswd", "mkpasswd", file, 0);
160 _exit(127);
161 }
162 while ((w = wait(&status)) != pid && w != -1)
163 ;
164 if (w == -1 || status != 0)
165 status = -1;
166 return(status);
167}