2 Copyright (C) Stefan Metzmacher <metze@samba.org> 2010
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 Published to the public domain
20 * This tool can set the DOMAIN-SID and nextRid counter in
21 * the local SAM on windows servers (tested with w2k8r2)
23 * dcpromo will use this values for the ad domain it creates.
25 * This might be useful for upgrades from a Samba3 domain.
33 /* Convert a binary SID to a character string */
34 static DWORD SidToString(const SID *sid,
42 return ERROR_INVALID_SID;
45 maxlen = sid->SubAuthorityCount * 11 + 25;
47 result = (char *)malloc(maxlen);
49 return ERROR_NOT_ENOUGH_MEMORY;
53 * BIG NOTE: this function only does SIDS where the identauth is not
54 * >= ^32 in a range of 2^48.
57 id_auth = sid->IdentifierAuthority.Value[5] +
58 (sid->IdentifierAuthority.Value[4] << 8) +
59 (sid->IdentifierAuthority.Value[3] << 16) +
60 (sid->IdentifierAuthority.Value[2] << 24);
62 ofs = snprintf(result, maxlen, "S-%u-%lu",
63 (unsigned int)sid->Revision, (unsigned long)id_auth);
65 for (i = 0; i < sid->SubAuthorityCount; i++) {
66 ofs += snprintf(result + ofs, maxlen - ofs, "-%lu",
67 (unsigned long)sid->SubAuthority[i]);
74 static DWORD StringToSid(const char *str,
82 return ERROR_INVALID_PARAMETER;
85 /* Sanity check for either "S-" or "s-" */
88 || (str[0]!='S' && str[0]!='s')
91 return ERROR_INVALID_PARAMETER;
94 /* Get the SID revision number */
97 x = (DWORD)strtol(p, &q, 10);
98 if (x==0 || !q || *q!='-') {
99 return ERROR_INVALID_SID;
101 sid->Revision = (BYTE)x;
103 /* Next the Identifier Authority. This is stored in big-endian
104 in a 6 byte array. */
107 x = (DWORD)strtol(p, &q, 10);
109 return ERROR_INVALID_SID;
111 sid->IdentifierAuthority.Value[5] = (x & 0x000000ff);
112 sid->IdentifierAuthority.Value[4] = (x & 0x0000ff00) >> 8;
113 sid->IdentifierAuthority.Value[3] = (x & 0x00ff0000) >> 16;
114 sid->IdentifierAuthority.Value[2] = (x & 0xff000000) >> 24;
115 sid->IdentifierAuthority.Value[1] = 0;
116 sid->IdentifierAuthority.Value[0] = 0;
118 /* now read the the subauthorities */
121 sid->SubAuthorityCount = 0;
122 while (sid->SubAuthorityCount < 6) {
123 x=(DWORD)strtoul(p, &q, 10);
127 return ERROR_INVALID_SID;
129 sid->SubAuthority[sid->SubAuthorityCount++] = x;
131 if ((*q!='-') || (*q=='\0'))
136 /* IF we ended early, then the SID could not be converted */
139 return ERROR_INVALID_SID;
142 return ERROR_SUCCESS;
145 #define MIN(a,b) ((a)<(b)?(a):(b))
146 static void print_asc(const unsigned char *buf,int len)
150 printf("%c", isprint(buf[i])?buf[i]:'.');
153 static void dump_data(const unsigned char *buf1,int len)
155 const unsigned char *buf = (const unsigned char *)buf1;
161 printf("%02X ",(int)buf[i]);
163 if (i%8 == 0) printf(" ");
165 print_asc(&buf[i-16],8); printf(" ");
166 print_asc(&buf[i-8],8); printf("\n");
167 if (i<len) printf("[%03X] ",i);
174 if (n>8) printf(" ");
175 while (n--) printf(" ");
177 print_asc(&buf[i-(i%16)],n); printf( " " );
179 if (n>0) print_asc(&buf[i-n],n);
184 static DWORD calc_tmp_HKLM_SECURITY_SD(SECURITY_DESCRIPTOR *old_sd,
185 SID *current_user_sid,
186 SECURITY_DESCRIPTOR **_old_parent_sd,
187 SECURITY_DESCRIPTOR **_old_child_sd,
188 SECURITY_DESCRIPTOR **_new_parent_sd,
189 SECURITY_DESCRIPTOR **_new_child_sd)
192 DWORD cbSecurityDescriptor = 0;
193 SECURITY_DESCRIPTOR *old_parent_sd = NULL;
194 SECURITY_DESCRIPTOR *old_child_sd = NULL;
195 SECURITY_DESCRIPTOR *new_parent_sd = NULL;
196 SECURITY_DESCRIPTOR *new_child_sd = NULL;
198 ACL *old_Dacl = NULL;
199 ACL *new_Dacl = NULL;
200 ACL_SIZE_INFORMATION dacl_info;
202 SECURITY_DESCRIPTOR *AbsoluteSD = NULL;
203 DWORD dwAbsoluteSDSize = 0;
204 DWORD dwRelativeSDSize = 0;
205 DWORD dwDaclSize = 0;
207 DWORD dwSaclSize = 0;
209 DWORD dwOwnerSize = 0;
210 SID *PrimaryGroup = NULL;
211 DWORD dwPrimaryGroupSize = 0;
212 ACCESS_ALLOWED_ACE *ace = NULL;
214 ok = MakeAbsoluteSD(old_sd,
224 &dwPrimaryGroupSize);
226 status = GetLastError();
228 if (status != ERROR_INSUFFICIENT_BUFFER) {
229 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
233 AbsoluteSD = (SECURITY_DESCRIPTOR *)malloc(dwAbsoluteSDSize+1024);
234 if (AbsoluteSD == NULL) {
235 printf("LINE:%u: Error: no memory\n", __LINE__);
236 return ERROR_NOT_ENOUGH_MEMORY;
238 old_Dacl = (ACL *)malloc(dwDaclSize + 1024);
239 if (old_Dacl == NULL) {
240 printf("LINE:%u: Error: no memory\n", __LINE__);
241 return ERROR_NOT_ENOUGH_MEMORY;
243 Sacl = (ACL *)malloc(dwSaclSize);
245 printf("LINE:%u: Error: no memory\n", __LINE__);
246 return ERROR_NOT_ENOUGH_MEMORY;
248 Owner = (SID *)malloc(dwOwnerSize);
250 printf("LINE:%u: Error: no memory\n", __LINE__);
251 return ERROR_NOT_ENOUGH_MEMORY;
253 PrimaryGroup = (SID *)malloc(dwPrimaryGroupSize);
254 if (PrimaryGroup == NULL) {
255 printf("LINE:%u: Error: no memory\n", __LINE__);
256 return ERROR_NOT_ENOUGH_MEMORY;
259 ok = MakeAbsoluteSD(old_sd,
269 &dwPrimaryGroupSize);
271 status = GetLastError();
272 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
276 AbsoluteSD->Control |= SE_DACL_AUTO_INHERITED | SE_DACL_AUTO_INHERIT_REQ | SE_DACL_PROTECTED;
277 dwRelativeSDSize = 0;
278 ok = MakeSelfRelativeSD(AbsoluteSD,
282 status = GetLastError();
284 if (status != ERROR_INSUFFICIENT_BUFFER) {
285 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
286 return ERROR_NOT_ENOUGH_MEMORY;
289 old_parent_sd = (SECURITY_DESCRIPTOR *)malloc(dwRelativeSDSize);
290 if (old_parent_sd == NULL) {
291 printf("LINE:%u: Error: no memory\n", __LINE__);
292 return ERROR_NOT_ENOUGH_MEMORY;
295 ok = MakeSelfRelativeSD(AbsoluteSD,
299 status = GetLastError();
300 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
304 ok = GetAclInformation(old_Dacl,
309 status = GetLastError();
310 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
314 new_Dacl = (ACL *)calloc(dacl_info.AclBytesInUse + 1024, 1);
315 if (new_Dacl == NULL) {
316 printf("LINE:%u: Error: no memory\n", __LINE__);
317 return ERROR_NOT_ENOUGH_MEMORY;
320 InitializeAcl(new_Dacl, dacl_info.AclBytesInUse + 1024, ACL_REVISION);
322 ok = AddAccessAllowedAce(new_Dacl, ACL_REVISION,
323 KEY_ALL_ACCESS, current_user_sid);
325 status = GetLastError();
326 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
330 ok = GetAce(new_Dacl, 0, (LPVOID *)&ace);
332 status = GetLastError();
333 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
337 ace->Header.AceFlags |= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
339 for (i=0; i < dacl_info.AceCount; i++) {
340 ok = GetAce(old_Dacl, i, (LPVOID *)&ace);
342 status = GetLastError();
343 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
347 ok = AddAce(new_Dacl, ACL_REVISION, MAXDWORD,
348 ace, ace->Header.AceSize);
350 status = GetLastError();
351 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
356 AbsoluteSD->Dacl = new_Dacl;
357 dwRelativeSDSize = 0;
358 ok = MakeSelfRelativeSD(AbsoluteSD,
362 status = GetLastError();
364 if (status != ERROR_INSUFFICIENT_BUFFER) {
365 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
366 return ERROR_NOT_ENOUGH_MEMORY;
369 new_parent_sd = (SECURITY_DESCRIPTOR *)malloc(dwRelativeSDSize);
370 if (new_parent_sd == NULL) {
371 printf("LINE:%u: Error: no memory\n", __LINE__);
372 return ERROR_NOT_ENOUGH_MEMORY;
375 ok = MakeSelfRelativeSD(AbsoluteSD,
379 status = GetLastError();
380 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
384 for (i=0; i < dacl_info.AceCount; i++) {
385 ok = GetAce(old_Dacl, i, (LPVOID *)&ace);
387 status = GetLastError();
388 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
392 ace->Header.AceFlags |= INHERITED_ACE;
395 AbsoluteSD->Control &= ~SE_DACL_PROTECTED;
396 AbsoluteSD->Dacl = old_Dacl;
397 dwRelativeSDSize = 0;
398 ok = MakeSelfRelativeSD(AbsoluteSD,
402 status = GetLastError();
404 if (status != ERROR_INSUFFICIENT_BUFFER) {
405 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
406 return ERROR_NOT_ENOUGH_MEMORY;
409 old_child_sd = (SECURITY_DESCRIPTOR *)malloc(dwRelativeSDSize);
410 if (old_child_sd == NULL) {
411 printf("LINE:%u: Error: no memory\n", __LINE__);
412 return ERROR_NOT_ENOUGH_MEMORY;
415 ok = MakeSelfRelativeSD(AbsoluteSD,
419 status = GetLastError();
420 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
424 for (i=0; i < dacl_info.AceCount + 1; i++) {
425 ok = GetAce(new_Dacl, i, (LPVOID *)&ace);
427 status = GetLastError();
428 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
432 ace->Header.AceFlags |= INHERITED_ACE;
435 AbsoluteSD->Dacl = new_Dacl;
436 dwRelativeSDSize = 0;
437 ok = MakeSelfRelativeSD(AbsoluteSD,
441 status = GetLastError();
443 if (status != ERROR_INSUFFICIENT_BUFFER) {
444 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
445 return ERROR_NOT_ENOUGH_MEMORY;
448 new_child_sd = (SECURITY_DESCRIPTOR *)malloc(dwRelativeSDSize);
449 if (new_child_sd == NULL) {
450 printf("LINE:%u: Error: no memory\n", __LINE__);
451 return ERROR_NOT_ENOUGH_MEMORY;
454 ok = MakeSelfRelativeSD(AbsoluteSD,
458 status = GetLastError();
459 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
463 *_old_parent_sd = old_parent_sd;
464 *_old_child_sd = old_child_sd;
465 *_new_parent_sd = new_parent_sd;
466 *_new_child_sd = new_child_sd;
467 return ERROR_SUCCESS;
470 static DWORD inherit_SD(HKEY parent_hk,
473 SECURITY_DESCRIPTOR *current_sd,
474 SECURITY_DESCRIPTOR *child_sd)
481 status = RegOpenKeyEx(parent_hk,
484 WRITE_DAC, /* samDesired */
486 if (status != ERROR_SUCCESS) {
487 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
491 status = RegSetKeySecurity(current_hk,
492 DACL_SECURITY_INFORMATION |
493 PROTECTED_DACL_SECURITY_INFORMATION |
494 UNPROTECTED_DACL_SECURITY_INFORMATION |
495 UNPROTECTED_SACL_SECURITY_INFORMATION,
496 current_sd /* pSecurityDescriptor */
498 if (status != ERROR_SUCCESS) {
499 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
503 RegCloseKey(current_hk);
506 status = RegOpenKeyEx(parent_hk,
509 KEY_ENUMERATE_SUB_KEYS, /* samDesired */
511 if (status != ERROR_SUCCESS) {
512 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
520 memset(subkey, 0, sizeof(subkey));
521 status = RegEnumKey(current_hk, i, subkey, sizeof(subkey));
522 if (status == ERROR_NO_MORE_ITEMS) {
525 if (status != ERROR_SUCCESS) {
526 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
531 printf("subkey: %s\n", subkey);
534 status = inherit_SD(current_hk, subkey, reset,
536 if (status != ERROR_SUCCESS) {
537 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
542 RegCloseKey(current_hk);
545 status = RegOpenKeyEx(parent_hk,
548 WRITE_DAC, /* samDesired */
550 if (status != ERROR_SUCCESS) {
551 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
555 status = RegSetKeySecurity(current_hk,
556 DACL_SECURITY_INFORMATION |
557 PROTECTED_DACL_SECURITY_INFORMATION |
558 UNPROTECTED_DACL_SECURITY_INFORMATION |
559 UNPROTECTED_SACL_SECURITY_INFORMATION,
560 current_sd /* pSecurityDescriptor */
562 if (status != ERROR_SUCCESS) {
563 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
567 RegCloseKey(current_hk);
570 return ERROR_SUCCESS;
573 static DWORD replaceSIDBuffer(BYTE *buf, DWORD len,
578 BYTE *oldb = ((BYTE *)oldDomainSid)+2;
579 BYTE *newb = ((BYTE *)newDomainSid)+2;
583 printf("replaceSIDBuffer: %u\n", len);
591 if (buf[0] != SID_REVISION) {
613 cmp = memcmp(&buf[2], oldb, 22);
618 memcpy(&buf[2], newb, 22);
623 static DWORD replaceSID(HKEY parent_hk,
624 const char *parent_path,
625 const char *current_key,
632 char current_path[10240];
634 snprintf(current_path, sizeof(current_path), "%s\\%s",
635 parent_path, current_key);
637 status = RegOpenKeyEx(parent_hk,
640 KEY_ALL_ACCESS, /* samDesired */
642 if (status != ERROR_SUCCESS) {
643 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
651 memset(subkey, 0, sizeof(subkey));
652 status = RegEnumKey(current_hk, i, subkey, sizeof(subkey));
653 if (status == ERROR_NO_MORE_ITEMS) {
656 if (status != ERROR_SUCCESS) {
657 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
662 printf("subkey: %s\n", subkey);
665 status = replaceSID(current_hk, current_path, subkey,
666 oldDomainSid, newDomainSid);
667 if (status != ERROR_SUCCESS) {
668 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
674 char valueName[10240];
677 BYTE *valueData = NULL;
678 DWORD cbValueData = 0;
680 BOOL modified = FALSE;
682 memset(valueName, 0, sizeof(valueName));
683 cbValueName = sizeof(valueName)-1;
684 status = RegEnumValue(current_hk, i,
685 valueName, &cbValueName,
688 if (status == ERROR_NO_MORE_ITEMS) {
691 if (status != ERROR_SUCCESS) {
692 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
696 valueData = (BYTE *)malloc(cbValueData);
697 if (valueData == NULL) {
698 printf("LINE:%u: Error: no memory\n", __LINE__);
699 return ERROR_NOT_ENOUGH_MEMORY;
702 cbValueName = sizeof(valueName)-1;
703 status = RegEnumValue(current_hk, i,
704 valueName, &cbValueName,
706 valueData, &cbValueData);
707 if (status != ERROR_SUCCESS) {
708 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
712 if (valueType != REG_BINARY) {
717 for (ofs=0; ofs < cbValueData;) {
720 len = replaceSIDBuffer(valueData + ofs,
730 printf("%s value[%u]:%s modified ofs:%u (0x%X) len:%u\n",
731 current_path, i, valueName, ofs, ofs, len);
743 printf("%s value[%u]:%s replacing data\n",
744 current_path, i, valueName);
745 status = RegSetValueEx(current_hk,
751 if (status != ERROR_SUCCESS) {
752 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
759 RegCloseKey(current_hk);
761 return ERROR_SUCCESS;
764 int main(int argc, char *argv[])
767 HANDLE tokenHandle = NULL;
768 TOKEN_USER *tokenUser = NULL;
769 DWORD cbTokenUser = 0;
772 HKEY hk_account_domain;
773 DWORD cbSecurityDescriptor = 0;
774 SECURITY_DESCRIPTOR *security_old_sd = NULL;
775 SECURITY_DESCRIPTOR *security_parent_old_sd = NULL;
776 SECURITY_DESCRIPTOR *security_child_old_sd = NULL;
777 SECURITY_DESCRIPTOR *security_parent_new_sd = NULL;
778 SECURITY_DESCRIPTOR *security_child_new_sd = NULL;
779 SID *currentUserSid = NULL;
780 char *currentUserSidString = NULL;
783 BYTE *AccountDomainF = NULL;
784 DWORD cbAccountDomainF = 0;
785 DWORD AccountDomainFType = 0;
786 DWORD *nextRid = NULL;
787 DWORD oldNextRid = 0;
788 DWORD newNextRid = 0;
789 BYTE *AccountDomainV = NULL;
790 DWORD cbAccountDomainV = 0;
791 SID *oldDomainSid = NULL;
792 char *oldDomainSidString = NULL;
793 SID *newDomainSid = NULL;
794 const char *newDomainSidString = NULL;
796 if (argc < 2 || argc > 3) {
797 printf("Usage: %s <DOMAINSID> [<NEXTRID>]\n", argv[0]);
801 newDomainSidString = argv[1];
803 newDomainSid = (SID *)malloc(24);
804 if (newDomainSid == NULL) {
805 printf("LINE:%u: Error: no memory\n", __LINE__);
809 status = StringToSid(newDomainSidString, newDomainSid);
810 if (status != ERROR_SUCCESS) {
811 printf("Failed to parse DOMAINSID[%s]: Error: %d (0x%X)\n",
812 newDomainSidString, status, status);
815 if (newDomainSid->SubAuthorityCount != 4) {
816 printf("DOMAINSID[%s]: Invalid SubAuthorityCount[%u] should be 4\n",
817 newDomainSidString, newDomainSid->SubAuthorityCount);
823 newNextRid = (DWORD)strtoul(argv[2], &q, 10);
824 if (newNextRid == 0 || newNextRid == 0xFFFFFFFF || !q || *q!='\0') {
825 printf("Invalid newNextRid[%s]\n", argv[2]);
828 if (newNextRid < 1000) {
829 printf("newNextRid[%u] < 1000\n", newNextRid);
834 ok = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &tokenHandle);
836 status = GetLastError();
837 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
841 ok = GetTokenInformation(tokenHandle, TokenUser,
842 NULL, 0, &cbTokenUser);
844 status = GetLastError();
846 if (status != ERROR_INSUFFICIENT_BUFFER) {
847 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
851 tokenUser = (TOKEN_USER *)malloc(cbTokenUser);
852 if (tokenUser == NULL) {
853 printf("LINE:%u: Error: no memory\n", __LINE__);
857 ok = GetTokenInformation(tokenHandle, TokenUser,
858 tokenUser, cbTokenUser, &cbTokenUser);
860 status = GetLastError();
861 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
865 currentUserSid = tokenUser->User.Sid;
867 status = SidToString(currentUserSid, ¤tUserSidString);
868 if (status != ERROR_SUCCESS) {
869 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
873 status = RegConnectRegistry(NULL, HKEY_LOCAL_MACHINE, &hklm);
874 if (status != ERROR_SUCCESS) {
875 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
879 status = RegOpenKeyEx(hklm, "SECURITY",
881 READ_CONTROL, /* samDesired */
883 if (status != ERROR_SUCCESS) {
884 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
888 status = RegGetKeySecurity(hk_security,
889 OWNER_SECURITY_INFORMATION |
890 GROUP_SECURITY_INFORMATION |
891 DACL_SECURITY_INFORMATION |
892 PROTECTED_DACL_SECURITY_INFORMATION |
893 UNPROTECTED_DACL_SECURITY_INFORMATION |
894 UNPROTECTED_SACL_SECURITY_INFORMATION,
895 NULL, /* pSecurityDescriptor */
896 &cbSecurityDescriptor /* lpcbSecurityDescriptor */
898 if (status != ERROR_INSUFFICIENT_BUFFER) {
899 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
903 security_old_sd = (SECURITY_DESCRIPTOR *)malloc(cbSecurityDescriptor);
904 if (security_old_sd == NULL) {
905 printf("LINE:%u: Error: no memory\n", __LINE__);
909 status = RegGetKeySecurity(hk_security,
910 OWNER_SECURITY_INFORMATION |
911 GROUP_SECURITY_INFORMATION |
912 DACL_SECURITY_INFORMATION |
913 PROTECTED_DACL_SECURITY_INFORMATION |
914 UNPROTECTED_DACL_SECURITY_INFORMATION |
915 UNPROTECTED_SACL_SECURITY_INFORMATION,
916 security_old_sd, /* pSecurityDescriptor */
917 &cbSecurityDescriptor /* lpcbSecurityDescriptor */
919 if (status != ERROR_SUCCESS) {
920 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
924 RegCloseKey(hk_security);
926 printf("currentUserSid: %s\n", currentUserSidString);
928 status = calc_tmp_HKLM_SECURITY_SD(security_old_sd,
930 &security_parent_old_sd,
931 &security_child_old_sd,
932 &security_parent_new_sd,
933 &security_child_new_sd);
934 if (status != ERROR_SUCCESS) {
935 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
939 printf("Grant full access to HKLM\\SECURITY\n");
940 status = inherit_SD(hklm, "SECURITY", FALSE,
941 security_parent_new_sd, security_child_new_sd);
942 if (status != ERROR_SUCCESS) {
943 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
947 status = RegOpenKeyEx(hklm, "SECURITY\\SAM\\Domains\\Account",
949 KEY_ALL_ACCESS, /* samDesired */
951 if (status != ERROR_SUCCESS) {
952 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
956 status = RegQueryValueEx(hk_account_domain,
960 if (status != ERROR_SUCCESS) {
961 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
965 AccountDomainF = (BYTE *)malloc(cbAccountDomainF);
966 if (AccountDomainF == NULL) {
967 printf("LINE:%u: Error: no memory\n", __LINE__);
971 status = RegQueryValueEx(hk_account_domain,
975 if (status != ERROR_SUCCESS) {
976 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
980 nextRid = (DWORD *)((BYTE *)AccountDomainF + 0x48);
981 oldNextRid = *nextRid;
982 if (newNextRid == 0) {
983 newNextRid = oldNextRid;
985 printf("AccountDomainF: %u bytes\n", cbAccountDomainF);
987 status = RegQueryValueEx(hk_account_domain,
991 if (status != ERROR_SUCCESS) {
992 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
996 AccountDomainV = (BYTE *)malloc(cbAccountDomainV);
997 if (AccountDomainV == NULL) {
998 printf("LINE:%u: Error: no memory\n", __LINE__);
1002 status = RegQueryValueEx(hk_account_domain,
1006 if (status != ERROR_SUCCESS) {
1007 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1011 printf("AccountDomainV: %u bytes\n", cbAccountDomainV);
1012 oldDomainSid = (SID *)((BYTE *)AccountDomainV + (cbAccountDomainV - 24));
1014 status = SidToString(oldDomainSid, &oldDomainSidString);
1015 if (status != ERROR_SUCCESS) {
1016 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1020 printf("Old Domain:%s, NextRid: %u (0x%08X)\n",
1021 oldDomainSidString, oldNextRid, oldNextRid);
1022 printf("New Domain:%s, NextRid: %u (0x%08X)\n",
1023 newDomainSidString, newNextRid, newNextRid);
1025 status = replaceSID(hklm, "HKLM", "SECURITY\\SAM\\Domains",
1026 oldDomainSid, newDomainSid);
1027 if (status != ERROR_SUCCESS) {
1028 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1032 status = RegQueryValueEx(hk_account_domain,
1033 "F", NULL, &AccountDomainFType,
1036 if (status != ERROR_SUCCESS) {
1037 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1040 nextRid = (DWORD *)((BYTE *)AccountDomainF + 0x48);
1041 *nextRid = newNextRid;
1043 printf("AccountDomainF replacing data (nextRid)\n");
1044 status = RegSetValueEx(hk_account_domain,
1050 if (status != ERROR_SUCCESS) {
1051 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1055 printf("Withdraw full access to HKLM\\SECURITY\n");
1056 status = inherit_SD(hklm, "SECURITY", TRUE,
1057 security_parent_old_sd, security_child_old_sd);
1058 if (status != ERROR_SUCCESS) {
1059 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1065 printf("Withdraw full access to HKLM\\SECURITY\n");
1066 status = inherit_SD(hklm, "SECURITY", TRUE,
1067 security_parent_old_sd, security_child_old_sd);
1068 if (status != ERROR_SUCCESS) {
1069 printf("LINE:%u: Error: %d (0x%X)\n", __LINE__, status, status);
1072 printf("FAILED!\n");