xref: /freebsd/contrib/sendmail/test/t_exclopen.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
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 <stdio.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 
37 char Attacker[128];
38 char Attackee[128];
39 
40 main(argc, argv)
41 	int argc;
42 	char **argv;
43 {
44 	struct stat st;
45 
46 	sprintf(Attacker, "/tmp/attacker.%d.%ld", getpid(), time(NULL));
47 	sprintf(Attackee, "/tmp/attackee.%d.%ld", getpid(), time(NULL));
48 
49 	if (symlink(Attackee, Attacker) < 0)
50 	{
51 		printf("Could not create %s->%s symlink: %d\n",
52 			Attacker, Attackee, errno);
53 		bail(1);
54 	}
55 	(void) unlink(Attackee);
56 	if (stat(Attackee, &st) >= 0)
57 	{
58 		printf("%s already exists -- remove and try again.\n",
59 			Attackee);
60 		bail(1);
61 	}
62 	if (open(Attacker, O_WRONLY|O_CREAT|O_EXCL, 0644) < 0)
63 	{
64 		int saveerr = errno;
65 
66 		if (stat(Attackee, &st) >= 0)
67 		{
68 			printf("Weird.  Open failed but %s was created anyhow (errno = %d)\n",
69 				Attackee, saveerr);
70 			bail(1);
71 		}
72 		printf("Good show!  Exclusive open works properly with symbolic links (errno = %d).\n",
73 			saveerr);
74 		bail(0);
75 	}
76 	if (stat(Attackee, &st) < 0)
77 	{
78 		printf("Weird.  Open succeeded but %s was not created\n",
79 			Attackee);
80 		bail(2);
81 	}
82 	printf("Bad news: you can do an exclusive open through a symbolic link\n");
83 	printf("\tBe sure you #define BOGUS_O_EXCL in conf.h\n");
84 	bail(1);
85 }
86 
87 bail(stat)
88 	int stat;
89 {
90 	(void) unlink(Attacker);
91 	(void) unlink(Attackee);
92 	exit(stat);
93 }
94