1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: NetAPI DLL 4 * FILE: reactos/dll/win32/netapi32/utils.c 5 * PURPOSE: Helper functions 6 * 7 * PROGRAMMERS: Eric Kohl 8 */ 9 10 /* INCLUDES ******************************************************************/ 11 12 #include "netapi32.h" 13 14 WINE_DEFAULT_DEBUG_CHANNEL(netapi32); 15 16 /* GLOBALS *******************************************************************/ 17 18 static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; 19 20 /* FUNCTIONS *****************************************************************/ 21 22 NTSTATUS 23 GetAccountDomainSid(IN PUNICODE_STRING ServerName, 24 OUT PSID *AccountDomainSid) 25 { 26 PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL; 27 LSA_OBJECT_ATTRIBUTES ObjectAttributes; 28 LSA_HANDLE PolicyHandle = NULL; 29 ULONG Length = 0; 30 NTSTATUS Status; 31 32 memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); 33 34 Status = LsaOpenPolicy(ServerName, 35 &ObjectAttributes, 36 POLICY_VIEW_LOCAL_INFORMATION, 37 &PolicyHandle); 38 if (!NT_SUCCESS(Status)) 39 { 40 ERR("LsaOpenPolicy failed (Status %08lx)\n", Status); 41 return Status; 42 } 43 44 Status = LsaQueryInformationPolicy(PolicyHandle, 45 PolicyAccountDomainInformation, 46 (PVOID *)&AccountDomainInfo); 47 if (!NT_SUCCESS(Status)) 48 { 49 ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status); 50 goto done; 51 } 52 53 Length = RtlLengthSid(AccountDomainInfo->DomainSid); 54 55 *AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); 56 if (*AccountDomainSid == NULL) 57 { 58 ERR("Failed to allocate SID\n"); 59 Status = STATUS_INSUFFICIENT_RESOURCES; 60 goto done; 61 } 62 63 memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length); 64 65 done: 66 if (AccountDomainInfo != NULL) 67 LsaFreeMemory(AccountDomainInfo); 68 69 LsaClose(PolicyHandle); 70 71 return Status; 72 } 73 74 75 NTSTATUS 76 GetBuiltinDomainSid(OUT PSID *BuiltinDomainSid) 77 { 78 PSID Sid = NULL; 79 PULONG Ptr; 80 NTSTATUS Status = STATUS_SUCCESS; 81 82 *BuiltinDomainSid = NULL; 83 84 Sid = RtlAllocateHeap(RtlGetProcessHeap(), 85 0, 86 RtlLengthRequiredSid(1)); 87 if (Sid == NULL) 88 return STATUS_INSUFFICIENT_RESOURCES; 89 90 Status = RtlInitializeSid(Sid, 91 &NtAuthority, 92 1); 93 if (!NT_SUCCESS(Status)) 94 goto done; 95 96 Ptr = RtlSubAuthoritySid(Sid, 0); 97 *Ptr = SECURITY_BUILTIN_DOMAIN_RID; 98 99 *BuiltinDomainSid = Sid; 100 101 done: 102 if (!NT_SUCCESS(Status)) 103 { 104 if (Sid != NULL) 105 RtlFreeHeap(RtlGetProcessHeap(), 0, Sid); 106 } 107 108 return Status; 109 } 110 111 112 NTSTATUS 113 OpenAccountDomain(IN SAM_HANDLE ServerHandle, 114 IN PUNICODE_STRING ServerName, 115 IN ULONG DesiredAccess, 116 OUT PSAM_HANDLE DomainHandle) 117 { 118 PSID DomainSid = NULL; 119 NTSTATUS Status; 120 121 Status = GetAccountDomainSid(ServerName, 122 &DomainSid); 123 if (!NT_SUCCESS(Status)) 124 { 125 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); 126 return Status; 127 } 128 129 Status = SamOpenDomain(ServerHandle, 130 DesiredAccess, 131 DomainSid, 132 DomainHandle); 133 134 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); 135 136 if (!NT_SUCCESS(Status)) 137 { 138 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 139 } 140 141 return Status; 142 } 143 144 145 NTSTATUS 146 OpenBuiltinDomain(IN SAM_HANDLE ServerHandle, 147 IN ULONG DesiredAccess, 148 OUT PSAM_HANDLE DomainHandle) 149 { 150 PSID DomainSid = NULL; 151 NTSTATUS Status; 152 153 Status = GetBuiltinDomainSid(&DomainSid); 154 if (!NT_SUCCESS(Status)) 155 { 156 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status); 157 return Status; 158 } 159 160 Status = SamOpenDomain(ServerHandle, 161 DesiredAccess, 162 DomainSid, 163 DomainHandle); 164 165 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); 166 167 if (!NT_SUCCESS(Status)) 168 { 169 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 170 } 171 172 return Status; 173 } 174 175 176 NET_API_STATUS 177 BuildSidFromSidAndRid(IN PSID SrcSid, 178 IN ULONG RelativeId, 179 OUT PSID *DestSid) 180 { 181 UCHAR RidCount; 182 PSID DstSid; 183 ULONG i; 184 ULONG DstSidSize; 185 PULONG p, q; 186 NET_API_STATUS ApiStatus = NERR_Success; 187 188 RidCount = *RtlSubAuthorityCountSid(SrcSid); 189 if (RidCount >= 8) 190 return ERROR_INVALID_PARAMETER; 191 192 DstSidSize = RtlLengthRequiredSid(RidCount + 1); 193 194 ApiStatus = NetApiBufferAllocate(DstSidSize, 195 &DstSid); 196 if (ApiStatus != NERR_Success) 197 return ApiStatus; 198 199 RtlInitializeSid(DstSid, 200 RtlIdentifierAuthoritySid(SrcSid), 201 RidCount + 1); 202 203 for (i = 0; i < (ULONG)RidCount; i++) 204 { 205 p = RtlSubAuthoritySid(SrcSid, i); 206 q = RtlSubAuthoritySid(DstSid, i); 207 *q = *p; 208 } 209 210 q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount); 211 *q = RelativeId; 212 213 *DestSid = DstSid; 214 215 return NERR_Success; 216 } 217 218 219 VOID 220 CopySidFromSidAndRid( 221 _Out_ PSID DstSid, 222 _In_ PSID SrcSid, 223 _In_ ULONG RelativeId) 224 { 225 UCHAR RidCount; 226 ULONG i; 227 PULONG p, q; 228 229 RidCount = *RtlSubAuthorityCountSid(SrcSid); 230 if (RidCount >= 8) 231 return; 232 233 RtlInitializeSid(DstSid, 234 RtlIdentifierAuthoritySid(SrcSid), 235 RidCount + 1); 236 237 for (i = 0; i < (ULONG)RidCount; i++) 238 { 239 p = RtlSubAuthoritySid(SrcSid, i); 240 q = RtlSubAuthoritySid(DstSid, i); 241 *q = *p; 242 } 243 244 q = RtlSubAuthoritySid(DstSid, (ULONG)RidCount); 245 *q = RelativeId; 246 } 247 248 /* EOF */ 249