xref: /csrg-svn/usr.sbin/vipw/vipw.c (revision 14911)
113736Ssam #ifndef lint
2*14911Sralph static char sccsid[] = "@(#)vipw.c	4.2 (Berkeley) 09/07/83";
313736Ssam #endif
413736Ssam 
513736Ssam #include <sys/types.h>
613736Ssam #include <sys/stat.h>
713736Ssam #include <sys/file.h>
813736Ssam 
913736Ssam #include <stdio.h>
1013736Ssam #include <errno.h>
1113736Ssam #include <signal.h>
1213736Ssam 
1313736Ssam /*
1413736Ssam  * Password file editor with locking.
1513736Ssam  */
1613736Ssam char	*temp = "/etc/ptmp";
1713736Ssam char	*passwd = "/etc/passwd";
1813736Ssam char	buf[BUFSIZ];
1913736Ssam char	*getenv();
2013736Ssam char	*index();
2113736Ssam extern	int errno;
2213736Ssam 
2313736Ssam main(argc, argv)
2413736Ssam 	char *argv[];
2513736Ssam {
2613736Ssam 	int fd;
2713736Ssam 	FILE *ft, *fp;
2813736Ssam 	char *editor;
2913736Ssam 
3013736Ssam 	signal(SIGINT, SIG_IGN);
3113736Ssam 	signal(SIGQUIT, SIG_IGN);
3213736Ssam 	signal(SIGHUP, SIG_IGN);
3313736Ssam 	setbuf(stderr, NULL);
34*14911Sralph 	umask(0);
3513736Ssam 	fd = open(temp, O_WRONLY|O_CREAT|O_EXCL, 0644);
3613736Ssam 	if (fd < 0) {
3713736Ssam 		if (errno == EEXIST) {
3813736Ssam 			fprintf(stderr, "vipw: password file busy\n");
3913736Ssam 			exit(1);
4013736Ssam 		}
4113736Ssam 		fprintf(stderr, "vipw: "); perror(temp);
4213736Ssam 		exit(1);
4313736Ssam 	}
4413736Ssam 	ft = fdopen(fd, "w");
4513736Ssam 	if (ft == NULL) {
4613736Ssam 		fprintf(stderr, "vipw: "); perror(temp);
4713736Ssam 		goto bad;
4813736Ssam 	}
4913736Ssam 	fp = fopen(passwd, "r");
5013736Ssam 	if (fp == NULL) {
5113736Ssam 		fprintf(stderr, "vipw: "); perror(passwd);
5213736Ssam 		goto bad;
5313736Ssam 	}
5413736Ssam 	while (fgets(buf, sizeof (buf) - 1, fp) != NULL)
5513736Ssam 		fputs(buf, ft);
5613736Ssam 	fclose(ft); fclose(fp);
5713736Ssam 	editor = getenv("EDITOR");
5813736Ssam 	if (editor == 0)
5913736Ssam 		editor = "vi";
6013736Ssam 	sprintf(buf, "%s %s", editor, temp);
6113736Ssam 	if (system(buf) == 0) {
6213736Ssam 		struct stat sbuf;
6313736Ssam 		int ok;
6413736Ssam 
6513736Ssam 		/* sanity checks */
6613736Ssam 		if (stat(temp, &sbuf) < 0) {
6713736Ssam 			fprintf(stderr,
6813736Ssam 			    "vipw: can't stat temp file, %s unchanged\n",
6913736Ssam 			    passwd);
7013736Ssam 			goto bad;
7113736Ssam 		}
7213736Ssam 		if (sbuf.st_size == 0) {
7313736Ssam 			fprintf(stderr, "vipw: bad temp file, %s unchanged\n",
7413736Ssam 			    passwd);
7513736Ssam 			goto bad;
7613736Ssam 		}
7713736Ssam 		ft = fopen(temp, "r");
7813736Ssam 		if (ft == NULL) {
7913736Ssam 			fprintf(stderr,
8013736Ssam 			    "vipw: can't reopen temp file, %s unchanged\n",
8113736Ssam 			    passwd);
8213736Ssam 			goto bad;
8313736Ssam 		}
8413736Ssam 		ok = 0;
8513736Ssam 		while (fgets(buf, sizeof (buf) - 1, ft) != NULL) {
8613736Ssam 			register char *cp;
8713736Ssam 
8813736Ssam 			cp = index(buf, '\n');
8913736Ssam 			if (cp == 0)
9013736Ssam 				continue;
9113736Ssam 			*cp = '\0';
9213736Ssam 			cp = index(buf, ':');
9313736Ssam 			if (cp == 0)
9413736Ssam 				continue;
9513736Ssam 			*cp = '\0';
9613736Ssam 			if (strcmp(buf, "root"))
9713736Ssam 				continue;
9813736Ssam 			/* password */
9913736Ssam 			cp = index(cp + 1, ':');
10013736Ssam 			if (cp == 0)
10113736Ssam 				break;
10213736Ssam 			/* uid */
10313736Ssam 			if (atoi(cp + 1) != 0)
10413736Ssam 				break;
10513736Ssam 			cp = index(cp + 1, ':');
10613736Ssam 			if (cp == 0)
10713736Ssam 				break;
10813736Ssam 			/* gid */
10913736Ssam 			cp = index(cp + 1, ':');
11013736Ssam 			if (cp == 0)
11113736Ssam 				break;
11213736Ssam 			/* gecos */
11313736Ssam 			cp = index(cp + 1, ':');
11413736Ssam 			if (cp == 0)
11513736Ssam 				break;
11613736Ssam 			/* login directory */
11713736Ssam 			if (strncmp(++cp, "/:"))
11813736Ssam 				break;
11913736Ssam 			cp += 2;
12013736Ssam 			if (*cp && strcmp(cp, "/bin/sh") &&
12113736Ssam 			    strcmp(cp, "/bin/csh"))
12213736Ssam 				break;
12313736Ssam 			ok++;
12413736Ssam 		}
12513736Ssam 		fclose(ft);
12613736Ssam 		if (ok) {
12713736Ssam 			if (rename(temp, passwd) < 0)
12813736Ssam 				fprintf(stderr, "vipw: "), perror("rename");
12913736Ssam 		} else
13013736Ssam 			fprintf(stderr,
13113736Ssam 			    "vipw: you mangled the temp file, %s unchanged\n",
13213736Ssam 			    passwd);
13313736Ssam 	}
13413736Ssam bad:
13513736Ssam 	unlink(temp);
13613736Ssam }
137