ReactOS  0.4.14-dev-49-gfb4591c
main.c
Go to the documentation of this file.
1 /*
2  * Schannel tests
3  *
4  * Copyright 2006 Yuval Fledel
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include "ntstatus.h"
24 #define WIN32_NO_STATUS
25 #include <windef.h>
26 #include <winbase.h>
27 #define SECURITY_WIN32
28 #include <security.h>
29 #include <schannel.h>
30 #include <ntsecapi.h>
31 #include <ntsecpkg.h>
32 
33 #include "wine/test.h"
34 
35 /* Helper macros to find the size of SECPKG_FUNCTION_TABLE */
36 #define SECPKG_FUNCTION_TABLE_SIZE_1 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
37  SetContextAttributes)
38 #define SECPKG_FUNCTION_TABLE_SIZE_2 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
39  SetCredentialsAttributes)
40 #define SECPKG_FUNCTION_TABLE_SIZE_3 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
41  ChangeAccountPassword)
42 #define SECPKG_FUNCTION_TABLE_SIZE_4 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
43  QueryMetaData)
44 #define SECPKG_FUNCTION_TABLE_SIZE_5 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
45  ValidateTargetInfo)
46 #define SECPKG_FUNCTION_TABLE_SIZE_6 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
47  PostLogonUser)
48 #define SECPKG_FUNCTION_TABLE_SIZE_7 sizeof(SECPKG_FUNCTION_TABLE)
49 
50 #define LSA_BASE_CAPS ( \
51  SECPKG_FLAG_INTEGRITY | \
52  SECPKG_FLAG_PRIVACY | \
53  SECPKG_FLAG_CONNECTION | \
54  SECPKG_FLAG_MULTI_REQUIRED | \
55  SECPKG_FLAG_EXTENDED_ERROR | \
56  SECPKG_FLAG_IMPERSONATION | \
57  SECPKG_FLAG_ACCEPT_WIN32_NAME | \
58  SECPKG_FLAG_STREAM | \
59  SECPKG_FLAG_MUTUAL_AUTH )
60 
61 static NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG,
63 static NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG,
65 
66 static void testInitialize(void)
67 {
68  PSECPKG_USER_FUNCTION_TABLE pUserTables, pUserTables2;
69  PSECPKG_FUNCTION_TABLE pTables, pTables2;
70  ULONG cTables = 0, cUserTables = 0, Version = 0;
72 
73  /* Passing NULL into one of the parameters of SpLsaModeInitialize or
74  SpUserModeInitialize causes a crash. */
75 
76  /* SpLsaModeInitialize does not care about the LSA version. */
77  status = pSpLsaModeInitialize(0, &Version, &pTables2, &cTables);
78  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
79  ok(cTables == 2 ||
80  broken(cTables == 1), /* Win2k */
81  "cTables: %d\n", cTables);
82  ok(pTables2 != NULL,"pTables: %p\n", pTables2);
83 
84  /* We can call it as many times we want. */
85  status = pSpLsaModeInitialize(0x10000, &Version, &pTables, &cTables);
86  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
87  ok(cTables == 2 ||
88  broken(cTables == 1), /* Win2k */
89  "cTables: %d\n", cTables);
90  ok(pTables != NULL, "pTables: %p\n", pTables);
91  /* It will always return the same pointer. */
92  ok(pTables == pTables2, "pTables: %p, pTables2: %p\n", pTables, pTables2);
93 
94  status = pSpLsaModeInitialize(0x23456, &Version, &pTables, &cTables);
95  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
96  ok(cTables == 2 ||
97  broken(cTables == 1), /* Win2k */
98  "cTables: %d\n", cTables);
99  ok(pTables != NULL, "pTables: %p\n", pTables);
100  ok(pTables == pTables2, "pTables: %p, pTables2: %p\n", pTables, pTables2);
101 
102  /* Bad versions to SpUserModeInitialize. Parameters unchanged */
103  Version = 0xdead;
104  cUserTables = 0xdead;
105  pUserTables = NULL;
106  status = pSpUserModeInitialize(0, &Version, &pUserTables, &cUserTables);
107  ok(status == STATUS_INVALID_PARAMETER, "status: 0x%x\n", status);
108  ok(Version == 0xdead, "Version: 0x%x\n", Version);
109  ok(cUserTables == 0xdead, "cTables: %d\n", cUserTables);
110  ok(pUserTables == NULL, "pUserTables: %p\n", pUserTables);
111 
112  status = pSpUserModeInitialize(0x20000, &Version, &pUserTables,
113  &cUserTables);
114  ok(status == STATUS_INVALID_PARAMETER, "status: 0x%x\n", status);
115  ok(Version == 0xdead, "Version: 0x%x\n", Version);
116  ok(cUserTables == 0xdead, "cTables: %d\n", cUserTables);
117  ok(pUserTables == NULL, "pUserTables: %p\n", pUserTables);
118 
119  /* Good version to SpUserModeInitialize */
120  status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &Version,
121  &pUserTables, &cUserTables);
122  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
123  ok(Version == SECPKG_INTERFACE_VERSION, "Version: 0x%x\n", Version);
124  ok(cUserTables == 2 ||
125  broken(cUserTables == 4), /* Win2k */
126  "cUserTables: %d\n", cUserTables);
127  ok(pUserTables != NULL, "pUserTables: %p\n", pUserTables);
128 
129  /* Initializing user again */
130  status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &Version,
131  &pUserTables2, &cTables);
132  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
133  ok(pUserTables == pUserTables2, "pUserTables: %p, pUserTables2: %p\n",
134  pUserTables, pUserTables2);
135 }
136 
137 /* A helper function to find the dispatch table of the next package.
138  Needed because SECPKG_FUNCTION_TABLE's size depend on the version */
140  ULONG Version)
141 {
142  size_t size;
143  PSECPKG_FUNCTION_TABLE pNextTable;
144 
159  else {
160  ok(FALSE, "Unknown package version 0x%x\n", Version);
161  return NULL;
162  }
163 
164  pNextTable = (PSECPKG_FUNCTION_TABLE)((PBYTE)pTable + size);
165  /* Win7 function tables appear to be SECPKG_INTERFACE_VERSION_6 format,
166  but unfortunately SpLsaModeInitialize returns SECPKG_INTERFACE_VERSION_3.
167  We detect that by comparing the "Initialize" pointer from the old table
168  to the "FreeCredentialsHandle" pointer of the new table. These functions
169  have different numbers of arguments, so they can't possibly point to the
170  same implementation */
171  if (broken((void *) pTable->Initialize == (void *) pNextTable->FreeCredentialsHandle &&
172  pNextTable->FreeCredentialsHandle != NULL))
173  {
174  win_skip("Invalid function pointers for next package\n");
175  return NULL;
176  }
177 
178  return pNextTable;
179 }
180 
181 static void testGetInfo(void)
182 {
183  PSECPKG_FUNCTION_TABLE pTables;
184  SecPkgInfoW PackageInfo;
185  ULONG cTables, Version;
187 
188  /* Get the dispatch table */
189  status = pSpLsaModeInitialize(0, &Version, &pTables, &cTables);
190  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
191 
192  /* Passing NULL into ->GetInfo causes a crash. */
193 
194  /* First package: Unified */
195  status = pTables->GetInfo(&PackageInfo);
196  ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
197  ok(PackageInfo.fCapabilities == LSA_BASE_CAPS ||
199  "fCapabilities: 0x%x\n", PackageInfo.fCapabilities);
200  ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion);
201  ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID);
202  ok(PackageInfo.cbMaxToken == 0x4000 ||
203  PackageInfo.cbMaxToken == 0x6000, /* Vista */
204  "cbMaxToken: 0x%x\n",
205  PackageInfo.cbMaxToken);
206 
207  /* Second package */
208  if (cTables == 1)
209  {
210  win_skip("Second package missing\n");
211  return;
212  }
213  pTables = getNextSecPkgTable(pTables, Version);
214  if (!pTables)
215  return;
216  if (!pTables->GetInfo)
217  {
218  win_skip("GetInfo function missing\n");
219  return;
220  }
221  status = pTables->GetInfo(&PackageInfo);
222  ok(SUCCEEDED(status) ||
223  status == SEC_E_UNSUPPORTED_FUNCTION, /* win2k3 */
224  "status: 0x%x\n", status);
225 
226  if (SUCCEEDED(status))
227  {
228  ok(PackageInfo.fCapabilities == LSA_BASE_CAPS ||
230  "fCapabilities: 0x%x\n", PackageInfo.fCapabilities);
231  ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion);
232  ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID);
233  ok(PackageInfo.cbMaxToken == 0x4000 ||
234  PackageInfo.cbMaxToken == 0x6000, /* Win7 */
235  "cbMaxToken: 0x%x\n",
236  PackageInfo.cbMaxToken);
237  }
238 }
239 
241 {
242  HMODULE hMod = LoadLibraryA("schannel.dll");
243  if (!hMod) {
244  win_skip("schannel.dll not available\n");
245  return;
246  }
247 
248  pSpLsaModeInitialize = (void *)GetProcAddress(hMod, "SpLsaModeInitialize");
249  pSpUserModeInitialize = (void *)GetProcAddress(hMod, "SpUserModeInitialize");
250 
251  if (pSpLsaModeInitialize && pSpUserModeInitialize)
252  {
253  testInitialize();
254  testGetInfo();
255  }
256  else win_skip( "schannel functions not found\n" );
257 
258  FreeLibrary(hMod);
259 }
#define SECPKG_INTERFACE_VERSION_3
Definition: ntsecpkg.h:36
#define SECPKG_FUNCTION_TABLE_SIZE_5
Definition: main.c:44
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
unsigned short wVersion
Definition: sspi.h:102
START_TEST(main)
Definition: main.c:511
SpFreeCredentialsHandleFn * FreeCredentialsHandle
Definition: ntsecpkg.h:439
#define SECPKG_INTERFACE_VERSION_6
Definition: ntsecpkg.h:39
#define SEC_E_UNSUPPORTED_FUNCTION
Definition: winerror.h:2911
ULONG fCapabilities
Definition: sspi.h:101
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define SECPKG_INTERFACE_VERSION_2
Definition: ntsecpkg.h:35
ULONG cbMaxToken
Definition: sspi.h:104
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
smooth NULL
Definition: ftsmooth.c:416
unsigned short wRPCID
Definition: sspi.h:103
#define SECPKG_INTERFACE_VERSION
Definition: ntsecpkg.h:34
#define SECPKG_FUNCTION_TABLE_SIZE_7
Definition: main.c:48
#define SECPKG_FUNCTION_TABLE_SIZE_4
Definition: main.c:42
#define FreeLibrary(x)
Definition: compat.h:405
GLsizeiptr size
Definition: glext.h:5919
#define SECPKG_INTERFACE_VERSION_7
Definition: ntsecpkg.h:40
static PSecPkgInfoA *static SEC_CHAR ULONG
Definition: main.c:37
static void testGetInfo(void)
Definition: main.c:181
#define SECPKG_FUNCTION_TABLE_SIZE_2
Definition: main.c:38
static void testInitialize(void)
Definition: main.c:66
int main(int argc, const char *argv[])
Definition: main.c:122
static PSECPKG_FUNCTION_TABLE getNextSecPkgTable(PSECPKG_FUNCTION_TABLE pTable, ULONG Version)
Definition: main.c:139
#define SECPKG_FUNCTION_TABLE_SIZE_1
Definition: main.c:36
#define broken(x)
Definition: _sntprintf.h:21
struct _SECPKG_FUNCTION_TABLE * PSECPKG_FUNCTION_TABLE
#define ok(value,...)
Definition: atltest.h:57
SpGetInfoFn * GetInfo
Definition: ntsecpkg.h:435
#define SECPKG_FLAG_APPCONTAINER_PASSTHROUGH
Definition: sspi.h:135
unsigned int ULONG
Definition: retypes.h:1
static PULONG
Definition: main.c:61
#define SECPKG_FUNCTION_TABLE_SIZE_6
Definition: main.c:46
#define GetProcAddress(x, y)
Definition: compat.h:410
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
#define SECPKG_FUNCTION_TABLE_SIZE_3
Definition: main.c:40
#define LSA_BASE_CAPS
Definition: main.c:50
#define SECPKG_INTERFACE_VERSION_5
Definition: ntsecpkg.h:38
return STATUS_SUCCESS
Definition: btrfs.c:2966
static SERVICE_STATUS status
Definition: service.c:31
#define win_skip
Definition: test.h:141
BYTE * PBYTE
Definition: pedump.c:66
#define SUCCEEDED(hr)
Definition: intsafe.h:57
#define SECPKG_INTERFACE_VERSION_4
Definition: ntsecpkg.h:37
static NTSTATUS(NTAPI *pSpLsaModeInitialize)(ULONG
Definition: ps.c:97