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.

422 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. SecurSup.c
  5. Abstract:
  6. This module implements the Named Pipe Security support routines
  7. Author:
  8. Gary Kimura [GaryKi] 06-May-1991
  9. Revision History:
  10. --*/
  11. #include "NpProcs.h"
  12. //
  13. // The debug trace level
  14. //
  15. #define Dbg (DEBUG_TRACE_SECURSUP)
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGE, NpCopyClientContext)
  18. #pragma alloc_text(PAGE, NpImpersonateClientContext)
  19. #pragma alloc_text(PAGE, NpInitializeSecurity)
  20. #pragma alloc_text(PAGE, NpGetClientSecurityContext)
  21. #pragma alloc_text(PAGE, NpUninitializeSecurity)
  22. #pragma alloc_text(PAGE, NpFreeClientSecurityContext)
  23. #endif
  24. NTSTATUS
  25. NpInitializeSecurity (
  26. IN PCCB Ccb,
  27. IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
  28. IN PETHREAD UserThread
  29. )
  30. /*++
  31. Routine Description:
  32. This routine initializes the security (impersonation) fields
  33. in the ccb. It is called when the client end gets opened.
  34. Arguments:
  35. Ccb - Supplies the ccb being initialized
  36. SecurityQos - Supplies the clients quality of service parameter
  37. UserThread - Supplise the client's user thread
  38. Return Value:
  39. NTSTATUS - Returns the result of the operation
  40. --*/
  41. {
  42. NTSTATUS Status;
  43. PAGED_CODE();
  44. DebugTrace(+1, Dbg, "NpInitializeSecurity, Ccb = %08lx\n", Ccb);
  45. //
  46. // Either copy the security qos parameter, if it is not null or
  47. // create a dummy qos
  48. //
  49. if (SecurityQos != NULL) {
  50. RtlCopyMemory( &Ccb->SecurityQos,
  51. SecurityQos,
  52. sizeof(SECURITY_QUALITY_OF_SERVICE) );
  53. } else {
  54. Ccb->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  55. Ccb->SecurityQos.ImpersonationLevel = SecurityImpersonation;
  56. Ccb->SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  57. Ccb->SecurityQos.EffectiveOnly = TRUE;
  58. }
  59. //
  60. // Because we might be asked to reinitialize the ccb we need
  61. // to first check if the security client context is not null and if so then
  62. // free its pool and zero out the context pointer so that if we raise out
  63. // this time then a second time through the code we won't try and free the
  64. // pool twice.
  65. //
  66. if (Ccb->SecurityClientContext != NULL) {
  67. SeDeleteClientSecurity( Ccb->SecurityClientContext );
  68. NpFreePool( Ccb->SecurityClientContext );
  69. Ccb->SecurityClientContext = NULL;
  70. }
  71. //
  72. // If the tracking mode is static then we need to capture the
  73. // client context now otherwise we set the client context field
  74. // to null
  75. //
  76. if (Ccb->SecurityQos.ContextTrackingMode == SECURITY_STATIC_TRACKING) {
  77. //
  78. // Allocate a client context record, and then initialize it
  79. //
  80. Ccb->SecurityClientContext = NpAllocatePagedPoolWithQuota ( sizeof(SECURITY_CLIENT_CONTEXT), 'sFpN' );
  81. if (Ccb->SecurityClientContext == NULL) {
  82. Status = STATUS_INSUFFICIENT_RESOURCES;
  83. } else {
  84. DebugTrace(0, Dbg, "Static tracking, ClientContext = %08lx\n", Ccb->SecurityClientContext);
  85. if (!NT_SUCCESS(Status = SeCreateClientSecurity( UserThread,
  86. &Ccb->SecurityQos,
  87. FALSE,
  88. Ccb->SecurityClientContext ))) {
  89. DebugTrace(0, Dbg, "Not successful at creating client security, %08lx\n", Status);
  90. NpFreePool( Ccb->SecurityClientContext );
  91. Ccb->SecurityClientContext = NULL;
  92. }
  93. }
  94. } else {
  95. DebugTrace(0, Dbg, "Dynamic tracking\n", 0);
  96. Ccb->SecurityClientContext = NULL;
  97. Status = STATUS_SUCCESS;
  98. }
  99. DebugTrace(-1, Dbg, "NpInitializeSecurity -> %08lx\n", Status);
  100. return Status;
  101. }
  102. VOID
  103. NpUninitializeSecurity (
  104. IN PCCB Ccb
  105. )
  106. /*++
  107. Routine Description:
  108. This routine deletes the client context referenced by the ccb
  109. Arguments:
  110. Ccb - Supplies the ccb being uninitialized
  111. Return Value:
  112. None
  113. --*/
  114. {
  115. PAGED_CODE();
  116. DebugTrace(+1, Dbg, "NpUninitializeSecurity, Ccb = %08lx\n", Ccb);
  117. //
  118. // We only have work to do if the client context field is not null
  119. // and then we need to delete the client context, and free the memory.
  120. //
  121. if (Ccb->SecurityClientContext != NULL) {
  122. DebugTrace(0, Dbg, "Delete client context, %08lx\n", Ccb->SecurityClientContext);
  123. SeDeleteClientSecurity( Ccb->SecurityClientContext );
  124. NpFreePool( Ccb->SecurityClientContext );
  125. Ccb->SecurityClientContext = NULL;
  126. }
  127. DebugTrace(-1, Dbg, "NpUninitializeSecurity -> VOID\n", 0);
  128. return;
  129. }
  130. VOID
  131. NpFreeClientSecurityContext (
  132. IN PSECURITY_CLIENT_CONTEXT SecurityContext
  133. )
  134. /*++
  135. Routine Description:
  136. This routine frees previously captured security context.
  137. Arguments:
  138. SecurityContext - Previously captured security context.
  139. Return Value:
  140. None.
  141. --*/
  142. {
  143. if (SecurityContext != NULL) {
  144. SeDeleteClientSecurity (SecurityContext);
  145. NpFreePool (SecurityContext );
  146. }
  147. }
  148. NTSTATUS
  149. NpGetClientSecurityContext (
  150. IN NAMED_PIPE_END NamedPipeEnd,
  151. IN PCCB Ccb,
  152. IN PETHREAD UserThread,
  153. OUT PSECURITY_CLIENT_CONTEXT *ppSecurityContext
  154. )
  155. /*++
  156. Routine Description:
  157. This routine captures a new client context and stores it in the indicated
  158. data entry, but only if the tracking mode is dynamic and only for the
  159. client end of the named pipe.
  160. Arguments:
  161. NamedPipeEnd - Indicates the client or server end of the named pipe.
  162. Only the client end does anything.
  163. Ccb - Supplies the ccb for this instance of the named pipe.
  164. DataEntry - Supplies the data entry to use to store the client context
  165. UserThread - Supplies the thread of the client
  166. Return Value:
  167. NTSTATUS - Returns our success code.
  168. --*/
  169. {
  170. NTSTATUS Status;
  171. PSECURITY_CLIENT_CONTEXT SecurityContext;
  172. PAGED_CODE();
  173. DebugTrace(+1, Dbg, "NpSetDataEntryClientContext, Ccb = %08lx\n", Ccb);
  174. //
  175. // Only do the work if this is the client end and tracking is dynamic
  176. //
  177. if ((NamedPipeEnd == FILE_PIPE_CLIENT_END) &&
  178. (Ccb->SecurityQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)) {
  179. //
  180. // Allocate a client context record, and then initialize it
  181. //
  182. SecurityContext = NpAllocatePagedPoolWithQuota (sizeof(SECURITY_CLIENT_CONTEXT), 'sFpN');
  183. if (SecurityContext == NULL) {
  184. return STATUS_INSUFFICIENT_RESOURCES;
  185. }
  186. DebugTrace(0, Dbg, "Client End, Dynamic Tracking, ClientContext = %08lx\n", DataEntry->SecurityClientContext);
  187. if (!NT_SUCCESS (Status = SeCreateClientSecurity (UserThread,
  188. &Ccb->SecurityQos,
  189. FALSE,
  190. SecurityContext))) {
  191. DebugTrace(0, Dbg, "Not successful at creating client security, %08lx\n", Status);
  192. NpFreePool (SecurityContext);
  193. SecurityContext = NULL;
  194. }
  195. } else {
  196. DebugTrace(0, Dbg, "Static Tracking or Not Client End\n", 0);
  197. SecurityContext = NULL;
  198. Status = STATUS_SUCCESS;
  199. }
  200. DebugTrace(-1, Dbg, "NpSetDataEntryClientContext -> %08lx\n", Status);
  201. *ppSecurityContext = SecurityContext;
  202. return Status;
  203. }
  204. VOID
  205. NpCopyClientContext (
  206. IN PCCB Ccb,
  207. IN PDATA_ENTRY DataEntry
  208. )
  209. /*++
  210. Routine Description:
  211. This routine copies the client context stored in the data entry into
  212. the ccb, but only for dynamic tracking.
  213. Arguments:
  214. Ccb - Supplies the ccb to update.
  215. DataEntry - Supplies the DataEntry to copy from.
  216. Return Value:
  217. --*/
  218. {
  219. PAGED_CODE();
  220. DebugTrace(+1, Dbg, "NpCopyClientContext, Ccb = %08lx\n", Ccb);
  221. //
  222. // Only do the copy if the data entries client context field is not null
  223. // which means that we are doing dynamic tracking. Note we will
  224. // not be called with a server write data entry that has a non null
  225. // client context.
  226. //
  227. if (DataEntry->SecurityClientContext != NULL) {
  228. DebugTrace(0, Dbg, "have something to copy %08lx\n", DataEntry->SecurityClientContext);
  229. //
  230. // First check if we need to delete and deallocate the client
  231. // context in the nonpaged ccb
  232. //
  233. if (Ccb->SecurityClientContext != NULL) {
  234. DebugTrace(0, Dbg, "Remove current client context %08lx\n", Ccb->SecurityClientContext);
  235. SeDeleteClientSecurity (Ccb->SecurityClientContext);
  236. NpFreePool (Ccb->SecurityClientContext);
  237. }
  238. //
  239. // Now copy over the reference to the client context, and zero
  240. // out the reference in the data entry.
  241. //
  242. Ccb->SecurityClientContext = DataEntry->SecurityClientContext;
  243. DataEntry->SecurityClientContext = NULL;
  244. }
  245. DebugTrace(-1, Dbg, "NpCopyClientContext -> VOID\n", 0 );
  246. return;
  247. }
  248. NTSTATUS
  249. NpImpersonateClientContext (
  250. IN PCCB Ccb
  251. )
  252. /*++
  253. Routine Description:
  254. This routine impersonates the current client context stored in the
  255. ccb
  256. Arguments:
  257. Ccb - Supplies the ccb for the named pipe
  258. Return Value:
  259. NTSTATUS - returns our status code.
  260. --*/
  261. {
  262. NTSTATUS Status;
  263. PAGED_CODE();
  264. DebugTrace(+1, Dbg, "NpImpersonateClientContext, Ccb = %08lx\n", Ccb);
  265. if (Ccb->SecurityClientContext == NULL) {
  266. DebugTrace(0, Dbg, "Cannot impersonate\n", 0);
  267. Status = STATUS_CANNOT_IMPERSONATE;
  268. } else {
  269. Status = SeImpersonateClientEx( Ccb->SecurityClientContext, NULL );
  270. }
  271. DebugTrace(-1, Dbg, "NpImpersonateClientContext -> %08lx\n", Status);
  272. return Status;
  273. }