Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2781 lines
68 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1990 - 1999
  6. //
  7. // File: handle.cxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /* --------------------------------------------------------------------
  11. Microsoft OS/2 LAN Manager
  12. Copyright(c) Microsoft Corp., 1990
  13. -------------------------------------------------------------------- */
  14. /* --------------------------------------------------------------------
  15. File: handle.cxx
  16. Description:
  17. The actual code for all of the classes specified by handle.hxx is
  18. contained in this file. These routines are independent of the actual RPC
  19. protocol / transport layer. In addition, these routines are also
  20. independent of the specific operating system in use.
  21. History :
  22. mikemon ??-??-?? First bit in the bucket.
  23. mikemon 12-28-90 Cleaned up the comments.
  24. Kamen Moutafov (KamenM) Dec 99 - Feb 2000 - Support for cell debugging stuff
  25. -------------------------------------------------------------------- */
  26. #include <precomp.hxx>
  27. #include <epmap.h>
  28. #include <rpccfg.h>
  29. #include <dispatch.h>
  30. #include <crypt.h>
  31. #include <charconv.hxx>
  32. extern unsigned DefaultMaxDatagramLength = DEFAULT_MAX_DATAGRAM_LENGTH;
  33. extern unsigned DefaultConnectionBufferLength = DEFAULT_CONNECTION_BUFFER_LENGTH;
  34. /*
  35. A helper routine to capture the logon ID of this thread, if it is
  36. impersonating another process.
  37. Routine returns RPC_S_OK on success. If the process is not impersonating,
  38. but running under its own process identity, this routine will fail.
  39. All failures, currently, get treated as if the thread is not impersonating
  40. */
  41. RPC_STATUS
  42. GetTokenStats(TOKEN_STATISTICS *pTokenStats)
  43. {
  44. BOOL Result;
  45. HANDLE Handle;
  46. unsigned long Size;
  47. Result = OpenThreadToken(
  48. GetCurrentThread(),
  49. TOKEN_READ,
  50. TRUE,
  51. &Handle
  52. );
  53. if (Result != TRUE)
  54. {
  55. return (GetLastError());
  56. }
  57. Result = GetTokenInformation(
  58. Handle,
  59. TokenStatistics,
  60. pTokenStats,
  61. sizeof(TOKEN_STATISTICS),
  62. &Size
  63. );
  64. CloseHandle(Handle);
  65. if (Result != TRUE)
  66. {
  67. return (GetLastError());
  68. }
  69. return RPC_S_OK;
  70. }
  71. RPC_STATUS
  72. CaptureModifiedId(
  73. LUID * ModifiedId
  74. )
  75. {
  76. TOKEN_STATISTICS TokenStatisticsInformation;
  77. RPC_STATUS Status;
  78. Status = GetTokenStats(&TokenStatisticsInformation);
  79. if (Status != RPC_S_OK)
  80. {
  81. return Status;
  82. }
  83. RpcpMemoryCopy(ModifiedId,
  84. &TokenStatisticsInformation.ModifiedId, sizeof(LUID));
  85. return (RPC_S_OK);
  86. }
  87. void WipeOutAuthIdentity (
  88. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  89. )
  90. /*++
  91. Routine Description:
  92. Wipes out the important parts of an auth identity structure.
  93. Works on encrypted and decrypted identities.
  94. Arguments:
  95. AuthIdentity - the auth identity to wipe out.
  96. Return Value:
  97. --*/
  98. {
  99. if (AuthIdentity == NULL)
  100. return;
  101. if (AuthIdentity->User != NULL)
  102. {
  103. RpcpMemorySet(AuthIdentity->User, 0, AuthIdentity->UserLength * sizeof(RPC_CHAR));
  104. }
  105. if (AuthIdentity->Domain != NULL)
  106. {
  107. RpcpMemorySet(AuthIdentity->Domain, 0, AuthIdentity->DomainLength * sizeof(RPC_CHAR));
  108. }
  109. if (AuthIdentity->Password != NULL)
  110. {
  111. RpcpMemorySet(AuthIdentity->Password, 0, AuthIdentity->PasswordLength * sizeof(RPC_CHAR));
  112. }
  113. }
  114. // if RTL_ENCRYPT_MEMORY_SIZE gets changed, the padding logic below
  115. // must get changed also
  116. C_ASSERT(RTL_ENCRYPT_MEMORY_SIZE == 8);
  117. RPC_CHAR *
  118. ReallocAndPad8IfNeccessary (
  119. IN RPC_CHAR *OldBuffer,
  120. IN OUT ULONG *Length
  121. )
  122. /*++
  123. Routine Description:
  124. Encrypts the important parts of an auth identity structure.
  125. On success, if reallocation was done, the old buffer is deleted.
  126. Arguments:
  127. OldBuffer - the old, unpadded buffer
  128. Length - on input, the length of the old unpadded buffer in characters without
  129. the terminating null. On output the length of the encrypted buffer with
  130. padding. Unmodified on failure.
  131. Return Value:
  132. The new buffer (may be the same as the old) or NULL if there is
  133. insufficient memory.
  134. --*/
  135. {
  136. ULONG NewLength;
  137. ULONG InputLength = *Length;
  138. RPC_CHAR *NewBuffer;
  139. NewLength = Align8(InputLength + 1);
  140. if (NewLength == InputLength + 1)
  141. {
  142. *Length = NewLength;
  143. return OldBuffer;
  144. }
  145. NewBuffer = new RPC_CHAR[NewLength];
  146. if (NewBuffer == NULL)
  147. return NULL;
  148. RpcpMemoryCopy(NewBuffer, OldBuffer, (InputLength + 1) * sizeof(RPC_CHAR));
  149. // wipe out the old buffer before freeing it
  150. RpcpMemorySet(OldBuffer, 0, (InputLength + 1) * sizeof(RPC_CHAR));
  151. delete [] OldBuffer;
  152. *Length = NewLength;
  153. return NewBuffer;
  154. }
  155. RPC_STATUS EncryptAuthIdentity (
  156. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  157. )
  158. /*++
  159. Routine Description:
  160. Encrypts the important parts of an auth identity structure.
  161. Arguments:
  162. AuthIdentity - the auth identity to encrypt.
  163. Return Value:
  164. RPC_S_OK or RPC_S_* error
  165. --*/
  166. {
  167. RPC_STATUS RpcStatus;
  168. NTSTATUS NtStatus;
  169. if (AuthIdentity->User != NULL)
  170. {
  171. AuthIdentity->User = ReallocAndPad8IfNeccessary(AuthIdentity->User,
  172. &AuthIdentity->UserLength
  173. );
  174. if (AuthIdentity->User == NULL)
  175. {
  176. WipeOutAuthIdentity(AuthIdentity);
  177. return RPC_S_OUT_OF_MEMORY;
  178. }
  179. NtStatus = RtlEncryptMemory(AuthIdentity->User,
  180. AuthIdentity->UserLength * sizeof(RPC_CHAR),
  181. 0);
  182. if (!NT_SUCCESS(NtStatus))
  183. {
  184. ASSERT(NtStatus != STATUS_INVALID_PARAMETER);
  185. WipeOutAuthIdentity(AuthIdentity);
  186. return RPC_S_OUT_OF_MEMORY;
  187. }
  188. }
  189. if (AuthIdentity->Domain != NULL)
  190. {
  191. AuthIdentity->Domain = ReallocAndPad8IfNeccessary(AuthIdentity->Domain,
  192. &AuthIdentity->DomainLength
  193. );
  194. if (AuthIdentity->Domain == NULL)
  195. {
  196. WipeOutAuthIdentity(AuthIdentity);
  197. return RPC_S_OUT_OF_MEMORY;
  198. }
  199. NtStatus = RtlEncryptMemory(AuthIdentity->Domain,
  200. AuthIdentity->DomainLength * sizeof(RPC_CHAR),
  201. 0);
  202. if (!NT_SUCCESS(NtStatus))
  203. {
  204. ASSERT(NtStatus != STATUS_INVALID_PARAMETER);
  205. WipeOutAuthIdentity(AuthIdentity);
  206. return RPC_S_OUT_OF_MEMORY;
  207. }
  208. }
  209. if (AuthIdentity->Password != NULL)
  210. {
  211. AuthIdentity->Password = ReallocAndPad8IfNeccessary(AuthIdentity->Password,
  212. &AuthIdentity->PasswordLength
  213. );
  214. if (AuthIdentity->Password == NULL)
  215. {
  216. WipeOutAuthIdentity(AuthIdentity);
  217. return RPC_S_OUT_OF_MEMORY;
  218. }
  219. NtStatus = RtlEncryptMemory(AuthIdentity->Password,
  220. AuthIdentity->PasswordLength * sizeof(RPC_CHAR),
  221. 0);
  222. if (!NT_SUCCESS(NtStatus))
  223. {
  224. ASSERT(NtStatus != STATUS_INVALID_PARAMETER);
  225. WipeOutAuthIdentity(AuthIdentity);
  226. return RPC_S_OUT_OF_MEMORY;
  227. }
  228. }
  229. return RPC_S_OK;
  230. }
  231. RPC_STATUS DecryptAuthIdentity (
  232. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  233. )
  234. /*++
  235. Routine Description:
  236. Decrypts the important parts of an auth identity structure.
  237. If decryption fails half way through, the auth identity will
  238. be wiped out.
  239. Arguments:
  240. AuthIdentity - the auth identity to decrypt.
  241. Return Value:
  242. RPC_S_OK or RPC_S_* error
  243. --*/
  244. {
  245. RPC_STATUS RpcStatus;
  246. NTSTATUS NtStatus;
  247. if (AuthIdentity->User != NULL)
  248. {
  249. NtStatus = RtlDecryptMemory(AuthIdentity->User,
  250. AuthIdentity->UserLength * sizeof(RPC_CHAR),
  251. 0);
  252. if (!NT_SUCCESS(NtStatus))
  253. {
  254. WipeOutAuthIdentity(AuthIdentity);
  255. return RPC_S_OUT_OF_MEMORY;
  256. }
  257. AuthIdentity->UserLength = RpcpStringLength(AuthIdentity->User);
  258. }
  259. if (AuthIdentity->Domain != NULL)
  260. {
  261. NtStatus = RtlDecryptMemory(AuthIdentity->Domain,
  262. AuthIdentity->DomainLength * sizeof(RPC_CHAR),
  263. 0);
  264. if (!NT_SUCCESS(NtStatus))
  265. {
  266. WipeOutAuthIdentity(AuthIdentity);
  267. return RPC_S_OUT_OF_MEMORY;
  268. }
  269. AuthIdentity->DomainLength = RpcpStringLength(AuthIdentity->Domain);
  270. }
  271. if (AuthIdentity->Password != NULL)
  272. {
  273. NtStatus = RtlDecryptMemory(AuthIdentity->Password,
  274. AuthIdentity->PasswordLength * sizeof(RPC_CHAR),
  275. 0);
  276. if (!NT_SUCCESS(NtStatus))
  277. {
  278. WipeOutAuthIdentity(AuthIdentity);
  279. return RPC_S_OUT_OF_MEMORY;
  280. }
  281. AuthIdentity->PasswordLength = RpcpStringLength(AuthIdentity->Password);
  282. }
  283. return RPC_S_OK;
  284. }
  285. void FreeAuthIdentity (
  286. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  287. )
  288. /*++
  289. Routine Description:
  290. Frees an auth identity structure.
  291. Arguments:
  292. AuthIdentity - the auth identity to free.
  293. Return Value:
  294. Notes:
  295. Does not wipe out the auth identity! It must
  296. have been wiped out by the caller.
  297. --*/
  298. {
  299. if (AuthIdentity->User != NULL)
  300. {
  301. delete [] AuthIdentity->User;
  302. AuthIdentity->User = NULL;
  303. }
  304. if (AuthIdentity->Domain != NULL)
  305. {
  306. delete [] AuthIdentity->Domain;
  307. AuthIdentity->Domain = NULL;
  308. }
  309. if (AuthIdentity->Password != NULL)
  310. {
  311. delete [] AuthIdentity->Password;
  312. AuthIdentity->Password = NULL;
  313. }
  314. delete AuthIdentity;
  315. }
  316. SEC_WINNT_AUTH_IDENTITY_W *DuplicateAuthIdentity (
  317. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity
  318. )
  319. /*++
  320. Routine Description:
  321. Duplicates an auth identity structure. It works on both
  322. encrypted and decrypted auth identity.
  323. Arguments:
  324. AuthIdentity - the auth identity to copy from.
  325. Return Value:
  326. Duplicated auth identity of NULL for failure
  327. --*/
  328. {
  329. SEC_WINNT_AUTH_IDENTITY_W *NewAuthIdentity;
  330. NewAuthIdentity = new SEC_WINNT_AUTH_IDENTITY_W;
  331. if (NewAuthIdentity == NULL)
  332. return NULL;
  333. RpcpMemoryCopy(NewAuthIdentity, AuthIdentity, sizeof(SEC_WINNT_AUTH_IDENTITY_W));
  334. NewAuthIdentity->User = NULL;
  335. NewAuthIdentity->Domain = NULL;
  336. NewAuthIdentity->Password = NULL;
  337. if (AuthIdentity->User)
  338. {
  339. NewAuthIdentity->User = new RPC_CHAR [AuthIdentity->UserLength + 1];
  340. if (NewAuthIdentity->User == NULL)
  341. {
  342. FreeAuthIdentity(NewAuthIdentity);
  343. return NULL;
  344. }
  345. RpcpMemoryCopy(NewAuthIdentity->User,
  346. AuthIdentity->User,
  347. (AuthIdentity->UserLength + 1) * sizeof(RPC_CHAR));
  348. }
  349. if (AuthIdentity->Domain)
  350. {
  351. NewAuthIdentity->Domain = new RPC_CHAR [AuthIdentity->DomainLength + 1];
  352. if (NewAuthIdentity->Domain == NULL)
  353. {
  354. WipeOutAuthIdentity(NewAuthIdentity);
  355. FreeAuthIdentity(NewAuthIdentity);
  356. return NULL;
  357. }
  358. RpcpMemoryCopy(NewAuthIdentity->Domain,
  359. AuthIdentity->Domain,
  360. (AuthIdentity->DomainLength + 1) * sizeof(RPC_CHAR));
  361. }
  362. if (AuthIdentity->Password)
  363. {
  364. NewAuthIdentity->Password = new RPC_CHAR [AuthIdentity->PasswordLength + 1];
  365. if (NewAuthIdentity->Password == NULL)
  366. {
  367. WipeOutAuthIdentity(NewAuthIdentity);
  368. FreeAuthIdentity(NewAuthIdentity);
  369. return NULL;
  370. }
  371. RpcpMemoryCopy(NewAuthIdentity->Password,
  372. AuthIdentity->Password,
  373. (AuthIdentity->PasswordLength + 1) * sizeof(RPC_CHAR));
  374. }
  375. return NewAuthIdentity;
  376. }
  377. int CompareAuthIdentity (
  378. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity1,
  379. IN SEC_WINNT_AUTH_IDENTITY_W *AuthIdentity2
  380. )
  381. /*++
  382. Routine Description:
  383. Compares 2 auth identity structures. Works on both
  384. encrypted and decrypted auth identities?
  385. Arguments:
  386. AuthIdentity1 - first auth identity structure
  387. AuthIdentity2 - second auth identity structure
  388. Return Value:
  389. 0 if they are equal. non-zero otherwise.
  390. --*/
  391. {
  392. ASSERT(_NOT_COVERED_);
  393. if (AuthIdentity1->Flags != AuthIdentity2->Flags)
  394. return 1;
  395. if (AuthIdentity1->User)
  396. {
  397. if (AuthIdentity2->User == NULL)
  398. return 1;
  399. if (AuthIdentity1->UserLength != AuthIdentity2->UserLength)
  400. return 1;
  401. if (RpcpMemoryCompare(AuthIdentity1->User,
  402. AuthIdentity2->User,
  403. AuthIdentity1->UserLength * sizeof(RPC_CHAR)) != 0)
  404. return 1;
  405. }
  406. else if (AuthIdentity2->User != NULL)
  407. return 1;
  408. if (AuthIdentity1->Domain)
  409. {
  410. if (AuthIdentity2->Domain == NULL)
  411. return 1;
  412. if (AuthIdentity1->DomainLength != AuthIdentity2->DomainLength)
  413. return 1;
  414. if (RpcpMemoryCompare(AuthIdentity1->Domain,
  415. AuthIdentity2->Domain,
  416. AuthIdentity1->DomainLength * sizeof(RPC_CHAR)) != 0)
  417. return 1;
  418. }
  419. else if (AuthIdentity2->Domain != NULL)
  420. return 1;
  421. if (AuthIdentity1->Password)
  422. {
  423. if (AuthIdentity2->Password == NULL)
  424. return 1;
  425. if (AuthIdentity1->Password != AuthIdentity2->Password)
  426. return 1;
  427. if (RpcpMemoryCompare(AuthIdentity1->Password,
  428. AuthIdentity2->Password,
  429. AuthIdentity1->PasswordLength * sizeof(RPC_CHAR)) != 0)
  430. return 1;
  431. }
  432. else if (AuthIdentity2->Password != NULL)
  433. return 1;
  434. return 0;
  435. }
  436. SEC_WINNT_AUTH_IDENTITY_W *ConvertAuthIdentity (
  437. IN SEC_WINNT_AUTH_IDENTITY_A *AuthIdentity
  438. )
  439. /*++
  440. Routine Description:
  441. Converts an auth identity structure.
  442. Conversion is done on a separate copy.
  443. Arguments:
  444. AuthIdentity - the auth identity to convert.
  445. Return Value:
  446. Pointer to duplicated/converted auth identity. If failure,
  447. NULL.
  448. --*/
  449. {
  450. SEC_WINNT_AUTH_IDENTITY_W *NewAuthIdentity;
  451. ASSERT(AuthIdentity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI);
  452. NewAuthIdentity = new SEC_WINNT_AUTH_IDENTITY_W;
  453. if (NewAuthIdentity == NULL)
  454. return NULL;
  455. RpcpMemoryCopy(NewAuthIdentity, AuthIdentity, sizeof(SEC_WINNT_AUTH_IDENTITY_W));
  456. NewAuthIdentity->User = NULL;
  457. NewAuthIdentity->Domain = NULL;
  458. NewAuthIdentity->Password = NULL;
  459. NewAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  460. if (AuthIdentity->User)
  461. {
  462. NewAuthIdentity->User = new RPC_CHAR [AuthIdentity->UserLength + 1];
  463. if (NewAuthIdentity->User == NULL)
  464. {
  465. FreeAuthIdentity(NewAuthIdentity);
  466. return NULL;
  467. }
  468. FullAnsiToUnicode((char *)AuthIdentity->User, NewAuthIdentity->User);
  469. }
  470. if (AuthIdentity->Domain)
  471. {
  472. NewAuthIdentity->Domain = new RPC_CHAR [AuthIdentity->DomainLength + 1];
  473. if (NewAuthIdentity->Domain == NULL)
  474. {
  475. WipeOutAuthIdentity(NewAuthIdentity);
  476. FreeAuthIdentity(NewAuthIdentity);
  477. return NULL;
  478. }
  479. FullAnsiToUnicode((char *)AuthIdentity->Domain, NewAuthIdentity->Domain);
  480. }
  481. if (AuthIdentity->Password)
  482. {
  483. NewAuthIdentity->Password = new RPC_CHAR [AuthIdentity->PasswordLength + 1];
  484. if (NewAuthIdentity->Password == NULL)
  485. {
  486. WipeOutAuthIdentity(NewAuthIdentity);
  487. FreeAuthIdentity(NewAuthIdentity);
  488. return NULL;
  489. }
  490. FullAnsiToUnicode((char *)AuthIdentity->Password, NewAuthIdentity->Password);
  491. }
  492. return NewAuthIdentity;
  493. }
  494. void FreeHttpTransportCredentials (
  495. IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *Credentials
  496. )
  497. /*++
  498. Routine Description:
  499. Duplicates Http transport credentials.
  500. Arguments:
  501. Credentials - the credentials to free.
  502. Return Value:
  503. --*/
  504. {
  505. if (Credentials->AuthnSchemes != NULL)
  506. {
  507. delete [] Credentials->AuthnSchemes;
  508. Credentials->AuthnSchemes = NULL;
  509. }
  510. if (Credentials->ServerCertificateSubject != NULL)
  511. {
  512. delete [] Credentials->ServerCertificateSubject;
  513. Credentials->ServerCertificateSubject = NULL;
  514. }
  515. if (Credentials->TransportCredentials != NULL)
  516. {
  517. FreeAuthIdentity(Credentials->TransportCredentials);
  518. Credentials->TransportCredentials = NULL;
  519. }
  520. }
  521. RPC_HTTP_TRANSPORT_CREDENTIALS_W *DuplicateHttpTransportCredentials (
  522. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *SourceCredentials
  523. )
  524. /*++
  525. Routine Description:
  526. Duplicates Http transport credentials.
  527. Arguments:
  528. SourceCredentials - the credentials to duplicate.
  529. Return Value:
  530. Duplicated credentials or NULL if there was not enough memory.
  531. --*/
  532. {
  533. RPC_HTTP_TRANSPORT_CREDENTIALS_W *NewCredentials;
  534. NewCredentials = new RPC_HTTP_TRANSPORT_CREDENTIALS_W;
  535. if (NewCredentials == NULL)
  536. return NewCredentials;
  537. NewCredentials->Flags = SourceCredentials->Flags;
  538. NewCredentials->AuthenticationTarget = SourceCredentials->AuthenticationTarget;
  539. NewCredentials->NumberOfAuthnSchemes = SourceCredentials->NumberOfAuthnSchemes;
  540. NewCredentials->AuthnSchemes = NULL;
  541. NewCredentials->ServerCertificateSubject = NULL;
  542. NewCredentials->TransportCredentials = NULL;
  543. if (SourceCredentials->AuthnSchemes)
  544. {
  545. NewCredentials->AuthnSchemes = new ULONG [SourceCredentials->NumberOfAuthnSchemes];
  546. if (NewCredentials->AuthnSchemes == NULL)
  547. {
  548. FreeHttpTransportCredentials(NewCredentials);
  549. return NULL;
  550. }
  551. RpcpMemoryCopy(NewCredentials->AuthnSchemes,
  552. SourceCredentials->AuthnSchemes,
  553. SourceCredentials->NumberOfAuthnSchemes * sizeof(ULONG)
  554. );
  555. }
  556. if (SourceCredentials->ServerCertificateSubject)
  557. {
  558. NewCredentials->ServerCertificateSubject
  559. = DuplicateString(SourceCredentials->ServerCertificateSubject);
  560. if (NewCredentials->ServerCertificateSubject == NULL)
  561. {
  562. FreeHttpTransportCredentials(NewCredentials);
  563. return NULL;
  564. }
  565. }
  566. if (SourceCredentials->TransportCredentials)
  567. {
  568. NewCredentials->TransportCredentials
  569. = DuplicateAuthIdentity(SourceCredentials->TransportCredentials);
  570. if (NewCredentials->TransportCredentials == NULL)
  571. {
  572. FreeHttpTransportCredentials(NewCredentials);
  573. return NULL;
  574. }
  575. }
  576. return NewCredentials;
  577. }
  578. int CompareHttpTransportCredentials (
  579. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *Credentials1,
  580. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *Credentials2
  581. )
  582. /*++
  583. Routine Description:
  584. Compares Http transport credentials.
  585. Arguments:
  586. Credentials1 - first set of credentials
  587. Credentials2 - second set of credentials
  588. Return Value:
  589. 0 if they are equal or non-zero if they are different
  590. --*/
  591. {
  592. ASSERT(_NOT_COVERED_);
  593. if (Credentials1->Flags != Credentials2->Flags)
  594. return 1;
  595. if (Credentials1->AuthenticationTarget != Credentials2->AuthenticationTarget)
  596. return 1;
  597. if (Credentials1->NumberOfAuthnSchemes != Credentials2->NumberOfAuthnSchemes)
  598. return 1;
  599. if (Credentials1->AuthnSchemes != NULL)
  600. {
  601. if (RpcpMemoryCompare(Credentials1->AuthnSchemes,
  602. Credentials2->AuthnSchemes,
  603. Credentials1->NumberOfAuthnSchemes) != 0)
  604. {
  605. return 1;
  606. }
  607. }
  608. else if (Credentials1->AuthnSchemes != NULL)
  609. return 1;
  610. if (Credentials1->ServerCertificateSubject != NULL)
  611. {
  612. if (RpcpStringCompare(Credentials1->ServerCertificateSubject,
  613. Credentials2->ServerCertificateSubject) != 0)
  614. {
  615. return 1;
  616. }
  617. }
  618. else if (Credentials1->ServerCertificateSubject != NULL)
  619. return 1;
  620. return CompareAuthIdentity(Credentials1->TransportCredentials, Credentials2->TransportCredentials);
  621. }
  622. RPC_HTTP_TRANSPORT_CREDENTIALS_W *ConvertToUnicodeHttpTransportCredentials (
  623. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_A *SourceCredentials
  624. )
  625. /*++
  626. Routine Description:
  627. Converts Http transport credentials from ANSI to Unicode.
  628. Conversion is done on a separate copy.
  629. Arguments:
  630. SourceCredentials - the credentials to convert.
  631. Return Value:
  632. Pointer to duplicated/converted credentials. If failure,
  633. NULL.
  634. --*/
  635. {
  636. RPC_HTTP_TRANSPORT_CREDENTIALS_W *NewCredentials;
  637. ULONG Length;
  638. NewCredentials = new RPC_HTTP_TRANSPORT_CREDENTIALS_W;
  639. if (NewCredentials == NULL)
  640. return NewCredentials;
  641. NewCredentials->Flags = SourceCredentials->Flags;
  642. NewCredentials->AuthenticationTarget = SourceCredentials->AuthenticationTarget;
  643. NewCredentials->NumberOfAuthnSchemes = SourceCredentials->NumberOfAuthnSchemes;
  644. NewCredentials->AuthnSchemes = NULL;
  645. NewCredentials->ServerCertificateSubject = NULL;
  646. NewCredentials->TransportCredentials = NULL;
  647. if (SourceCredentials->AuthnSchemes)
  648. {
  649. NewCredentials->AuthnSchemes = new ULONG [SourceCredentials->NumberOfAuthnSchemes];
  650. if (NewCredentials->AuthnSchemes == NULL)
  651. {
  652. FreeHttpTransportCredentials(NewCredentials);
  653. return NULL;
  654. }
  655. RpcpMemoryCopy(NewCredentials->AuthnSchemes,
  656. SourceCredentials->AuthnSchemes,
  657. SourceCredentials->NumberOfAuthnSchemes * sizeof(ULONG)
  658. );
  659. }
  660. if (SourceCredentials->ServerCertificateSubject)
  661. {
  662. Length = RpcpStringLengthA((const char *)SourceCredentials->ServerCertificateSubject) + 1;
  663. NewCredentials->ServerCertificateSubject = new RPC_CHAR[Length];
  664. if (NewCredentials->ServerCertificateSubject == NULL)
  665. {
  666. FreeHttpTransportCredentials(NewCredentials);
  667. return NULL;
  668. }
  669. FullAnsiToUnicode((char *)SourceCredentials->ServerCertificateSubject,
  670. NewCredentials->ServerCertificateSubject);
  671. }
  672. if (SourceCredentials->TransportCredentials)
  673. {
  674. NewCredentials->TransportCredentials
  675. = ConvertAuthIdentity(SourceCredentials->TransportCredentials);
  676. if (NewCredentials->TransportCredentials == NULL)
  677. {
  678. FreeHttpTransportCredentials(NewCredentials);
  679. return NULL;
  680. }
  681. }
  682. return NewCredentials;
  683. }
  684. RPC_HTTP_TRANSPORT_CREDENTIALS_W *
  685. I_RpcTransGetHttpCredentials (
  686. const IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *SourceCredentials
  687. )
  688. /*++
  689. Routine Description:
  690. Takes runtime encrypted credentials and returns a duplicate,
  691. decrypted credentials.
  692. Arguments:
  693. SourceCredentials - the encrypted runtime credentials given to the
  694. transport during Open.
  695. Return Value:
  696. Pointer to duplicated/converted credentials. If failure,
  697. NULL.
  698. --*/
  699. {
  700. RPC_HTTP_TRANSPORT_CREDENTIALS_W *NewCredentials;
  701. RPC_STATUS RpcStatus;
  702. NewCredentials = DuplicateHttpTransportCredentials(SourceCredentials);
  703. if (NewCredentials && NewCredentials->TransportCredentials)
  704. {
  705. RpcStatus = DecryptAuthIdentity(NewCredentials->TransportCredentials);
  706. if (RpcStatus != RPC_S_OK)
  707. {
  708. // if Decrypt fails, it will wipe out the auth identity
  709. FreeHttpTransportCredentials(NewCredentials);
  710. NewCredentials = NULL;
  711. }
  712. }
  713. return NewCredentials;
  714. }
  715. void I_RpcTransFreeHttpCredentials (
  716. IN RPC_HTTP_TRANSPORT_CREDENTIALS_W *SourceCredentials
  717. )
  718. /*++
  719. Routine Description:
  720. Frees credentials obtained by the transport through
  721. I_RpcTransGetHttpCredentials.
  722. Arguments:
  723. SourceCredentials - the credentials to free.
  724. Return Value:
  725. --*/
  726. {
  727. ASSERT(SourceCredentials);
  728. WipeOutAuthIdentity(SourceCredentials->TransportCredentials);
  729. FreeHttpTransportCredentials(SourceCredentials);
  730. }
  731. /* ====================================================================
  732. GENERIC_OBJECT
  733. ==================================================================== */
  734. /* --------------------------------------------------------------------
  735. This routine validates a handle. The HandleType argument is a set of
  736. flags specifying the valid handle types. Note that the handle types
  737. defined in handle.hxx are flags rather than being enumerated.
  738. -------------------------------------------------------------------- */
  739. unsigned int
  740. GENERIC_OBJECT::InvalidHandle ( // Validate a handle.
  741. IN HANDLE_TYPE BaseType
  742. )
  743. {
  744. // Checking for a 0 handle should work for all operating environments. Where
  745. // we can (such as on NT), we should check for readable and writeable memory.
  746. if (this == 0)
  747. {
  748. return(1);
  749. }
  750. // Check the magic long. This allows us to catch stale handles and handles
  751. // which are just passed in as arbitray pointers into memory. It does not
  752. // handle the case of copying the contents of a handle.
  753. if (MagicLong != MAGICLONG)
  754. {
  755. return(1);
  756. }
  757. //
  758. // Finally, check that the type of handle is one of the allowed ones
  759. // specified by the HandleType argument. Remember that the call to Type
  760. // is a virtual method which each type of handle will implement.
  761. //
  762. if (ObjectType & BaseType)
  763. {
  764. return 0;
  765. }
  766. return(1);
  767. }
  768. RPC_STATUS
  769. MESSAGE_OBJECT::BindingCopy (
  770. OUT BINDING_HANDLE * PAPI * DestinationBinding,
  771. IN unsigned int MaintainContext
  772. )
  773. {
  774. UNUSED(this);
  775. UNUSED(DestinationBinding);
  776. UNUSED(MaintainContext);
  777. ASSERT( 0 );
  778. return(RPC_S_INTERNAL_ERROR);
  779. }
  780. void
  781. CLIENT_AUTH_INFO::ReferenceCredentials() const
  782. {
  783. if (Credentials != 0)
  784. {
  785. Credentials->ReferenceCredentials();
  786. }
  787. }
  788. int
  789. CLIENT_AUTH_INFO::CredentialsMatch(
  790. SECURITY_CREDENTIALS PAPI * SuppliedCredentials
  791. ) const
  792. {
  793. return(Credentials->CompareCredentials(SuppliedCredentials) == 0);
  794. }
  795. CLIENT_AUTH_INFO::CLIENT_AUTH_INFO(
  796. const CLIENT_AUTH_INFO * myAuthInfo,
  797. RPC_STATUS __RPC_FAR * pStatus
  798. )
  799. {
  800. if (myAuthInfo)
  801. {
  802. *this = *myAuthInfo;
  803. if (myAuthInfo->ServerPrincipalName)
  804. {
  805. RPC_CHAR * NewString;
  806. NewString = DuplicateString(myAuthInfo->ServerPrincipalName);
  807. ServerPrincipalName = NewString;
  808. if (0 == NewString)
  809. {
  810. *pStatus = RPC_S_OUT_OF_MEMORY;
  811. }
  812. }
  813. ASSERT((AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  814. || (AdditionalTransportCredentialsType == 0));
  815. if (myAuthInfo->AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  816. {
  817. ASSERT(myAuthInfo->AdditionalCredentials != NULL);
  818. AdditionalCredentials = DuplicateHttpTransportCredentials(
  819. (const RPC_HTTP_TRANSPORT_CREDENTIALS_W *)myAuthInfo->AdditionalCredentials);
  820. if (AdditionalCredentials == NULL)
  821. {
  822. *pStatus = RPC_S_OUT_OF_MEMORY;
  823. }
  824. }
  825. myAuthInfo->ReferenceCredentials();
  826. }
  827. else
  828. {
  829. AuthenticationLevel = RPC_C_AUTHN_LEVEL_NONE;
  830. AuthenticationService = RPC_C_AUTHN_NONE;
  831. AuthorizationService = RPC_C_AUTHZ_NONE;
  832. ServerPrincipalName = 0;
  833. AuthIdentity = 0;
  834. Credentials = 0;
  835. ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
  836. IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
  837. Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
  838. DefaultLogonId = 1;
  839. AdditionalTransportCredentialsType = 0;
  840. AdditionalCredentials = NULL;
  841. }
  842. }
  843. CLIENT_AUTH_INFO::~CLIENT_AUTH_INFO(
  844. )
  845. {
  846. delete ServerPrincipalName;
  847. if (Credentials)
  848. {
  849. Credentials->DereferenceCredentials();
  850. }
  851. ASSERT((AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  852. || (AdditionalTransportCredentialsType == 0));
  853. if (AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  854. {
  855. ASSERT(AdditionalCredentials != NULL);
  856. FreeHttpTransportCredentials((RPC_HTTP_TRANSPORT_CREDENTIALS_W *)AdditionalCredentials);
  857. AdditionalCredentials = NULL;
  858. }
  859. }
  860. int
  861. CLIENT_AUTH_INFO::IsSupportedAuthInfo (
  862. IN const CLIENT_AUTH_INFO * ClientAuthInfo,
  863. IN BOOL fNamedPipe
  864. ) const
  865. /*++
  866. Arguments:
  867. ClientAuthInfo - Supplies the authentication and authorization information
  868. required of this connection. A value of zero (the pointer is
  869. zero) indicates that we want an unauthenticated connection.
  870. Return Value:
  871. Non-zero indicates that the connection has the requested authentication
  872. and authorization information; otherwise, zero will be returned.
  873. --*/
  874. {
  875. if ( ClientAuthInfo == 0 )
  876. {
  877. return(AuthenticationLevel
  878. == RPC_C_AUTHN_LEVEL_NONE);
  879. }
  880. if ( ClientAuthInfo->AuthenticationService != AuthenticationService )
  881. {
  882. return(0);
  883. }
  884. if (ClientAuthInfo->AuthenticationService == RPC_C_AUTHN_NONE)
  885. {
  886. if (fNamedPipe)
  887. {
  888. if ((ClientAuthInfo->DefaultLogonId != DefaultLogonId)
  889. || ((ClientAuthInfo->DefaultLogonId == FALSE)
  890. && (!FastCompareLUIDAligned(&ClientAuthInfo->ModifiedId, &ModifiedId))))
  891. {
  892. return 0;
  893. }
  894. }
  895. return 1;
  896. }
  897. if ( ClientAuthInfo->AuthenticationLevel
  898. != AuthenticationLevel )
  899. {
  900. return(0);
  901. }
  902. if ( ClientAuthInfo->AuthorizationService != AuthorizationService )
  903. {
  904. return(0);
  905. }
  906. if (CredentialsMatch(ClientAuthInfo->Credentials) == 0)
  907. {
  908. //Credentials Dont Match
  909. return(0);
  910. }
  911. if ( ClientAuthInfo->ImpersonationType != ImpersonationType )
  912. {
  913. return (0);
  914. }
  915. if ( (ClientAuthInfo->IdentityTracking == RPC_C_QOS_IDENTITY_DYNAMIC)
  916. && (IdentityTracking == RPC_C_QOS_IDENTITY_DYNAMIC)
  917. && (
  918. (ClientAuthInfo->DefaultLogonId != DefaultLogonId)
  919. || (
  920. (ClientAuthInfo->DefaultLogonId == FALSE)
  921. && (!FastCompareLUIDAligned(&ClientAuthInfo->ModifiedId, &ModifiedId))
  922. )
  923. )
  924. || (ClientAuthInfo->IdentityTracking != IdentityTracking) )
  925. {
  926. return (0);
  927. }
  928. if ( (ClientAuthInfo->Capabilities != Capabilities)
  929. &&(ClientAuthInfo->Capabilities != RPC_C_QOS_CAPABILITIES_DEFAULT) )
  930. {
  931. return (0);
  932. }
  933. if ( ClientAuthInfo->ServerPrincipalName == 0
  934. || ServerPrincipalName == 0 )
  935. {
  936. return(ServerPrincipalName == ClientAuthInfo->ServerPrincipalName);
  937. }
  938. if ( RpcpStringCompare(ClientAuthInfo->ServerPrincipalName,
  939. ServerPrincipalName) == 0 )
  940. {
  941. return(1);
  942. }
  943. ASSERT((AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  944. || (AdditionalTransportCredentialsType == 0));
  945. if (AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  946. {
  947. return CompareHttpTransportCredentials((RPC_HTTP_TRANSPORT_CREDENTIALS_W *)AdditionalCredentials,
  948. (RPC_HTTP_TRANSPORT_CREDENTIALS_W *)ClientAuthInfo->AdditionalCredentials);
  949. }
  950. return(0);
  951. }
  952. RPC_STATUS
  953. CALL::Cancel(
  954. void * ThreadHandle
  955. )
  956. {
  957. return RPC_S_OK;
  958. }
  959. unsigned
  960. CALL::TestCancel(
  961. )
  962. {
  963. return 0;
  964. }
  965. /* ====================================================================
  966. CCALL
  967. ==================================================================== */
  968. RPC_STATUS CCALL::SetDebugClientCallInformation(OUT DebugClientCallInfo **ppClientCallInfo,
  969. OUT CellTag *ClientCallInfoCellTag,
  970. OUT DebugCallTargetInfo **ppCallTargetInfo,
  971. OUT CellTag *CallTargetInfoCellTag,
  972. IN OUT PRPC_MESSAGE Message,
  973. IN DebugThreadInfo *ThreadDebugCell OPTIONAL,
  974. IN CellTag ThreadCellTag OPTIONAL)
  975. {
  976. RPC_STATUS Status;
  977. DebugClientCallInfo *ClientCallInfo;
  978. DebugCallTargetInfo *CallTargetInfo;
  979. Status = InitializeServerSideCellHeapIfNecessary();
  980. if (Status != RPC_S_OK)
  981. return Status;
  982. ClientCallInfo = (DebugClientCallInfo *) AllocateCell(ClientCallInfoCellTag);
  983. if (ClientCallInfo == NULL)
  984. {
  985. return RPC_S_OUT_OF_MEMORY;
  986. }
  987. CallTargetInfo = (DebugCallTargetInfo *) AllocateCell(CallTargetInfoCellTag);
  988. if (CallTargetInfo == NULL)
  989. {
  990. FreeCell(ClientCallInfo, ClientCallInfoCellTag);
  991. return RPC_S_OUT_OF_MEMORY;
  992. }
  993. ClientCallInfo->TypeHeader = 0;
  994. ClientCallInfo->Type = dctClientCallInfo;
  995. ClientCallInfo->IfStart = *((DWORD *)Message->RpcInterfaceInformation + 1);
  996. ClientCallInfo->ProcNum = (unsigned short)Message->ProcNum;
  997. GetDebugCellIDFromDebugCell((DebugCellUnion *)CallTargetInfo,
  998. CallTargetInfoCellTag, &ClientCallInfo->CallTargetID);
  999. if (ThreadDebugCell)
  1000. {
  1001. GetDebugCellIDFromDebugCell((DebugCellUnion *)ThreadDebugCell,
  1002. &ThreadCellTag, &ClientCallInfo->ServicingThread);
  1003. }
  1004. else
  1005. {
  1006. ClientCallInfo->ServicingThread.CellID = 0;
  1007. ClientCallInfo->ServicingThread.SectionID = 0;
  1008. }
  1009. CallTargetInfo->TypeHeader = 0;
  1010. CallTargetInfo->Type = dctCallTargetInfo;
  1011. CallTargetInfo->LastUpdateTime = NtGetTickCount();
  1012. *ppClientCallInfo = ClientCallInfo;
  1013. *ppCallTargetInfo = CallTargetInfo;
  1014. return RPC_S_OK;
  1015. }
  1016. /* ====================================================================
  1017. BINDING_HANDLE
  1018. ==================================================================== */
  1019. BINDING_HANDLE::BINDING_HANDLE (
  1020. IN OUT RPC_STATUS *pStatus
  1021. ) : BindingMutex(pStatus)
  1022. /*++
  1023. Routine Description:
  1024. In addition to initializing a binding handle instance in this
  1025. constructor, we also need to put the binding handle into a global
  1026. set of binding handle. This is necessary only for windows.
  1027. --*/
  1028. {
  1029. Timeout = RPC_C_BINDING_DEFAULT_TIMEOUT;
  1030. NullObjectUuidFlag = 1;
  1031. ObjectUuid.SetToNullUuid();
  1032. EntryNameSyntax = 0;
  1033. EntryName = 0;
  1034. EpLookupHandle = 0;
  1035. pvTransportOptions = NULL;
  1036. OptionsVector = NULL;
  1037. }
  1038. BINDING_HANDLE::~BINDING_HANDLE (
  1039. )
  1040. {
  1041. if (EpLookupHandle != 0)
  1042. {
  1043. EpFreeLookupHandle(EpLookupHandle);
  1044. }
  1045. delete EntryName;
  1046. if (pvTransportOptions)
  1047. {
  1048. I_RpcFree(pvTransportOptions);
  1049. }
  1050. if (OptionsVector)
  1051. {
  1052. I_RpcFree(OptionsVector);
  1053. }
  1054. }
  1055. RPC_STATUS
  1056. BINDING_HANDLE::Clone (
  1057. BINDING_HANDLE * Handle
  1058. )
  1059. {
  1060. RPC_STATUS Status = 0;
  1061. Timeout = Handle->Timeout;
  1062. ObjectUuid = Handle->ObjectUuid;
  1063. NullObjectUuidFlag = Handle->NullObjectUuidFlag;
  1064. /*
  1065. All of these duplicate what is done in the constructor.
  1066. EntryName = 0;
  1067. EntryNameSyntax = 0;
  1068. EpLookupHandle = 0;
  1069. pvTransportOptions = 0;
  1070. OptionsVector = 0;
  1071. */
  1072. if (Handle->OptionsVector)
  1073. {
  1074. OptionsVector = new ULONG_PTR[ RPC_C_OPT_MAX_OPTIONS ];
  1075. if (OptionsVector == 0)
  1076. {
  1077. return RPC_S_OUT_OF_MEMORY;
  1078. }
  1079. RpcpMemoryCopy( OptionsVector, Handle->OptionsVector, RPC_C_OPT_MAX_OPTIONS * sizeof( ULONG_PTR) );
  1080. }
  1081. CLIENT_AUTH_INFO * AuthInfo;
  1082. if ((AuthInfo = Handle->InquireAuthInformation()) != 0)
  1083. {
  1084. Status = SetAuthInformation(
  1085. AuthInfo->ServerPrincipalName,
  1086. AuthInfo->AuthenticationLevel,
  1087. AuthInfo->AuthenticationService,
  1088. AuthInfo->AuthIdentity,
  1089. AuthInfo->AuthorizationService,
  1090. AuthInfo->Credentials,
  1091. AuthInfo->ImpersonationType,
  1092. AuthInfo->IdentityTracking,
  1093. AuthInfo->Capabilities,
  1094. FALSE, // bAcquireNewCredentials
  1095. AuthInfo->AdditionalTransportCredentialsType,
  1096. AuthInfo->AdditionalCredentials
  1097. );
  1098. if (Status != RPC_S_OK)
  1099. {
  1100. ASSERT(Status == RPC_S_OUT_OF_MEMORY);
  1101. //
  1102. // Previous code maps all security errors to this.
  1103. //
  1104. return RPC_S_OUT_OF_MEMORY;
  1105. }
  1106. }
  1107. return Status;
  1108. }
  1109. void
  1110. BINDING_HANDLE::InquireObjectUuid (
  1111. OUT RPC_UUID PAPI * ObjectUuid
  1112. )
  1113. /*++
  1114. Routine Description:
  1115. This routine copies the object uuid from the binding handle into
  1116. the supplied ObjectUuid argument.
  1117. Arguments:
  1118. ObjectUuid - Returns a copy of the object uuid in the binding handle.
  1119. --*/
  1120. {
  1121. ObjectUuid->CopyUuid(&(this->ObjectUuid));
  1122. }
  1123. void
  1124. BINDING_HANDLE::SetObjectUuid (
  1125. IN RPC_UUID PAPI * ObjectUuid
  1126. )
  1127. /*++
  1128. Routine Description:
  1129. This routine copies the object uuid supplied in the ObjectUuid argument
  1130. into the binding handle.
  1131. Arguments:
  1132. ObjectUuid - Supplies the object uuid to copy into the binding handle.
  1133. --*/
  1134. {
  1135. if ( ( ObjectUuid == 0 )
  1136. || ( ObjectUuid->IsNullUuid() != 0 ) )
  1137. {
  1138. NullObjectUuidFlag = 1;
  1139. this->ObjectUuid.SetToNullUuid();
  1140. }
  1141. else
  1142. {
  1143. this->ObjectUuid.CopyUuid(ObjectUuid);
  1144. NullObjectUuidFlag = 0;
  1145. }
  1146. }
  1147. RPC_STATUS
  1148. BINDING_HANDLE::SetComTimeout (
  1149. IN unsigned int Timeout
  1150. )
  1151. /*++
  1152. Routine Description:
  1153. This routine sets the communications timeout value in this binding
  1154. handle. The specified timeout is range checked.
  1155. Arguments:
  1156. Timeout - Supplies the new communications timeout value for this
  1157. binding handle.
  1158. Return Value:
  1159. RPC_S_OK - The operation completed successfully.
  1160. RPC_S_INVALID_TIMEOUT - The specified timeout value is not in the
  1161. correct range.
  1162. --*/
  1163. {
  1164. // We just need to check to see if the timeout value is too large,
  1165. // since the timeout is unsigned and the lowest value is zero.
  1166. if (Timeout > RPC_C_BINDING_INFINITE_TIMEOUT)
  1167. return(RPC_S_INVALID_TIMEOUT);
  1168. this->Timeout = Timeout;
  1169. return(RPC_S_OK);
  1170. }
  1171. RPC_CHAR *pNS_DLL_NAME = RPC_STRING_LITERAL("RPCNS4");
  1172. const char *pNS_ENTRYPOINT_NAME = "I_GetDefaultEntrySyntax";
  1173. typedef unsigned long (RPC_ENTRY * GET_DEFAULT_ENTRY_FN)();
  1174. RPC_STATUS
  1175. BINDING_HANDLE::InquireEntryName (
  1176. IN unsigned long EntryNameSyntax,
  1177. OUT RPC_CHAR PAPI * PAPI * EntryName
  1178. )
  1179. /*++
  1180. Routine Description:
  1181. This method is used to obtain the entry name for the binding handle,
  1182. if it has one. The entry name is the name of the name service object
  1183. from which a binding handle is imported or looked up. If the binding
  1184. handle was not imported or looked up, then it has no entry name.
  1185. Arguments:
  1186. EntryNameSyntax - Supplies the entry name syntax which the caller
  1187. wants the entry name to be returned in. This may require that
  1188. we convert the entry name in the binding handle into a different
  1189. syntax.
  1190. EntryName - Returns the entry name of the binding handle in the
  1191. requested entry name syntax.
  1192. Return Value:
  1193. RPC_S_OK - This binding handle has an entry name, and we were able
  1194. to convert the entry name in the binding handle into the requested
  1195. entry name syntax.
  1196. RPC_S_NO_ENTRY_NAME - The binding handle does not have an entry
  1197. name. If this value is returned, the entry name return value
  1198. will be set to point to a newly allocated empty string.
  1199. RPC_S_INVALID_NAME_SYNTAX - The entry name in the binding handle
  1200. can not be converted to the entry name syntax requested.
  1201. RPC_S_UNSUPPORTED_NAME_SYNTAX - The entry name syntax requested
  1202. is not supported by the current configuration.
  1203. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete
  1204. the operation.
  1205. --*/
  1206. {
  1207. if ( this->EntryName == 0 )
  1208. {
  1209. *EntryName = AllocateEmptyStringPAPI();
  1210. if (*EntryName == 0)
  1211. return(RPC_S_OUT_OF_MEMORY);
  1212. return(RPC_S_NO_ENTRY_NAME);
  1213. }
  1214. //
  1215. // If he chose the default syntax and the binding has an entry,
  1216. // ask the name service for the default entry syntax.
  1217. // The NS dll should already be loaded because otherwise we'd not have an
  1218. // associated entry.
  1219. //
  1220. if (EntryNameSyntax == RPC_C_NS_SYNTAX_DEFAULT)
  1221. {
  1222. HINSTANCE NsDll = GetModuleHandle((const RPC_SCHAR *)pNS_DLL_NAME);
  1223. if (NsDll)
  1224. {
  1225. GET_DEFAULT_ENTRY_FN GetDefaultEntry =
  1226. (GET_DEFAULT_ENTRY_FN)
  1227. GetProcAddress(NsDll,
  1228. pNS_ENTRYPOINT_NAME
  1229. );
  1230. if (GetDefaultEntry)
  1231. {
  1232. EntryNameSyntax = (*GetDefaultEntry)();
  1233. }
  1234. else
  1235. {
  1236. //
  1237. // leave EntryNameSyntax zero; the fn will fail
  1238. // with invalid_name_syntax
  1239. //
  1240. }
  1241. }
  1242. else
  1243. {
  1244. //
  1245. // leave EntryNameSyntax zero; the fn will fail
  1246. // with invalid_name_syntax
  1247. //
  1248. }
  1249. }
  1250. if (EntryNameSyntax == this->EntryNameSyntax)
  1251. {
  1252. *EntryName = DuplicateStringPAPI(this->EntryName);
  1253. if (*EntryName == 0)
  1254. return(RPC_S_OUT_OF_MEMORY);
  1255. return(RPC_S_OK);
  1256. }
  1257. return(RPC_S_INVALID_NAME_SYNTAX);
  1258. }
  1259. RPC_STATUS
  1260. BINDING_HANDLE::SetEntryName (
  1261. IN unsigned long EntryNameSyntax,
  1262. IN RPC_CHAR PAPI * EntryName
  1263. )
  1264. /*++
  1265. Routine Description:
  1266. This method is used to set the entry name and entry name syntax
  1267. for a binding handle.
  1268. Arguments:
  1269. EntryNameSyntax - Supplies the syntax of the entry name argument.
  1270. EntryName - Supplies the entry name for this binding handle.
  1271. Return Value:
  1272. RPC_S_OK - We successfully set the entry name (and entry name syntax)
  1273. for this binding handle.
  1274. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to set the
  1275. entry name.
  1276. --*/
  1277. {
  1278. RPC_CHAR * NewEntryName;
  1279. NewEntryName = DuplicateString(EntryName);
  1280. if (NewEntryName == 0)
  1281. return(RPC_S_OUT_OF_MEMORY);
  1282. this->EntryNameSyntax = EntryNameSyntax;
  1283. if (this->EntryName != 0)
  1284. delete this->EntryName;
  1285. this->EntryName = NewEntryName;
  1286. return(RPC_S_OK);
  1287. }
  1288. RPC_STATUS
  1289. BINDING_HANDLE::InquireDynamicEndpoint (
  1290. OUT RPC_CHAR PAPI * PAPI * DynamicEndpoint
  1291. )
  1292. /*++
  1293. Routine Description:
  1294. This routine is used to obtain the dynamic endpoint from a binding
  1295. handle which was created from an rpc address. For all other binding
  1296. handles, we just return the fact that there is no dynamic endpoint.
  1297. Arguments:
  1298. DynamicEndpoint - Returns a pointer to the dynamic endpoint, if there
  1299. is one, or zero.
  1300. Return Value:
  1301. RPC_S_OK - This value will always be returned.
  1302. --*/
  1303. {
  1304. *DynamicEndpoint = 0;
  1305. return(RPC_S_OK);
  1306. }
  1307. int
  1308. BINDING_HANDLE::SetServerPrincipalName (
  1309. IN RPC_CHAR PAPI * ServerPrincipalName
  1310. )
  1311. /*++
  1312. Routine Description:
  1313. A protocol module will use this routine to set the principal name of
  1314. a server if it is not yet known.
  1315. Arguments;
  1316. ServerPrincipalName - Supplies the new principal name of the server.
  1317. Return Value:
  1318. Zero will be returned if this operation completes successfully; otherwise,
  1319. non-zero will be returned indicating that insufficient memory is available
  1320. to make a copy of the server principal name.
  1321. --*/
  1322. {
  1323. RequestGlobalMutex();
  1324. if ( ClientAuthInfo.ServerPrincipalName == 0 )
  1325. {
  1326. ClientAuthInfo.ServerPrincipalName = DuplicateString(ServerPrincipalName);
  1327. if ( ClientAuthInfo.ServerPrincipalName == 0 )
  1328. {
  1329. ClearGlobalMutex();
  1330. return(1);
  1331. }
  1332. }
  1333. ClearGlobalMutex();
  1334. return(0);
  1335. }
  1336. unsigned long
  1337. BINDING_HANDLE::MapAuthenticationLevel (
  1338. IN unsigned long AuthenticationLevel
  1339. )
  1340. /*++
  1341. Routine Description:
  1342. This method is to provide a way for a protocol module to map a requested
  1343. authentication level into one supported by that protocol module.
  1344. Arguments:
  1345. AuthenticationLevel - Supplies the proposed authentication level; this
  1346. value has already been validated.
  1347. Return Value:
  1348. The authentication level to be used is returned.
  1349. --*/
  1350. {
  1351. return(AuthenticationLevel);
  1352. }
  1353. BOOL
  1354. BINDING_HANDLE::SetTransportAuthentication(
  1355. IN unsigned long ulAuthenticationLevel,
  1356. IN unsigned long ulAuthenticationService,
  1357. OUT RPC_STATUS *pStatus )
  1358. /*
  1359. Routine Descritpion:
  1360. Called inside of SetAuthInformation(), this function allows for
  1361. transport level authentication to be set. If this function is not
  1362. overridden then it returns RPC_S_NOT_SUPPORTED and the normal RPC
  1363. level authentication is used.
  1364. */
  1365. {
  1366. *pStatus = RPC_S_CANNOT_SUPPORT;
  1367. return TRUE;
  1368. }
  1369. RPC_STATUS
  1370. BINDING_HANDLE::SendReceive (
  1371. IN OUT PRPC_MESSAGE Message
  1372. )
  1373. {
  1374. UNUSED(Message);
  1375. ASSERT( 0 );
  1376. return(RPC_S_INTERNAL_ERROR);
  1377. }
  1378. RPC_STATUS
  1379. BINDING_HANDLE::Send (
  1380. IN OUT PRPC_MESSAGE Message
  1381. )
  1382. {
  1383. UNUSED(Message);
  1384. ASSERT( 0 );
  1385. return(RPC_S_INTERNAL_ERROR);
  1386. }
  1387. RPC_STATUS
  1388. BINDING_HANDLE::Receive (
  1389. IN OUT PRPC_MESSAGE Message,
  1390. IN unsigned int Size
  1391. )
  1392. {
  1393. UNUSED(Message);
  1394. ASSERT( 0 );
  1395. return(RPC_S_INTERNAL_ERROR);
  1396. }
  1397. void
  1398. BINDING_HANDLE::FreeBuffer (
  1399. IN PRPC_MESSAGE Message
  1400. )
  1401. {
  1402. UNUSED(Message);
  1403. ASSERT( 0 );
  1404. }
  1405. RPC_STATUS
  1406. BINDING_HANDLE::ReAcquireCredentialsIfNecessary(
  1407. )
  1408. {
  1409. LUID CurrentModifiedId;
  1410. RPC_STATUS Status = CaptureModifiedId(&CurrentModifiedId);
  1411. SECURITY_CREDENTIALS * SecurityCredentials;
  1412. BOOL MyDefaultLogonId;
  1413. if (Status == RPC_S_OK)
  1414. {
  1415. MyDefaultLogonId = FALSE;
  1416. }
  1417. else
  1418. {
  1419. MyDefaultLogonId = TRUE;
  1420. }
  1421. if (MyDefaultLogonId != ClientAuthInfo.DefaultLogonId
  1422. || (MyDefaultLogonId == FALSE
  1423. && (FastCompareLUIDAligned(&CurrentModifiedId,
  1424. &ClientAuthInfo.ModifiedId) == FALSE)))
  1425. {
  1426. ClientAuthInfo.DefaultLogonId = MyDefaultLogonId;
  1427. Status = RPC_S_OK;
  1428. SecurityCredentials = new SECURITY_CREDENTIALS(&Status);
  1429. if ((SecurityCredentials == 0) || (Status != RPC_S_OK))
  1430. {
  1431. if (SecurityCredentials == 0)
  1432. {
  1433. Status = RPC_S_OUT_OF_MEMORY;
  1434. }
  1435. delete SecurityCredentials;
  1436. return (Status);
  1437. }
  1438. // Dynamic identity tracking - need to get the current credentials.
  1439. Status = SecurityCredentials->AcquireCredentialsForClient(
  1440. ClientAuthInfo.AuthIdentity,
  1441. ClientAuthInfo.AuthenticationService,
  1442. ClientAuthInfo.AuthenticationLevel
  1443. );
  1444. if ( Status != RPC_S_OK )
  1445. {
  1446. VALIDATE(Status)
  1447. {
  1448. RPC_S_OUT_OF_MEMORY,
  1449. RPC_S_UNKNOWN_AUTHN_SERVICE,
  1450. RPC_S_UNKNOWN_AUTHN_LEVEL,
  1451. RPC_S_SEC_PKG_ERROR,
  1452. ERROR_SHUTDOWN_IN_PROGRESS,
  1453. RPC_S_INVALID_AUTH_IDENTITY
  1454. } END_VALIDATE;
  1455. delete SecurityCredentials;
  1456. return(Status);
  1457. }
  1458. if (ClientAuthInfo.CredentialsMatch(SecurityCredentials) != 0)
  1459. {
  1460. SecurityCredentials->DereferenceCredentials();
  1461. }
  1462. else
  1463. {
  1464. BindingMutex.Request();
  1465. if (ClientAuthInfo.Credentials != 0)
  1466. {
  1467. ClientAuthInfo.Credentials->DereferenceCredentials();
  1468. }
  1469. ClientAuthInfo.Credentials = SecurityCredentials;
  1470. BindingMutex.Clear();
  1471. }
  1472. FastCopyLUIDAligned(&ClientAuthInfo.ModifiedId, &CurrentModifiedId);
  1473. }
  1474. return (RPC_S_OK);
  1475. }
  1476. RPC_STATUS
  1477. BINDING_HANDLE::SetTransportOption( IN unsigned long option,
  1478. IN ULONG_PTR optionValue )
  1479. {
  1480. if (option > RPC_C_OPT_MAX_OPTIONS)
  1481. {
  1482. return RPC_S_INVALID_ARG;
  1483. }
  1484. if (OptionsVector == NULL)
  1485. {
  1486. BindingMutex.Request();
  1487. if (OptionsVector == NULL)
  1488. {
  1489. OptionsVector = new ULONG_PTR[ RPC_C_OPT_MAX_OPTIONS ];
  1490. if (OptionsVector == 0)
  1491. {
  1492. BindingMutex.Clear();
  1493. return RPC_S_OUT_OF_MEMORY;
  1494. }
  1495. RpcpMemorySet(OptionsVector, 0, RPC_C_OPT_MAX_OPTIONS * sizeof(OptionsVector[0]) );
  1496. }
  1497. BindingMutex.Clear();
  1498. }
  1499. OptionsVector[option] = optionValue;
  1500. return RPC_S_OK;
  1501. }
  1502. RPC_STATUS
  1503. BINDING_HANDLE::InqTransportOption( IN unsigned long option,
  1504. OUT ULONG_PTR * pOptionValue )
  1505. {
  1506. if (OptionsVector == NULL)
  1507. {
  1508. *pOptionValue = 0;
  1509. }
  1510. else
  1511. {
  1512. *pOptionValue = OptionsVector[option];
  1513. }
  1514. return RPC_S_OK;
  1515. }
  1516. RPC_STATUS
  1517. CALL::Send (
  1518. IN OUT PRPC_MESSAGE Message
  1519. )
  1520. /*++
  1521. Function Name:Send
  1522. Parameters:
  1523. Description:
  1524. Returns:
  1525. --*/
  1526. {
  1527. ASSERT(!"improper CCALL member called\n");
  1528. return (RPC_S_CANNOT_SUPPORT) ;
  1529. }
  1530. RPC_STATUS
  1531. CALL::Receive (
  1532. IN OUT PRPC_MESSAGE Message,
  1533. IN unsigned int Size
  1534. )
  1535. /*++
  1536. Function Name:Receive
  1537. Parameters:
  1538. Description:
  1539. Returns:
  1540. --*/
  1541. {
  1542. ASSERT(!"improper CCALL member called\n");
  1543. return (RPC_S_CANNOT_SUPPORT) ;
  1544. }
  1545. RPC_STATUS
  1546. CALL::AsyncSend (
  1547. IN OUT PRPC_MESSAGE Message
  1548. )
  1549. /*++
  1550. Function Name:AsyncSend
  1551. Parameters:
  1552. Description:
  1553. Returns:
  1554. --*/
  1555. {
  1556. ASSERT(!"improper CCALL member called\n");
  1557. return (RPC_S_CANNOT_SUPPORT) ;
  1558. }
  1559. RPC_STATUS
  1560. CALL::AsyncReceive (
  1561. IN OUT PRPC_MESSAGE Message,
  1562. IN unsigned int Size
  1563. )
  1564. /*++
  1565. Function Name:AsyncReceive
  1566. Parameters:
  1567. Description:
  1568. Returns:
  1569. --*/
  1570. {
  1571. ASSERT(!"improper CCALL member called\n");
  1572. return (RPC_S_CANNOT_SUPPORT) ;
  1573. }
  1574. RPC_STATUS
  1575. CALL::AbortAsyncCall (
  1576. IN PRPC_ASYNC_STATE pAsync,
  1577. IN unsigned long ExceptionCode
  1578. )
  1579. /*++
  1580. Function Name:AbortAsyncCall
  1581. Parameters:
  1582. Description:
  1583. Returns:
  1584. --*/
  1585. {
  1586. ASSERT(!"improper CCALL member called\n");
  1587. return (RPC_S_CANNOT_SUPPORT) ;
  1588. }
  1589. void
  1590. CALL::ProcessResponse (
  1591. IN BOOL fDirectCall
  1592. )
  1593. /*++
  1594. Function Name:ProcessResponse
  1595. Parameters:
  1596. Description:
  1597. Returns:
  1598. --*/
  1599. {
  1600. }
  1601. void
  1602. CALL::FreeAPCInfo (
  1603. IN RPC_APC_INFO *pAPCInfo
  1604. )
  1605. /*++
  1606. Function Name:FreeAPCInfo
  1607. Parameters:
  1608. Description:
  1609. Returns:
  1610. --*/
  1611. {
  1612. if (pAPCInfo == &CachedAPCInfo)
  1613. {
  1614. CachedAPCInfoAvailable = 1;
  1615. }
  1616. else
  1617. {
  1618. delete pAPCInfo ;
  1619. }
  1620. }
  1621. BOOL
  1622. CALL::QueueAPC (
  1623. IN RPC_ASYNC_EVENT Event,
  1624. IN void *Context
  1625. )
  1626. /*++
  1627. Function Name:QueueAPC
  1628. Parameters:
  1629. Description:
  1630. Returns:
  1631. --*/
  1632. {
  1633. RPC_APC_INFO *pAPCInfo ;
  1634. HANDLE hThread ;
  1635. if (CachedAPCInfoAvailable)
  1636. {
  1637. pAPCInfo = &CachedAPCInfo ;
  1638. CachedAPCInfoAvailable = 0;
  1639. }
  1640. else
  1641. {
  1642. pAPCInfo = new RPC_APC_INFO ;
  1643. }
  1644. if (pAPCInfo == 0)
  1645. {
  1646. return 0 ;
  1647. }
  1648. pAPCInfo->Context = Context;
  1649. pAPCInfo->Event = Event ;
  1650. pAPCInfo->pAsync = pAsync ;
  1651. pAPCInfo->hCall = this ;
  1652. if (pAsync->u.APC.hThread)
  1653. {
  1654. hThread = pAsync->u.APC.hThread ;
  1655. }
  1656. else
  1657. {
  1658. hThread = CallingThread->ThreadHandle() ;
  1659. }
  1660. if (!QueueUserAPC(
  1661. (PAPCFUNC) I_RpcAPCRoutine,
  1662. hThread,
  1663. (ULONG_PTR) pAPCInfo))
  1664. {
  1665. #if DBG
  1666. PrintToDebugger("RPC: QueueUserAPC failed: %d\n", GetLastError());
  1667. #endif
  1668. return 0 ;
  1669. }
  1670. return 1;
  1671. }
  1672. BOOL
  1673. RpcPostMessageWrapper (
  1674. HWND hWnd,
  1675. UINT Msg,
  1676. WPARAM wParam,
  1677. LPARAM lParam);
  1678. typedef BOOL (*RPCPOSTMESSAGE) (
  1679. HWND hWnd,
  1680. UINT Msg,
  1681. WPARAM wParam,
  1682. LPARAM lParam);
  1683. RPCPOSTMESSAGE RpcPostMessage = RpcPostMessageWrapper;
  1684. BOOL
  1685. RpcPostMessageWrapper (
  1686. HWND hWnd,
  1687. UINT Msg,
  1688. WPARAM wParam,
  1689. LPARAM lParam)
  1690. /*++
  1691. Function Name:RpcPostMessageWrapper
  1692. Parameters:
  1693. Description:
  1694. Returns:
  1695. --*/
  1696. {
  1697. HMODULE hLibrary;
  1698. if (RpcPostMessage == RpcPostMessageWrapper)
  1699. {
  1700. GlobalMutexRequest();
  1701. if (RpcPostMessage == RpcPostMessageWrapper)
  1702. {
  1703. hLibrary = LoadLibrary(RPC_CONST_SSTRING("user32.dll"));
  1704. if (hLibrary == 0)
  1705. {
  1706. GlobalMutexClear();
  1707. return FALSE;
  1708. }
  1709. RpcPostMessage =
  1710. (RPCPOSTMESSAGE) GetProcAddress(hLibrary, "PostMessageW");
  1711. if (RpcPostMessage == 0)
  1712. {
  1713. RpcPostMessage = RpcPostMessageWrapper;
  1714. FreeLibrary(hLibrary);
  1715. GlobalMutexClear();
  1716. return FALSE;
  1717. }
  1718. }
  1719. GlobalMutexClear();
  1720. }
  1721. return RpcPostMessage(hWnd, Msg, wParam, lParam);
  1722. }
  1723. BOOL
  1724. CALL::IssueNotificationEntry (
  1725. IN RPC_ASYNC_EVENT Event
  1726. )
  1727. {
  1728. int Retries = 0;
  1729. if (pAsync == 0
  1730. || (Event == RpcCallComplete
  1731. && InterlockedIncrement(&NotificationIssued) > 0))
  1732. {
  1733. #if DBG
  1734. PrintToDebugger("RPC: IssueCallCompleteNotification was a no-op\n") ;
  1735. #endif
  1736. return 0;
  1737. }
  1738. // an unlikely, but possible race condition - the send thread hasn't
  1739. // reached back the NDR code, which means the NdrLock is still held -
  1740. // we cannot issue a notification until this is released, or the
  1741. // client thread cannot complete the call
  1742. while (TRUE)
  1743. {
  1744. if (pAsync->Lock > 0)
  1745. {
  1746. PauseExecution(200);
  1747. // yes, we don't break if the Retries go through the roof -
  1748. // this is just to figure out how many times we have looped
  1749. // on a checked build
  1750. Retries ++;
  1751. }
  1752. else
  1753. break;
  1754. }
  1755. ASSERT(pAsync->Size == RPC_ASYNC_VERSION_1_0);
  1756. LogEvent(SU_SCALL, EV_NOTIFY, CallingThread, this, (ULONG_PTR) pAsync, 1);
  1757. pAsync->Event = Event;
  1758. return 1;
  1759. }
  1760. BOOL
  1761. CALL::IssueNotificationMain (
  1762. IN RPC_ASYNC_EVENT Event
  1763. )
  1764. {
  1765. switch (pAsync->NotificationType)
  1766. {
  1767. case RpcNotificationTypeNone:
  1768. break;
  1769. case RpcNotificationTypeHwnd:
  1770. RpcPostMessage(
  1771. pAsync->u.HWND.hWnd,
  1772. pAsync->u.HWND.Msg,
  1773. 0,
  1774. (LPARAM) pAsync) ;
  1775. break;
  1776. case RpcNotificationTypeCallback:
  1777. pAsync->u.NotificationRoutine(pAsync, 0, Event);
  1778. break;
  1779. case RpcNotificationTypeEvent:
  1780. if (!SetEvent(pAsync->u.hEvent))
  1781. {
  1782. #if DBG
  1783. PrintToDebugger("RPC: SetEvent failed: %d\n", GetLastError());
  1784. #endif
  1785. return 0;
  1786. }
  1787. break;
  1788. case RpcNotificationTypeApc:
  1789. if (!QueueAPC(Event))
  1790. {
  1791. #if DBG
  1792. PrintToDebugger("RPC: QueueAPC failed\n");
  1793. #endif
  1794. return 0;
  1795. }
  1796. break;
  1797. case RpcNotificationTypeIoc:
  1798. if (!PostQueuedCompletionStatus(
  1799. pAsync->u.IOC.hIOPort,
  1800. pAsync->u.IOC.dwNumberOfBytesTransferred,
  1801. pAsync->u.IOC.dwCompletionKey,
  1802. pAsync->u.IOC.lpOverlapped))
  1803. {
  1804. #if DBG
  1805. PrintToDebugger("RPC: PostQueuedCompletionStatus failed %d\n",
  1806. GetLastError());
  1807. #endif
  1808. return 0;
  1809. }
  1810. break;
  1811. default:
  1812. ASSERT(!"Invalid notification type") ;
  1813. return 0;
  1814. }
  1815. return 1;
  1816. }
  1817. BOOL
  1818. CALL::IssueNotification (
  1819. IN RPC_ASYNC_EVENT Event
  1820. )
  1821. /*++
  1822. Function Name:IssueNotification
  1823. Parameters:
  1824. Description:
  1825. Returns:
  1826. --*/
  1827. {
  1828. if (IssueNotificationEntry(Event))
  1829. return IssueNotificationMain(Event);
  1830. else
  1831. return 0;
  1832. }
  1833. void
  1834. CALL::ProcessEvent (
  1835. )
  1836. /*++
  1837. Function Name:ProcessEvent
  1838. Parameters:
  1839. Description:
  1840. Returns:
  1841. --*/
  1842. {
  1843. ASSERT(0) ;
  1844. }
  1845. RPC_STATUS
  1846. DispatchCallback(
  1847. IN PRPC_DISPATCH_TABLE DispatchTableCallback,
  1848. IN OUT PRPC_MESSAGE Message,
  1849. OUT RPC_STATUS PAPI * ExceptionCode
  1850. )
  1851. /*++
  1852. Routine Description:
  1853. This method is used to dispatch remote procedure calls to the
  1854. appropriate stub and hence to the appropriate manager entry point.
  1855. This routine is used for calls having a null UUID (implicit or
  1856. explicit).
  1857. Arguments:
  1858. DispatchTableCallback - Callback table.
  1859. Message - Supplies the response message and returns the reply
  1860. message.
  1861. ExceptionCode - Returns the remote exception code if
  1862. RPC_P_EXCEPTION_OCCURED is returned.
  1863. Return Value:
  1864. RPC_S_OK - Everything worked just fine.
  1865. RPC_P_EXCEPTION_OCCURED - An exception of some sort occured. The
  1866. exact exception code will be returned in the ExceptionCode
  1867. argument.
  1868. RPC_S_PROCNUM_OUT_OF_RANGE - The supplied operation number in the
  1869. message is too large.
  1870. --*/
  1871. {
  1872. RPC_STATUS RpcStatus = RPC_S_OK;
  1873. void PAPI *OriginalBuffer = Message->Buffer;
  1874. // N.B. We could reset the flag after sendreceive is completed for
  1875. // each protocol engine
  1876. Message->RpcFlags |= RPC_BUFFER_COMPLETE ;
  1877. if ( Message->ProcNum >= DispatchTableCallback->DispatchTableCount )
  1878. {
  1879. return(RPC_S_PROCNUM_OUT_OF_RANGE);
  1880. }
  1881. Message->ManagerEpv = 0;
  1882. RpcpPurgeEEInfo();
  1883. if ( DispatchToStubInC(DispatchTableCallback->DispatchTable[
  1884. Message->ProcNum], Message, ExceptionCode) != 0 )
  1885. {
  1886. RpcStatus = RPC_P_EXCEPTION_OCCURED;
  1887. }
  1888. if (((MESSAGE_OBJECT *) Message->Handle)->IsSyncCall())
  1889. {
  1890. if (OriginalBuffer == Message->Buffer && RpcStatus == RPC_S_OK)
  1891. {
  1892. //
  1893. // If the stub has NO out data, it may skip the call to
  1894. // I_RpcGetBuffer(). If it called I_RpcGetBuffer and
  1895. // still has the same Buffer, we have a bug!
  1896. //
  1897. Message->BufferLength = 0;
  1898. ((MESSAGE_OBJECT *) Message->Handle)->GetBuffer(Message, 0);
  1899. }
  1900. }
  1901. return(RpcStatus);
  1902. }
  1903. /* ====================================================================
  1904. Client DLL initialization routine.
  1905. ==================================================================== */
  1906. int
  1907. InitializeClientDLL (void
  1908. )
  1909. {
  1910. // We don't want to do this under DOS. The first time
  1911. // LoadableTransportClientInfo (in tranclnt.cxx) is called, it will
  1912. // perform the appropriate initialization. See the first few lines
  1913. // of that routine for more description.
  1914. if (InitializeLoadableTransportClient() != 0)
  1915. return(1);
  1916. if (InitializeRpcProtocolOfsClient() != 0)
  1917. return(1);
  1918. if (InitializeRpcProtocolDgClient() != 0)
  1919. return(1);
  1920. return(0);
  1921. }
  1922. RPC_STATUS
  1923. BINDING_HANDLE::SetAuthInformation (
  1924. IN RPC_CHAR PAPI * ServerPrincipalName, OPTIONAL
  1925. IN unsigned long AuthenticationLevel,
  1926. IN unsigned long AuthenticationService,
  1927. IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, OPTIONAL
  1928. IN unsigned long AuthorizationService,
  1929. IN SECURITY_CREDENTIALS * Credentials,
  1930. IN unsigned long ImpersonationType,
  1931. IN unsigned long IdentityTracking,
  1932. IN unsigned long Capabilities,
  1933. IN BOOL bAcquireNewCredentials, OPTIONAL
  1934. IN ULONG AdditionalTransportCredentialsType, OPTIONAL
  1935. IN void *AdditionalCredentials OPTIONAL
  1936. )
  1937. /*++
  1938. Routine Description:
  1939. We set the authentication and authorization information in this binding
  1940. handle.
  1941. Arguments:
  1942. ServerPrincipalName - Optionally supplies the server principal name.
  1943. AuthenticationLevel - Supplies the authentication level to use.
  1944. AuthenticationService - Supplies the authentication service to use.
  1945. AuthIdentity - Optionally supplies the security context to use.
  1946. AuthorizationService - Supplies the authorization service to use.
  1947. AdditionalTransportCredentialsType - the type of additional credentials
  1948. supplied in AdditionalCredentials
  1949. AdditionalCredentials - pointer to additional credentials if any
  1950. Return Value:
  1951. RPC_S_OK - The supplied authentication and authorization information has
  1952. been set in the binding handle.
  1953. RPC_S_OUT_OF_MEMORY - Insufficient memory is available to complete the
  1954. operation.
  1955. RPC_S_UNKNOWN_AUTHN_SERVICE - The specified authentication service is
  1956. not supported.
  1957. RPC_S_UNKNOWN_AUTHN_LEVEL - The specified authentication level is
  1958. not supported.
  1959. RPC_S_INVALID_AUTH_IDENTITY - The specified security context (supplied
  1960. by the auth identity argument) is invalid.
  1961. RPC_S_UNKNOWN_AUTHZ_SERVICE - The specified authorization service is
  1962. not supported.
  1963. --*/
  1964. {
  1965. RPC_CHAR * NewString;
  1966. RPC_STATUS RpcStatus = RPC_S_OK;
  1967. SECURITY_CREDENTIALS * SecurityCredentials = NULL;
  1968. unsigned long MappedAuthenticationLevel;
  1969. if ( AuthenticationLevel == RPC_C_AUTHN_LEVEL_DEFAULT )
  1970. {
  1971. RpcpGetDefaultSecurityProviderInfo();
  1972. AuthenticationLevel = DefaultAuthLevel;
  1973. }
  1974. if ( AuthenticationLevel > RPC_C_AUTHN_LEVEL_PKT_PRIVACY )
  1975. {
  1976. return(RPC_S_UNKNOWN_AUTHN_LEVEL);
  1977. }
  1978. MappedAuthenticationLevel = MapAuthenticationLevel(AuthenticationLevel);
  1979. ASSERT( MappedAuthenticationLevel != RPC_C_AUTHN_LEVEL_DEFAULT &&
  1980. MappedAuthenticationLevel <= RPC_C_AUTHN_LEVEL_PKT_PRIVACY );
  1981. //
  1982. // See if this is transport level authentication:
  1983. //
  1984. if (!SetTransportAuthentication( MappedAuthenticationLevel,
  1985. AuthenticationService,
  1986. &RpcStatus ))
  1987. {
  1988. return RpcStatus;
  1989. }
  1990. RpcStatus = RPC_S_OK;
  1991. ASSERT((AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  1992. || (AdditionalTransportCredentialsType == 0));
  1993. if (AdditionalTransportCredentialsType == RPC_C_AUTHN_INFO_TYPE_HTTP)
  1994. {
  1995. ClientAuthInfo.AdditionalCredentials
  1996. = DuplicateHttpTransportCredentials (
  1997. (const RPC_HTTP_TRANSPORT_CREDENTIALS_W *) AdditionalCredentials);
  1998. if (ClientAuthInfo.AdditionalCredentials == NULL)
  1999. return RPC_S_OUT_OF_MEMORY;
  2000. if (((RPC_HTTP_TRANSPORT_CREDENTIALS_W *)(ClientAuthInfo.AdditionalCredentials))->TransportCredentials)
  2001. {
  2002. RpcStatus = EncryptAuthIdentity(((RPC_HTTP_TRANSPORT_CREDENTIALS_W *)(ClientAuthInfo.AdditionalCredentials))->TransportCredentials);
  2003. if (RpcStatus != RPC_S_OK)
  2004. {
  2005. FreeAuthIdentity(((RPC_HTTP_TRANSPORT_CREDENTIALS_W *)ClientAuthInfo.AdditionalCredentials)->TransportCredentials);
  2006. return RpcStatus;
  2007. }
  2008. }
  2009. }
  2010. else
  2011. {
  2012. ASSERT(AdditionalCredentials == NULL);
  2013. }
  2014. //
  2015. // Clear out stuff for NULL AUTHN_SVC
  2016. //
  2017. if (AuthenticationService == RPC_C_AUTHN_NONE)
  2018. {
  2019. //
  2020. // Dereference Credentials.. ServerPrincipal Name is
  2021. // handled by deleting CLIENT_AUTH_INFO .. Each AUTH_INFO explicitly
  2022. // copy the credentials around...
  2023. //
  2024. if (ClientAuthInfo.Credentials != 0)
  2025. {
  2026. ClientAuthInfo.Credentials->DereferenceCredentials();
  2027. ClientAuthInfo.Credentials = 0;
  2028. }
  2029. }
  2030. else
  2031. {
  2032. if (bAcquireNewCredentials == FALSE)
  2033. {
  2034. ASSERT(Credentials);
  2035. Credentials->ReferenceCredentials();
  2036. SecurityCredentials = Credentials;
  2037. }
  2038. else
  2039. {
  2040. SecurityCredentials = new SECURITY_CREDENTIALS(&RpcStatus);
  2041. if ((SecurityCredentials == 0) || (RpcStatus != RPC_S_OK))
  2042. {
  2043. if (SecurityCredentials == 0)
  2044. {
  2045. RpcStatus = RPC_S_OUT_OF_MEMORY;
  2046. }
  2047. delete SecurityCredentials;
  2048. return (RpcStatus);
  2049. }
  2050. RpcStatus = SecurityCredentials->AcquireCredentialsForClient(
  2051. AuthIdentity,
  2052. AuthenticationService,
  2053. MappedAuthenticationLevel
  2054. );
  2055. if ( RpcStatus != RPC_S_OK )
  2056. {
  2057. VALIDATE(RpcStatus)
  2058. {
  2059. RPC_S_OUT_OF_MEMORY,
  2060. RPC_S_UNKNOWN_AUTHN_SERVICE,
  2061. RPC_S_UNKNOWN_AUTHN_LEVEL,
  2062. RPC_S_SEC_PKG_ERROR,
  2063. ERROR_SHUTDOWN_IN_PROGRESS,
  2064. RPC_S_INVALID_AUTH_IDENTITY
  2065. } END_VALIDATE;
  2066. delete SecurityCredentials;
  2067. return(RpcStatus);
  2068. }
  2069. }
  2070. if (ARGUMENT_PRESENT(ServerPrincipalName))
  2071. {
  2072. //
  2073. // SSL has unique SPN requirements.
  2074. //
  2075. if (AuthenticationService == RPC_C_AUTHN_GSS_SCHANNEL)
  2076. {
  2077. RpcStatus = ValidateSchannelPrincipalName(ServerPrincipalName);
  2078. if (RpcStatus != RPC_S_OK)
  2079. {
  2080. VALIDATE(RpcStatus)
  2081. {
  2082. ERROR_INVALID_PARAMETER
  2083. }
  2084. END_VALIDATE;
  2085. if (SecurityCredentials)
  2086. SecurityCredentials->DereferenceCredentials();
  2087. return RpcStatus;
  2088. }
  2089. }
  2090. NewString = DuplicateString(ServerPrincipalName);
  2091. if ( NewString == 0 )
  2092. {
  2093. if (SecurityCredentials)
  2094. SecurityCredentials->DereferenceCredentials();
  2095. return(RPC_S_OUT_OF_MEMORY);
  2096. }
  2097. RequestGlobalMutex();
  2098. if ( ClientAuthInfo.ServerPrincipalName != 0 )
  2099. {
  2100. delete ClientAuthInfo.ServerPrincipalName;
  2101. }
  2102. ClientAuthInfo.ServerPrincipalName = NewString;
  2103. ClearGlobalMutex();
  2104. }
  2105. if ( (ClientAuthInfo.Credentials != 0 ) &&
  2106. (ClientAuthInfo.CredentialsMatch(SecurityCredentials) != 0) )
  2107. {
  2108. SecurityCredentials->DereferenceCredentials();
  2109. }
  2110. else
  2111. {
  2112. if (ClientAuthInfo.Credentials != 0)
  2113. {
  2114. ClientAuthInfo.Credentials->DereferenceCredentials();
  2115. }
  2116. ClientAuthInfo.Credentials = SecurityCredentials;
  2117. }
  2118. if (IdentityTracking == RPC_C_QOS_IDENTITY_DYNAMIC)
  2119. {
  2120. RpcStatus = CaptureModifiedId(&ClientAuthInfo.ModifiedId);
  2121. //
  2122. // If The Thread is not impersonating CaptureLogonId fails
  2123. // All failures get treated as if this process is using *default*
  2124. // identity. Mark the AuthId as such and proceed
  2125. //
  2126. if (RpcStatus != RPC_S_OK)
  2127. {
  2128. ClientAuthInfo.DefaultLogonId = TRUE;
  2129. }
  2130. else
  2131. {
  2132. ClientAuthInfo.DefaultLogonId = FALSE;
  2133. }
  2134. }
  2135. }
  2136. ClientAuthInfo.AuthenticationService = AuthenticationService;
  2137. ClientAuthInfo.AuthorizationService = AuthorizationService;
  2138. ClientAuthInfo.AuthIdentity = AuthIdentity;
  2139. ClientAuthInfo.AdditionalTransportCredentialsType
  2140. = AdditionalTransportCredentialsType;
  2141. if (AuthenticationService == RPC_C_AUTHN_NONE)
  2142. {
  2143. ClientAuthInfo.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC;
  2144. ClientAuthInfo.AuthenticationLevel = RPC_C_AUTHN_LEVEL_NONE;
  2145. }
  2146. else
  2147. {
  2148. ClientAuthInfo.AuthenticationLevel = MappedAuthenticationLevel;
  2149. ClientAuthInfo.IdentityTracking = IdentityTracking;
  2150. }
  2151. ClientAuthInfo.ImpersonationType = ImpersonationType;
  2152. ClientAuthInfo.Capabilities = Capabilities;
  2153. return(RPC_S_OK);
  2154. }
  2155. const RPC_SYNTAX_IDENTIFIER NDR20TransferSyntaxValue
  2156. = {{0x8A885D04, 0x1CEB, 0x11C9, {0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60}}, {2, 0}};
  2157. const RPC_SYNTAX_IDENTIFIER *NDR20TransferSyntax = &NDR20TransferSyntaxValue;
  2158. const RPC_SYNTAX_IDENTIFIER NDR64TransferSyntaxValue
  2159. = {{0x71710533, 0xBEBA, 0x4937, {0x83, 0x19, 0xB5, 0xDB, 0xEF, 0x9C, 0xCC, 0x36}}, {1, 0}};
  2160. const RPC_SYNTAX_IDENTIFIER *NDR64TransferSyntax = &NDR64TransferSyntaxValue;
  2161. const RPC_SYNTAX_IDENTIFIER NDRTestTransferSyntaxValue
  2162. = {{0xb4537da9, 0x3d03, 0x4f6b, {0xb5, 0x94, 0x52, 0xb2, 0x87, 0x4e, 0xe9, 0xd0}}, {1, 0}};
  2163. const RPC_SYNTAX_IDENTIFIER *NDRTestTransferSyntax = &NDRTestTransferSyntaxValue;