xref: /reactos/dll/win32/netapi32/utils.c (revision 0425d866)
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