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 FIELD_OFFSET(SECPKG_FUNCTION_TABLE, \
48 #define SECPKG_FUNCTION_TABLE_SIZE_7 sizeof(SECPKG_FUNCTION_TABLE)
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 )
61 static NTSTATUS (NTAPI
*pSpLsaModeInitialize
)(ULONG
, PULONG
,
62 PSECPKG_FUNCTION_TABLE
*, PULONG
);
63 static NTSTATUS (NTAPI
*pSpUserModeInitialize
)(ULONG
, PULONG
,
64 PSECPKG_USER_FUNCTION_TABLE
*, PULONG
);
66 static void testInitialize(void)
68 PSECPKG_USER_FUNCTION_TABLE pUserTables
, pUserTables2
;
69 PSECPKG_FUNCTION_TABLE pTables
, pTables2
;
70 ULONG cTables
= 0, cUserTables
= 0, Version
= 0;
73 /* Passing NULL into one of the parameters of SpLsaModeInitialize or
74 SpUserModeInitialize causes a crash. */
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
);
80 broken(cTables
== 1), /* Win2k */
81 "cTables: %d\n", cTables
);
82 ok(pTables2
!= NULL
,"pTables: %p\n", pTables2
);
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
);
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
);
94 status
= pSpLsaModeInitialize(0x23456, &Version
, &pTables
, &cTables
);
95 ok(status
== STATUS_SUCCESS
, "status: 0x%x\n", status
);
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
);
102 /* Bad versions to SpUserModeInitialize. Parameters unchanged */
104 cUserTables
= 0xdead;
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
);
112 status
= pSpUserModeInitialize(0x20000, &Version
, &pUserTables
,
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
);
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
);
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
);
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 */
139 static PSECPKG_FUNCTION_TABLE
getNextSecPkgTable(PSECPKG_FUNCTION_TABLE pTable
,
143 PSECPKG_FUNCTION_TABLE pNextTable
;
145 if (Version
== SECPKG_INTERFACE_VERSION
)
146 size
= SECPKG_FUNCTION_TABLE_SIZE_1
;
147 else if (Version
== SECPKG_INTERFACE_VERSION_2
)
148 size
= SECPKG_FUNCTION_TABLE_SIZE_2
;
149 else if (Version
== SECPKG_INTERFACE_VERSION_3
)
150 size
= SECPKG_FUNCTION_TABLE_SIZE_3
;
151 else if (Version
== SECPKG_INTERFACE_VERSION_4
)
152 size
= SECPKG_FUNCTION_TABLE_SIZE_4
;
153 else if (Version
== SECPKG_INTERFACE_VERSION_5
)
154 size
= SECPKG_FUNCTION_TABLE_SIZE_5
;
155 else if (Version
== SECPKG_INTERFACE_VERSION_6
)
156 size
= SECPKG_FUNCTION_TABLE_SIZE_6
;
157 else if (Version
== SECPKG_INTERFACE_VERSION_7
)
158 size
= SECPKG_FUNCTION_TABLE_SIZE_7
;
160 ok(FALSE
, "Unknown package version 0x%x\n", Version
);
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
))
174 win_skip("Invalid function pointers for next package\n");
181 static void testGetInfo(void)
183 PSECPKG_FUNCTION_TABLE pTables
;
184 SecPkgInfoW PackageInfo
;
185 ULONG cTables
, Version
;
188 /* Get the dispatch table */
189 status
= pSpLsaModeInitialize(0, &Version
, &pTables
, &cTables
);
190 ok(status
== STATUS_SUCCESS
, "status: 0x%x\n", status
);
192 /* Passing NULL into ->GetInfo causes a crash. */
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
||
198 PackageInfo
.fCapabilities
== (LSA_BASE_CAPS
|SECPKG_FLAG_APPCONTAINER_PASSTHROUGH
),
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
);
210 win_skip("Second package missing\n");
213 pTables
= getNextSecPkgTable(pTables
, Version
);
216 if (!pTables
->GetInfo
)
218 win_skip("GetInfo function missing\n");
221 status
= pTables
->GetInfo(&PackageInfo
);
222 ok(SUCCEEDED(status
) ||
223 status
== SEC_E_UNSUPPORTED_FUNCTION
, /* win2k3 */
224 "status: 0x%x\n", status
);
226 if (SUCCEEDED(status
))
228 ok(PackageInfo
.fCapabilities
== LSA_BASE_CAPS
||
229 PackageInfo
.fCapabilities
== (LSA_BASE_CAPS
|SECPKG_FLAG_APPCONTAINER_PASSTHROUGH
),
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
);
242 HMODULE hMod
= LoadLibraryA("schannel.dll");
244 win_skip("schannel.dll not available\n");
248 pSpLsaModeInitialize
= (void *)GetProcAddress(hMod
, "SpLsaModeInitialize");
249 pSpUserModeInitialize
= (void *)GetProcAddress(hMod
, "SpUserModeInitialize");
251 if (pSpLsaModeInitialize
&& pSpUserModeInitialize
)
256 else win_skip( "schannel functions not found\n" );