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 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 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 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