xref: /freebsd/contrib/sendmail/test/t_exclopen.c (revision 1b6c76a2fe091c74f08427e6c870851025a9cf67)
1 /*
2 **  This program tests your system to see if you have the lovely
3 **  security-defeating semantics that an open with O_CREAT|O_EXCL
4 **  set will successfully open a file named by a symbolic link that
5 **  points to a non-existent file.  Sadly, Posix is mute on what
6 **  should happen in this situation.
7 **
8 **  Results to date:
9 **	AIX 3.2		OK
10 **	BSD family	OK
11 **	  BSD/OS 2.1	OK
12 **	  FreeBSD 2.1	OK
13 **	DEC OSF/1 3.0	OK
14 **	HP-UX 9.04	FAIL
15 **	HP-UX 9.05	FAIL
16 **	HP-UX 9.07	OK
17 **	HP-UX 10.01	OK
18 **	HP-UX 10.10	OK
19 **	HP-UX 10.20	OK
20 **	Irix 5.3	OK
21 **	Irix 6.2	OK
22 **	Irix 6.3	OK
23 **	Irix 6.4	OK
24 **	Linux		OK
25 **	NeXT 2.1	OK
26 **	Solaris 2.x	OK
27 **	SunOS 4.x	OK
28 **	Ultrix 4.3	OK
29 */
30 
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <stdio.h>
36 #include <unistd.h>
37 
38 #ifndef lint
39 static char id[] = "@(#)$Id: t_exclopen.c,v 8.5 1999/08/28 00:25:28 gshapiro Exp $";
40 #endif /* ! lint */
41 
42 static char Attacker[128];
43 static char Attackee[128];
44 
45 static void
46 bail(status)
47 	int status;
48 {
49 	(void) unlink(Attacker);
50 	(void) unlink(Attackee);
51 	exit(status);
52 }
53 
54 int
55 main(argc, argv)
56 	int argc;
57 	char **argv;
58 {
59 	struct stat st;
60 
61 	sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL));
62 	sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL));
63 
64 	if (symlink(Attackee, Attacker) < 0)
65 	{
66 		printf("Could not create %s->%s symlink: %d\n",
67 			Attacker, Attackee, errno);
68 		bail(1);
69 	}
70 	(void) unlink(Attackee);
71 	if (stat(Attackee, &st) >= 0)
72 	{
73 		printf("%s already exists -- remove and try again.\n",
74 			Attackee);
75 		bail(1);
76 	}
77 	if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0)
78 	{
79 		int save_errno = errno;
80 
81 		if (stat(Attackee, &st) >= 0)
82 		{
83 			printf("Weird.  Open failed but %s was created anyhow (errno = %d)\n",
84 				Attackee, save_errno);
85 			bail(1);
86 		}
87 		printf("Good show!  Exclusive open works properly with symbolic links (errno = %d).\n",
88 			save_errno);
89 		bail(0);
90 	}
91 	if (stat(Attackee, &st) < 0)
92 	{
93 		printf("Weird.  Open succeeded but %s was not created\n",
94 			Attackee);
95 		bail(2);
96 	}
97 	printf("Bad news: you can do an exclusive open through a symbolic link\n");
98 	printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n");
99 	bail(1);
100 
101 	/* NOTREACHED */
102 	exit(0);
103 }
104