|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)vipw.c 4.2 (Berkeley) 9/7/83";
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: */
16: char *temp = "/etc/ptmp";
17: char *passwd = "/etc/passwd";
18: char buf[BUFSIZ];
19: char *getenv();
20: char *index();
21: extern int errno;
22:
23: main(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: umask(0);
35: fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
36: if (fd < 0) {
37: if (errno == EEXIST) {
38: fprintf(stderr, "vipw: password file busy\n");
39: exit(1);
40: }
41: fprintf(stderr, "vipw: "); perror(temp);
42: exit(1);
43: }
44: ft = fdopen(fd, "w");
45: if (ft == NULL) {
46: fprintf(stderr, "vipw: "); perror(temp);
47: goto bad;
48: }
49: fp = fopen(passwd, "r");
50: if (fp == NULL) {
51: fprintf(stderr, "vipw: "); perror(passwd);
52: goto bad;
53: }
54: while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
55: fputs(buf, ft);
56: fclose(ft); fclose(fp);
57: editor = getenv("EDITOR");
58: if (editor == 0)
59: editor = "vi";
60: sprintf(buf, "%s %s", editor, temp);
61: if (system(buf) == 0) {
62: struct stat sbuf;
63: int ok;
64:
65: /* sanity checks */
66: if (stat(temp, &sbuf) < 0) {
67: fprintf(stderr,
68: "vipw: can't stat temp file, %s unchanged\n",
69: passwd);
70: goto bad;
71: }
72: if (sbuf.st_size == 0) {
73: fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
74: passwd);
75: goto bad;
76: }
77: ft = fopen(temp, "r");
78: if (ft == NULL) {
79: fprintf(stderr,
80: "vipw: can't reopen temp file, %s unchanged\n",
81: passwd);
82: goto bad;
83: }
84: ok = 0;
85: while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
86: register char *cp;
87:
88: cp = index(buf, '\n');
89: if (cp == 0)
90: continue;
91: *cp = '\0';
92: cp = index(buf, ':');
93: if (cp == 0)
94: continue;
95: *cp = '\0';
96: if (strcmp(buf, "root"))
97: continue;
98: /* password */
99: cp = index(cp + 1, ':');
100: if (cp == 0)
101: break;
102: /* uid */
103: if (atoi(cp + 1) != 0)
104: break;
105: cp = index(cp + 1, ':');
106: if (cp == 0)
107: break;
108: /* gid */
109: cp = index(cp + 1, ':');
110: if (cp == 0)
111: break;
112: /* gecos */
113: cp = index(cp + 1, ':');
114: if (cp == 0)
115: break;
116: /* login directory */
117: if (strncmp(++cp, "/:"))
118: break;
119: cp += 2;
120: if (*cp && strcmp(cp, "/bin/sh") &&
121: strcmp(cp, "/bin/csh"))
122: break;
123: ok++;
124: }
125: fclose(ft);
126: if (ok) {
127: if (rename(temp, passwd) < 0)
128: fprintf(stderr, "vipw: "), perror("rename");
129: } else
130: fprintf(stderr,
131: "vipw: you mangled the temp file, %s unchanged\n",
132: passwd);
133: }
134: bad:
135: unlink(temp);
136: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.