1 /* Copyright (C) 2004 Juan Lang 2 * 3 * This file implements thunks between wide char and multibyte functions for 4 * SSPs that only provide one or the other. 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 #include "precomp.h" 21 22 #include "wine/debug.h" 23 24 WINE_DEFAULT_DEBUG_CHANNEL(secur32); 25 26 SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleA( 27 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse, 28 PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, 29 PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) 30 { 31 SECURITY_STATUS ret; 32 33 TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal), 34 debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, 35 pvGetKeyArgument, phCredential, ptsExpiry); 36 if (pszPackage) 37 { 38 UNICODE_STRING principal, package; 39 40 RtlCreateUnicodeStringFromAsciiz(&principal, pszPrincipal); 41 RtlCreateUnicodeStringFromAsciiz(&package, pszPackage); 42 ret = AcquireCredentialsHandleW(principal.Buffer, package.Buffer, 43 fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, 44 phCredential, ptsExpiry); 45 RtlFreeUnicodeString(&principal); 46 RtlFreeUnicodeString(&package); 47 } 48 else 49 ret = SEC_E_SECPKG_NOT_FOUND; 50 return ret; 51 } 52 53 SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW( 54 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, 55 PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, 56 PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) 57 { 58 SECURITY_STATUS ret; 59 60 TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal), 61 debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, 62 pvGetKeyArgument, phCredential, ptsExpiry); 63 if (pszPackage) 64 { 65 PSTR principal, package; 66 67 principal = SECUR32_AllocMultiByteFromWide(pszPrincipal); 68 package = SECUR32_AllocMultiByteFromWide(pszPackage); 69 ret = AcquireCredentialsHandleA(principal, package, fCredentialsUse, 70 pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, 71 ptsExpiry); 72 HeapFree(GetProcessHeap(), 0, principal); 73 HeapFree(GetProcessHeap(), 0, package); 74 } 75 else 76 ret = SEC_E_SECPKG_NOT_FOUND; 77 return ret; 78 } 79 80 /* thunking is pretty dicey for these--the output type depends on ulAttribute, 81 * so we have to know about every type the caller does 82 */ 83 SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesA( 84 PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) 85 { 86 SECURITY_STATUS ret; 87 88 TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer); 89 if (phCredential) 90 { 91 SecurePackage *package = (SecurePackage *)phCredential->dwUpper; 92 PCredHandle cred = (PCredHandle)phCredential->dwLower; 93 94 if (package && package->provider) 95 { 96 if (package->provider->fnTableW.QueryCredentialsAttributesW) 97 { 98 ret = package->provider->fnTableW.QueryCredentialsAttributesW( 99 cred, ulAttribute, pBuffer); 100 if (ret == SEC_E_OK) 101 { 102 switch (ulAttribute) 103 { 104 case SECPKG_CRED_ATTR_NAMES: 105 { 106 PSecPkgCredentials_NamesW names = 107 (PSecPkgCredentials_NamesW)pBuffer; 108 SEC_WCHAR *oldUser = names->sUserName; 109 110 if (oldUser) 111 { 112 names->sUserName = 113 (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser); 114 package->provider->fnTableW.FreeContextBuffer( 115 oldUser); 116 } 117 break; 118 } 119 default: 120 WARN("attribute type %d unknown\n", ulAttribute); 121 ret = SEC_E_INTERNAL_ERROR; 122 } 123 } 124 } 125 else 126 ret = SEC_E_UNSUPPORTED_FUNCTION; 127 } 128 else 129 ret = SEC_E_INVALID_HANDLE; 130 } 131 else 132 ret = SEC_E_INVALID_HANDLE; 133 return ret; 134 } 135 136 SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesW( 137 PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) 138 { 139 SECURITY_STATUS ret; 140 141 TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer); 142 if (phCredential) 143 { 144 SecurePackage *package = (SecurePackage *)phCredential->dwUpper; 145 PCredHandle cred = (PCredHandle)phCredential->dwLower; 146 147 if (package && package->provider) 148 { 149 if (package->provider->fnTableA.QueryCredentialsAttributesA) 150 { 151 ret = package->provider->fnTableA.QueryCredentialsAttributesA( 152 cred, ulAttribute, pBuffer); 153 if (ret == SEC_E_OK) 154 { 155 switch (ulAttribute) 156 { 157 case SECPKG_CRED_ATTR_NAMES: 158 { 159 PSecPkgCredentials_NamesA names = 160 (PSecPkgCredentials_NamesA)pBuffer; 161 SEC_CHAR *oldUser = names->sUserName; 162 163 if (oldUser) 164 { 165 names->sUserName = 166 (PSTR)SECUR32_AllocWideFromMultiByte(oldUser); 167 package->provider->fnTableA.FreeContextBuffer( 168 oldUser); 169 } 170 break; 171 } 172 default: 173 WARN("attribute type %d unknown\n", ulAttribute); 174 ret = SEC_E_INTERNAL_ERROR; 175 } 176 } 177 } 178 else 179 ret = SEC_E_UNSUPPORTED_FUNCTION; 180 } 181 else 182 ret = SEC_E_INVALID_HANDLE; 183 } 184 else 185 ret = SEC_E_INVALID_HANDLE; 186 return ret; 187 } 188 189 SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextA( 190 PCredHandle phCredential, PCtxtHandle phContext, 191 SEC_CHAR *pszTargetName, ULONG fContextReq, 192 ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, 193 ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, 194 ULONG *pfContextAttr, PTimeStamp ptsExpiry) 195 { 196 SECURITY_STATUS ret; 197 198 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext, 199 debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, 200 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); 201 if (phCredential) 202 { 203 SecurePackage *package = (SecurePackage *)phCredential->dwUpper; 204 205 if (package && package->provider) 206 { 207 if (package->provider->fnTableW.InitializeSecurityContextW) 208 { 209 UNICODE_STRING target; 210 211 RtlCreateUnicodeStringFromAsciiz(&target, pszTargetName); 212 ret = package->provider->fnTableW.InitializeSecurityContextW( 213 phCredential, phContext, target.Buffer, fContextReq, Reserved1, 214 TargetDataRep, pInput, Reserved2, phNewContext, pOutput, 215 pfContextAttr, ptsExpiry); 216 RtlFreeUnicodeString(&target); 217 } 218 else 219 ret = SEC_E_UNSUPPORTED_FUNCTION; 220 } 221 else 222 ret = SEC_E_INVALID_HANDLE; 223 } 224 else 225 ret = SEC_E_INVALID_HANDLE; 226 return ret; 227 } 228 229 SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextW( 230 PCredHandle phCredential, PCtxtHandle phContext, 231 SEC_WCHAR *pszTargetName, ULONG fContextReq, 232 ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, 233 ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, 234 ULONG *pfContextAttr, PTimeStamp ptsExpiry) 235 { 236 SECURITY_STATUS ret; 237 238 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext, 239 debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, 240 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); 241 if (phCredential) 242 { 243 SecurePackage *package = (SecurePackage *)phCredential->dwUpper; 244 245 if (package && package->provider) 246 { 247 if (package->provider->fnTableA.InitializeSecurityContextA) 248 { 249 PSTR target = SECUR32_AllocMultiByteFromWide(pszTargetName); 250 251 ret = package->provider->fnTableA.InitializeSecurityContextA( 252 phCredential, phContext, target, fContextReq, Reserved1, 253 TargetDataRep, pInput, Reserved2, phNewContext, pOutput, 254 pfContextAttr, ptsExpiry); 255 HeapFree(GetProcessHeap(), 0, target); 256 } 257 else 258 ret = SEC_E_UNSUPPORTED_FUNCTION; 259 } 260 else 261 ret = SEC_E_INVALID_HANDLE; 262 } 263 else 264 ret = SEC_E_INVALID_HANDLE; 265 return ret; 266 } 267 268 SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsA(PCredHandle hCredentials, 269 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, 270 void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, 271 PTimeStamp ptsExpiry) 272 { 273 SECURITY_STATUS ret; 274 275 TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal), 276 debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn, 277 pvGetKeyArgument, ptsExpiry); 278 if (hCredentials) 279 { 280 SecurePackage *package = (SecurePackage *)hCredentials->dwUpper; 281 PCredHandle cred = (PCtxtHandle)hCredentials->dwLower; 282 283 if (package && package->provider) 284 { 285 if (package->provider->fnTableW.AddCredentialsW) 286 { 287 UNICODE_STRING szPrincipal, szPackage; 288 289 RtlCreateUnicodeStringFromAsciiz(&szPrincipal, pszPrincipal); 290 RtlCreateUnicodeStringFromAsciiz(&szPackage, pszPackage); 291 ret = package->provider->fnTableW.AddCredentialsW( 292 cred, szPrincipal.Buffer, szPackage.Buffer, fCredentialUse, 293 pAuthData, pGetKeyFn, pvGetKeyArgument, ptsExpiry); 294 RtlFreeUnicodeString(&szPrincipal); 295 RtlFreeUnicodeString(&szPackage); 296 } 297 else 298 ret = SEC_E_UNSUPPORTED_FUNCTION; 299 } 300 else 301 ret = SEC_E_INVALID_HANDLE; 302 } 303 else 304 ret = SEC_E_INVALID_HANDLE; 305 return ret; 306 } 307 308 SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsW(PCredHandle hCredentials, 309 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, 310 void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, 311 PTimeStamp ptsExpiry) 312 { 313 SECURITY_STATUS ret; 314 315 TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal), 316 debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn, 317 pvGetKeyArgument, ptsExpiry); 318 if (hCredentials) 319 { 320 SecurePackage *package = (SecurePackage *)hCredentials->dwUpper; 321 PCredHandle cred = (PCtxtHandle)hCredentials->dwLower; 322 323 if (package && package->provider) 324 { 325 if (package->provider->fnTableA.AddCredentialsA) 326 { 327 PSTR szPrincipal = SECUR32_AllocMultiByteFromWide(pszPrincipal); 328 PSTR szPackage = SECUR32_AllocMultiByteFromWide(pszPackage); 329 330 ret = package->provider->fnTableA.AddCredentialsA( 331 cred, szPrincipal, szPackage, fCredentialUse, pAuthData, 332 pGetKeyFn, pvGetKeyArgument, ptsExpiry); 333 HeapFree(GetProcessHeap(), 0, szPrincipal); 334 HeapFree(GetProcessHeap(), 0, szPackage); 335 } 336 else 337 ret = SEC_E_UNSUPPORTED_FUNCTION; 338 } 339 else 340 ret = SEC_E_INVALID_HANDLE; 341 } 342 else 343 ret = SEC_E_INVALID_HANDLE; 344 return ret; 345 } 346 347 static PSecPkgInfoA _copyPackageInfoFlatWToA(const SecPkgInfoW *infoW) 348 { 349 PSecPkgInfoA ret; 350 351 if (infoW) 352 { 353 size_t bytesNeeded = sizeof(SecPkgInfoA); 354 int nameLen = 0, commentLen = 0; 355 356 if (infoW->Name) 357 { 358 nameLen = WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, 359 NULL, 0, NULL, NULL); 360 bytesNeeded += nameLen; 361 } 362 if (infoW->Comment) 363 { 364 commentLen = WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, 365 NULL, 0, NULL, NULL); 366 bytesNeeded += commentLen; 367 } 368 ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); 369 if (ret) 370 { 371 PSTR nextString = (PSTR)((PBYTE)ret + sizeof(SecPkgInfoA)); 372 373 memcpy(ret, infoW, sizeof(SecPkgInfoA)); 374 if (infoW->Name) 375 { 376 ret->Name = nextString; 377 WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, nextString, 378 nameLen, NULL, NULL); 379 nextString += nameLen; 380 } 381 else 382 ret->Name = NULL; 383 if (infoW->Comment) 384 { 385 ret->Comment = nextString; 386 WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, nextString, 387 nameLen, NULL, NULL); 388 } 389 else 390 ret->Comment = NULL; 391 } 392 } 393 else 394 ret = NULL; 395 return ret; 396 } 397 398 static SECURITY_STATUS thunk_ContextAttributesWToA(SecurePackage *package, 399 ULONG ulAttribute, void *pBuffer) 400 { 401 SECURITY_STATUS ret = SEC_E_OK; 402 403 if (package && pBuffer) 404 { 405 switch (ulAttribute) 406 { 407 case SECPKG_ATTR_NAMES: 408 { 409 PSecPkgContext_NamesW names = (PSecPkgContext_NamesW)pBuffer; 410 SEC_WCHAR *oldUser = names->sUserName; 411 412 if (oldUser) 413 { 414 names->sUserName = 415 (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser); 416 package->provider->fnTableW.FreeContextBuffer(oldUser); 417 } 418 break; 419 } 420 case SECPKG_ATTR_AUTHORITY: 421 { 422 PSecPkgContext_AuthorityW names = 423 (PSecPkgContext_AuthorityW)pBuffer; 424 SEC_WCHAR *oldAuth = names->sAuthorityName; 425 426 if (oldAuth) 427 { 428 names->sAuthorityName = 429 (PWSTR)SECUR32_AllocMultiByteFromWide(oldAuth); 430 package->provider->fnTableW.FreeContextBuffer(oldAuth); 431 } 432 break; 433 } 434 case SECPKG_ATTR_KEY_INFO: 435 { 436 PSecPkgContext_KeyInfoW info = (PSecPkgContext_KeyInfoW)pBuffer; 437 SEC_WCHAR *oldSigAlgName = info->sSignatureAlgorithmName; 438 SEC_WCHAR *oldEncAlgName = info->sEncryptAlgorithmName; 439 440 if (oldSigAlgName) 441 { 442 info->sSignatureAlgorithmName = 443 (PWSTR)SECUR32_AllocMultiByteFromWide(oldSigAlgName); 444 package->provider->fnTableW.FreeContextBuffer( 445 oldSigAlgName); 446 } 447 if (oldEncAlgName) 448 { 449 info->sEncryptAlgorithmName = 450 (PWSTR)SECUR32_AllocMultiByteFromWide(oldEncAlgName); 451 package->provider->fnTableW.FreeContextBuffer( 452 oldEncAlgName); 453 } 454 break; 455 } 456 case SECPKG_ATTR_PACKAGE_INFO: 457 { 458 PSecPkgContext_PackageInfoW info = 459 (PSecPkgContext_PackageInfoW)pBuffer; 460 PSecPkgInfoW oldPkgInfo = info->PackageInfo; 461 462 if (oldPkgInfo) 463 { 464 info->PackageInfo = (PSecPkgInfoW) 465 _copyPackageInfoFlatWToA(oldPkgInfo); 466 package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); 467 } 468 break; 469 } 470 case SECPKG_ATTR_NEGOTIATION_INFO: 471 { 472 PSecPkgContext_NegotiationInfoW info = 473 (PSecPkgContext_NegotiationInfoW)pBuffer; 474 PSecPkgInfoW oldPkgInfo = info->PackageInfo; 475 476 if (oldPkgInfo) 477 { 478 info->PackageInfo = (PSecPkgInfoW) 479 _copyPackageInfoFlatWToA(oldPkgInfo); 480 package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); 481 } 482 break; 483 } 484 case SECPKG_ATTR_NATIVE_NAMES: 485 { 486 PSecPkgContext_NativeNamesW names = 487 (PSecPkgContext_NativeNamesW)pBuffer; 488 PWSTR oldClient = names->sClientName; 489 PWSTR oldServer = names->sServerName; 490 491 if (oldClient) 492 { 493 names->sClientName = (PWSTR)SECUR32_AllocMultiByteFromWide( 494 oldClient); 495 package->provider->fnTableW.FreeContextBuffer(oldClient); 496 } 497 if (oldServer) 498 { 499 names->sServerName = (PWSTR)SECUR32_AllocMultiByteFromWide( 500 oldServer); 501 package->provider->fnTableW.FreeContextBuffer(oldServer); 502 } 503 break; 504 } 505 case SECPKG_ATTR_CREDENTIAL_NAME: 506 { 507 PSecPkgContext_CredentialNameW name = 508 (PSecPkgContext_CredentialNameW)pBuffer; 509 PWSTR oldCred = name->sCredentialName; 510 511 if (oldCred) 512 { 513 name->sCredentialName = 514 (PWSTR)SECUR32_AllocMultiByteFromWide(oldCred); 515 package->provider->fnTableW.FreeContextBuffer(oldCred); 516 } 517 break; 518 } 519 /* no thunking needed: */ 520 case SECPKG_ATTR_ACCESS_TOKEN: 521 case SECPKG_ATTR_DCE_INFO: 522 case SECPKG_ATTR_FLAGS: 523 case SECPKG_ATTR_LIFESPAN: 524 case SECPKG_ATTR_PASSWORD_EXPIRY: 525 case SECPKG_ATTR_SESSION_KEY: 526 case SECPKG_ATTR_SIZES: 527 case SECPKG_ATTR_STREAM_SIZES: 528 case SECPKG_ATTR_TARGET_INFORMATION: 529 break; 530 default: 531 WARN("attribute type %d unknown\n", ulAttribute); 532 ret = SEC_E_INTERNAL_ERROR; 533 } 534 } 535 else 536 ret = SEC_E_INVALID_TOKEN; 537 return ret; 538 } 539 540 SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesA(PCtxtHandle phContext, 541 ULONG ulAttribute, void *pBuffer) 542 { 543 SECURITY_STATUS ret; 544 545 TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); 546 if (phContext) 547 { 548 SecurePackage *package = (SecurePackage *)phContext->dwUpper; 549 PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; 550 551 if (package && package->provider) 552 { 553 if (package->provider->fnTableW.QueryContextAttributesW) 554 { 555 ret = package->provider->fnTableW.QueryContextAttributesW( 556 ctxt, ulAttribute, pBuffer); 557 if (ret == SEC_E_OK) 558 ret = thunk_ContextAttributesWToA(package, ulAttribute, 559 pBuffer); 560 } 561 else 562 ret = SEC_E_UNSUPPORTED_FUNCTION; 563 } 564 else 565 ret = SEC_E_INVALID_HANDLE; 566 } 567 else 568 ret = SEC_E_INVALID_HANDLE; 569 return ret; 570 } 571 572 static PSecPkgInfoW _copyPackageInfoFlatAToW(const SecPkgInfoA *infoA) 573 { 574 PSecPkgInfoW ret; 575 576 if (infoA) 577 { 578 size_t bytesNeeded = sizeof(SecPkgInfoW); 579 int nameLen = 0, commentLen = 0; 580 581 if (infoA->Name) 582 { 583 nameLen = MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, 584 NULL, 0); 585 bytesNeeded += nameLen * sizeof(WCHAR); 586 } 587 if (infoA->Comment) 588 { 589 commentLen = MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, 590 NULL, 0); 591 bytesNeeded += commentLen * sizeof(WCHAR); 592 } 593 ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); 594 if (ret) 595 { 596 PWSTR nextString = (PWSTR)((PBYTE)ret + sizeof(SecPkgInfoW)); 597 598 memcpy(ret, infoA, sizeof(SecPkgInfoA)); 599 if (infoA->Name) 600 { 601 ret->Name = nextString; 602 MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, nextString, 603 nameLen); 604 nextString += nameLen; 605 } 606 else 607 ret->Name = NULL; 608 if (infoA->Comment) 609 { 610 ret->Comment = nextString; 611 MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, nextString, 612 commentLen); 613 } 614 else 615 ret->Comment = NULL; 616 } 617 } 618 else 619 ret = NULL; 620 return ret; 621 } 622 623 static SECURITY_STATUS thunk_ContextAttributesAToW(SecurePackage *package, 624 ULONG ulAttribute, void *pBuffer) 625 { 626 SECURITY_STATUS ret = SEC_E_OK; 627 628 if (package && pBuffer) 629 { 630 switch (ulAttribute) 631 { 632 case SECPKG_ATTR_NAMES: 633 { 634 PSecPkgContext_NamesA names = (PSecPkgContext_NamesA)pBuffer; 635 SEC_CHAR *oldUser = names->sUserName; 636 637 if (oldUser) 638 { 639 names->sUserName = 640 (PSTR)SECUR32_AllocWideFromMultiByte(oldUser); 641 package->provider->fnTableW.FreeContextBuffer(oldUser); 642 } 643 break; 644 } 645 case SECPKG_ATTR_AUTHORITY: 646 { 647 PSecPkgContext_AuthorityA names = 648 (PSecPkgContext_AuthorityA)pBuffer; 649 SEC_CHAR *oldAuth = names->sAuthorityName; 650 651 if (oldAuth) 652 { 653 names->sAuthorityName = 654 (PSTR)SECUR32_AllocWideFromMultiByte(oldAuth); 655 package->provider->fnTableW.FreeContextBuffer(oldAuth); 656 } 657 break; 658 } 659 case SECPKG_ATTR_KEY_INFO: 660 { 661 PSecPkgContext_KeyInfoA info = (PSecPkgContext_KeyInfoA)pBuffer; 662 SEC_CHAR *oldSigAlgName = info->sSignatureAlgorithmName; 663 SEC_CHAR *oldEncAlgName = info->sEncryptAlgorithmName; 664 665 if (oldSigAlgName) 666 { 667 info->sSignatureAlgorithmName = 668 (PSTR)SECUR32_AllocWideFromMultiByte(oldSigAlgName); 669 package->provider->fnTableW.FreeContextBuffer( 670 oldSigAlgName); 671 } 672 if (oldEncAlgName) 673 { 674 info->sEncryptAlgorithmName = 675 (PSTR)SECUR32_AllocWideFromMultiByte( 676 oldEncAlgName); 677 package->provider->fnTableW.FreeContextBuffer( 678 oldEncAlgName); 679 } 680 break; 681 } 682 case SECPKG_ATTR_PACKAGE_INFO: 683 { 684 PSecPkgContext_PackageInfoA info = 685 (PSecPkgContext_PackageInfoA)pBuffer; 686 PSecPkgInfoA oldPkgInfo = info->PackageInfo; 687 688 if (oldPkgInfo) 689 { 690 info->PackageInfo = (PSecPkgInfoA) 691 _copyPackageInfoFlatAToW(oldPkgInfo); 692 package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); 693 } 694 break; 695 } 696 case SECPKG_ATTR_NEGOTIATION_INFO: 697 { 698 PSecPkgContext_NegotiationInfoA info = 699 (PSecPkgContext_NegotiationInfoA)pBuffer; 700 PSecPkgInfoA oldPkgInfo = info->PackageInfo; 701 702 if (oldPkgInfo) 703 { 704 info->PackageInfo = (PSecPkgInfoA) 705 _copyPackageInfoFlatAToW(oldPkgInfo); 706 package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); 707 } 708 break; 709 } 710 case SECPKG_ATTR_NATIVE_NAMES: 711 { 712 PSecPkgContext_NativeNamesA names = 713 (PSecPkgContext_NativeNamesA)pBuffer; 714 PSTR oldClient = names->sClientName; 715 PSTR oldServer = names->sServerName; 716 717 if (oldClient) 718 { 719 names->sClientName = (PSTR)SECUR32_AllocWideFromMultiByte( 720 oldClient); 721 package->provider->fnTableW.FreeContextBuffer(oldClient); 722 } 723 if (oldServer) 724 { 725 names->sServerName = (PSTR)SECUR32_AllocWideFromMultiByte( 726 oldServer); 727 package->provider->fnTableW.FreeContextBuffer(oldServer); 728 } 729 break; 730 } 731 case SECPKG_ATTR_CREDENTIAL_NAME: 732 { 733 PSecPkgContext_CredentialNameA name = 734 (PSecPkgContext_CredentialNameA)pBuffer; 735 PSTR oldCred = name->sCredentialName; 736 737 if (oldCred) 738 { 739 name->sCredentialName = 740 (PSTR)SECUR32_AllocWideFromMultiByte(oldCred); 741 package->provider->fnTableW.FreeContextBuffer(oldCred); 742 } 743 break; 744 } 745 /* no thunking needed: */ 746 case SECPKG_ATTR_ACCESS_TOKEN: 747 case SECPKG_ATTR_DCE_INFO: 748 case SECPKG_ATTR_FLAGS: 749 case SECPKG_ATTR_LIFESPAN: 750 case SECPKG_ATTR_PASSWORD_EXPIRY: 751 case SECPKG_ATTR_SESSION_KEY: 752 case SECPKG_ATTR_SIZES: 753 case SECPKG_ATTR_STREAM_SIZES: 754 case SECPKG_ATTR_TARGET_INFORMATION: 755 break; 756 default: 757 WARN("attribute type %d unknown\n", ulAttribute); 758 ret = SEC_E_INTERNAL_ERROR; 759 } 760 } 761 else 762 ret = SEC_E_INVALID_TOKEN; 763 return ret; 764 } 765 766 SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesW(PCtxtHandle phContext, 767 ULONG ulAttribute, void *pBuffer) 768 { 769 SECURITY_STATUS ret; 770 771 TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); 772 if (phContext) 773 { 774 SecurePackage *package = (SecurePackage *)phContext->dwUpper; 775 PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; 776 777 if (package && package->provider) 778 { 779 if (package->provider->fnTableA.QueryContextAttributesA) 780 { 781 ret = package->provider->fnTableA.QueryContextAttributesA( 782 ctxt, ulAttribute, pBuffer); 783 if (ret == SEC_E_OK) 784 ret = thunk_ContextAttributesAToW(package, ulAttribute, 785 pBuffer); 786 } 787 else 788 ret = SEC_E_UNSUPPORTED_FUNCTION; 789 } 790 else 791 ret = SEC_E_INVALID_HANDLE; 792 } 793 else 794 ret = SEC_E_INVALID_HANDLE; 795 return ret; 796 } 797 798 SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesA(PCtxtHandle phContext, 799 ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) 800 { 801 SECURITY_STATUS ret; 802 803 TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer); 804 if (phContext) 805 { 806 SecurePackage *package = (SecurePackage *)phContext->dwUpper; 807 PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; 808 809 if (package && package->provider && pBuffer && cbBuffer) 810 { 811 if (package->provider->fnTableW.SetContextAttributesW) 812 { 813 /* TODO: gotta validate size too! */ 814 ret = thunk_ContextAttributesWToA(package, ulAttribute, 815 pBuffer); 816 if (ret == SEC_E_OK) 817 ret = package->provider->fnTableW.SetContextAttributesW( 818 ctxt, ulAttribute, pBuffer, cbBuffer); 819 } 820 else 821 ret = SEC_E_UNSUPPORTED_FUNCTION; 822 } 823 else 824 ret = SEC_E_INVALID_HANDLE; 825 } 826 else 827 ret = SEC_E_INVALID_HANDLE; 828 return ret; 829 } 830 831 SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesW(PCtxtHandle phContext, 832 ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) 833 { 834 SECURITY_STATUS ret; 835 836 TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer); 837 if (phContext) 838 { 839 SecurePackage *package = (SecurePackage *)phContext->dwUpper; 840 PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; 841 842 if (package && package->provider && pBuffer && cbBuffer) 843 { 844 if (package->provider->fnTableA.SetContextAttributesA) 845 { 846 /* TODO: gotta validate size too! */ 847 ret = thunk_ContextAttributesAToW(package, ulAttribute, 848 pBuffer); 849 if (ret == SEC_E_OK) 850 ret = package->provider->fnTableA.SetContextAttributesA( 851 ctxt, ulAttribute, pBuffer, cbBuffer); 852 } 853 else 854 ret = SEC_E_UNSUPPORTED_FUNCTION; 855 } 856 else 857 ret = SEC_E_INVALID_HANDLE; 858 } 859 else 860 ret = SEC_E_INVALID_HANDLE; 861 return ret; 862 } 863 864 SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextA( 865 SEC_CHAR *pszPackage, PSecBuffer pPackedContext, void *Token, 866 PCtxtHandle phContext) 867 { 868 SECURITY_STATUS ret; 869 UNICODE_STRING package; 870 871 TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token, 872 phContext); 873 RtlCreateUnicodeStringFromAsciiz(&package, pszPackage); 874 ret = ImportSecurityContextW(package.Buffer, pPackedContext, Token, 875 phContext); 876 RtlFreeUnicodeString(&package); 877 return ret; 878 } 879 880 SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextW( 881 SEC_WCHAR *pszPackage, PSecBuffer pPackedContext, void *Token, 882 PCtxtHandle phContext) 883 { 884 SECURITY_STATUS ret; 885 PSTR package = SECUR32_AllocMultiByteFromWide(pszPackage); 886 887 TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token, 888 phContext); 889 ret = ImportSecurityContextA(package, pPackedContext, Token, phContext); 890 HeapFree(GetProcessHeap(), 0, package); 891 return ret; 892 } 893