1 /* 2 * PROJECT: ReactOS Named Pipe FileSystem 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: drivers/filesystems/npfs/secursup.c 5 * PURPOSE: Pipes Security Support 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "npfs.h" 12 13 // File ID number for NPFS bugchecking support 14 #define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_SECURSUP) 15 16 /* FUNCTIONS ******************************************************************/ 17 18 NTSTATUS 19 NTAPI 20 NpImpersonateClientContext(IN PNP_CCB Ccb) 21 { 22 NTSTATUS Status; 23 PSECURITY_CLIENT_CONTEXT ClientContext; 24 PAGED_CODE(); 25 26 ClientContext = Ccb->ClientContext; 27 if (ClientContext) 28 { 29 Status = SeImpersonateClientEx(ClientContext, NULL); 30 } 31 else 32 { 33 Status = STATUS_CANNOT_IMPERSONATE; 34 } 35 return Status; 36 } 37 38 VOID 39 NTAPI 40 NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext) 41 { 42 TOKEN_TYPE TokenType; 43 PVOID ClientToken; 44 45 if (!ClientContext) return; 46 47 TokenType = SeTokenType(ClientContext->ClientToken); 48 ClientToken = ClientContext->ClientToken; 49 if ((TokenType == TokenPrimary) || (ClientToken)) 50 { 51 ObDereferenceObject(ClientToken); 52 } 53 ExFreePool(ClientContext); 54 } 55 56 VOID 57 NTAPI 58 NpCopyClientContext(IN PNP_CCB Ccb, 59 IN PNP_DATA_QUEUE_ENTRY DataQueueEntry) 60 { 61 PAGED_CODE(); 62 63 if (!DataQueueEntry->ClientSecurityContext) return; 64 65 NpFreeClientSecurityContext(Ccb->ClientContext); 66 Ccb->ClientContext = DataQueueEntry->ClientSecurityContext; 67 DataQueueEntry->ClientSecurityContext = NULL; 68 } 69 70 VOID 71 NTAPI 72 NpUninitializeSecurity(IN PNP_CCB Ccb) 73 { 74 PAGED_CODE(); 75 76 NpFreeClientSecurityContext(Ccb->ClientContext); 77 Ccb->ClientContext = NULL; 78 } 79 80 NTSTATUS 81 NTAPI 82 NpInitializeSecurity(IN PNP_CCB Ccb, 83 IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, 84 IN PETHREAD Thread) 85 { 86 PSECURITY_CLIENT_CONTEXT ClientContext; 87 NTSTATUS Status; 88 PAGED_CODE(); 89 90 if (SecurityQos) 91 { 92 Ccb->ClientQos = *SecurityQos; 93 } 94 else 95 { 96 Ccb->ClientQos.Length = sizeof(Ccb->ClientQos); 97 Ccb->ClientQos.ImpersonationLevel = SecurityImpersonation; 98 Ccb->ClientQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; 99 Ccb->ClientQos.EffectiveOnly = TRUE; 100 } 101 102 NpUninitializeSecurity(Ccb); 103 104 if (Ccb->ClientQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING) 105 { 106 Status = STATUS_SUCCESS; 107 Ccb->ClientContext = NULL; 108 return Status; 109 } 110 111 ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), NPFS_CLIENT_SEC_CTX_TAG); 112 Ccb->ClientContext = ClientContext; 113 if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES; 114 115 Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext); 116 if (!NT_SUCCESS(Status)) return Status; 117 118 ExFreePool(Ccb->ClientContext); 119 Ccb->ClientContext = NULL; 120 return Status; 121 } 122 123 NTSTATUS 124 NTAPI 125 NpGetClientSecurityContext(IN ULONG NamedPipeEnd, 126 IN PNP_CCB Ccb, 127 IN PETHREAD Thread, 128 IN PSECURITY_CLIENT_CONTEXT *Context) 129 { 130 131 PSECURITY_CLIENT_CONTEXT NewContext; 132 NTSTATUS Status; 133 PAGED_CODE(); 134 135 if (NamedPipeEnd == FILE_PIPE_SERVER_END || Ccb->ClientQos.ContextTrackingMode != SECURITY_DYNAMIC_TRACKING) 136 { 137 NewContext = NULL; 138 Status = STATUS_SUCCESS; 139 } 140 else 141 { 142 NewContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, 143 sizeof(*NewContext), 144 NPFS_CLIENT_SEC_CTX_TAG); 145 if (!NewContext) return STATUS_INSUFFICIENT_RESOURCES; 146 147 Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext); 148 if (!NT_SUCCESS(Status)) 149 { 150 ExFreePool(NewContext); 151 NewContext = NULL; 152 } 153 } 154 *Context = NewContext; 155 return Status; 156 } 157 158 /* EOF */ 159