xref: /openbsd-src/regress/sys/kern/getpeereid/getpeereid_test.c (revision 6822f9c8033774f6aab00bcb43e8718e7034e67d)
1*6822f9c8Santon /* $OpenBSD: getpeereid_test.c,v 1.5 2024/08/23 12:56:26 anton Exp $ */
207642774Sespie /* Written by Marc Espie in 2006 */
307642774Sespie /* Public domain */
407642774Sespie #include <sys/types.h>
507642774Sespie #include <sys/socket.h>
607642774Sespie #include <sys/stat.h>
707642774Sespie #include <sys/un.h>
807642774Sespie #include <sys/wait.h>
907642774Sespie #include <err.h>
1007642774Sespie #include <string.h>
1107642774Sespie #include <unistd.h>
1207642774Sespie #include <stdlib.h>
1307642774Sespie #include <stdio.h>
1407642774Sespie #include <errno.h>
1507642774Sespie 
1607642774Sespie char path[1024];
1707642774Sespie char *dir;
1807642774Sespie 
1907642774Sespie char *
2007642774Sespie check_id(int fd)
2107642774Sespie {
2207642774Sespie 	uid_t sockuid, myuid;
2307642774Sespie 	gid_t sockgid, mygid;
2407642774Sespie 	static char problem[1024];
2507642774Sespie 
2607642774Sespie 	if (getpeereid(fd, &sockuid, &sockgid) == -1) {
2707642774Sespie 		snprintf(problem, sizeof problem, "getpeereid: %s",
2807642774Sespie 		    strerror(errno));
2907642774Sespie 		return problem;
3007642774Sespie 	}
3107642774Sespie 	myuid = geteuid();
3207642774Sespie 	mygid = getgid();
3307642774Sespie 	if (myuid != sockuid) {
3407642774Sespie 		snprintf(problem, sizeof problem, "uid discrepancy %ld vs %ld",
3507642774Sespie 			(long)myuid, (long)sockuid);
3607642774Sespie 		return problem;
3707642774Sespie 	}
3807642774Sespie 	if (mygid != sockgid) {
3907642774Sespie 		snprintf(problem, sizeof problem, "gid discrepancy %ld vs %ld",
4007642774Sespie 			(long)mygid, (long)sockgid);
4107642774Sespie 		return problem;
4207642774Sespie 	}
4307642774Sespie 	return NULL;
4407642774Sespie }
4507642774Sespie 
4607642774Sespie void
4707642774Sespie client(struct sockaddr_un *sun)
4807642774Sespie {
4907642774Sespie 	int s;
5007642774Sespie 	int i;
5107642774Sespie 	int r;
5207642774Sespie 	char *problem;
5307642774Sespie 
5407642774Sespie 	s = socket(AF_UNIX, SOCK_STREAM, 0);
5507642774Sespie 	if (s == -1)
5607642774Sespie 		err(1, "Bad socket");
5707642774Sespie 
5807642774Sespie 	/* XXX make sure the server started alright */
5907642774Sespie 	for (i = 0; i < 10; i++) {
6007642774Sespie 		r = connect(s, (struct sockaddr *)sun, sizeof(*sun));
6107642774Sespie 		if (r == 0) {
6207642774Sespie 			problem = check_id(s);
6307642774Sespie 			if (problem)
6431782559Sderaadt 				errx(1, "%s", problem);
6507642774Sespie 			exit(0);
6607642774Sespie 		}
6707642774Sespie 		sleep(5);
6807642774Sespie 	}
6907642774Sespie 	errx(1, "Could not connect after 10 tries");
7007642774Sespie }
7107642774Sespie 
7207642774Sespie 
7307642774Sespie void
7407642774Sespie server(struct sockaddr_un *sun)
7507642774Sespie {
7607642774Sespie 	int s, fd;
7707642774Sespie 	struct sockaddr_storage client_addr;
7807642774Sespie 	socklen_t client_len;
7907642774Sespie 	char *problem;
8007642774Sespie 
8107642774Sespie 	s = socket(AF_UNIX, SOCK_STREAM, 0);
8207642774Sespie 	if (s == -1)
8307642774Sespie 		err(1, "Bad socket");
8407642774Sespie 
8507642774Sespie 	if (bind(s, (struct sockaddr *)sun, sizeof(*sun)) != 0)
8607642774Sespie 		err(1, "bind");
8707642774Sespie 	if (listen(s, 5) != 0) {
88ffb4dd05Sguenther 		int saved_errno = errno;
8907642774Sespie 		unlink(path);
9007642774Sespie 		rmdir(dir);
91ffb4dd05Sguenther 		errc(1, saved_errno, "listen");
9207642774Sespie 	}
9307642774Sespie 	fd = accept(s, (struct sockaddr *)&client_addr, &client_len);
9407642774Sespie 	if (fd == -1) {
95ffb4dd05Sguenther 		int saved_errno = errno;
9607642774Sespie 		unlink(path);
9707642774Sespie 		rmdir(dir);
98ffb4dd05Sguenther 		errc(1, saved_errno, "accept");
9907642774Sespie 	}
10007642774Sespie 	problem = check_id(fd);
10107642774Sespie 	if (problem)  {
10207642774Sespie 		unlink(path);
10307642774Sespie 		rmdir(dir);
10431782559Sderaadt 		errx(1, "%s", problem);
10507642774Sespie 	}
10607642774Sespie 	unlink(path);
10707642774Sespie 	rmdir(dir);
10807642774Sespie }
10907642774Sespie 
11007642774Sespie 
11107642774Sespie 
11207642774Sespie int
11307642774Sespie main()
11407642774Sespie {
11507642774Sespie 	pid_t pid;
11607642774Sespie 	struct sockaddr_un sun;
11707642774Sespie 	char dir_template[] = "/tmp/peer.XXXXXX";
11807642774Sespie 
11907642774Sespie 	dir = mkdtemp(dir_template);
12007642774Sespie 	if (!dir)
12107642774Sespie 		err(1, "mkdtemp");
12207642774Sespie 	snprintf(path, sizeof path, "%s/%s", dir, "socket");
12307642774Sespie 
12407642774Sespie 	memset(&sun, 0, sizeof(struct sockaddr_un));
12507642774Sespie 	if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
12607642774Sespie 	    sizeof(sun.sun_path))
12707642774Sespie 		errx(1, "Memory error");
12807642774Sespie 	sun.sun_family = AF_UNIX;
12907642774Sespie 
13007642774Sespie 	/* let's make those two rendez-vous, a bit artificial */
13107642774Sespie 	pid = fork();
13207642774Sespie 	if (pid == -1)
13307642774Sespie 		err(1, "can't fork");
13407642774Sespie 	if (pid == 0) {
13507642774Sespie 		client(&sun);
13607642774Sespie 		exit(0);
13707642774Sespie 	} else {
13807642774Sespie 		int status;
13907642774Sespie 
14007642774Sespie 		server(&sun);
14107642774Sespie 		waitpid(pid, &status, 0);
14207642774Sespie 		if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
14307642774Sespie 			printf("getpeereid test okay\n");
14407642774Sespie 			exit(0);
145*6822f9c8Santon 		} else {
146*6822f9c8Santon 			errx(1, "Problem with child");
147*6822f9c8Santon 		}
14807642774Sespie 	}
14907642774Sespie }
150