cscript: Correct forming cmd for forwarding to wscript.
[wine] / dlls / schannel / tests / main.c
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 sizeof(SECPKG_FUNCTION_TABLE)
47
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 )
58
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);
63
64 static void testInitialize(void)
65 {
66     PSECPKG_USER_FUNCTION_TABLE pUserTables, pUserTables2;
67     PSECPKG_FUNCTION_TABLE pTables, pTables2;
68     ULONG cTables = 0, cUserTables = 0, Version = 0;
69     NTSTATUS status;
70
71     /* Passing NULL into one of the parameters of SpLsaModeInitialize or
72        SpUserModeInitialize causes a crash. */
73
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);
77     ok(cTables == 2 ||
78        broken(cTables == 1), /* Win2k */
79        "cTables: %d\n", cTables);
80     ok(pTables2 != NULL,"pTables: %p\n", pTables2);
81
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);
85     ok(cTables == 2 ||
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);
91
92     status = pSpLsaModeInitialize(0x23456, &Version, &pTables, &cTables);
93     ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
94     ok(cTables == 2 ||
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);
99
100     /* Bad versions to SpUserModeInitialize. Parameters unchanged */
101     Version = 0xdead;
102     cUserTables = 0xdead;
103     pUserTables = NULL;
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);
109
110     status = pSpUserModeInitialize(0x20000, &Version, &pUserTables,
111                                    &cUserTables);
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);
116
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);
126
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);
133 }
134
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,
138                                                  ULONG Version)
139 {
140     size_t size;
141     PSECPKG_FUNCTION_TABLE pNextTable;
142
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;
155     else {
156         ok(FALSE, "Unknown package version 0x%x\n", Version);
157         return NULL;
158     }
159
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))
169     {
170         win_skip("Invalid function pointers for next package\n");
171         return NULL;
172     }
173
174     return pNextTable;
175 }
176
177 static void testGetInfo(void)
178 {
179     PSECPKG_FUNCTION_TABLE pTables;
180     SecPkgInfoW PackageInfo;
181     ULONG cTables, Version;
182     NTSTATUS status;
183
184     /* Get the dispatch table */
185     status = pSpLsaModeInitialize(0, &Version, &pTables, &cTables);
186     ok(status == STATUS_SUCCESS, "status: 0x%x\n", status);
187
188     /* Passing NULL into ->GetInfo causes a crash. */
189
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);
202
203     /* Second package */
204     if (cTables == 1)
205     {
206         win_skip("Second package missing\n");
207         return;
208     }
209     pTables = getNextSecPkgTable(pTables, Version);
210     if (!pTables)
211         return;
212     status = pTables->GetInfo(&PackageInfo);
213     ok(status == STATUS_SUCCESS ||
214        status == SEC_E_UNSUPPORTED_FUNCTION, /* win2k3 */
215        "status: 0x%x\n", status);
216
217     if (status == STATUS_SUCCESS)
218     {
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);
227     }
228 }
229
230 START_TEST(main)
231 {
232     HMODULE hMod = LoadLibraryA("schannel.dll");
233     if (!hMod) {
234         win_skip("schannel.dll not available\n");
235         return;
236     }
237
238     pSpLsaModeInitialize  = (void *)GetProcAddress(hMod, "SpLsaModeInitialize");
239     pSpUserModeInitialize = (void *)GetProcAddress(hMod, "SpUserModeInitialize");
240
241     if (pSpLsaModeInitialize && pSpUserModeInitialize)
242     {
243         testInitialize();
244         testGetInfo();
245     }
246     else win_skip( "schannel functions not found\n" );
247
248     FreeLibrary(hMod);
249 }