1 /* 2 * PROJECT: Local Security Authority Server DLL 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/win32/samsrv/domain.c 5 * PURPOSE: Domain specific helper functions 6 * COPYRIGHT: Copyright 2013 Eric Kohl 7 */ 8 9 #include "samsrv.h" 10 11 /* FUNCTIONS ***************************************************************/ 12 13 NTSTATUS 14 SampSetAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, 15 IN LPCWSTR lpContainerName, 16 IN LPCWSTR lpAccountName, 17 IN ULONG ulRelativeId) 18 { 19 HANDLE ContainerKeyHandle = NULL; 20 HANDLE NamesKeyHandle = NULL; 21 NTSTATUS Status; 22 23 TRACE("SampSetAccountNameInDomain()\n"); 24 25 /* Open the container key */ 26 Status = SampRegOpenKey(DomainObject->KeyHandle, 27 lpContainerName, 28 KEY_ALL_ACCESS, 29 &ContainerKeyHandle); 30 if (!NT_SUCCESS(Status)) 31 return Status; 32 33 /* Open the 'Names' key */ 34 Status = SampRegOpenKey(ContainerKeyHandle, 35 L"Names", 36 KEY_ALL_ACCESS, 37 &NamesKeyHandle); 38 if (!NT_SUCCESS(Status)) 39 goto done; 40 41 /* Set the alias value */ 42 Status = SampRegSetValue(NamesKeyHandle, 43 lpAccountName, 44 REG_DWORD, 45 (LPVOID)&ulRelativeId, 46 sizeof(ULONG)); 47 48 done: 49 SampRegCloseKey(&NamesKeyHandle); 50 SampRegCloseKey(&ContainerKeyHandle); 51 52 return Status; 53 } 54 55 56 NTSTATUS 57 SampRemoveAccountNameFromDomain(IN PSAM_DB_OBJECT DomainObject, 58 IN LPCWSTR lpContainerName, 59 IN LPCWSTR lpAccountName) 60 { 61 HANDLE ContainerKeyHandle = NULL; 62 HANDLE NamesKeyHandle = NULL; 63 NTSTATUS Status; 64 65 TRACE("(%S %S)\n", lpContainerName, lpAccountName); 66 67 /* Open the container key */ 68 Status = SampRegOpenKey(DomainObject->KeyHandle, 69 lpContainerName, 70 KEY_ALL_ACCESS, 71 &ContainerKeyHandle); 72 if (!NT_SUCCESS(Status)) 73 return Status; 74 75 /* Open the 'Names' key */ 76 Status = SampRegOpenKey(ContainerKeyHandle, 77 L"Names", 78 KEY_SET_VALUE, 79 &NamesKeyHandle); 80 if (!NT_SUCCESS(Status)) 81 goto done; 82 83 /* Delete the account name value */ 84 Status = SampRegDeleteValue(NamesKeyHandle, 85 lpAccountName); 86 87 done: 88 SampRegCloseKey(&NamesKeyHandle); 89 SampRegCloseKey(&ContainerKeyHandle); 90 91 return Status; 92 } 93 94 95 NTSTATUS 96 SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, 97 IN LPCWSTR lpAccountName) 98 { 99 HANDLE AccountKey = NULL; 100 HANDLE NamesKey = NULL; 101 NTSTATUS Status; 102 103 TRACE("SampCheckAccountNameInDomain()\n"); 104 105 Status = SampRegOpenKey(DomainObject->KeyHandle, 106 L"Aliases", 107 KEY_READ, 108 &AccountKey); 109 if (NT_SUCCESS(Status)) 110 { 111 Status = SampRegOpenKey(AccountKey, 112 L"Names", 113 KEY_READ, 114 &NamesKey); 115 if (NT_SUCCESS(Status)) 116 { 117 Status = SampRegQueryValue(NamesKey, 118 lpAccountName, 119 NULL, 120 NULL, 121 NULL); 122 if (Status == STATUS_SUCCESS) 123 { 124 SampRegCloseKey(&NamesKey); 125 Status = STATUS_ALIAS_EXISTS; 126 } 127 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 128 Status = STATUS_SUCCESS; 129 } 130 131 SampRegCloseKey(&AccountKey); 132 } 133 134 if (!NT_SUCCESS(Status)) 135 { 136 TRACE("Checking for alias account failed (Status 0x%08lx)\n", Status); 137 return Status; 138 } 139 140 Status = SampRegOpenKey(DomainObject->KeyHandle, 141 L"Groups", 142 KEY_READ, 143 &AccountKey); 144 if (NT_SUCCESS(Status)) 145 { 146 Status = SampRegOpenKey(AccountKey, 147 L"Names", 148 KEY_READ, 149 &NamesKey); 150 if (NT_SUCCESS(Status)) 151 { 152 Status = SampRegQueryValue(NamesKey, 153 lpAccountName, 154 NULL, 155 NULL, 156 NULL); 157 if (Status == STATUS_SUCCESS) 158 { 159 SampRegCloseKey(&NamesKey); 160 Status = STATUS_GROUP_EXISTS; 161 } 162 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 163 Status = STATUS_SUCCESS; 164 } 165 166 SampRegCloseKey(&AccountKey); 167 } 168 169 if (!NT_SUCCESS(Status)) 170 { 171 TRACE("Checking for group account failed (Status 0x%08lx)\n", Status); 172 return Status; 173 } 174 175 Status = SampRegOpenKey(DomainObject->KeyHandle, 176 L"Users", 177 KEY_READ, 178 &AccountKey); 179 if (NT_SUCCESS(Status)) 180 { 181 Status = SampRegOpenKey(AccountKey, 182 L"Names", 183 KEY_READ, 184 &NamesKey); 185 if (NT_SUCCESS(Status)) 186 { 187 Status = SampRegQueryValue(NamesKey, 188 lpAccountName, 189 NULL, 190 NULL, 191 NULL); 192 if (Status == STATUS_SUCCESS) 193 { 194 SampRegCloseKey(&NamesKey); 195 Status = STATUS_USER_EXISTS; 196 } 197 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 198 Status = STATUS_SUCCESS; 199 } 200 201 SampRegCloseKey(&AccountKey); 202 } 203 204 if (!NT_SUCCESS(Status)) 205 { 206 TRACE("Checking for user account failed (Status 0x%08lx)\n", Status); 207 } 208 209 return Status; 210 } 211 212 213 NTSTATUS 214 SampRemoveMemberFromAllAliases(IN PSAM_DB_OBJECT DomainObject, 215 IN PRPC_SID MemberSid) 216 { 217 WCHAR AliasKeyName[64]; 218 LPWSTR MemberSidString = NULL; 219 HANDLE AliasesKey = NULL; 220 HANDLE MembersKey = NULL; 221 HANDLE AliasKey = NULL; 222 ULONG Index; 223 NTSTATUS Status; 224 225 TRACE("(%p %p)\n", DomainObject, MemberSid); 226 227 ConvertSidToStringSidW(MemberSid, &MemberSidString); 228 TRACE("Member SID: %S\n", MemberSidString); 229 230 Status = SampRegOpenKey(DomainObject->KeyHandle, 231 L"Aliases", 232 KEY_READ, 233 &AliasesKey); 234 if (NT_SUCCESS(Status)) 235 { 236 Index = 0; 237 while (TRUE) 238 { 239 Status = SampRegEnumerateSubKey(AliasesKey, 240 Index, 241 64, 242 AliasKeyName); 243 if (!NT_SUCCESS(Status)) 244 { 245 if (Status == STATUS_NO_MORE_ENTRIES) 246 Status = STATUS_SUCCESS; 247 break; 248 } 249 250 TRACE("Alias key name: %S\n", AliasKeyName); 251 252 Status = SampRegOpenKey(AliasesKey, 253 AliasKeyName, 254 KEY_READ, 255 &AliasKey); 256 if (NT_SUCCESS(Status)) 257 { 258 Status = SampRegOpenKey(AliasKey, 259 L"Members", 260 KEY_WRITE, 261 &MembersKey); 262 if (NT_SUCCESS(Status)) 263 { 264 Status = SampRegDeleteValue(AliasKey, 265 MemberSidString); 266 267 SampRegCloseKey(&MembersKey); 268 } 269 else if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 270 Status = STATUS_SUCCESS; 271 272 SampRegCloseKey(&AliasKey); 273 } 274 275 Index++; 276 } 277 278 Status = SampRegOpenKey(AliasesKey, 279 L"Members", 280 KEY_WRITE, 281 &MembersKey); 282 if (NT_SUCCESS(Status)) 283 { 284 Status = SampRegDeleteKey(MembersKey, 285 MemberSidString); 286 if (Status == STATUS_OBJECT_NAME_NOT_FOUND) 287 Status = STATUS_SUCCESS; 288 289 SampRegCloseKey(&MembersKey); 290 } 291 292 SampRegCloseKey(&AliasesKey); 293 } 294 295 if (MemberSidString != NULL) 296 LocalFree(MemberSidString); 297 298 return Status; 299 } 300 301 302 NTSTATUS 303 SampCreateAccountSid(IN PSAM_DB_OBJECT DomainObject, 304 IN ULONG ulRelativeId, 305 IN OUT PSID *AccountSid) 306 { 307 PSID DomainSid = NULL; 308 ULONG Length = 0; 309 NTSTATUS Status; 310 311 Status = SampGetObjectAttribute(DomainObject, 312 L"SID", 313 NULL, 314 NULL, 315 &Length); 316 if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) 317 { 318 TRACE("Status 0x%08lx\n", Status); 319 goto done; 320 } 321 322 TRACE("Length: %lu\n", Length); 323 324 DomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length); 325 if (DomainSid == NULL) 326 { 327 Status = STATUS_INSUFFICIENT_RESOURCES; 328 goto done; 329 } 330 331 Status = SampGetObjectAttribute(DomainObject, 332 L"SID", 333 NULL, 334 DomainSid, 335 &Length); 336 if (!NT_SUCCESS(Status)) 337 { 338 TRACE("Status 0x%08lx\n", Status); 339 goto done; 340 } 341 342 *AccountSid = AppendRidToSid(DomainSid, 343 ulRelativeId); 344 345 done: 346 if (DomainSid != NULL) 347 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); 348 349 return Status; 350 } 351 352 /* EOF */ 353