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