xref: /reactos/dll/win32/samsrv/group.c (revision c2c66aff)
1 /*
2  * PROJECT:     Local Security Authority Server DLL
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/win32/samsrv/group.c
5  * PURPOSE:     Group specific helper functions
6  * COPYRIGHT:   Copyright 2013 Eric Kohl
7  */
8 
9 #include "samsrv.h"
10 
11 /* FUNCTIONS ***************************************************************/
12 
13 NTSTATUS
SampOpenGroupObject(IN PSAM_DB_OBJECT DomainObject,IN ULONG GroupId,IN ACCESS_MASK DesiredAccess,OUT PSAM_DB_OBJECT * GroupObject)14 SampOpenGroupObject(IN PSAM_DB_OBJECT DomainObject,
15                     IN ULONG GroupId,
16                     IN ACCESS_MASK DesiredAccess,
17                     OUT PSAM_DB_OBJECT *GroupObject)
18 {
19     WCHAR szRid[9];
20 
21     TRACE("(%p %lu %lx %p)\n",
22           DomainObject, GroupId, DesiredAccess, GroupObject);
23 
24     /* Convert the RID into a string (hex) */
25     swprintf(szRid, L"%08lX", GroupId);
26 
27     /* Create the user object */
28     return SampOpenDbObject(DomainObject,
29                             L"Groups",
30                             szRid,
31                             GroupId,
32                             SamDbGroupObject,
33                             DesiredAccess,
34                             GroupObject);
35 }
36 
37 
38 NTSTATUS
SampAddMemberToGroup(IN PSAM_DB_OBJECT GroupObject,IN ULONG MemberId)39 SampAddMemberToGroup(IN PSAM_DB_OBJECT GroupObject,
40                      IN ULONG MemberId)
41 {
42     PULONG MembersBuffer = NULL;
43     ULONG MembersCount = 0;
44     ULONG Length = 0;
45     ULONG i;
46     NTSTATUS Status;
47 
48     Status = SampGetObjectAttribute(GroupObject,
49                                     L"Members",
50                                     NULL,
51                                     NULL,
52                                     &Length);
53     if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND)
54         goto done;
55 
56     MembersBuffer = midl_user_allocate(Length + sizeof(ULONG));
57     if (MembersBuffer == NULL)
58     {
59         Status = STATUS_INSUFFICIENT_RESOURCES;
60         goto done;
61     }
62 
63     if (Status != STATUS_OBJECT_NAME_NOT_FOUND)
64     {
65         Status = SampGetObjectAttribute(GroupObject,
66                                         L"Members",
67                                         NULL,
68                                         MembersBuffer,
69                                         &Length);
70         if (!NT_SUCCESS(Status))
71             goto done;
72 
73         MembersCount = Length / sizeof(ULONG);
74     }
75 
76     for (i = 0; i < MembersCount; i++)
77     {
78         if (MembersBuffer[i] == MemberId)
79         {
80             Status = STATUS_MEMBER_IN_GROUP;
81             goto done;
82         }
83     }
84 
85     MembersBuffer[MembersCount] = MemberId;
86     Length += sizeof(ULONG);
87 
88     Status = SampSetObjectAttribute(GroupObject,
89                                     L"Members",
90                                     REG_BINARY,
91                                     MembersBuffer,
92                                     Length);
93 
94 done:
95     if (MembersBuffer != NULL)
96         midl_user_free(MembersBuffer);
97 
98     return Status;
99 }
100 
101 
102 NTSTATUS
SampRemoveMemberFromGroup(IN PSAM_DB_OBJECT GroupObject,IN ULONG MemberId)103 SampRemoveMemberFromGroup(IN PSAM_DB_OBJECT GroupObject,
104                           IN ULONG MemberId)
105 {
106     PULONG MembersBuffer = NULL;
107     ULONG MembersCount = 0;
108     ULONG Length = 0;
109     ULONG i;
110     NTSTATUS Status;
111 
112     SampGetObjectAttribute(GroupObject,
113                            L"Members",
114                            NULL,
115                            NULL,
116                            &Length);
117 
118     if (Length == 0)
119         return STATUS_MEMBER_NOT_IN_GROUP;
120 
121     MembersBuffer = midl_user_allocate(Length);
122     if (MembersBuffer == NULL)
123     {
124         Status = STATUS_INSUFFICIENT_RESOURCES;
125         goto done;
126     }
127 
128     Status = SampGetObjectAttribute(GroupObject,
129                                     L"Members",
130                                     NULL,
131                                     MembersBuffer,
132                                     &Length);
133     if (!NT_SUCCESS(Status))
134         goto done;
135 
136     Status = STATUS_MEMBER_NOT_IN_GROUP;
137 
138     MembersCount = Length / sizeof(ULONG);
139     for (i = 0; i < MembersCount; i++)
140     {
141         if (MembersBuffer[i] == MemberId)
142         {
143             Length -= sizeof(ULONG);
144             Status = STATUS_SUCCESS;
145 
146             if (MembersCount - i - 1 > 0)
147             {
148                 CopyMemory(&MembersBuffer[i],
149                            &MembersBuffer[i + 1],
150                            (MembersCount - i - 1) * sizeof(ULONG));
151             }
152 
153             break;
154         }
155     }
156 
157     if (!NT_SUCCESS(Status))
158         goto done;
159 
160     Status = SampSetObjectAttribute(GroupObject,
161                                     L"Members",
162                                     REG_BINARY,
163                                     MembersBuffer,
164                                     Length);
165 
166 done:
167     if (MembersBuffer != NULL)
168         midl_user_free(MembersBuffer);
169 
170     return Status;
171 }
172 
173 /* EOF */
174