4 * Copyright 2006 Robert Reif
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
27 #define SECURITY_WIN32
31 #include "wine/test.h"
33 static HMODULE secdll
;
35 static SECURITY_STATUS (SEC_ENTRY
*pSspiEncodeAuthIdentityAsStrings
)
36 (PSEC_WINNT_AUTH_IDENTITY_OPAQUE
, PCWSTR
*, PCWSTR
*, PCWSTR
*);
37 static SECURITY_STATUS (SEC_ENTRY
*pSspiEncodeStringsAsAuthIdentity
)
38 (PCWSTR
, PCWSTR
, PCWSTR
, PSEC_WINNT_AUTH_IDENTITY_OPAQUE
*);
39 static void (SEC_ENTRY
*pSspiFreeAuthIdentity
)
40 (PSEC_WINNT_AUTH_IDENTITY_OPAQUE
);
41 static void (SEC_ENTRY
*pSspiLocalFree
)
43 static void (SEC_ENTRY
*pSspiZeroAuthIdentity
)
44 (PSEC_WINNT_AUTH_IDENTITY_OPAQUE
);
46 static BOOLEAN (WINAPI
* pGetComputerObjectNameA
)(EXTENDED_NAME_FORMAT NameFormat
, LPSTR lpNameBuffer
, PULONG lpnSize
);
47 static BOOLEAN (WINAPI
* pGetComputerObjectNameW
)(EXTENDED_NAME_FORMAT NameFormat
, LPWSTR lpNameBuffer
, PULONG lpnSize
);
48 static BOOLEAN (WINAPI
* pGetUserNameExA
)(EXTENDED_NAME_FORMAT NameFormat
, LPSTR lpNameBuffer
, PULONG lpnSize
);
49 static BOOLEAN (WINAPI
* pGetUserNameExW
)(EXTENDED_NAME_FORMAT NameFormat
, LPWSTR lpNameBuffer
, PULONG lpnSize
);
50 static PSecurityFunctionTableA (SEC_ENTRY
* pInitSecurityInterfaceA
)(void);
51 static PSecurityFunctionTableW (SEC_ENTRY
* pInitSecurityInterfaceW
)(void);
53 static EXTENDED_NAME_FORMAT formats
[] = {
54 NameUnknown
, NameFullyQualifiedDN
, NameSamCompatible
, NameDisplay
,
55 NameUniqueId
, NameCanonical
, NameUserPrincipal
, NameCanonicalEx
,
56 NameServicePrincipal
, NameDnsDomain
59 static void testGetComputerObjectNameA(void)
66 for (i
= 0; i
< (sizeof(formats
) / sizeof(formats
[0])); i
++) {
68 ZeroMemory(name
, sizeof(name
));
69 rc
= pGetComputerObjectNameA(formats
[i
], name
, &size
);
70 ok(rc
|| ((formats
[i
] == NameUnknown
) &&
71 (GetLastError() == ERROR_INVALID_PARAMETER
)) ||
72 (GetLastError() == ERROR_CANT_ACCESS_DOMAIN_INFO
) ||
73 (GetLastError() == ERROR_NO_SUCH_DOMAIN
) ||
74 (GetLastError() == ERROR_NO_SUCH_USER
) ||
75 (GetLastError() == ERROR_NONE_MAPPED
) ||
76 (GetLastError() == ERROR_ACCESS_DENIED
),
77 "GetComputerObjectNameA(%d) failed: %d\n",
78 formats
[i
], GetLastError());
80 trace("GetComputerObjectNameA() returned %s\n", name
);
84 static void testGetComputerObjectNameW(void)
91 for (i
= 0; i
< (sizeof(formats
) / sizeof(formats
[0])); i
++) {
92 size
= sizeof(nameW
)/sizeof(nameW
[0]);
93 ZeroMemory(nameW
, sizeof(nameW
));
94 rc
= pGetComputerObjectNameW(formats
[i
], nameW
, &size
);
95 ok(rc
|| ((formats
[i
] == NameUnknown
) &&
96 (GetLastError() == ERROR_INVALID_PARAMETER
)) ||
97 (GetLastError() == ERROR_CANT_ACCESS_DOMAIN_INFO
) ||
98 (GetLastError() == ERROR_NO_SUCH_DOMAIN
) ||
99 (GetLastError() == ERROR_NO_SUCH_USER
) ||
100 (GetLastError() == ERROR_NONE_MAPPED
) ||
101 (GetLastError() == ERROR_ACCESS_DENIED
),
102 "GetComputerObjectNameW(%d) failed: %d\n",
103 formats
[i
], GetLastError());
106 WideCharToMultiByte( CP_ACP
, 0, nameW
, -1, name
, sizeof(name
), NULL
, NULL
);
107 trace("GetComputerObjectNameW() returned %s\n", name
);
112 static void testGetUserNameExA(void)
119 for (i
= 0; i
< (sizeof(formats
) / sizeof(formats
[0])); i
++) {
121 ZeroMemory(name
, sizeof(name
));
122 rc
= pGetUserNameExA(formats
[i
], name
, &size
);
124 (formats
[i
] == NameUnknown
&&
125 GetLastError() == ERROR_NO_SUCH_USER
) ||
126 GetLastError() == ERROR_NONE_MAPPED
||
127 broken(formats
[i
] == NameDnsDomain
&&
128 GetLastError() == ERROR_INVALID_PARAMETER
),
129 "GetUserNameExW(%d) failed: %d\n",
130 formats
[i
], GetLastError());
133 if (0) /* Crashes on Windows */
134 pGetUserNameExA(NameSamCompatible
, NULL
, NULL
);
137 rc
= pGetUserNameExA(NameSamCompatible
, NULL
, &size
);
138 ok(! rc
&& GetLastError() == ERROR_MORE_DATA
, "Expected fail with ERROR_MORE_DATA, got %d with %u\n", rc
, GetLastError());
139 ok(size
!= 0, "Expected size to be set to required size\n");
141 if (0) /* Crashes on Windows with big enough size */
143 /* Returned size is already big enough */
144 pGetUserNameExA(NameSamCompatible
, NULL
, &size
);
148 rc
= pGetUserNameExA(NameSamCompatible
, name
, &size
);
149 ok(! rc
&& GetLastError() == ERROR_MORE_DATA
, "Expected fail with ERROR_MORE_DATA, got %d with %u\n", rc
, GetLastError());
150 ok(size
!= 0, "Expected size to be set to required size\n");
153 rc
= pGetUserNameExA(NameSamCompatible
, name
, &size
);
154 ok(! rc
&& GetLastError() == ERROR_MORE_DATA
, "Expected fail with ERROR_MORE_DATA, got %d with %u\n", rc
, GetLastError());
155 ok(1 < size
, "Expected size to be set to required size\n");
156 ok(name
[0] == (char) 0xff, "Expected unchanged buffer\n");
159 static void testGetUserNameExW(void)
166 for (i
= 0; i
< (sizeof(formats
) / sizeof(formats
[0])); i
++) {
167 size
= sizeof(nameW
);
168 ZeroMemory(nameW
, sizeof(nameW
));
169 rc
= pGetUserNameExW(formats
[i
], nameW
, &size
);
171 (formats
[i
] == NameUnknown
&&
172 GetLastError() == ERROR_NO_SUCH_USER
) ||
173 GetLastError() == ERROR_NONE_MAPPED
||
174 broken(formats
[i
] == NameDnsDomain
&&
175 GetLastError() == ERROR_INVALID_PARAMETER
),
176 "GetUserNameExW(%d) failed: %d\n",
177 formats
[i
], GetLastError());
180 if (0) /* Crashes on Windows */
181 pGetUserNameExW(NameSamCompatible
, NULL
, NULL
);
184 rc
= pGetUserNameExW(NameSamCompatible
, NULL
, &size
);
185 ok(! rc
&& GetLastError() == ERROR_MORE_DATA
, "Expected fail with ERROR_MORE_DATA, got %d with %u\n", rc
, GetLastError());
186 ok(size
!= 0, "Expected size to be set to required size\n");
188 if (0) /* Crashes on Windows with big enough size */
190 /* Returned size is already big enough */
191 pGetUserNameExW(NameSamCompatible
, NULL
, &size
);
195 rc
= pGetUserNameExW(NameSamCompatible
, nameW
, &size
);
196 ok(! rc
&& GetLastError() == ERROR_MORE_DATA
, "Expected fail with ERROR_MORE_DATA, got %d with %u\n", rc
, GetLastError());
197 ok(size
!= 0, "Expected size to be set to required size\n");
200 rc
= pGetUserNameExW(NameSamCompatible
, nameW
, &size
);
201 ok(! rc
&& GetLastError() == ERROR_MORE_DATA
, "Expected fail with ERROR_MORE_DATA, got %d with %u\n", rc
, GetLastError());
202 ok(1 < size
, "Expected size to be set to required size\n");
203 ok(nameW
[0] == (WCHAR
) 0xff, "Expected unchanged buffer\n");
206 static void test_InitSecurityInterface(void)
208 PSecurityFunctionTableA sftA
;
209 PSecurityFunctionTableW sftW
;
211 sftA
= pInitSecurityInterfaceA();
212 ok(sftA
!= NULL
, "pInitSecurityInterfaceA failed\n");
213 ok(sftA
->dwVersion
== SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION
, "wrong dwVersion %d in security function table\n", sftA
->dwVersion
);
215 "Reserved2 should be NULL instead of %p in security function table\n",
217 ok(sftA
->Reserved3
== sftA
->EncryptMessage
,
218 "Reserved3 should be equal to EncryptMessage in the security function table\n");
219 ok(sftA
->Reserved4
== sftA
->DecryptMessage
,
220 "Reserved4 should be equal to DecryptMessage in the security function table\n");
222 if (!pInitSecurityInterfaceW
)
224 win_skip("InitSecurityInterfaceW not exported by secur32.dll\n");
228 sftW
= pInitSecurityInterfaceW();
229 ok(sftW
!= NULL
, "pInitSecurityInterfaceW failed\n");
230 ok(sftW
->dwVersion
== SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION
, "wrong dwVersion %d in security function table\n", sftW
->dwVersion
);
231 ok(!sftW
->Reserved2
, "Reserved2 should be NULL instead of %p in security function table\n", sftW
->Reserved2
);
232 ok(sftW
->Reserved3
== sftW
->EncryptMessage
, "Reserved3 should be equal to EncryptMessage in the security function table\n");
233 ok(sftW
->Reserved4
== sftW
->DecryptMessage
, "Reserved4 should be equal to DecryptMessage in the security function table\n");
236 static void test_SspiEncodeStringsAsAuthIdentity(void)
238 static const WCHAR username
[] = {'u','s','e','r','n','a','m','e',0};
239 static const WCHAR domainname
[] = {'d','o','m','a','i','n','n','a','m','e',0};
240 static const WCHAR password
[] = {'p','a','s','s','w','o','r','d',0};
241 const WCHAR
*username_ptr
, *domainname_ptr
, *password_ptr
;
242 PSEC_WINNT_AUTH_IDENTITY_OPAQUE id
;
243 SECURITY_STATUS status
;
245 if (!pSspiEncodeStringsAsAuthIdentity
)
247 win_skip( "SspiEncodeAuthIdentityAsStrings not exported by secur32.dll\n" );
251 status
= pSspiEncodeStringsAsAuthIdentity( NULL
, NULL
, NULL
, NULL
);
252 ok( status
== SEC_E_INVALID_TOKEN
, "got %08x\n", status
);
254 id
= (PSEC_WINNT_AUTH_IDENTITY_OPAQUE
)0xdeadbeef;
255 status
= pSspiEncodeStringsAsAuthIdentity( NULL
, NULL
, NULL
, &id
);
256 ok( status
== SEC_E_INVALID_TOKEN
, "got %08x\n", status
);
257 ok( id
== (PSEC_WINNT_AUTH_IDENTITY_OPAQUE
)0xdeadbeef, "id set\n" );
260 status
= pSspiEncodeStringsAsAuthIdentity( NULL
, NULL
, password
, &id
);
261 ok( status
== SEC_E_OK
, "got %08x\n", status
);
262 ok( id
!= NULL
, "id not set\n" );
263 pSspiFreeAuthIdentity( id
);
266 status
= pSspiEncodeStringsAsAuthIdentity( NULL
, domainname
, password
, &id
);
267 ok( status
== SEC_E_OK
, "got %08x\n", status
);
268 ok( id
!= NULL
, "id not set\n" );
269 pSspiFreeAuthIdentity( id
);
272 status
= pSspiEncodeStringsAsAuthIdentity( username
, NULL
, password
, &id
);
273 ok( status
== SEC_E_OK
, "got %08x\n", status
);
274 ok( id
!= NULL
, "id not set\n" );
275 pSspiFreeAuthIdentity( id
);
278 status
= pSspiEncodeStringsAsAuthIdentity( username
, NULL
, NULL
, &id
);
279 ok( status
== SEC_E_OK
, "got %08x\n", status
);
280 ok( id
!= NULL
, "id not set\n" );
281 pSspiFreeAuthIdentity( id
);
284 status
= pSspiEncodeStringsAsAuthIdentity( username
, domainname
, password
, &id
);
285 ok( status
== SEC_E_OK
, "got %08x\n", status
);
286 ok( id
!= NULL
, "id not set\n" );
288 username_ptr
= domainname_ptr
= password_ptr
= NULL
;
289 status
= pSspiEncodeAuthIdentityAsStrings( id
, &username_ptr
, &domainname_ptr
, &password_ptr
);
290 ok( status
== SEC_E_OK
, "got %08x\n", status
);
291 ok( !lstrcmpW( username
, username_ptr
), "wrong username\n" );
292 ok( !lstrcmpW( domainname
, domainname_ptr
), "wrong domainname\n" );
293 ok( !lstrcmpW( password
, password_ptr
), "wrong password\n" );
295 pSspiZeroAuthIdentity( id
);
297 pSspiLocalFree( (void *)username_ptr
);
298 pSspiLocalFree( (void *)domainname_ptr
);
299 pSspiLocalFree( (void *)password_ptr
);
300 pSspiFreeAuthIdentity( id
);
303 status
= pSspiEncodeStringsAsAuthIdentity( username
, NULL
, password
, &id
);
304 ok( status
== SEC_E_OK
, "got %08x\n", status
);
305 ok( id
!= NULL
, "id not set\n" );
307 username_ptr
= password_ptr
= NULL
;
308 domainname_ptr
= (const WCHAR
*)0xdeadbeef;
309 status
= pSspiEncodeAuthIdentityAsStrings( id
, &username_ptr
, &domainname_ptr
, &password_ptr
);
310 ok( status
== SEC_E_OK
, "got %08x\n", status
);
311 ok( !lstrcmpW( username
, username_ptr
), "wrong username\n" );
312 ok( domainname_ptr
== NULL
, "domainname_ptr not cleared\n" );
313 ok( !lstrcmpW( password
, password_ptr
), "wrong password\n" );
315 pSspiLocalFree( (void *)username_ptr
);
316 pSspiLocalFree( (void *)password_ptr
);
317 pSspiFreeAuthIdentity( id
);
320 static void test_kerberos(void)
325 SECURITY_STATUS status
;
327 SEC_CHAR provider
[] = {'K','e','r','b','e','r','o','s',0};
329 static const ULONG expected_flags
=
330 SECPKG_FLAG_INTEGRITY
331 | SECPKG_FLAG_PRIVACY
332 | SECPKG_FLAG_TOKEN_ONLY
333 | SECPKG_FLAG_DATAGRAM
334 | SECPKG_FLAG_CONNECTION
335 | SECPKG_FLAG_MULTI_REQUIRED
336 | SECPKG_FLAG_EXTENDED_ERROR
337 | SECPKG_FLAG_IMPERSONATION
338 | SECPKG_FLAG_ACCEPT_WIN32_NAME
339 | SECPKG_FLAG_NEGOTIABLE
340 | SECPKG_FLAG_GSS_COMPATIBLE
342 | SECPKG_FLAG_MUTUAL_AUTH
343 | SECPKG_FLAG_DELEGATION
344 | SECPKG_FLAG_READONLY_WITH_CHECKSUM
;
345 static const ULONG optional_mask
=
346 SECPKG_FLAG_RESTRICTED_TOKENS
347 | SECPKG_FLAG_APPCONTAINER_CHECKS
;
349 status
= QuerySecurityPackageInfoA(provider
, &info
);
350 ok(status
== SEC_E_OK
, "Kerberos package not installed, skipping test\n");
351 if(status
!= SEC_E_OK
)
354 ok( (info
->fCapabilities
& ~optional_mask
) == expected_flags
, "got %08x, expected %08x\n", info
->fCapabilities
, expected_flags
);
355 ok( info
->wVersion
== 1, "got %u\n", info
->wVersion
);
356 ok( info
->wRPCID
== RPC_C_AUTHN_GSS_KERBEROS
, "got %u\n", info
->wRPCID
);
357 ok( info
->cbMaxToken
>= 12000, "got %u\n", info
->cbMaxToken
);
358 ok( !lstrcmpA( info
->Name
, "Kerberos" ), "got %s\n", info
->Name
);
359 ok( !lstrcmpA( info
->Comment
, "Microsoft Kerberos V1.0" ), "got %s\n", info
->Comment
);
360 FreeContextBuffer( info
);
362 status
= AcquireCredentialsHandleA( NULL
, provider
, SECPKG_CRED_OUTBOUND
, NULL
,
363 NULL
, NULL
, NULL
, &cred
, &ttl
);
364 todo_wine
ok( status
== SEC_E_OK
, "AcquireCredentialsHandleA returned %08x\n", status
);
365 if(status
== SEC_E_OK
)
366 FreeCredentialHandle( &cred
);
371 secdll
= LoadLibraryA("secur32.dll");
374 secdll
= LoadLibraryA("security.dll");
378 pSspiEncodeAuthIdentityAsStrings
= (void *)GetProcAddress(secdll
, "SspiEncodeAuthIdentityAsStrings");
379 pSspiEncodeStringsAsAuthIdentity
= (void *)GetProcAddress(secdll
, "SspiEncodeStringsAsAuthIdentity");
380 pSspiFreeAuthIdentity
= (void *)GetProcAddress(secdll
, "SspiFreeAuthIdentity");
381 pSspiLocalFree
= (void *)GetProcAddress(secdll
, "SspiLocalFree");
382 pSspiZeroAuthIdentity
= (void *)GetProcAddress(secdll
, "SspiZeroAuthIdentity");
383 pGetComputerObjectNameA
= (PVOID
)GetProcAddress(secdll
, "GetComputerObjectNameA");
384 pGetComputerObjectNameW
= (PVOID
)GetProcAddress(secdll
, "GetComputerObjectNameW");
385 pGetUserNameExA
= (PVOID
)GetProcAddress(secdll
, "GetUserNameExA");
386 pGetUserNameExW
= (PVOID
)GetProcAddress(secdll
, "GetUserNameExW");
387 pInitSecurityInterfaceA
= (PVOID
)GetProcAddress(secdll
, "InitSecurityInterfaceA");
388 pInitSecurityInterfaceW
= (PVOID
)GetProcAddress(secdll
, "InitSecurityInterfaceW");
390 if (pGetComputerObjectNameA
)
391 testGetComputerObjectNameA();
393 win_skip("GetComputerObjectNameA not exported by secur32.dll\n");
395 if (pGetComputerObjectNameW
)
396 testGetComputerObjectNameW();
398 win_skip("GetComputerObjectNameW not exported by secur32.dll\n");
401 testGetUserNameExA();
403 win_skip("GetUserNameExA not exported by secur32.dll\n");
406 testGetUserNameExW();
408 win_skip("GetUserNameExW not exported by secur32.dll\n");
410 test_InitSecurityInterface();
411 test_SspiEncodeStringsAsAuthIdentity();