[SAMSRV]
[reactos.git] / reactos / dll / win32 / samsrv / user.c
1 /*
2 * PROJECT: Local Security Authority Server DLL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/samsrv/user.c
5 * PURPOSE: User specific helper functions
6 * COPYRIGHT: Copyright 2013 Eric Kohl
7 */
8
9 /* INCLUDES ****************************************************************/
10
11 #include "samsrv.h"
12
13 WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
14
15
16 /* FUNCTIONS ***************************************************************/
17
18 NTSTATUS
19 SampOpenUserObject(IN PSAM_DB_OBJECT DomainObject,
20 IN ULONG UserId,
21 IN ACCESS_MASK DesiredAccess,
22 OUT PSAM_DB_OBJECT *UserObject)
23 {
24 WCHAR szRid[9];
25
26 TRACE("(%p %lu %lx %p)\n",
27 DomainObject, UserId, DesiredAccess, UserObject);
28
29 /* Convert the RID into a string (hex) */
30 swprintf(szRid, L"%08lX", UserId);
31
32 /* Create the user object */
33 return SampOpenDbObject(DomainObject,
34 L"Users",
35 szRid,
36 UserId,
37 SamDbUserObject,
38 DesiredAccess,
39 UserObject);
40 }
41
42
43 NTSTATUS
44 SampAddGroupMembershipToUser(IN PSAM_DB_OBJECT UserObject,
45 IN ULONG GroupId,
46 IN ULONG Attributes)
47 {
48 PGROUP_MEMBERSHIP GroupsBuffer = NULL;
49 ULONG GroupsCount = 0;
50 ULONG Length = 0;
51 ULONG i;
52 NTSTATUS Status;
53
54 TRACE("(%p %lu %lx)\n",
55 UserObject, GroupId, Attributes);
56
57 Status = SampGetObjectAttribute(UserObject,
58 L"Groups",
59 NULL,
60 NULL,
61 &Length);
62 if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
63 goto done;
64
65 GroupsBuffer = midl_user_allocate(Length + sizeof(GROUP_MEMBERSHIP));
66 if (GroupsBuffer == NULL)
67 {
68 Status = STATUS_INSUFFICIENT_RESOURCES;
69 goto done;
70 }
71
72 if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
73 {
74 Status = SampGetObjectAttribute(UserObject,
75 L"Groups",
76 NULL,
77 GroupsBuffer,
78 &Length);
79 if (!NT_SUCCESS(Status))
80 goto done;
81
82 GroupsCount = Length / sizeof(GROUP_MEMBERSHIP);
83 }
84
85 for (i = 0; i < GroupsCount; i++)
86 {
87 if (GroupsBuffer[i].RelativeId == GroupId)
88 {
89 Status = STATUS_MEMBER_IN_GROUP;
90 goto done;
91 }
92 }
93
94 GroupsBuffer[GroupsCount].RelativeId = GroupId;
95 GroupsBuffer[GroupsCount].Attributes = Attributes;
96 Length += sizeof(GROUP_MEMBERSHIP);
97
98 Status = SampSetObjectAttribute(UserObject,
99 L"Groups",
100 REG_BINARY,
101 GroupsBuffer,
102 Length);
103
104 done:
105 if (GroupsBuffer != NULL)
106 midl_user_free(GroupsBuffer);
107
108 return Status;
109 }
110
111
112 NTSTATUS
113 SampRemoveGroupMembershipFromUser(IN PSAM_DB_OBJECT UserObject,
114 IN ULONG GroupId)
115 {
116 PGROUP_MEMBERSHIP GroupsBuffer = NULL;
117 ULONG GroupsCount = 0;
118 ULONG Length = 0;
119 ULONG i;
120 NTSTATUS Status;
121
122 TRACE("(%p %lu)\n",
123 UserObject, GroupId);
124
125 Status = SampGetObjectAttribute(UserObject,
126 L"Groups",
127 NULL,
128 NULL,
129 &Length);
130
131 if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
132 return STATUS_MEMBER_NOT_IN_GROUP;
133
134 if (!NT_SUCCESS(Status))
135 return Status;
136
137 GroupsBuffer = midl_user_allocate(Length);
138 if (GroupsBuffer == NULL)
139 {
140 Status = STATUS_INSUFFICIENT_RESOURCES;
141 goto done;
142 }
143
144 Status = SampGetObjectAttribute(UserObject,
145 L"Groups",
146 NULL,
147 GroupsBuffer,
148 &Length);
149 if (!NT_SUCCESS(Status))
150 goto done;
151
152 Status = STATUS_MEMBER_NOT_IN_GROUP;
153
154 GroupsCount = Length / sizeof(GROUP_MEMBERSHIP);
155 for (i = 0; i < GroupsCount; i++)
156 {
157 if (GroupsBuffer[i].RelativeId == GroupId)
158 {
159 Length -= sizeof(GROUP_MEMBERSHIP);
160 Status = STATUS_SUCCESS;
161 break;
162 }
163
164 if (Status == STATUS_SUCCESS && i < GroupsCount - 1)
165 {
166 CopyMemory(&GroupsBuffer[i],
167 &GroupsBuffer[i + 1],
168 sizeof(GROUP_MEMBERSHIP));
169 }
170 }
171
172 if (!NT_SUCCESS(Status))
173 goto done;
174
175 Status = SampSetObjectAttribute(UserObject,
176 L"Groups",
177 REG_BINARY,
178 GroupsBuffer,
179 Length);
180
181 done:
182 if (GroupsBuffer != NULL)
183 midl_user_free(GroupsBuffer);
184
185 return Status;
186 }
187
188
189 NTSTATUS
190 SampGetUserGroupAttributes(IN PSAM_DB_OBJECT DomainObject,
191 IN ULONG UserId,
192 IN ULONG GroupId,
193 OUT PULONG GroupAttributes)
194 {
195 PSAM_DB_OBJECT UserObject = NULL;
196 PGROUP_MEMBERSHIP GroupsBuffer = NULL;
197 ULONG Length = 0;
198 ULONG i;
199 NTSTATUS Status;
200
201 Status = SampOpenUserObject(DomainObject,
202 UserId,
203 0,
204 &UserObject);
205 if (!NT_SUCCESS(Status))
206 {
207 return Status;
208 }
209
210 SampGetObjectAttribute(UserObject,
211 L"Groups",
212 NULL,
213 NULL,
214 &Length);
215
216 if (Length == 0)
217 return STATUS_UNSUCCESSFUL; /* FIXME */
218
219 GroupsBuffer = midl_user_allocate(Length);
220 if (GroupsBuffer == NULL)
221 {
222 Status = STATUS_INSUFFICIENT_RESOURCES;
223 goto done;
224 }
225
226 Status = SampGetObjectAttribute(UserObject,
227 L"Groups",
228 NULL,
229 GroupsBuffer,
230 &Length);
231 if (!NT_SUCCESS(Status))
232 goto done;
233
234 for (i = 0; i < (Length / sizeof(GROUP_MEMBERSHIP)); i++)
235 {
236 if (GroupsBuffer[i].RelativeId == GroupId)
237 {
238 *GroupAttributes = GroupsBuffer[i].Attributes;
239 goto done;
240 }
241 }
242
243 done:
244 if (GroupsBuffer != NULL)
245 midl_user_free(GroupsBuffer);
246
247 if (UserObject != NULL)
248 SampCloseDbObject(UserObject);
249
250 return Status;
251 }
252
253
254 NTSTATUS
255 SampSetUserGroupAttributes(IN PSAM_DB_OBJECT DomainObject,
256 IN ULONG UserId,
257 IN ULONG GroupId,
258 IN ULONG GroupAttributes)
259 {
260 PSAM_DB_OBJECT UserObject = NULL;
261 PGROUP_MEMBERSHIP GroupsBuffer = NULL;
262 ULONG Length = 0;
263 ULONG i;
264 NTSTATUS Status;
265
266 Status = SampOpenUserObject(DomainObject,
267 UserId,
268 0,
269 &UserObject);
270 if (!NT_SUCCESS(Status))
271 {
272 return Status;
273 }
274
275 SampGetObjectAttribute(UserObject,
276 L"Groups",
277 NULL,
278 NULL,
279 &Length);
280
281 if (Length == 0)
282 return STATUS_UNSUCCESSFUL; /* FIXME */
283
284 GroupsBuffer = midl_user_allocate(Length);
285 if (GroupsBuffer == NULL)
286 {
287 Status = STATUS_INSUFFICIENT_RESOURCES;
288 goto done;
289 }
290
291 Status = SampGetObjectAttribute(UserObject,
292 L"Groups",
293 NULL,
294 GroupsBuffer,
295 &Length);
296 if (!NT_SUCCESS(Status))
297 goto done;
298
299 for (i = 0; i < (Length / sizeof(GROUP_MEMBERSHIP)); i++)
300 {
301 if (GroupsBuffer[i].RelativeId == GroupId)
302 {
303 GroupsBuffer[i].Attributes = GroupAttributes;
304 break;
305 }
306 }
307
308 Status = SampSetObjectAttribute(UserObject,
309 L"Groups",
310 REG_BINARY,
311 GroupsBuffer,
312 Length);
313
314 done:
315 if (GroupsBuffer != NULL)
316 midl_user_free(GroupsBuffer);
317
318 if (UserObject != NULL)
319 SampCloseDbObject(UserObject);
320
321 return Status;
322 }
323
324 /* EOF */