4 * Copyright 2006 Yuval Fledel
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.
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.
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
24 #define WIN32_NO_STATUS
27 #define SECURITY_WIN32
33 #include "wine/test.h"
35 /* Helper macros to find the size of SECPKG_FUNCTION_TABLE */
36 #define SECPKG_FUNCTION_TABLE_SIZE_1 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
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, \
44 #define SECPKG_FUNCTION_TABLE_SIZE_5 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
46 #define SECPKG_FUNCTION_TABLE_SIZE_6 sizeof(SECPKG_FUNCTION_TABLE)
48 #define LSA_BASE_CAPS ( \
49 SECPKG_FLAG_INTEGRITY | \
50 SECPKG_FLAG_PRIVACY | \
51 SECPKG_FLAG_CONNECTION | \
52 SECPKG_FLAG_MULTI_REQUIRED | \
53 SECPKG_FLAG_EXTENDED_ERROR | \
54 SECPKG_FLAG_IMPERSONATION | \
55 SECPKG_FLAG_ACCEPT_WIN32_NAME | \
56 SECPKG_FLAG_STREAM | \
57 SECPKG_FLAG_MUTUAL_AUTH )
59 static NTSTATUS (NTAPI *pSpLsaModeInitialize)(ULONG, PULONG,
60 PSECPKG_FUNCTION_TABLE*, PULONG);
61 static NTSTATUS (NTAPI *pSpUserModeInitialize)(ULONG, PULONG,
62 PSECPKG_USER_FUNCTION_TABLE*, PULONG);
64 static void testInitialize(void)
66 PSECPKG_USER_FUNCTION_TABLE pUserTables, pUserTables2;
67 PSECPKG_FUNCTION_TABLE pTables, pTables2;
68 ULONG cTables = 0, cUserTables = 0, Version = 0;
71 /* Passing NULL into one of the parameters of SpLsaModeInitialize or
72 SpUserModeInitialize causes a crash. */
74 /* SpLsaModeInitialize does not care about the LSA version. */
75 status = pSpLsaModeInitialize(0, &Version, &pTables2, &cTables);
76 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
78 broken(cTables == 1), /* Win2k */
79 "cTables: %d\n", cTables);
80 ok(pTables2 != NULL,"pTables: %p\n", pTables2);
82 /* We can call it as many times we want. */
83 status = pSpLsaModeInitialize(0x10000, &Version, &pTables, &cTables);
84 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
86 broken(cTables == 1), /* Win2k */
87 "cTables: %d\n", cTables);
88 ok(pTables != NULL, "pTables: %p\n", pTables);
89 /* It will always return the same pointer. */
90 ok(pTables == pTables2, "pTables: %p, pTables2: %p\n", pTables, pTables2);
92 status = pSpLsaModeInitialize(0x23456, &Version, &pTables, &cTables);
93 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
95 broken(cTables == 1), /* Win2k */
96 "cTables: %d\n", cTables);
97 ok(pTables != NULL, "pTables: %p\n", pTables);
98 ok(pTables == pTables2, "pTables: %p, pTables2: %p\n", pTables, pTables2);
100 /* Bad versions to SpUserModeInitialize. Parameters unchanged */
102 cUserTables = 0xdead;
104 status = pSpUserModeInitialize(0, &Version, &pUserTables, &cUserTables);
105 ok(status == STATUS_INVALID_PARAMETER, "status: 0x%x\n", status);
106 ok(Version == 0xdead, "Version: 0x%x\n", Version);
107 ok(cUserTables == 0xdead, "cTables: %d\n", cUserTables);
108 ok(pUserTables == NULL, "pUserTables: %p\n", pUserTables);
110 status = pSpUserModeInitialize(0x20000, &Version, &pUserTables,
112 ok(status == STATUS_INVALID_PARAMETER, "status: 0x%x\n", status);
113 ok(Version == 0xdead, "Version: 0x%x\n", Version);
114 ok(cUserTables == 0xdead, "cTables: %d\n", cUserTables);
115 ok(pUserTables == NULL, "pUserTables: %p\n", pUserTables);
117 /* Good version to SpUserModeInitialize */
118 status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &Version,
119 &pUserTables, &cUserTables);
120 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
121 ok(Version == SECPKG_INTERFACE_VERSION, "Version: 0x%x\n", Version);
122 ok(cUserTables == 2 ||
123 broken(cUserTables == 4), /* Win2k */
124 "cUserTables: %d\n", cUserTables);
125 ok(pUserTables != NULL, "pUserTables: %p\n", pUserTables);
127 /* Initializing user again */
128 status = pSpUserModeInitialize(SECPKG_INTERFACE_VERSION, &Version,
129 &pUserTables2, &cTables);
130 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
131 ok(pUserTables == pUserTables2, "pUserTables: %p, pUserTables2: %p\n",
132 pUserTables, pUserTables2);
135 /* A helper function to find the dispatch table of the next package.
136 Needed because SECPKG_FUNCTION_TABLE's size depend on the version */
137 static PSECPKG_FUNCTION_TABLE getNextSecPkgTable(PSECPKG_FUNCTION_TABLE pTable,
141 PSECPKG_FUNCTION_TABLE pNextTable;
143 if (Version == SECPKG_INTERFACE_VERSION)
144 size = SECPKG_FUNCTION_TABLE_SIZE_1;
145 else if (Version == SECPKG_INTERFACE_VERSION_2)
146 size = SECPKG_FUNCTION_TABLE_SIZE_2;
147 else if (Version == SECPKG_INTERFACE_VERSION_3)
148 size = SECPKG_FUNCTION_TABLE_SIZE_3;
149 else if (Version == SECPKG_INTERFACE_VERSION_4)
150 size = SECPKG_FUNCTION_TABLE_SIZE_4;
151 else if (Version == SECPKG_INTERFACE_VERSION_5)
152 size = SECPKG_FUNCTION_TABLE_SIZE_5;
153 else if (Version == SECPKG_INTERFACE_VERSION_6)
154 size = SECPKG_FUNCTION_TABLE_SIZE_6;
156 ok(FALSE, "Unknown package version 0x%x\n", Version);
160 pNextTable = (PSECPKG_FUNCTION_TABLE)((PBYTE)pTable + size);
161 /* Win7 function tables appear to be SECPKG_INTERFACE_VERSION_6 format,
162 but unfortunately SpLsaModeInitialize returns SECPKG_INTERFACE_VERSION_3.
163 We detect that by comparing the "Initialize" pointer from the old table
164 to the "FreeCredentialsHandle" pointer of the new table. These functions
165 have different numbers of arguments, so they can't possibly point to the
166 same implementation */
167 if (broken((void *) pTable->Initialize == (void *) pNextTable->FreeCredentialsHandle &&
168 pNextTable->FreeCredentialsHandle != NULL))
170 win_skip("Invalid function pointers for next package\n");
177 static void testGetInfo(void)
179 PSECPKG_FUNCTION_TABLE pTables;
180 SecPkgInfoW PackageInfo;
181 ULONG cTables, Version;
184 /* Get the dispatch table */
185 status = pSpLsaModeInitialize(0, &Version, &pTables, &cTables);
186 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
188 /* Passing NULL into ->GetInfo causes a crash. */
190 /* First package: Unified */
191 status = pTables->GetInfo(&PackageInfo);
192 ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
193 ok(PackageInfo.fCapabilities == LSA_BASE_CAPS ||
194 PackageInfo.fCapabilities == (LSA_BASE_CAPS|SECPKG_FLAG_APPCONTAINER_PASSTHROUGH),
195 "fCapabilities: 0x%x\n", PackageInfo.fCapabilities);
196 ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion);
197 ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID);
198 ok(PackageInfo.cbMaxToken == 0x4000 ||
199 PackageInfo.cbMaxToken == 0x6000, /* Vista */
200 "cbMaxToken: 0x%x\n",
201 PackageInfo.cbMaxToken);
206 win_skip("Second package missing\n");
209 pTables = getNextSecPkgTable(pTables, Version);
212 status = pTables->GetInfo(&PackageInfo);
213 ok(status == STATUS_SUCCESS ||
214 status == SEC_E_UNSUPPORTED_FUNCTION, /* win2k3 */
215 "status: 0x%x\n", status);
217 if (status == STATUS_SUCCESS)
219 ok(PackageInfo.fCapabilities == LSA_BASE_CAPS, "fCapabilities: 0x%x\n",
220 PackageInfo.fCapabilities);
221 ok(PackageInfo.wVersion == 1, "wVersion: %d\n", PackageInfo.wVersion);
222 ok(PackageInfo.wRPCID == 14, "wRPCID: %d\n", PackageInfo.wRPCID);
223 ok(PackageInfo.cbMaxToken == 0x4000 ||
224 PackageInfo.cbMaxToken == 0x6000, /* Win7 */
225 "cbMaxToken: 0x%x\n",
226 PackageInfo.cbMaxToken);
232 HMODULE hMod = LoadLibraryA("schannel.dll");
234 win_skip("schannel.dll not available\n");
238 pSpLsaModeInitialize = (void *)GetProcAddress(hMod, "SpLsaModeInitialize");
239 pSpUserModeInitialize = (void *)GetProcAddress(hMod, "SpUserModeInitialize");
241 if (pSpLsaModeInitialize && pSpUserModeInitialize)
246 else win_skip( "schannel functions not found\n" );