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
GetAccountDomainSid(IN PUNICODE_STRING ServerName,OUT PSID * AccountDomainSid)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
GetBuiltinDomainSid(OUT PSID * BuiltinDomainSid)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
OpenAccountDomain(IN SAM_HANDLE ServerHandle,IN PUNICODE_STRING ServerName,IN ULONG DesiredAccess,OUT PSAM_HANDLE DomainHandle)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
OpenBuiltinDomain(IN SAM_HANDLE ServerHandle,IN ULONG DesiredAccess,OUT PSAM_HANDLE DomainHandle)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
BuildSidFromSidAndRid(IN PSID SrcSid,IN ULONG RelativeId,OUT PSID * DestSid)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
CopySidFromSidAndRid(_Out_ PSID DstSid,_In_ PSID SrcSid,_In_ ULONG RelativeId)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