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");