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