|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)vipw.c 5.1 (Berkeley) 5/28/85";
15: #endif not lint
16:
17: #include <sys/types.h>
18: #include <sys/stat.h>
19: #include <sys/file.h>
20:
21: #include <stdio.h>
22: #include <errno.h>
23: #include <signal.h>
24:
25: /*
26: * Password file editor with locking.
27: */
28: char temp[] = "/etc/ptmp";
29: char temp_pag[] = "/etc/ptmp.pag";
30: char temp_dir[] = "/etc/ptmp.dir";
31: char passwd[] = "/etc/passwd";
32: char passwd_pag[] = "/etc/passwd.pag";
33: char passwd_dir[] = "/etc/passwd.dir";
34: char buf[BUFSIZ];
35: char *getenv();
36: char *index();
37: extern int errno;
38:
39: main(argc, argv)
40: char *argv[];
41: {
42: int fd;
43: FILE *ft, *fp;
44: char *editor;
45:
46: signal(SIGHUP, SIG_IGN);
47: signal(SIGINT, SIG_IGN);
48: signal(SIGQUIT, SIG_IGN);
49: setbuf(stderr, NULL);
50: umask(0);
51: fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
52: if (fd < 0) {
53: if (errno == EEXIST) {
54: fprintf(stderr, "vipw: password file busy\n");
55: exit(1);
56: }
57: fprintf(stderr, "vipw: "); perror(temp);
58: exit(1);
59: }
60: ft = fdopen(fd, "w");
61: if (ft == NULL) {
62: fprintf(stderr, "vipw: "); perror(temp);
63: goto bad;
64: }
65: fp = fopen(passwd, "r");
66: if (fp == NULL) {
67: fprintf(stderr, "vipw: "); perror(passwd);
68: goto bad;
69: }
70: while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
71: fputs(buf, ft);
72: fclose(ft); fclose(fp);
73: editor = getenv("EDITOR");
74: if (editor == 0)
75: editor = "vi";
76: sprintf(buf, "%s %s", editor, temp);
77: if (system(buf) == 0) {
78: struct stat sbuf;
79: int ok;
80:
81: /* sanity checks */
82: if (stat(temp, &sbuf) < 0) {
83: fprintf(stderr,
84: "vipw: can't stat temp file, %s unchanged\n",
85: passwd);
86: goto bad;
87: }
88: if (sbuf.st_size == 0) {
89: fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
90: passwd);
91: goto bad;
92: }
93: ft = fopen(temp, "r");
94: if (ft == NULL) {
95: fprintf(stderr,
96: "vipw: can't reopen temp file, %s unchanged\n",
97: passwd);
98: goto bad;
99: }
100: ok = 0;
101: while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
102: register char *cp;
103:
104: cp = index(buf, '\n');
105: if (cp == 0)
106: continue;
107: *cp = '\0';
108: cp = index(buf, ':');
109: if (cp == 0)
110: continue;
111: *cp = '\0';
112: if (strcmp(buf, "root"))
113: continue;
114: /* password */
115: cp = index(cp + 1, ':');
116: if (cp == 0)
117: break;
118: /* uid */
119: if (atoi(cp + 1) != 0)
120: break;
121: cp = index(cp + 1, ':');
122: if (cp == 0)
123: break;
124: /* gid */
125: cp = index(cp + 1, ':');
126: if (cp == 0)
127: break;
128: /* gecos */
129: cp = index(cp + 1, ':');
130: if (cp == 0)
131: break;
132: /* login directory */
133: if (strncmp(++cp, "/:", 2))
134: break;
135: cp += 2;
136: if (*cp && strcmp(cp, "/bin/sh") &&
137: strcmp(cp, "/bin/csh"))
138: break;
139: ok++;
140: }
141: fclose(ft);
142: if (ok) {
143: if (makedb(temp) < 0)
144: fprintf(stderr, "vipw: mkpasswd failed\n");
145: else if (rename(temp_pag, passwd_pag) < 0)
146: fprintf(stderr, "vipw: "), perror(temp_pag);
147: else if (rename(temp_dir, passwd_dir) < 0)
148: fprintf(stderr, "vipw: "), perror(temp_dir);
149: else if (rename(temp, passwd) < 0)
150: fprintf(stderr, "vipw: "), perror("rename");
151: else
152: exit(0);
153: } else
154: fprintf(stderr,
155: "vipw: you mangled the temp file, %s unchanged\n",
156: passwd);
157: }
158: bad:
159: unlink(temp_pag);
160: unlink(temp_dir);
161: unlink(temp);
162: exit(1);
163: }
164:
165: makedb(file)
166: char *file;
167: {
168: int status, pid, w;
169:
170: if ((pid = vfork()) == 0) {
171: execl("/etc/mkpasswd", "mkpasswd", file, 0);
172: _exit(127);
173: }
174: while ((w = wait(&status)) != pid && w != -1)
175: ;
176: if (w == -1 || status != 0)
177: status = -1;
178: return(status);
179: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.