Leaked source code of windows server 2003
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.

1402 lines
43 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. stub.c
  5. Abstract:
  6. Kerberos Security Support Provider client stubs.
  7. Author:
  8. Chandana Surlu (ChandanS) 11-Feb-1997
  9. Environment: Win9x User Mode
  10. Revision History:
  11. --*/
  12. #include <kerb.hxx>
  13. #include <rpc.h> // PSEC_WINNT_AUTH_IDENTITY
  14. #include <stdarg.h> // Variable-length argument support
  15. #define KERBSTUB_ALLOCATE
  16. #include <kerbp.h>
  17. SECPKG_DLL_FUNCTIONS UserFunctionTable;
  18. VOID
  19. KerbShutdownSecurityInterface(
  20. VOID
  21. );
  22. VOID DumpLogonSession();
  23. BOOL WINAPI DllMain(
  24. HINSTANCE hInstance,
  25. ULONG dwReason,
  26. PVOID lpReserved)
  27. {
  28. if (dwReason == DLL_PROCESS_ATTACH)
  29. {
  30. InitializeCriticalSection( &KerbDllCritSect );
  31. #if DBG
  32. InitializeCriticalSection( &KerbGlobalLogFileCritSect );
  33. KerbInfoLevel = DEB_ERROR | DEB_WARN | DEB_TRACE | DEB_TRACE_API |
  34. DEB_TRACE_CRED | DEB_TRACE_CTXT | DEB_TRACE_LOCKS |
  35. DEB_TRACE_CTXT2 | DEB_TRACE_KDC | DEB_TRACE_LSESS |
  36. DEB_TRACE_LOGON;
  37. #endif // DBG
  38. }
  39. else if (dwReason == DLL_PROCESS_DETACH)
  40. {
  41. KerbShutdownSecurityInterface();
  42. #if DBG
  43. DeleteCriticalSection( &KerbGlobalLogFileCritSect );
  44. #endif // DBG
  45. DeleteCriticalSection( &KerbDllCritSect );
  46. }
  47. return TRUE;
  48. }
  49. PSecurityFunctionTable
  50. InitSecurityInterfaceA(
  51. VOID
  52. )
  53. /*++
  54. Routine Description:
  55. RPC calls this function to get the addresses of all the other functions
  56. that it might call.
  57. Arguments:
  58. None.
  59. Return Value:
  60. A pointer to our static SecurityFunctionTable. The caller need
  61. not deallocate this table.
  62. --*/
  63. {
  64. HKEY hRegKey;
  65. DWORD dwError = 0, dwSize = 0;
  66. DWORD dwType = REG_BINARY;
  67. LPWSTR pUserName = NULL, pDomainName = NULL;
  68. PKERB_LOGON_SESSION_CACHE RegLogonSession = NULL;
  69. PKERB_LOGON_SESSION LogonSession = NULL;
  70. SECURITY_STATUS Status = SEC_E_OK;
  71. // BUBUG Init this to something, we need Parameters.DomainName,
  72. // Parameters.DnsDomainName & Parameters.version at least
  73. SECPKG_PARAMETERS Parameters;
  74. PVOID ignored = NULL;
  75. DebugLog((DEB_TRACE_API, "Entering KerbInitSecurityInterface\n"));
  76. // Initialize the SecurityFunctionTable
  77. ZeroMemory( &KerbDllSecurityFunctionTable,
  78. sizeof(KerbDllSecurityFunctionTable) );
  79. KerbGlobalCapabilities = KERBEROS_CAPABILITIES;
  80. KerberosState = KerberosUserMode;
  81. KerbDllSecurityFunctionTable.dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION;
  82. KerbDllSecurityFunctionTable.EnumerateSecurityPackages = KerbEnumerateSecurityPackages;
  83. KerbDllSecurityFunctionTable.AcquireCredentialsHandle = KerbAcquireCredentialsHandle;
  84. KerbDllSecurityFunctionTable.FreeCredentialHandle = KerbFreeCredentialsHandle;
  85. KerbDllSecurityFunctionTable.InitializeSecurityContext = KerbInitializeSecurityContext;
  86. KerbDllSecurityFunctionTable.QueryCredentialsAttributes = KerbQueryCredentialsAttributes;
  87. KerbDllSecurityFunctionTable.AcceptSecurityContext = NULL;
  88. KerbDllSecurityFunctionTable.CompleteAuthToken = KerbCompleteAuthToken;
  89. KerbDllSecurityFunctionTable.QueryContextAttributes = KerbQueryContextAttributes;
  90. KerbDllSecurityFunctionTable.SspiLogonUser = KerbSspiLogonUser;
  91. KerbDllSecurityFunctionTable.DeleteSecurityContext = KerbDeleteSecurityContext;
  92. KerbDllSecurityFunctionTable.ApplyControlToken = KerbApplyControlToken;
  93. KerbDllSecurityFunctionTable.ImpersonateSecurityContext = KerbImpersonateSecurityContext;
  94. KerbDllSecurityFunctionTable.RevertSecurityContext = KerbRevertSecurityContext;
  95. KerbDllSecurityFunctionTable.MakeSignature = KerbMakeSignature;
  96. KerbDllSecurityFunctionTable.VerifySignature = KerbVerifySignature;
  97. KerbDllSecurityFunctionTable.FreeContextBuffer = KerbFreeContextBuffer;
  98. KerbDllSecurityFunctionTable.QuerySecurityPackageInfo = KerbQuerySecurityPackageInfo;
  99. KerbDllSecurityFunctionTable.Reserved3 = KerbSealMessage;
  100. KerbDllSecurityFunctionTable.Reserved4 = KerbUnsealMessage;
  101. KerbDllSecurityFunctionTable.EncryptMessage = KerbSealMessage;
  102. KerbDllSecurityFunctionTable.DecryptMessage = KerbUnsealMessage;
  103. // Before we call SpInitialize, fill a table of LsaFunctions that are
  104. // imlemented locally. This is done so that the code does not look awful.
  105. // Fill in dummy functions in case more functions are used so we don't
  106. // av
  107. // FunctionTable.CreateLogonSession = CreateLogonSession;
  108. // FunctionTable.DeleteLogonSession = DeleteLogonSession;
  109. // FunctionTable.AddCredential = AddCredential;
  110. // FunctionTable.GetCredentials = GetCredentials;
  111. // FunctionTable.DeleteCredential = DeleteCredential;
  112. FunctionTable.AllocateLsaHeap = AllocateLsaHeap;
  113. FunctionTable.FreeLsaHeap = FreeLsaHeap;
  114. FunctionTable.AllocateClientBuffer = AllocateClientBuffer;
  115. FunctionTable.FreeClientBuffer = FreeClientBuffer;
  116. FunctionTable.CopyToClientBuffer = CopyToClientBuffer;
  117. FunctionTable.CopyFromClientBuffer = CopyFromClientBuffer;
  118. // FunctionTable.ImpersonateClient = ImperosnateClient;
  119. // FunctionTable.UnloadPackage = UnloadPackage;
  120. FunctionTable.DuplicateHandle = KerbDuplicateHandle;
  121. // FunctionTable.SaveSupplementalCredentials = SaveSupplementalCredentials;
  122. // FunctionTable.GetWindow = GetWindow;
  123. // FunctionTable.ReleaseWindow = ReleaseWindow;
  124. // FunctionTable.CreateThread = CreateThread;
  125. FunctionTable.GetClientInfo = GetClientInfo;
  126. // FunctionTable.RegisterNotification = RegisterNotification;
  127. // FunctionTable.CancelNotification = CancelNotification;
  128. FunctionTable.MapBuffer = MapBuffer;
  129. // FunctionTable.CreateToken = CreateToken;
  130. FunctionTable.AuditLogon = AuditLogon;
  131. // FunctionTable.CallPackage = CallPackage;
  132. FunctionTable.FreeReturnBuffer = FreeReturnBuffer;
  133. FunctionTable.GetCallInfo = GetCallInfo;
  134. // FunctionTable.CallPackageEx = CallPackageEx;
  135. // FunctionTable.CreateSharedMemory = CreateSharedMemory;
  136. // FunctionTable.AllocateSharedMemory = AllocateSharedMemory;
  137. // FunctionTable.FreeSharedMemory = FreeSharedMemory;
  138. // FunctionTable.DeleteSharedMemory = DeleteSharedMemory;
  139. // FunctionTable.OpenSamUser = OpenSamUser;
  140. // FunctionTable.GetUserCredentials = GetUserCredentials;
  141. // FunctionTable.GetUserAuthData = GetUserAuthData;
  142. // FunctionTable.CloseSamUser = CloseSamUser;
  143. // FunctionTable.ConvertAuthDataToTokenInfo = ConvertAuthDataToTokenInfo;
  144. // we call into the kerb routines
  145. Parameters.Version = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION;
  146. Parameters.MachineState = SECPKG_STATE_STANDALONE;
  147. // NOTE - Yikes!
  148. Parameters.DomainName.Buffer = L"";
  149. Parameters.DomainName.Length = 0;
  150. Parameters.DomainName.MaximumLength = 2;
  151. Parameters.DnsDomainName.Buffer = L"";
  152. Parameters.DnsDomainName.Length = 0;
  153. Parameters.DnsDomainName.MaximumLength = 2;
  154. // If logon session data exists, load it
  155. if ( ERROR_SUCCESS != ( dwError = RegOpenKeyEx (
  156. HKEY_LOCAL_MACHINE,
  157. KERBEROS_TICKET_KEY,
  158. 0,
  159. KEY_ALL_ACCESS,
  160. &hRegKey ) ) )
  161. {
  162. DebugLog((DEB_ERROR, "Error opening KERBEROS_TICKET_KEY\n"));
  163. goto RestOfInit;
  164. }
  165. // get username size
  166. if ( ERROR_SUCCESS != ( dwError = RegQueryValueEx (
  167. hRegKey,
  168. KERBEROS_TICKET_USERNAME_KEY,
  169. NULL,
  170. &dwType,
  171. NULL,
  172. &dwSize )))
  173. {
  174. DebugLog((DEB_ERROR, "Error reading KERBEROS_TICKET_USERNAME_KEY size\n"));
  175. goto RestOfInit;
  176. }
  177. if (dwSize == 0 )
  178. {
  179. DebugLog((DEB_ERROR, "KERBEROS_TICKET_USERNAME_KEY contains 0 bytes\n"));
  180. goto RestOfInit;
  181. }
  182. pUserName = (LPWSTR) KerbAllocate(dwSize);
  183. if (pUserName == NULL)
  184. {
  185. DebugLog((DEB_ERROR, "Error allocing KERBEROS_TICKET_USERNAME_KEY \n"));
  186. goto RestOfInit;
  187. }
  188. // get username into LogonSession->PrimaryCredentials->Username
  189. if ( ERROR_SUCCESS != ( dwError = RegQueryValueEx (
  190. hRegKey,
  191. KERBEROS_TICKET_USERNAME_KEY,
  192. NULL,
  193. &dwType,
  194. (PUCHAR) pUserName,
  195. &dwSize )))
  196. {
  197. DebugLog((DEB_ERROR, "Error reading from KERBEROS_TICKET_USERNAME_KEY\n"));
  198. goto RestOfInit;
  199. }
  200. // get domainname
  201. if ( ERROR_SUCCESS != ( dwError = RegQueryValueEx (
  202. hRegKey,
  203. KERBEROS_TICKET_DOMAINNAME_KEY,
  204. NULL,
  205. &dwType,
  206. NULL,
  207. &dwSize )))
  208. {
  209. DebugLog((DEB_ERROR, "Error reading KERBEROS_TICKET_DOMAINNAME_KEY size\n"));
  210. goto RestOfInit;
  211. }
  212. if (dwSize == 0 )
  213. {
  214. DebugLog((DEB_ERROR, "KERBEROS_TICKET_DOMAINNAME_KEY contains 0 bytes\n"));
  215. goto RestOfInit;
  216. }
  217. pDomainName = (LPWSTR) KerbAllocate(dwSize);
  218. if (pDomainName == NULL)
  219. {
  220. DebugLog((DEB_ERROR, "Error allocing KERBEROS_TICKET_DOMAINNAME_KEY \n"));
  221. goto RestOfInit;
  222. }
  223. // get domainname into LogonSession->PrimaryCredentials->Domainname
  224. if ( ERROR_SUCCESS != ( dwError = RegQueryValueEx (
  225. hRegKey,
  226. KERBEROS_TICKET_DOMAINNAME_KEY,
  227. NULL,
  228. &dwType,
  229. (PUCHAR) pDomainName,
  230. &dwSize )))
  231. {
  232. DebugLog((DEB_ERROR, "Error reading from KERBEROS_TICKET_DOMAINNAME_KEY\n"));
  233. goto RestOfInit;
  234. }
  235. // get domainname into Parameters.DomainName
  236. Parameters.DomainName.Buffer = pDomainName;
  237. Parameters.DomainName.Length = (USHORT)dwSize;
  238. Parameters.DomainName.MaximumLength = (USHORT)dwSize;
  239. // get logon session data size
  240. if ( ERROR_SUCCESS != ( dwError = RegQueryValueEx (
  241. hRegKey,
  242. KERBEROS_TICKET_LOGONSESSION_KEY,
  243. NULL,
  244. &dwType,
  245. NULL,
  246. &dwSize )))
  247. {
  248. DebugLog((DEB_ERROR, "Error reading from KERBEROS_TICKET_LOGONSESSION_KEY\n"));
  249. goto RestOfInit;
  250. }
  251. if (dwSize == 0 )
  252. {
  253. DebugLog((DEB_ERROR, "KERBEROS_TICKET_LOGONSESSION_KEY contains 0 bytes\n"));
  254. goto RestOfInit;
  255. }
  256. RegLogonSession = (PKERB_LOGON_SESSION_CACHE) KerbAllocate(dwSize);
  257. if (RegLogonSession == NULL)
  258. {
  259. DebugLog((DEB_ERROR, "Error allocing KERBEROS_TICKET_LOGONSESSION_KEY \n"));
  260. goto RestOfInit;
  261. }
  262. // get logon session into LogonSession->PrimaryCredentials->Domainname
  263. if ( ERROR_SUCCESS != ( dwError = RegQueryValueEx (
  264. hRegKey,
  265. KERBEROS_TICKET_LOGONSESSION_KEY,
  266. NULL,
  267. &dwType,
  268. (PUCHAR) RegLogonSession,
  269. &dwSize )))
  270. {
  271. DebugLog((DEB_ERROR, "Error reading from KERBEROS_TICKET_LOGONSESSION_KEY\n"));
  272. goto RestOfInit;
  273. }
  274. if ( ERROR_SUCCESS != ( dwError = RegCloseKey ( hRegKey) ))
  275. {
  276. DebugLog((DEB_ERROR, "Error closing KERBEROS_TICKET_KEY\n"));
  277. goto RestOfInit;
  278. }
  279. RestOfInit:
  280. Status = SpInitialize(1, &Parameters, &FunctionTable);
  281. // Do the user mode init too
  282. // Before we call SpInstanceInit, fill a table of functions that are
  283. // imlemented locally. This is done so that the code does not look awful.
  284. // Fill in dummy functions in case more functions are used so we don't
  285. // av
  286. UserFunctionTable.FreeHeap = FreeLsaHeap;
  287. UserFunctionTable.AllocateHeap = AllocateLsaHeap;
  288. Status = SpInstanceInit(SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION,
  289. &UserFunctionTable,
  290. &ignored );
  291. // Now, copy the logon sessions (if they exist)
  292. // This is kina what KerbCreateLogonSession does, expect that we don't
  293. // have to build password list etc.
  294. if (RegLogonSession != NULL)
  295. {
  296. LUID LogonId;
  297. NTSTATUS Status;
  298. ULONG PasswordSize, EncryptKeySize, CredentialSize;
  299. ULONG Index;
  300. PUCHAR Base;
  301. UINT Offset;
  302. //
  303. // Allocate the new logon session
  304. //
  305. Status = NtAllocateLocallyUniqueId (&LogonId);
  306. if (!NT_SUCCESS(Status))
  307. {
  308. goto Cleanup;
  309. }
  310. Status = KerbAllocateLogonSession( &LogonSession );
  311. if (!NT_SUCCESS(Status))
  312. {
  313. goto Cleanup;
  314. }
  315. //
  316. // Fill in the logon session components
  317. //
  318. LogonSession->Lifetime = RegLogonSession->Lifetime;
  319. LogonSession->LogonSessionFlags = RegLogonSession->LogonSessionFlags;
  320. LogonSession->LogonId = LogonId;
  321. //
  322. // Munge RegLogonSession & ptrs for username & domainame
  323. //
  324. RegLogonSession->UserName.Buffer = (LPWSTR)((PUCHAR)RegLogonSession + (INT)(RegLogonSession->UserName.Buffer));
  325. RegLogonSession->DomainName.Buffer = (LPWSTR)((PUCHAR)RegLogonSession + (INT)(RegLogonSession->DomainName.Buffer));
  326. //
  327. // actually copy the username struct and alloc username.buffer
  328. //
  329. LogonSession->PrimaryCredentials.UserName.Buffer = (LPWSTR) KerbAllocate(RegLogonSession->UserName.MaximumLength);
  330. if (LogonSession->PrimaryCredentials.UserName.Buffer == NULL)
  331. {
  332. DebugLog((DEB_ERROR, "Error allocing KERBEROS_TICKET_LOGONSESSION_KEY \n"));
  333. goto Cleanup;
  334. }
  335. RtlCopyMemory(LogonSession->PrimaryCredentials.UserName.Buffer,
  336. RegLogonSession->UserName.Buffer,
  337. RegLogonSession->UserName.MaximumLength);
  338. LogonSession->PrimaryCredentials.UserName.Length = RegLogonSession->UserName.Length;
  339. LogonSession->PrimaryCredentials.UserName.MaximumLength = RegLogonSession->UserName.MaximumLength;
  340. // actually copy the domainname struct and alloc domainname.buffer
  341. LogonSession->PrimaryCredentials.DomainName.Buffer = (LPWSTR) KerbAllocate(RegLogonSession->DomainName.MaximumLength);
  342. if (LogonSession->PrimaryCredentials.DomainName.Buffer == NULL)
  343. {
  344. DebugLog((DEB_ERROR, "Error allocing KERBEROS_TICKET_LOGONSESSION_KEY \n"));
  345. goto Cleanup;
  346. }
  347. RtlCopyMemory(LogonSession->PrimaryCredentials.DomainName.Buffer,
  348. RegLogonSession->DomainName.Buffer,
  349. RegLogonSession->DomainName.MaximumLength);
  350. LogonSession->PrimaryCredentials.DomainName.Length = RegLogonSession->DomainName.Length;
  351. LogonSession->PrimaryCredentials.DomainName.MaximumLength = RegLogonSession->DomainName.MaximumLength;
  352. //
  353. // What is the size of the Credentials struct
  354. //
  355. EncryptKeySize = sizeof(KERB_KEY_DATA) * RegLogonSession->CredentialCount;
  356. PasswordSize = 0;
  357. for (Index = 0; Index < RegLogonSession->CredentialCount ; Index++ )
  358. {
  359. PasswordSize += RegLogonSession->Credentials[Index].keyvalue.length;
  360. RegLogonSession->Credentials[Index].keyvalue.value = (unsigned char*)
  361. ((PUCHAR) RegLogonSession +
  362. (INT)(RegLogonSession->Credentials[Index].keyvalue.value));
  363. } // for
  364. //
  365. // Alloc & copy over the Credentials block
  366. //
  367. CredentialSize = sizeof(KERB_STORED_CREDENTIAL) -
  368. (ANYSIZE_ARRAY * sizeof(KERB_KEY_DATA)) +
  369. EncryptKeySize + PasswordSize;
  370. LogonSession->PrimaryCredentials.Passwords = (PKERB_STORED_CREDENTIAL) KerbAllocate(CredentialSize);
  371. if (LogonSession->PrimaryCredentials.Passwords == NULL)
  372. {
  373. DebugLog((DEB_ERROR, "Error allocing KERBEROS_TICKET_LOGONSESSION_KEY \n"));
  374. goto Cleanup;
  375. }
  376. //
  377. // copy revision, flags & credentialcount
  378. //
  379. LogonSession->PrimaryCredentials.Passwords->Revision = RegLogonSession->Revision;
  380. LogonSession->PrimaryCredentials.Passwords->Flags = RegLogonSession->Flags;
  381. LogonSession->PrimaryCredentials.Passwords->CredentialCount = RegLogonSession->CredentialCount;
  382. //
  383. // copy all keyvalue.value
  384. //
  385. Offset = 0;
  386. Base = (PUCHAR)LogonSession->PrimaryCredentials.Passwords +
  387. CredentialSize - PasswordSize;
  388. for (Index = 0; Index < RegLogonSession->CredentialCount ; Index++ )
  389. {
  390. RtlCopyMemory(Base + Offset,
  391. RegLogonSession->Credentials[Index].keyvalue.value,
  392. RegLogonSession->Credentials[Index].keyvalue.length);
  393. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keytype =
  394. RegLogonSession->Credentials[Index].keytype;
  395. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.length =
  396. RegLogonSession->Credentials[Index].keyvalue.length;
  397. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.value =
  398. (unsigned char*) (Base + Offset);
  399. Offset += RegLogonSession->Credentials[Index].keyvalue.length;
  400. } // for
  401. //
  402. // All logons are deferred until proven otherwise
  403. //
  404. LogonSession->LogonSessionFlags = KERB_LOGON_DEFERRED;
  405. if (LogonSession->PrimaryCredentials.Passwords == NULL)
  406. {
  407. LogonSession->LogonSessionFlags |= KERB_LOGON_NO_PASSWORD;
  408. }
  409. //
  410. // Now that the logon session structure is filled out insert it
  411. // into the list. After this you need to hold the logon session lock
  412. // to read or write this logon session.
  413. //
  414. Status = KerbInsertLogonSession(LogonSession);
  415. if (!NT_SUCCESS(Status))
  416. {
  417. goto Cleanup;
  418. }
  419. }
  420. Cleanup:
  421. if (!NT_SUCCESS(Status))
  422. {
  423. if (LogonSession != NULL)
  424. {
  425. KerbReferenceLogonSessionByPointer(LogonSession, TRUE);
  426. KerbFreeLogonSession(LogonSession);
  427. }
  428. }
  429. else
  430. {
  431. if (LogonSession != NULL)
  432. {
  433. KerbDereferenceLogonSession(LogonSession);
  434. }
  435. }
  436. if (RegLogonSession != NULL)
  437. {
  438. KerbFree(RegLogonSession);
  439. }
  440. // NOTE - what about pUsername & pDomainname
  441. DebugLog((DEB_TRACE_API, "Leaving KerbInitSecurityInterface\n"));
  442. return SEC_SUCCESS(Status) ? &KerbDllSecurityFunctionTable : NULL;
  443. }
  444. VOID
  445. KerbShutdownSecurityInterface(
  446. VOID
  447. )
  448. /*++
  449. Routine Description:
  450. Cleanup the data shared by the DLL and SERVICE.
  451. Arguments:
  452. None.
  453. Return Value:
  454. None.
  455. --*/
  456. {
  457. PKERB_LOGON_SESSION LogonSession;
  458. LUID LogonId;
  459. PKERB_LOGON_SESSION_CACHE RegLogonSession;
  460. HKEY hRegKey;
  461. DWORD dwDisposition;
  462. DWORD dwError = 0;
  463. NTSTATUS Status = STATUS_SUCCESS;
  464. DebugLog((DEB_TRACE_API, "Entering KerbShutdownSecurityInterface\n"));
  465. Status = NtAllocateLocallyUniqueId (&LogonId);
  466. LogonSession = KerbReferenceLogonSession(
  467. &LogonId,
  468. TRUE);
  469. // Need to dump out logon session info in the registry
  470. // create or open the parameters key
  471. if ( ( dwError = RegCreateKeyEx (
  472. HKEY_LOCAL_MACHINE,
  473. KERBEROS_TICKET_KEY,
  474. 0,
  475. "",
  476. REG_OPTION_NON_VOLATILE,
  477. KEY_ALL_ACCESS,
  478. NULL,
  479. &hRegKey,
  480. &dwDisposition) ) )
  481. {
  482. DebugLog((DEB_ERROR, "Error creating KERBEROS_TICKET_KEY\n"));
  483. goto Cleanup;
  484. }
  485. if (LogonSession != NULL)
  486. {
  487. ULONG PasswordSize, Offset;
  488. ULONG Index;
  489. ULONG TotalSize = 0 ;
  490. PUCHAR Base;
  491. //
  492. // Compute the size of the passwords, which are assumed to be
  493. // marshalled in order.
  494. //
  495. PasswordSize = sizeof(KERB_LOGON_SESSION_CACHE) - sizeof(KERB_KEY_DATA) * ANYSIZE_ARRAY +
  496. LogonSession->PrimaryCredentials.Passwords->CredentialCount * sizeof(KERB_KEY_DATA);
  497. for (Index = 0; Index < LogonSession->PrimaryCredentials.Passwords->CredentialCount ; Index++ )
  498. {
  499. PasswordSize += LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.length;
  500. DsysAssert((PUCHAR) LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.value <=
  501. (PUCHAR) LogonSession->PrimaryCredentials.Passwords + PasswordSize );
  502. }
  503. // Total size of the logon session cache
  504. TotalSize = LogonSession->PrimaryCredentials.UserName.MaximumLength +
  505. LogonSession->PrimaryCredentials.DomainName.MaximumLength +
  506. PasswordSize;
  507. RegLogonSession = (PKERB_LOGON_SESSION_CACHE) KerbAllocate(TotalSize);
  508. if (RegLogonSession == NULL)
  509. {
  510. Status = STATUS_INSUFFICIENT_RESOURCES;
  511. goto Cleanup;
  512. }
  513. RegLogonSession->Lifetime =
  514. LogonSession->Lifetime;
  515. RegLogonSession->LogonSessionFlags =
  516. LogonSession->LogonSessionFlags;
  517. RegLogonSession->UserName.Length =
  518. LogonSession->PrimaryCredentials.UserName.Length;
  519. RegLogonSession->UserName.MaximumLength =
  520. LogonSession->PrimaryCredentials.UserName.MaximumLength;
  521. RegLogonSession->DomainName.Length =
  522. LogonSession->PrimaryCredentials.DomainName.Length;
  523. RegLogonSession->DomainName.MaximumLength =
  524. LogonSession->PrimaryCredentials.DomainName.MaximumLength;
  525. RegLogonSession->Revision =
  526. LogonSession->PrimaryCredentials.Passwords->Revision;
  527. RegLogonSession->Flags =
  528. LogonSession->PrimaryCredentials.Passwords->Flags;
  529. RegLogonSession->CredentialCount=
  530. LogonSession->PrimaryCredentials.Passwords->CredentialCount;
  531. Base = (PUCHAR) RegLogonSession;
  532. Offset = sizeof(KERB_LOGON_SESSION_CACHE) -
  533. (ANYSIZE_ARRAY * sizeof(KERB_KEY_DATA)) +
  534. (RegLogonSession->CredentialCount * sizeof(KERB_KEY_DATA));
  535. // Offset from the struct
  536. RegLogonSession->UserName.Buffer = (LPWSTR)Offset;
  537. RtlCopyMemory(Base + Offset,
  538. LogonSession->PrimaryCredentials.UserName.Buffer,
  539. LogonSession->PrimaryCredentials.UserName.MaximumLength);
  540. Offset += LogonSession->PrimaryCredentials.UserName.MaximumLength;
  541. RegLogonSession->DomainName.Buffer = (LPWSTR)(Offset);
  542. RtlCopyMemory(Base + Offset,
  543. LogonSession->PrimaryCredentials.DomainName.Buffer,
  544. LogonSession->PrimaryCredentials.DomainName.MaximumLength);
  545. Offset += LogonSession->PrimaryCredentials.DomainName.MaximumLength;
  546. for (Index = 0; Index < RegLogonSession->CredentialCount ; Index++ )
  547. {
  548. RegLogonSession->Credentials[Index].keytype =
  549. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keytype;
  550. RegLogonSession->Credentials[Index].keyvalue.length =
  551. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.length;
  552. RegLogonSession->Credentials[Index].keyvalue.value =
  553. (unsigned char *) (Offset);
  554. RtlCopyMemory(Base + Offset,
  555. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.value,
  556. LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.length);
  557. Offset += LogonSession->PrimaryCredentials.Passwords->Credentials[Index].Key.keyvalue.length;
  558. } // for
  559. // add username from LogonSession->PrimaryCredentials->Username
  560. if ( ( dwError = RegSetValueEx (
  561. hRegKey,
  562. KERBEROS_TICKET_USERNAME_KEY,
  563. 0,
  564. REG_BINARY,
  565. (LPBYTE) LogonSession->PrimaryCredentials.UserName.Buffer,
  566. LogonSession->PrimaryCredentials.UserName.Length
  567. ) ))
  568. {
  569. DebugLog((DEB_ERROR, "Error writing to KERBEROS_TICKET_USERNAME_KEY\n"));
  570. goto Cleanup;
  571. }
  572. // add domainname from LogonSession->PrimaryCredentials->domainname
  573. if ( ( dwError = RegSetValueEx (
  574. hRegKey,
  575. KERBEROS_TICKET_DOMAINNAME_KEY,
  576. 0,
  577. REG_BINARY,
  578. (LPBYTE) LogonSession->PrimaryCredentials.DomainName.Buffer,
  579. LogonSession->PrimaryCredentials.DomainName.Length)))
  580. {
  581. DebugLog((DEB_ERROR, "Error writing to KERBEROS_TICKET_DOMAINNAME_KEY\n"));
  582. goto Cleanup;
  583. }
  584. // add logon session data from RegLogonSession & TotalSize
  585. if ( ( dwError = RegSetValueEx (
  586. hRegKey,
  587. KERBEROS_TICKET_LOGONSESSION_KEY,
  588. 0,
  589. REG_BINARY,
  590. (LPBYTE) RegLogonSession,
  591. TotalSize) ) )
  592. {
  593. DebugLog((DEB_ERROR, "Error writing to KERBEROS_TICKET_LOGONSESSION_KEY\n"));
  594. goto Cleanup;
  595. }
  596. }
  597. else // (LogonSession is NULL)
  598. {
  599. // We did not have any valid kerberos logon sessions.
  600. // Delete all the registry values in keys.
  601. DebugLog((DEB_TRACE, "No Kerberos LogonSession\n"));
  602. if ( ( dwError = RegDeleteValue (
  603. hRegKey,
  604. KERBEROS_TICKET_USERNAME_KEY)))
  605. {
  606. DebugLog((DEB_ERROR, "Error deleting value KERBEROS_TICKET_USERNAME_KEY\n"));
  607. }
  608. if ( ( dwError = RegDeleteValue (
  609. hRegKey,
  610. KERBEROS_TICKET_DOMAINNAME_KEY)))
  611. {
  612. DebugLog((DEB_ERROR, "Error deleting value KERBEROS_TICKET_DOMAINNAME_KEY\n"));
  613. }
  614. if ( ( dwError = RegDeleteValue (
  615. hRegKey,
  616. KERBEROS_TICKET_LOGONSESSION_KEY)))
  617. {
  618. DebugLog((DEB_ERROR, "Error deleting value KERBEROS_TICKET_LOGONSESSION_KEY\n"));
  619. }
  620. }
  621. Cleanup:
  622. if ( ( dwError = RegFlushKey ( hRegKey) ))
  623. {
  624. DebugLog((DEB_ERROR, "Error Flushing KERBEROS_TICKET_KEY\n"));
  625. }
  626. if ( ( dwError = RegCloseKey ( hRegKey) ))
  627. {
  628. DebugLog((DEB_ERROR, "Error closing KERBEROS_TICKET_KEY\n"));
  629. }
  630. if (LogonSession != NULL)
  631. {
  632. KerbDereferenceLogonSession(LogonSession);
  633. LogonSession = NULL;
  634. }
  635. SpShutdown();
  636. DebugLog((DEB_TRACE_API, "Leaving KerbShutdownSecurityInterface\n"));
  637. }
  638. SECURITY_STATUS
  639. KerbSpGetInfo(
  640. IN LPTSTR PackageName,
  641. OUT PSecPkgInfo *PackageInfo
  642. )
  643. /*++
  644. Routine Description:
  645. This API is intended to provide basic information about Security
  646. Packages themselves. This information will include the bounds on sizes
  647. of authentication information, credentials and contexts.
  648. ?? This is a local routine rather than the real API call since the API
  649. call has a bad interface that neither allows me to allocate the
  650. buffer nor tells me how big the buffer is. Perhaps when the real API
  651. is fixed, I'll make this the real API.
  652. Arguments:
  653. PackageName - Name of the package being queried.
  654. PackageInfo - Returns a pointer to an allocated block describing the
  655. security package. The allocated block must be freed using
  656. FreeContextBuffer.
  657. Return Value:
  658. SEC_E_OK -- Call completed successfully
  659. SEC_E_PACKAGE_UNKNOWN -- Package being queried is not this package
  660. SEC_E_INSUFFICIENT_MEMORY -- Not enough memory
  661. --*/
  662. {
  663. LPTSTR Where;
  664. //
  665. // Ensure the correct package name was passed in.
  666. //
  667. if ( lstrcmpi( PackageName, KERBEROS_PACKAGE_NAME ) != 0 ) {
  668. return SEC_E_SECPKG_NOT_FOUND;
  669. }
  670. //
  671. // Allocate a buffer for the PackageInfo
  672. //
  673. *PackageInfo = (PSecPkgInfo) LocalAlloc( 0, sizeof(SecPkgInfo) +
  674. sizeof(KERBEROS_PACKAGE_NAME) +
  675. sizeof(KERBEROS_PACKAGE_COMMENT) );
  676. if ( *PackageInfo == NULL ) {
  677. return SEC_E_INSUFFICIENT_MEMORY;
  678. }
  679. //
  680. // Fill in the information.
  681. //
  682. (*PackageInfo)->fCapabilities = KerbGlobalCapabilities;
  683. (*PackageInfo)->wVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION;
  684. (*PackageInfo)->wRPCID = RPC_C_AUTHN_GSS_KERBEROS;
  685. (*PackageInfo)->cbMaxToken = KERBEROS_MAX_TOKEN;
  686. Where = (LPTSTR)((*PackageInfo)+1);
  687. (*PackageInfo)->Name = Where;
  688. lstrcpy( Where, KERBEROS_PACKAGE_NAME);
  689. Where += lstrlen(Where) + 1;
  690. (*PackageInfo)->Comment = Where;
  691. lstrcpy( Where, KERBEROS_PACKAGE_COMMENT);
  692. Where += lstrlen(Where) + 1;
  693. return SEC_E_OK;
  694. }
  695. SECURITY_STATUS
  696. KerbEnumerateSecurityPackages(
  697. OUT PULONG PackageCount,
  698. OUT PSecPkgInfo *PackageInfo
  699. )
  700. /*++
  701. Routine Description:
  702. This API returns a list of Security Packages available to client (i.e.
  703. those that are either loaded or can be loaded on demand). The caller
  704. must free the returned buffer with FreeContextBuffer. This API returns
  705. a list of all the security packages available to a service. The names
  706. returned can then be used to acquire credential handles, as well as
  707. determine which package in the system best satisfies the requirements
  708. of the caller. It is assumed that all available packages can be
  709. included in the single call.
  710. This is really a dummy API that just returns information about this
  711. security package. It is provided to ensure this security package has the
  712. same interface as the multiplexer DLL does.
  713. Arguments:
  714. PackageCount - Returns the number of packages supported.
  715. PackageInfo - Returns an allocate array of structures
  716. describing the security packages. The array must be freed
  717. using FreeContextBuffer.
  718. Return Value:
  719. SEC_E_OK -- Call completed successfully
  720. SEC_E_PACKAGE_UNKNOWN -- Package being queried is not this package
  721. SEC_E_INSUFFICIENT_MEMORY -- Not enough memory
  722. --*/
  723. {
  724. //
  725. // Get the information for this package.
  726. //
  727. LPTSTR Where;
  728. *PackageCount = 1;
  729. //
  730. // Allocate a buffer for the PackageInfo
  731. //
  732. *PackageInfo = (PSecPkgInfo) LocalAlloc( 0, sizeof(SecPkgInfo) +
  733. sizeof(KERBEROS_PACKAGE_NAME) +
  734. sizeof(KERBEROS_PACKAGE_COMMENT) );
  735. if ( *PackageInfo == NULL ) {
  736. return SEC_E_INSUFFICIENT_MEMORY;
  737. }
  738. //
  739. // Fill in the information.
  740. //
  741. (*PackageInfo)->fCapabilities = KerbGlobalCapabilities;
  742. (*PackageInfo)->wVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION;
  743. (*PackageInfo)->wRPCID = RPC_C_AUTHN_GSS_KERBEROS;
  744. (*PackageInfo)->cbMaxToken = KERBEROS_MAX_TOKEN;
  745. Where = (LPTSTR)((*PackageInfo)+1);
  746. (*PackageInfo)->Name = Where;
  747. lstrcpy( Where, KERBEROS_PACKAGE_NAME);
  748. Where += lstrlen(Where) + 1;
  749. (*PackageInfo)->Comment = Where;
  750. lstrcpy( Where, KERBEROS_PACKAGE_COMMENT);
  751. Where += lstrlen(Where) + 1;
  752. return SEC_E_OK;
  753. }
  754. SECURITY_STATUS
  755. KerbQuerySecurityPackageInfo (
  756. LPTSTR PackageName,
  757. PSecPkgInfo SEC_FAR * Package
  758. )
  759. {
  760. return ( KerbSpGetInfo(
  761. PackageName,
  762. Package));
  763. }
  764. SECURITY_STATUS SEC_ENTRY
  765. KerbFreeContextBuffer (
  766. void __SEC_FAR * ContextBuffer
  767. )
  768. /*++
  769. Routine Description:
  770. This API is provided to allow callers of security API such as
  771. InitializeSecurityContext() for free the memory buffer allocated for
  772. returning the outbound context token.
  773. Arguments:
  774. ContextBuffer - Address of the buffer to be freed.
  775. Return Value:
  776. SEC_E_OK - Call completed successfully
  777. --*/
  778. {
  779. //
  780. // The only allocated buffer that the kerb currently returns to the caller
  781. // is from EnumeratePackages. It uses LocalAlloc to allocate memory. If
  782. // we ever need memory to be allocated by the service, we have to rethink
  783. // how this routine distinguishes between to two types of allocated memory.
  784. //
  785. (VOID) LocalFree( ContextBuffer );
  786. return SEC_E_OK;
  787. }
  788. #if DBG
  789. //
  790. // Control which messages get displayed
  791. //
  792. // DWORD KerbInfoLevel = DEB_ERROR | DEB_WARN | DEB_TRACE | DEB_TRACE_API;
  793. //
  794. // SspPrintRoutine - Displays debug output
  795. //
  796. VOID __cdecl
  797. KerbPrintRoutine(
  798. IN DWORD DebugFlag,
  799. IN LPCSTR FormatString, // PRINTF()-STYLE FORMAT STRING.
  800. ... // OTHER ARGUMENTS ARE POSSIBLE.
  801. )
  802. {
  803. static char prefix[] = "KERB: ";
  804. char outbuf[256];
  805. va_list args;
  806. if ( DebugFlag & KerbInfoLevel) {
  807. EnterCriticalSection( &KerbGlobalLogFileCritSect );
  808. lstrcpy(outbuf, prefix);
  809. va_start(args, FormatString);
  810. wvsprintf(outbuf + sizeof(prefix) - 1, FormatString, args);
  811. OutputDebugString(outbuf);
  812. LeaveCriticalSection( &KerbGlobalLogFileCritSect );
  813. }
  814. return;
  815. }
  816. #endif DBG
  817. SECURITY_STATUS
  818. KerbAcquireCredentialsHandle(
  819. IN LPTSTR PrincipalName,
  820. IN LPTSTR PackageName,
  821. IN ULONG CredentialUseFlags,
  822. IN PVOID LogonId,
  823. IN PVOID AuthData,
  824. IN SEC_GET_KEY_FN GetKeyFunction,
  825. IN PVOID GetKeyArgument,
  826. OUT PCredHandle CredentialHandle,
  827. OUT PTimeStamp Lifetime
  828. )
  829. {
  830. SECURITY_STATUS SecStatus = SEC_E_OK;
  831. UNICODE_STRING NewPrincipalName;
  832. //
  833. // Validate the arguments
  834. //
  835. if ( lstrcmpi( PackageName, KERBEROS_PACKAGE_NAME ) != 0 ) {
  836. SecStatus = SEC_E_SECPKG_NOT_FOUND;
  837. goto Cleanup;
  838. }
  839. if ( (CredentialUseFlags & SECPKG_CRED_OUTBOUND) &&
  840. ARGUMENT_PRESENT(PrincipalName) && *PrincipalName != '\0' ) {
  841. SecStatus = SEC_E_UNKNOWN_CREDENTIALS;
  842. goto Cleanup;
  843. }
  844. if ( ARGUMENT_PRESENT(LogonId) ) {
  845. SecStatus = SEC_E_UNSUPPORTED_FUNCTION;
  846. goto Cleanup;
  847. }
  848. if ( ARGUMENT_PRESENT(GetKeyFunction) ) {
  849. SecStatus = SEC_E_UNSUPPORTED_FUNCTION;
  850. goto Cleanup;
  851. }
  852. if ( ARGUMENT_PRESENT(GetKeyArgument) ) {
  853. SecStatus = SEC_E_UNSUPPORTED_FUNCTION;
  854. goto Cleanup;
  855. }
  856. //
  857. // Don't allow inbound credentials if we don't have an authentication
  858. // server avaiable
  859. //
  860. if ( (KerbGlobalCapabilities & SECPKG_FLAG_CLIENT_ONLY)
  861. && (CredentialUseFlags & SECPKG_CRED_INBOUND) ) {
  862. DebugLog(( SSP_API,
  863. "KerbAcquireCredentialHandle: no authentication service for inbound handle.\n" ));
  864. SecStatus = SEC_E_NO_AUTHENTICATING_AUTHORITY;
  865. goto Cleanup;
  866. }
  867. if (!RtlCreateUnicodeStringFromAsciiz( &NewPrincipalName, PrincipalName)){
  868. SecStatus = SEC_E_INSUFFICIENT_MEMORY;;
  869. goto Cleanup;
  870. }
  871. SecStatus = SpAcquireCredentialsHandle(
  872. &NewPrincipalName,
  873. CredentialUseFlags,
  874. (PLUID)LogonId,
  875. AuthData,
  876. GetKeyFunction,
  877. GetKeyArgument,
  878. &CredentialHandle->dwUpper,
  879. Lifetime );
  880. Cleanup:
  881. return SecStatus;
  882. }
  883. SECURITY_STATUS
  884. KerbFreeCredentialsHandle(
  885. IN PCredHandle CredentialHandle
  886. )
  887. /*++
  888. Routine Description:
  889. This API is used to notify the security system that the credentials are
  890. no longer needed and allows the application to free the handle acquired
  891. in the call described above. When all references to this credential
  892. set has been removed then the credentials may themselves be removed.
  893. Arguments:
  894. CredentialHandle - Credential Handle obtained through
  895. AcquireCredentialHandle.
  896. Return Value:
  897. SEC_E_OK -- Call completed successfully
  898. SEC_E_NO_SPM -- Security Support Provider is not running
  899. SEC_E_INVALID_HANDLE -- Credential Handle is invalid
  900. --*/
  901. {
  902. SECURITY_STATUS SecStatus;
  903. SecStatus = SpFreeCredentialsHandle(
  904. CredentialHandle->dwUpper );
  905. return SecStatus;
  906. }
  907. SECURITY_STATUS
  908. KerbQueryCredentialsAttributes(
  909. IN PCredHandle CredentialsHandle,
  910. IN ULONG Attribute,
  911. OUT PVOID Buffer
  912. )
  913. {
  914. SECURITY_STATUS SecStatus;
  915. SecStatus = SpQueryCredentialsAttributes(
  916. CredentialsHandle->dwUpper,
  917. Attribute,
  918. Buffer );
  919. return SecStatus;
  920. }
  921. SECURITY_STATUS
  922. KerbInitializeSecurityContext(
  923. IN PCredHandle CredentialHandle,
  924. IN PCtxtHandle OldContextHandle,
  925. IN LPTSTR TargetName,
  926. IN ULONG ContextReqFlags,
  927. IN ULONG Reserved1,
  928. IN ULONG TargetDataRep,
  929. IN PSecBufferDesc InputToken,
  930. IN ULONG Reserved2,
  931. OUT PCtxtHandle NewContextHandle,
  932. OUT PSecBufferDesc OutputToken,
  933. OUT PULONG ContextAttributes,
  934. OUT PTimeStamp ExpirationTime
  935. )
  936. {
  937. UNICODE_STRING TargetNameUStr;
  938. BOOLEAN fMappedContext;
  939. SecBuffer ContextData;
  940. SECURITY_STATUS SecStatus = SEC_E_OK;
  941. SECURITY_STATUS SecondaryStatus = SEC_E_OK;
  942. SecBufferDesc EmptyBuffer = {0,0, NULL};
  943. RtlCreateUnicodeStringFromAsciiz (&TargetNameUStr, TargetName);
  944. if (!ARGUMENT_PRESENT(InputToken))
  945. {
  946. InputToken = &EmptyBuffer;
  947. }
  948. if (!ARGUMENT_PRESENT(OutputToken))
  949. {
  950. OutputToken = &EmptyBuffer;
  951. }
  952. SecStatus = SpInitLsaModeContext (
  953. CredentialHandle ? CredentialHandle->dwUpper : NULL,
  954. OldContextHandle ? OldContextHandle->dwUpper : NULL,
  955. &TargetNameUStr,
  956. ContextReqFlags,
  957. TargetDataRep,
  958. InputToken,
  959. &NewContextHandle->dwUpper,
  960. OutputToken,
  961. ContextAttributes,
  962. ExpirationTime,
  963. &fMappedContext,
  964. &ContextData);
  965. if (NT_SUCCESS(SecStatus) && fMappedContext)
  966. {
  967. SecondaryStatus = SpInitUserModeContext(NewContextHandle->dwUpper,
  968. &ContextData);
  969. if (!NT_SUCCESS(SecondaryStatus))
  970. {
  971. SecStatus = SecondaryStatus;
  972. SecondaryStatus = KerbDeleteSecurityContext(NewContextHandle);
  973. }
  974. }
  975. return SecStatus;
  976. }
  977. SECURITY_STATUS
  978. KerbDeleteSecurityContext (
  979. IN PCtxtHandle ContextHandle
  980. )
  981. {
  982. SECURITY_STATUS SecStatus = SEC_E_OK;
  983. SecStatus = SpDeleteContext (ContextHandle->dwUpper);
  984. return SecStatus;
  985. }
  986. SECURITY_STATUS
  987. KerbApplyControlToken (
  988. PCtxtHandle ContextHandle,
  989. PSecBufferDesc Input
  990. )
  991. {
  992. SECURITY_STATUS SecStatus = SEC_E_OK;
  993. SecStatus = SpApplyControlToken(ContextHandle->dwUpper, Input);
  994. return SecStatus;
  995. }
  996. SECURITY_STATUS
  997. KerbImpersonateSecurityContext (
  998. PCtxtHandle ContextHandle
  999. )
  1000. {
  1001. return (SEC_E_NO_IMPERSONATION);
  1002. }
  1003. SECURITY_STATUS
  1004. KerbRevertSecurityContext (
  1005. PCtxtHandle ContextHandle
  1006. )
  1007. {
  1008. return (SEC_E_NO_IMPERSONATION);
  1009. }
  1010. SECURITY_STATUS
  1011. KerbQueryContextAttributes(
  1012. IN PCtxtHandle ContextHandle,
  1013. IN ULONG Attribute,
  1014. OUT PVOID Buffer
  1015. )
  1016. {
  1017. SECURITY_STATUS SecStatus = SEC_E_OK;
  1018. SecStatus = SpQueryContextAttributes(ContextHandle->dwUpper,
  1019. Attribute,
  1020. Buffer);
  1021. return SecStatus;
  1022. }
  1023. SECURITY_STATUS SEC_ENTRY
  1024. KerbCompleteAuthToken (
  1025. PCtxtHandle ContextHandle,
  1026. PSecBufferDesc BufferDescriptor
  1027. )
  1028. {
  1029. SECURITY_STATUS SecStatus = SEC_E_OK;
  1030. SecStatus = SpCompleteAuthToken(ContextHandle->dwUpper, BufferDescriptor);
  1031. return SecStatus;
  1032. }
  1033. SECURITY_STATUS
  1034. KerbMakeSignature (
  1035. PCtxtHandle ContextHandle,
  1036. unsigned long QualityOfProtection,
  1037. PSecBufferDesc Message,
  1038. unsigned long SequenceNumber
  1039. )
  1040. {
  1041. SECURITY_STATUS SecStatus = SEC_E_OK;
  1042. SecStatus = SpMakeSignature(ContextHandle->dwUpper,
  1043. QualityOfProtection,
  1044. Message,
  1045. SequenceNumber);
  1046. return SecStatus;
  1047. }
  1048. SECURITY_STATUS
  1049. KerbVerifySignature (
  1050. PCtxtHandle ContextHandle,
  1051. PSecBufferDesc Message,
  1052. unsigned long SequenceNumber,
  1053. unsigned long * QualityOfProtection
  1054. )
  1055. {
  1056. SECURITY_STATUS SecStatus = SEC_E_OK;
  1057. SecStatus = SpVerifySignature(ContextHandle->dwUpper,
  1058. Message,
  1059. SequenceNumber,
  1060. QualityOfProtection);
  1061. return SecStatus;
  1062. }
  1063. SECURITY_STATUS
  1064. KerbSealMessage (
  1065. PCtxtHandle ContextHandle,
  1066. unsigned long QualityOfProtection,
  1067. PSecBufferDesc Message,
  1068. unsigned long SequenceNumber
  1069. )
  1070. {
  1071. SECURITY_STATUS SecStatus = SEC_E_OK;
  1072. SecStatus = SpSealMessage(ContextHandle->dwUpper,
  1073. QualityOfProtection,
  1074. Message,
  1075. SequenceNumber);
  1076. return SecStatus;
  1077. }
  1078. SECURITY_STATUS
  1079. KerbUnsealMessage (
  1080. PCtxtHandle ContextHandle,
  1081. PSecBufferDesc Message,
  1082. unsigned long SequenceNumber,
  1083. unsigned long * QualityOfProtection
  1084. )
  1085. {
  1086. SECURITY_STATUS SecStatus = SEC_E_OK;
  1087. SecStatus = SpUnsealMessage(ContextHandle->dwUpper,
  1088. Message,
  1089. SequenceNumber,
  1090. QualityOfProtection);
  1091. return SecStatus;
  1092. }