1 /* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 // First include (the generated) my_config.h, to get correct platform defines.
24 #include "my_config.h"
25 #include <gtest/gtest.h>
26 #include "test_utils.h"
27
28 #include "my_global.h"
29 #include "named_pipe.h"
30 #include "log.h"
31 #include "my_thread.h"
32 #include <sddl.h>
33
34 namespace win_unittest {
35 using my_testing::Server_initializer;
36 using my_testing::Mock_error_handler;
37
38 class NamedPipeTest : public ::testing::Test
39 {
40 protected:
SetUpTestCase()41 static void SetUpTestCase()
42 {
43 m_old_error_handler_hook = error_handler_hook;
44 // Make sure my_error() ends up calling my_message_sql so that
45 // Mock_error_handler is actually triggered.
46 error_handler_hook = my_message_sql;
47 }
48
TearDownTestCase()49 static void TearDownTestCase()
50 {
51 error_handler_hook = m_old_error_handler_hook;
52 }
53
SetUp()54 virtual void SetUp()
55 {
56 m_initializer.SetUp();
57
58 char pipe_rand_name[256];
59
60 m_pipe_handle= INVALID_HANDLE_VALUE;
61
62 /*
63 Generate a Unique Pipe Name incase multiple instances of the test is run.
64 */
65 sprintf_s(pipe_rand_name, sizeof(pipe_rand_name), "Pipe-%x",
66 GetTickCount());
67
68 const ::testing::TestInfo* const test_info =
69 ::testing::UnitTest::GetInstance()->current_test_info();
70
71 m_name.append(pipe_rand_name);
72 m_name.append("gunit");
73 m_name.append(test_info->name());
74 }
75
TearDown()76 virtual void TearDown()
77 {
78 if (m_pipe_handle != INVALID_HANDLE_VALUE)
79 {
80 EXPECT_TRUE(CloseHandle(m_pipe_handle));
81 }
82 m_initializer.TearDown();
83 }
84
85 SECURITY_ATTRIBUTES *mp_sec_attr;
86 char m_pipe_name[256];
87 HANDLE m_pipe_handle;
88 std::string m_name;
89 Server_initializer m_initializer;
90
91 static void(*m_old_error_handler_hook)(uint, const char *, myf);
92 };
93 void(*NamedPipeTest::m_old_error_handler_hook)(uint, const char *, myf);
94
95
96 // Basic test: create a named pipe.
TEST_F(NamedPipeTest,CreatePipe)97 TEST_F(NamedPipeTest, CreatePipe)
98 {
99 char exp_pipe_name[256];
100
101 m_pipe_handle= create_server_named_pipe(&mp_sec_attr,
102 1024,
103 m_name.c_str(),
104 m_pipe_name,
105 sizeof(m_pipe_name));
106
107 strxnmov(exp_pipe_name, sizeof(exp_pipe_name) - 1, "\\\\.\\pipe\\",
108 m_name.c_str(), NullS);
109
110 EXPECT_STREQ(m_pipe_name, exp_pipe_name);
111 EXPECT_NE(INVALID_HANDLE_VALUE, m_pipe_handle);
112 }
113
114
115 // Verify that we fail if we try to create the same named pipe twice.
TEST_F(NamedPipeTest,CreatePipeTwice)116 TEST_F(NamedPipeTest, CreatePipeTwice)
117 {
118 m_pipe_handle= create_server_named_pipe(&mp_sec_attr,
119 1024,
120 m_name.c_str(),
121 m_pipe_name,
122 sizeof(m_pipe_name));
123 EXPECT_NE(INVALID_HANDLE_VALUE, m_pipe_handle);
124
125 Mock_error_handler error_handler(m_initializer.thd(),
126 ER_CANT_START_SERVER_NAMED_PIPE);
127 HANDLE handle= create_server_named_pipe(&mp_sec_attr,
128 1024,
129 m_name.c_str(),
130 m_pipe_name,
131 sizeof(m_pipe_name));
132 EXPECT_EQ(INVALID_HANDLE_VALUE, handle);
133 }
134
135 // Verify that a warning is written to the error log when using
136 // "*everyone* as the full access group name.
TEST_F(NamedPipeTest,CreatePipeForEveryone)137 TEST_F(NamedPipeTest, CreatePipeForEveryone)
138 {
139 Mock_error_handler error_handler(m_initializer.thd(),
140 WARN_NAMED_PIPE_ACCESS_EVERYONE);
141 m_pipe_handle = create_server_named_pipe(&mp_sec_attr,
142 1024,
143 m_name.c_str(),
144 m_pipe_name,
145 sizeof(m_pipe_name),
146 "*everyone*");
147 EXPECT_NE(INVALID_HANDLE_VALUE, m_pipe_handle);
148 }
149
150 // Verify that a warning is written to the error log when using
151 // the group name corresponding to the built in Windows group
152 // with SID S-1-1-0 (i.e. "everyone" on English systems)
TEST_F(NamedPipeTest,CreatePipeForEveryoneSid)153 TEST_F(NamedPipeTest, CreatePipeForEveryoneSid)
154 {
155 PSID everyone_SID;
156 EXPECT_TRUE(ConvertStringSidToSid("S-1-1-0", &everyone_SID));
157 const DWORD max_name_len = 256;
158 char everyone_name[max_name_len];
159 DWORD everyone_name_size = max_name_len;
160 char domain_name[max_name_len];
161 DWORD domain_name_size = max_name_len;
162 SID_NAME_USE name_use;
163
164 EXPECT_TRUE(LookupAccountSid(NULL, everyone_SID, everyone_name, &everyone_name_size,
165 domain_name, &domain_name_size, &name_use));
166 // The "S-1-1-0" SID is well known, so we expect the domain_name to empty and
167 // the name_use to be SidTypeWellKnownGroup
168 EXPECT_EQ(domain_name_size, 0);
169 EXPECT_EQ(name_use, SidTypeWellKnownGroup);
170
171 Mock_error_handler error_handler(m_initializer.thd(),
172 WARN_NAMED_PIPE_ACCESS_EVERYONE);
173 m_pipe_handle = create_server_named_pipe(&mp_sec_attr,
174 1024,
175 m_name.c_str(),
176 m_pipe_name,
177 sizeof(m_pipe_name),
178 everyone_name);
179 EXPECT_NE(INVALID_HANDLE_VALUE, m_pipe_handle);
180 }
181
182 }
183