|
|
1.1 root 1:
2: /******************************************************************************\
3: * This is a part of the Microsoft Source Code Samples.
4: * Copyright (C) 1993 Microsoft Corporation.
5: * All rights reserved.
6: * This source code is only intended as a supplement to
7: * Microsoft Development Tools and/or WinHelp documentation.
8: * See these sources for detailed information regarding the
9: * Microsoft samples programs.
10: \******************************************************************************/
11:
12: /****************************************************************************\
13: *
14: * MODULE: check_sd.c
15: *
16: * In the Win32 .hlp file, if you click on Search, goto "Security
17: * Overview", then choose from the list of topics under
18: * Security Overview the sub-topic "Allowing Access", you'll
19: * find the comment
20: *
21: * Note: It is fine to write code like this that builds
22: * security descriptors from scratch. It is, however, a good
23: * practice for people who write code that builds or
24: * manipulates security descriptors to first write code that
25: * explores the default security descriptors that Windows NT
26: * places on objects. For example, if Windows NT by default
27: * includes in a DACL an ACE granting the Local Logon SID
28: * certain access, it's good to know that, so that a decision
29: * not to grant any access to the Local Logon SID would be a
30: * conscious decision
31: *
32: * PURPOSE: The comment in the .hlp file is accurate, however, for many
33: * people this task of examining the SD is easier if there is
34: * sample code to start from. So, the purpose of this sample
35: * is to assist people by providing sample code people can
36: * start from as they examine SD(s). This sample as is
37: * examines the SD on files, and this code can be modified to
38: * examine the SD on other objects
39: *
40: * This sample is not a supported utility
41: *
42: * TO RUN: Type Check_sd to check the SD on the \\.\A: device
43: *
44: * Type Check_sd d:\a.fil to check the SD on the d:\a.fil file.
45: * In this case d: must be formatted NTFS, because only NTFS
46: * files have SD(s)
47: *
48: \****************************************************************************/
49:
50: /****************************************************************************\
51: * INCLUDES, DEFINES
52: \****************************************************************************/
53: #define STRICT
54: #include <windows.h>
55: #include <stdlib.h>
56: #include <stdio.h>
57:
58: #define PERR(api) printf("\n%s: Error %d from %s on line %d", \
59: __FILE__, GetLastError(), api, __LINE__);
60: #define PMSG(msg) printf("\n%s line %d: %s", \
61: __FILE__, __LINE__, msg);
62:
63: /****************************************************************************\
64: * GLOBAL VARIABLES AND TYPEDEFS
65: \****************************************************************************/
66:
67: typedef enum _KINDS_OF_ACCESSMASKS_DECODED {
68: FileAccessMask,
69: ProcessAccessMask,
70: WindowStationAccessMask,
71: RegKeyAccessMask,
72: ServiceAccessMask,
73: DefaultDaclInAccessTokenAccessMask
74: } KINDS_OF_ACCESSMASKS_DECODED, * PKINDS_OF_ACCESSMASKS_DECODED;
75:
76: // These hold the well-known SIDs
77:
78: PSID psidNullSid;
79: PSID psidWorldSid;
80: PSID psidLocalSid;
81: PSID psidCreatorOwnerSid;
82: PSID psidCreatorGroupSid;
83: PSID psidNtAuthoritySid;
84: PSID psidDialupSid;
85: PSID psidNetworkSid;
86: PSID psidBatchSid;
87: PSID psidInteractiveSid;
88: PSID psidLogonIdsSid; // But the X and Y values are bogus at first!!! (See below)
89: PSID psidServiceSid;
90: PSID psidLocalSystemSid;
91: PSID psidBuiltinDomainSid;
92:
93: /****************************************************************************\
94: * FUNCTION PROTOTYPES
95: \****************************************************************************/
96:
97: VOID ExamineAccessToken(HANDLE hAccessToken);
98: BOOL ExamineSD (PSECURITY_DESCRIPTOR psdSD,
99: KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask);
100: BOOL ExamineACL (PACL paclACL, LPTSTR lpszOldIndent,
101: KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask);
102: VOID ExamineMask (ACCESS_MASK amMask, LPTSTR lpszOldIndent,
103: KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask);
104: BOOL LookupSIDName(PSID psidSID, LPTSTR lpszOldIndent);
105: BOOL SIDStringName(PSID psidSID, LPTSTR lpszSIDStringName);
106: BOOL SetPrivilegeInAccessToken(VOID);
107: VOID InitializeWellKnownSIDs(VOID);
108: VOID DisplayHelp(VOID);
109:
110: UINT main(UINT argc, char *argv[])
111: {
112:
113: HANDLE hProcess;
114: HANDLE hAccessToken;
115: #define DEFAULT_FILE_TO_CHECK "\\\\.\\A:"
116: #define SZ_NAME_BUF MAX_PATH
117: UCHAR ucPathBuf[SZ_NAME_BUF];
118: LPTSTR lpszFullName = (LPTSTR)&ucPathBuf;
119: #define SZ_SD_BUF 8096
120: UCHAR ucBuf [SZ_SD_BUF] = "";
121: DWORD dwSDLength = SZ_SD_BUF;
122: DWORD dwSDLengthNeeded;
123: PSECURITY_DESCRIPTOR psdSD = (PSECURITY_DESCRIPTOR)&ucBuf;
124: DWORD dwErrorMode;
125:
126: /**************************************************************************\
127: *
128: * This sample is not inside a Win32 service, however if this code were to be
129: * moved inside a Win32 service, the following defines and code that
130: * redirects stdout will be handy, because services cannot write to the
131: * screen
132: *
133: * You may wish to choose a different file name for the output file if you
134: * use this mechanism - note that the "w+" will destroy an existing file!
135: *
136: \**************************************************************************/
137:
138: #define WE_ARE_IN_A_SERVICE_SO_REDIRECT_STDOUT (0==1)
139: #define FILE_TO_REDIRECT_STDOUT_TO "c:\\check_sd.out"
140:
141: if (WE_ARE_IN_A_SERVICE_SO_REDIRECT_STDOUT)
142: { freopen(FILE_TO_REDIRECT_STDOUT_TO,"w+",stdout);
143: }
144:
145:
146: if (1 == argc)
147: { strcpy(lpszFullName,DEFAULT_FILE_TO_CHECK);
148: }
149: else if (2 == argc)
150: { strcpy(lpszFullName,argv[1]);
151: }
152: else
153: { DisplayHelp();
154: return(0);
155: }
156:
157: /**************************************************************************\
158: *
159: * Set up the well-known SID(s) in global variables, and enable the privilege
160: * needed in the access token to work with SACL(s)
161: *
162: \**************************************************************************/
163:
164: InitializeWellKnownSIDs();
165:
166: if (!SetPrivilegeInAccessToken())
167: { return(1);
168: }
169:
170: /**************************************************************************\
171: *
172: * This sample's primary purpose is to explore Security Descriptors.
173: * However, it is all too easy to over-focus on SD(s), while losing isght
174: * of the importance of Access Tokens. So, we will now digress briefly to
175: * examine the access token of the current process
176: *
177: \**************************************************************************/
178:
179: hProcess = GetCurrentProcess();
180: if (!hProcess)
181: { PERR("GetCurrentProcess");
182: return(1);
183: }
184:
185: if (!OpenProcessToken(hProcess,
186: (TOKEN_READ | TOKEN_QUERY_SOURCE),
187: &hAccessToken))
188: { PERR("OpenProcessToken");
189: return(1);
190: }
191:
192: ExamineAccessToken(hAccessToken);
193:
194: /**************************************************************************\
195: *
196: * Back to examining SD(s)
197: *
198: \**************************************************************************/
199:
200: printf("\nChecking SD on %s",lpszFullName);
201:
202: /**************************************************************************\
203: *
204: * SetErrorMode so we don't get the error due to no floppy disk in the floppy
205: * drive
206: *
207: \**************************************************************************/
208:
209: dwErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
210:
211: if (!GetFileSecurity
212: (lpszFullName,
213: (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
214: | GROUP_SECURITY_INFORMATION
215: | DACL_SECURITY_INFORMATION
216: | SACL_SECURITY_INFORMATION),
217: psdSD,
218: dwSDLength,
219: (LPDWORD)&dwSDLengthNeeded))
220: { PERR("GetFileSecurity");
221: return(1);
222: }
223:
224: SetErrorMode(dwErrorMode);
225:
226: if(!ExamineSD(psdSD,FileAccessMask))
227: { PERR("ExamineSD failed");
228: return(1);
229: }
230:
231: /**************************************************************************\
232: *
233: * The above code showed how to examine an SD on a file. There are SDs on
234: * other objects that could be examined by the function ExamineSD (and the
235: * other functions it calls). The following are one example call each of
236: * the other four api's that are used to retrieve the SD from each of the
237: * types of Win32 objects that can have an SD
238: *
239: * These calls will execute properly without any work on your part, however,
240: * some work on your part will be required to get the sample calls below to
241: * show the SD for the objects your program uses! You would need to make
242: * copy of this sample in a new directory, and write the code to get a
243: * handle to the object you're interested in, so you can pass that handle
244: * to the applicable api call below
245: *
246: * To insert the SD checking code into your own code you would do
247: * something like
248: *
249: * 1) Add the global variables above in your globals
250: *
251: * 2) Add the function prototypes above in your globals
252: *
253: * 3) Add the includes and PERR/PMSG macroes above to your code
254: *
255: * 4) Add all the functions defined below (except DisplayHelp and except
256: * ExamineAccessToken) to your code
257: *
258: * 5) Add a call sequence such as that in main() above that gets an
259: * SD and passes it to Examine SD. Or add a call sequence such as
260: * one of those that follows that gets a handle, gets the SD on the
261: * object the handle addresses, then calls ExamineSD
262: *
263: * 6) If you are examining a type SD not already listed in
264: * KINDS_OF_ACCESSMASKS_DECODED, then you will have to add the new type to
265: * KINDS_OF_ACCESSMASKS_DECODED, and add to ExamineMask() the necessary
266: * code to crack that type of SD's access mask bits into the defines
267: *
268: \**************************************************************************/
269:
270: #define I_DO_NOT_WANT_THIS_CODE_TO_CLUTTER_THIS_PROGRAM_S_OUTPUT (0==0)
271:
272: if (!I_DO_NOT_WANT_THIS_CODE_TO_CLUTTER_THIS_PROGRAM_S_OUTPUT)
273: { HANDLE hProcess;
274: HANDLE hWindowStation;
275: HKEY hKey;
276: SC_HANDLE schService;
277: SC_HANDLE schSCManager;
278: SECURITY_INFORMATION siSInfo =
279: (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
280: | GROUP_SECURITY_INFORMATION
281: | DACL_SECURITY_INFORMATION
282: | SACL_SECURITY_INFORMATION);
283:
284: printf("\n\nChecking SD on current process");
285:
286: hProcess = GetCurrentProcess();
287: if (!hProcess)
288: { PERR("GetCurrentProcess");
289: return(1);
290: }
291:
292: dwSDLength = SZ_SD_BUF;
293:
294: if (!GetKernelObjectSecurity
295: (hProcess,
296: (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
297: | GROUP_SECURITY_INFORMATION
298: | DACL_SECURITY_INFORMATION),
299: psdSD,
300: dwSDLength,
301: (LPDWORD)&dwSDLengthNeeded))
302: { PERR("GetKernelObjectSecurity");
303: return(1);
304: }
305:
306: /************************************************************************\
307: *
308: * It is important to close all handles as soon as your code no longer
309: * needs them. This conserves system resources. In a sample such as
310: * this one, the practical effect is close to nil, since as soon as the
311: * sample exits (which only takes a few seconds, Windows NT destroys the
312: * process this sample was running in, which reclaims all resources
313: *
314: * However, in a program that creates many objects (such as threads), or
315: * where that program will be running for a long time, closing handles as
316: * soon as the program no longer needs them can save significant
317: * resources
318: *
319: * It is a good coding practice to make a habit of closing handles as soon
320: * as your code no longer needs the handle
321: *
322: \************************************************************************/
323:
324: CloseHandle(hProcess);
325:
326: if(!ExamineSD(psdSD,ProcessAccessMask))
327: { PERR("ExamineSD failed");
328: return(1);
329: }
330:
331:
332: printf("\n\nChecking SD on current Window-station");
333:
334: hWindowStation = GetProcessWindowStation();
335: if (INVALID_HANDLE_VALUE == hWindowStation)
336: { PERR("GetProcessWindowStation");
337: return(1);
338: }
339:
340: dwSDLength = SZ_SD_BUF;
341:
342: if (!GetUserObjectSecurity
343: (hWindowStation,
344: &siSInfo,
345: psdSD,
346: dwSDLength,
347: (LPDWORD)&dwSDLengthNeeded))
348: { PERR("GetUserObjectSecurity");
349: return(1);
350: }
351:
352: CloseHandle(hWindowStation);
353:
354: if(!ExamineSD(psdSD,WindowStationAccessMask))
355: { PERR("ExamineSD failed");
356: return(1);
357: }
358:
359:
360: printf("\n\nChecking SD on registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet");
361:
362: if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
363: "SYSTEM\\CurrentControlSet",
364: 0,
365: KEY_READ,
366: &hKey))
367: { PERR("RegOpenKeyEx");
368: return(1);
369: }
370:
371: dwSDLength = SZ_SD_BUF;
372:
373: if (ERROR_SUCCESS != RegGetKeySecurity
374: (hKey,
375: (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
376: | GROUP_SECURITY_INFORMATION
377: | DACL_SECURITY_INFORMATION),
378: psdSD,
379: &dwSDLength))
380: { PERR("RegGetKeySecurity");
381: return(1);
382: }
383:
384: RegCloseKey(hKey);
385:
386: if(!ExamineSD(psdSD,RegKeyAccessMask))
387: { PERR("ExamineSD failed");
388: return(1);
389: }
390:
391:
392: /************************************************************************\
393: *
394: * Any service will do here, just be sure to pick one that is in the
395: * Service Control Manager's database, and use the service name, not the
396: * service's display name. For example, ClipSrv is displayed as Clipbook
397: * in the Services Control Panel applet
398: *
399: \************************************************************************/
400:
401: printf("\n\nChecking SD on service Clipbook");
402:
403: schSCManager = OpenSCManager(
404: NULL, // machine (NULL == local)
405: NULL, // database (NULL == default)
406: SC_MANAGER_ALL_ACCESS // access required
407: );
408:
409: if (!schSCManager)
410: { PERR("OpenSCManager");
411: return(1);
412: }
413:
414: schService = OpenService(schSCManager,"ClipSrv",SERVICE_ALL_ACCESS);
415: if (!schService)
416: { PERR("OpenService");
417: return(1);
418: }
419:
420: CloseServiceHandle(schSCManager);
421:
422: dwSDLength = SZ_SD_BUF;
423:
424: if (!QueryServiceObjectSecurity
425: (schService,
426: (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
427: | GROUP_SECURITY_INFORMATION
428: | DACL_SECURITY_INFORMATION),
429: psdSD,
430: dwSDLength,
431: (LPDWORD)&dwSDLengthNeeded))
432: { PERR("QueryServiceObjectSecurity");
433: return(1);
434: }
435:
436: CloseServiceHandle(schService);
437:
438: if(!ExamineSD(psdSD,ServiceAccessMask))
439: { PERR("ExamineSD failed");
440: return(1);
441: }
442: }
443:
444: return(0);
445: }
446:
447: /****************************************************************************\
448: *
449: * FUNCTION: ExamineSD
450: *
451: \****************************************************************************/
452:
453: BOOL ExamineSD (PSECURITY_DESCRIPTOR psdSD,
454: KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask)
455: {
456:
457: PACL paclDACL;
458: PACL paclSACL;
459: BOOL bHasDACL = FALSE;
460: BOOL bHasSACL = FALSE;
461: BOOL bDaclDefaulted = FALSE;
462: BOOL bSaclDefaulted = FALSE;
463: BOOL bOwnerDefaulted = FALSE;
464: BOOL bGroupDefaulted = FALSE;
465: PSID psidOwner;
466: PSID psidGroup;
467: SECURITY_DESCRIPTOR_CONTROL sdcSDControl;
468: DWORD dwSDRevision;
469: DWORD dwSDLength;
470:
471: if (!IsValidSecurityDescriptor(psdSD))
472: { PERR("IsValidSecurityDescriptor");
473: return(FALSE);
474: }
475:
476: dwSDLength = GetSecurityDescriptorLength(psdSD);
477:
478: if (!GetSecurityDescriptorDacl(psdSD,
479: (LPBOOL)&bHasDACL,
480: (PACL *)&paclDACL,
481: (LPBOOL)&bDaclDefaulted))
482: { PERR("GetSecurityDescriptorDacl");
483: return(FALSE);
484: }
485:
486: if (!GetSecurityDescriptorSacl(psdSD,
487: (LPBOOL)&bHasSACL,
488: (PACL *)&paclSACL,
489: (LPBOOL)&bSaclDefaulted))
490: { PERR("GetSecurityDescriptorSacl");
491: return(FALSE);
492: }
493:
494: if (!GetSecurityDescriptorOwner(psdSD,
495: (PSID *)&psidOwner,
496: (LPBOOL)&bOwnerDefaulted))
497: { PERR("GetSecurityDescriptorOwner");
498: return(FALSE);
499: }
500:
501: if (!GetSecurityDescriptorGroup(psdSD,
502: (PSID *)&psidGroup,
503: (LPBOOL)&bGroupDefaulted))
504: { PERR("GetSecurityDescriptorGroup");
505: return(FALSE);
506: }
507:
508: if (!GetSecurityDescriptorControl(psdSD,
509: (PSECURITY_DESCRIPTOR_CONTROL)&sdcSDControl,
510: (LPDWORD)&dwSDRevision))
511: { PERR("GetSecurityDescriptorControl");
512: return(FALSE);
513: }
514:
515: printf("\nSD is valid. SD is %d bytes long. SD revision is %d == ",dwSDLength,dwSDRevision);
516:
517: switch (dwSDRevision)
518: {
519: case SECURITY_DESCRIPTOR_REVISION1 :
520: { printf("SECURITY_DESCRIPTOR_REVISION1");
521: break;
522: }
523: default :
524: { printf("! SD Revision is an IMPOSSIBLE SD revision!!! Perhaps a new revision was added...");
525: return(FALSE);
526: }
527: }
528:
529: if (SE_SELF_RELATIVE & sdcSDControl)
530: printf("\nSD is in self-relative format (all SDs returned by the system are)");
531:
532: if (NULL == psidOwner)
533: { printf("\nSD's Owner is NULL, so SE_OWNER_DEFAULTED is ignored");
534: }
535: else
536: { printf("\nSD's Owner is Not NULL");
537: if (bOwnerDefaulted )
538: { printf("\nSD's Owner-Defaulted flag is TRUE");
539: }
540: else
541: { printf("\nSD's Owner-Defaulted flag is FALSE");
542: }
543: if(!LookupSIDName(psidOwner,""))
544: { PERR("LookupSIDName failed");
545: }
546: }
547:
548: /**************************************************************************\
549: *
550: * The other use for psidGroup is for Macintosh client support
551: *
552: \**************************************************************************/
553:
554: if (NULL == psidGroup)
555: { printf("\nSD's Group is NULL, so SE_GROUP_DEFAULTED is ignored");
556: printf("\nSD's Group being NULL is typical, GROUP in SD(s) is mainly for POSIX compliance");
557: }
558: else
559: { if (bGroupDefaulted)
560: { printf("\nSD's Group-Defaulted flag is TRUE");
561: }
562: else
563: { printf("\nSD's Group-Defaulted flag is FALSE");
564: }
565: if(!LookupSIDName(psidGroup,""))
566: { PERR("LookupSIDName failed");
567: }
568: }
569:
570: if (SE_DACL_PRESENT & sdcSDControl)
571: { printf("\nSD's DACL is Present");
572: if (bDaclDefaulted)
573: { printf("\nSD's DACL-Defaulted flag is TRUE");
574: }
575: else
576: { printf("\nSD's DACL-Defaulted flag is FALSE");
577: }
578:
579: if (NULL == paclDACL)
580: { printf("\nSD has a NULL DACL explicitly specified (allows all access to Everyone)");
581: printf("\n This does not apply to this SD, but for comparison,");
582: printf("\n a non-NULL DACL pointer to a 0-length ACL allows no access to anyone");
583: }
584: else if(!ExamineACL(paclDACL,"",kamKindOfMask))
585: { PERR("ExamineACL failed");
586: }
587: }
588: else
589: { printf("\nSD's DACL is Not Present, so SE_DACL_DEFAULTED is ignored");
590: printf("\nSD has no DACL at all (allows all access to Everyone)");
591: }
592:
593: if (SE_SACL_PRESENT & sdcSDControl)
594: { printf("\nSD's SACL is Present");
595: if (bSaclDefaulted)
596: { printf("\nSD's SACL-Defaulted flag is TRUE");
597: }
598: else
599: { printf("\nSD's SACL-Defaulted flag is FALSE");
600: }
601:
602: if (NULL == paclSACL)
603: { printf("\nSD has a NULL SACL explicitly specified");
604: }
605: else if(!ExamineACL(paclSACL,"",kamKindOfMask))
606: { PERR("ExamineACL failed");
607: }
608: }
609: else
610: { printf("\nSD's SACL is Not Present, so SE_SACL_DEFAULTED is ignored");
611: printf("\nSD has no SACL at all (or we did not request to see it)");
612: }
613: }
614:
615: /****************************************************************************\
616: *
617: * FUNCTION: ExamineACL
618: *
619: \****************************************************************************/
620:
621: BOOL ExamineACL (PACL paclACL, LPTSTR lpszOldIndent,
622: KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask)
623: {
624: #define SZ_INDENT_BUF 80
625: UCHAR ucIndentBuf[SZ_INDENT_BUF] = "";
626: ACL_SIZE_INFORMATION asiAclSize;
627: ACL_REVISION_INFORMATION ariAclRevision;
628: DWORD dwBufLength;
629: DWORD dwAcl_i;
630: ACCESS_ALLOWED_ACE *paaAllowedAce;
631:
632: strcpy(ucIndentBuf,lpszOldIndent);
633: strcat(ucIndentBuf," ");
634:
635: if (!IsValidAcl(paclACL))
636: { PERR("IsValidAcl");
637: return(FALSE);
638: }
639:
640: dwBufLength = sizeof(asiAclSize);
641:
642: if (!GetAclInformation(paclACL,
643: (LPVOID)&asiAclSize,
644: (DWORD)dwBufLength,
645: (ACL_INFORMATION_CLASS)AclSizeInformation))
646: { PERR("GetAclInformation");
647: return(FALSE);
648: }
649:
650: dwBufLength = sizeof(ariAclRevision);
651:
652: if (!GetAclInformation(paclACL,
653: (LPVOID)&ariAclRevision,
654: (DWORD)dwBufLength,
655: (ACL_INFORMATION_CLASS)AclRevisionInformation))
656: { PERR("GetAclInformation");
657: return(FALSE);
658: }
659:
660: printf("\n%sACL has %d ACE(s), %d bytes used, %d bytes free",ucIndentBuf,
661: asiAclSize.AceCount,
662: asiAclSize.AclBytesInUse,
663: asiAclSize.AclBytesFree);
664:
665: printf("\n%sACL revision is %d == ",ucIndentBuf,ariAclRevision.AclRevision);
666:
667: switch (ariAclRevision.AclRevision)
668: {
669: case ACL_REVISION1 :
670: { printf("ACL_REVISION1");
671: break;
672: }
673: case ACL_REVISION2 :
674: { printf("ACL_REVISION2");
675: break;
676: }
677: default :
678: { printf("\n%sACL Revision is an IMPOSSIBLE ACL revision!!! Perhaps a new revision was added...",ucIndentBuf);
679: return(FALSE);
680: }
681: }
682:
683: for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount; dwAcl_i++)
684: {
685: if (!GetAce(paclACL,
686: dwAcl_i,
687: (LPVOID *)&paaAllowedAce))
688: { PERR("GetAce");
689: return(FALSE);
690: }
691:
692: printf("\n%sACE %d size %d",ucIndentBuf,dwAcl_i,paaAllowedAce->Header.AceSize);
693:
694: { DWORD dwAceFlags = paaAllowedAce->Header.AceFlags;
695:
696: printf("\n%sACE %d flags 0x%.2x",ucIndentBuf,dwAcl_i,dwAceFlags);
697:
698: if (dwAceFlags)
699: {
700: DWORD dwExtraBits;
701: UCHAR ucIndentBitsBuf[SZ_INDENT_BUF] = "";
702:
703: strcpy(ucIndentBitsBuf,ucIndentBuf);
704: strcat(ucIndentBitsBuf," ");
705:
706: if ((dwAceFlags & OBJECT_INHERIT_ACE ) == OBJECT_INHERIT_ACE )
707: { printf("\n%s0x01 OBJECT_INHERIT_ACE ",ucIndentBitsBuf);
708: }
709: if ((dwAceFlags & CONTAINER_INHERIT_ACE ) == CONTAINER_INHERIT_ACE )
710: { printf("\n%s0x02 CONTAINER_INHERIT_ACE ",ucIndentBitsBuf);
711: }
712: if ((dwAceFlags & NO_PROPAGATE_INHERIT_ACE ) == NO_PROPAGATE_INHERIT_ACE )
713: { printf("\n%s0x04 NO_PROPAGATE_INHERIT_ACE ",ucIndentBitsBuf);
714: }
715: if ((dwAceFlags & INHERIT_ONLY_ACE ) == INHERIT_ONLY_ACE )
716: { printf("\n%s0x08 INHERIT_ONLY_ACE ",ucIndentBitsBuf);
717: }
718: if ((dwAceFlags & VALID_INHERIT_FLAGS ) == VALID_INHERIT_FLAGS )
719: { printf("\n%s0x0F VALID_INHERIT_FLAGS ",ucIndentBitsBuf);
720: }
721: if ((dwAceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) == SUCCESSFUL_ACCESS_ACE_FLAG)
722: { printf("\n%s0x40 SUCCESSFUL_ACCESS_ACE_FLAG",ucIndentBitsBuf);
723: }
724: if ((dwAceFlags & FAILED_ACCESS_ACE_FLAG ) == FAILED_ACCESS_ACE_FLAG )
725: { printf("\n%s0x80 FAILED_ACCESS_ACE_FLAG ",ucIndentBitsBuf);
726: }
727:
728: dwExtraBits = dwAceFlags & ( ~( OBJECT_INHERIT_ACE
729: | CONTAINER_INHERIT_ACE
730: | NO_PROPAGATE_INHERIT_ACE
731: | INHERIT_ONLY_ACE
732: | VALID_INHERIT_FLAGS
733: | SUCCESSFUL_ACCESS_ACE_FLAG
734: | FAILED_ACCESS_ACE_FLAG) );
735: if (dwExtraBits)
736: { printf("\n%sExtra AceFlag bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
737: }
738: }
739: }
740:
741: switch (paaAllowedAce->Header.AceType)
742: {
743: case ACCESS_ALLOWED_ACE_TYPE :
744: { printf("\n%sACE %d is an ACCESS_ALLOWED_ACE_TYPE",ucIndentBuf,dwAcl_i);
745: break;
746: }
747: case ACCESS_DENIED_ACE_TYPE :
748: { printf("\n%sACE %d is an ACCESS_DENIED_ACE_TYPE",ucIndentBuf,dwAcl_i);
749: break;
750: }
751: case SYSTEM_AUDIT_ACE_TYPE :
752: { printf("\n%sACE %d is a SYSTEM_AUDIT_ACE_TYPE",ucIndentBuf,dwAcl_i);
753: break;
754: }
755: case SYSTEM_ALARM_ACE_TYPE :
756: { printf("\n%sACE %d is a SYSTEM_ALARM_ACE_TYPE",ucIndentBuf,dwAcl_i);
757: break;
758: }
759: default :
760: { printf("\n%sACE %d is an IMPOSSIBLE ACE_TYPE!!! Run debugger, examine value!",ucIndentBuf,dwAcl_i);
761: return(FALSE);
762: }
763: }
764:
765: printf("\n%sACE %d mask == 0x%.8x",ucIndentBuf,dwAcl_i,paaAllowedAce->Mask);
766:
767: ExamineMask(paaAllowedAce->Mask,ucIndentBuf,kamKindOfMask);
768:
769: if(!LookupSIDName((PSID)&(paaAllowedAce->SidStart),ucIndentBuf))
770: { PERR("LookupSIDName failed");
771: }
772: }
773: }
774:
775: /****************************************************************************\
776: *
777: * FUNCTION: ExamineMask
778: *
779: \****************************************************************************/
780:
781: VOID ExamineMask (ACCESS_MASK amMask, LPTSTR lpszOldIndent,
782: KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask)
783: {
784: #define STANDARD_RIGHTS_ALL_THE_BITS 0x00FF0000L
785: #define GENERIC_RIGHTS_ALL_THE_BITS 0xF0000000L
786: UCHAR ucIndentBuf[SZ_INDENT_BUF] = "";
787: UCHAR ucIndentBitsBuf[SZ_INDENT_BUF] = "";
788: DWORD dwGenericBits;
789: DWORD dwStandardBits;
790: DWORD dwSpecificBits;
791: DWORD dwAccessSystemSecurityBit;
792: DWORD dwExtraBits;
793:
794: strcpy(ucIndentBuf, lpszOldIndent);
795: strcat(ucIndentBuf, " ");
796: strcpy(ucIndentBitsBuf,lpszOldIndent);
797: strcat(ucIndentBitsBuf," ");
798:
799: dwStandardBits = (amMask & STANDARD_RIGHTS_ALL_THE_BITS);
800: dwSpecificBits = (amMask & SPECIFIC_RIGHTS_ALL );
801: dwAccessSystemSecurityBit = (amMask & ACCESS_SYSTEM_SECURITY );
802: dwGenericBits = (amMask & GENERIC_RIGHTS_ALL_THE_BITS );
803:
804: /**************************************************************************\
805: *
806: * Print then decode the standard rights bits
807: *
808: \**************************************************************************/
809:
810: printf("\n%sStandard Rights == 0x%.8x",ucIndentBuf,dwStandardBits);
811:
812: if (dwStandardBits)
813: {
814: if ((dwStandardBits & DELETE ) == DELETE )
815: { printf("\n%s0x00010000 DELETE ",ucIndentBitsBuf);
816: }
817: if ((dwStandardBits & READ_CONTROL ) == READ_CONTROL )
818: { printf("\n%s0x00020000 READ_CONTROL ",ucIndentBitsBuf);
819: }
820: if ((dwStandardBits & STANDARD_RIGHTS_READ ) == STANDARD_RIGHTS_READ )
821: { printf("\n%s0x00020000 STANDARD_RIGHTS_READ ",ucIndentBitsBuf);
822: }
823: if ((dwStandardBits & STANDARD_RIGHTS_WRITE ) == STANDARD_RIGHTS_WRITE )
824: { printf("\n%s0x00020000 STANDARD_RIGHTS_WRITE ",ucIndentBitsBuf);
825: }
826: if ((dwStandardBits & STANDARD_RIGHTS_EXECUTE ) == STANDARD_RIGHTS_EXECUTE )
827: { printf("\n%s0x00020000 STANDARD_RIGHTS_EXECUTE ",ucIndentBitsBuf);
828: }
829: if ((dwStandardBits & WRITE_DAC ) == WRITE_DAC )
830: { printf("\n%s0x00040000 WRITE_DAC ",ucIndentBitsBuf);
831: }
832: if ((dwStandardBits & WRITE_OWNER ) == WRITE_OWNER )
833: { printf("\n%s0x00080000 WRITE_OWNER ",ucIndentBitsBuf);
834: }
835: if ((dwStandardBits & SYNCHRONIZE ) == SYNCHRONIZE )
836: { printf("\n%s0x00100000 SYNCHRONIZE ",ucIndentBitsBuf);
837: }
838: if ((dwStandardBits & STANDARD_RIGHTS_REQUIRED) == STANDARD_RIGHTS_REQUIRED)
839: { printf("\n%s0x000F0000 STANDARD_RIGHTS_REQUIRED",ucIndentBitsBuf);
840: }
841: if ((dwStandardBits & STANDARD_RIGHTS_ALL ) == STANDARD_RIGHTS_ALL )
842: { printf("\n%s0x001F0000 STANDARD_RIGHTS_ALL ",ucIndentBitsBuf);
843: }
844:
845: dwExtraBits = dwStandardBits & ( ~( DELETE
846: | READ_CONTROL
847: | STANDARD_RIGHTS_READ
848: | STANDARD_RIGHTS_WRITE
849: | STANDARD_RIGHTS_EXECUTE
850: | WRITE_DAC
851: | WRITE_OWNER
852: | SYNCHRONIZE
853: | STANDARD_RIGHTS_REQUIRED
854: | STANDARD_RIGHTS_ALL) );
855: if (dwExtraBits)
856: { printf("\n%sExtra standard bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
857: }
858: }
859:
860: /**************************************************************************\
861: *
862: * Print then decode the specific rights bits
863: *
864: \**************************************************************************/
865:
866: printf("\n%sSpecific Rights == 0x%.8x",ucIndentBuf,dwSpecificBits);
867:
868: if (dwSpecificBits)
869: {
870: if (FileAccessMask == kamKindOfMask)
871: {
872: if ((dwSpecificBits & FILE_READ_DATA ) == FILE_READ_DATA )
873: { printf("\n%s0x00000001 FILE_READ_DATA (file & pipe) ",ucIndentBitsBuf);
874: }
875: if ((dwSpecificBits & FILE_LIST_DIRECTORY ) == FILE_LIST_DIRECTORY )
876: { printf("\n%s0x00000001 FILE_LIST_DIRECTORY (directory) ",ucIndentBitsBuf);
877: }
878: if ((dwSpecificBits & FILE_WRITE_DATA ) == FILE_WRITE_DATA )
879: { printf("\n%s0x00000002 FILE_WRITE_DATA (file & pipe) ",ucIndentBitsBuf);
880: }
881: if ((dwSpecificBits & FILE_ADD_FILE ) == FILE_ADD_FILE )
882: { printf("\n%s0x00000002 FILE_ADD_FILE (directory) ",ucIndentBitsBuf);
883: }
884: if ((dwSpecificBits & FILE_APPEND_DATA ) == FILE_APPEND_DATA )
885: { printf("\n%s0x00000004 FILE_APPEND_DATA (file) ",ucIndentBitsBuf);
886: }
887: if ((dwSpecificBits & FILE_ADD_SUBDIRECTORY ) == FILE_ADD_SUBDIRECTORY )
888: { printf("\n%s0x00000004 FILE_ADD_SUBDIRECTORY (directory) ",ucIndentBitsBuf);
889: }
890: if ((dwSpecificBits & FILE_CREATE_PIPE_INSTANCE) == FILE_CREATE_PIPE_INSTANCE)
891: { printf("\n%s0x00000004 FILE_CREATE_PIPE_INSTANCE (named pipe) ",ucIndentBitsBuf);
892: }
893: if ((dwSpecificBits & FILE_READ_EA ) == FILE_READ_EA )
894: { printf("\n%s0x00000008 FILE_READ_EA (file & directory)",ucIndentBitsBuf);
895: }
896: if ((dwSpecificBits & FILE_WRITE_EA ) == FILE_WRITE_EA )
897: { printf("\n%s0x00000010 FILE_WRITE_EA (file & directory)",ucIndentBitsBuf);
898: }
899: if ((dwSpecificBits & FILE_EXECUTE ) == FILE_EXECUTE )
900: { printf("\n%s0x00000020 FILE_EXECUTE (file) ",ucIndentBitsBuf);
901: }
902: if ((dwSpecificBits & FILE_TRAVERSE ) == FILE_TRAVERSE )
903: { printf("\n%s0x00000020 FILE_TRAVERSE (directory) ",ucIndentBitsBuf);
904: }
905: if ((dwSpecificBits & FILE_DELETE_CHILD ) == FILE_DELETE_CHILD )
906: { printf("\n%s0x00000040 FILE_DELETE_CHILD (directory) ",ucIndentBitsBuf);
907: }
908: if ((dwSpecificBits & FILE_READ_ATTRIBUTES ) == FILE_READ_ATTRIBUTES )
909: { printf("\n%s0x00000080 FILE_READ_ATTRIBUTES (all) ",ucIndentBitsBuf);
910: }
911: if ((dwSpecificBits & FILE_WRITE_ATTRIBUTES ) == FILE_WRITE_ATTRIBUTES )
912: { printf("\n%s0x00000100 FILE_WRITE_ATTRIBUTES (all) ",ucIndentBitsBuf);
913: }
914:
915: if (((dwStandardBits | dwSpecificBits )
916: & FILE_ALL_ACCESS ) == FILE_ALL_ACCESS )
917: { printf("\n%s0x001F01FF FILE_ALL_ACCESS == (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)",ucIndentBitsBuf);
918: }
919: if (((dwStandardBits | dwSpecificBits )
920: & FILE_GENERIC_READ ) == FILE_GENERIC_READ )
921: { printf("\n%s0x00120089 FILE_GENERIC_READ == (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)",ucIndentBitsBuf);
922: }
923: if (((dwStandardBits | dwSpecificBits )
924: & FILE_GENERIC_WRITE ) == FILE_GENERIC_WRITE )
925: { printf("\n%s0x00120116 FILE_GENERIC_WRITE == (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)",ucIndentBitsBuf);
926: }
927: if (((dwStandardBits | dwSpecificBits )
928: & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE)
929: { printf("\n%s0x001200A0 FILE_GENERIC_EXECUTE == (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)",ucIndentBitsBuf);
930: }
931:
932: dwExtraBits = dwSpecificBits & ( ~( FILE_READ_DATA
933: | FILE_LIST_DIRECTORY
934: | FILE_WRITE_DATA
935: | FILE_ADD_FILE
936: | FILE_APPEND_DATA
937: | FILE_ADD_SUBDIRECTORY
938: | FILE_CREATE_PIPE_INSTANCE
939: | FILE_READ_EA
940: | FILE_WRITE_EA
941: | FILE_EXECUTE
942: | FILE_TRAVERSE
943: | FILE_DELETE_CHILD
944: | FILE_READ_ATTRIBUTES
945: | FILE_WRITE_ATTRIBUTES
946: | (FILE_ALL_ACCESS & SPECIFIC_RIGHTS_ALL)
947: | (FILE_GENERIC_READ & SPECIFIC_RIGHTS_ALL)
948: | (FILE_GENERIC_WRITE & SPECIFIC_RIGHTS_ALL)
949: | (FILE_GENERIC_EXECUTE & SPECIFIC_RIGHTS_ALL) ) );
950: if (dwExtraBits)
951: { printf("\n%sExtra specific bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
952: }
953: }
954: else if (ProcessAccessMask == kamKindOfMask)
955: {
956: if ((dwSpecificBits & PROCESS_TERMINATE ) == PROCESS_TERMINATE )
957: { printf("\n%s0x00000001 PROCESS_TERMINATE ",ucIndentBitsBuf);
958: }
959: if ((dwSpecificBits & PROCESS_CREATE_THREAD ) == PROCESS_CREATE_THREAD )
960: { printf("\n%s0x00000002 PROCESS_CREATE_THREAD ",ucIndentBitsBuf);
961: }
962: if ((dwSpecificBits & PROCESS_VM_OPERATION ) == PROCESS_VM_OPERATION )
963: { printf("\n%s0x00000008 PROCESS_VM_OPERATION ",ucIndentBitsBuf);
964: }
965: if ((dwSpecificBits & PROCESS_VM_READ ) == PROCESS_VM_READ )
966: { printf("\n%s0x00000010 PROCESS_VM_READ ",ucIndentBitsBuf);
967: }
968: if ((dwSpecificBits & PROCESS_VM_WRITE ) == PROCESS_VM_WRITE )
969: { printf("\n%s0x00000020 PROCESS_VM_WRITE ",ucIndentBitsBuf);
970: }
971: if ((dwSpecificBits & PROCESS_DUP_HANDLE ) == PROCESS_DUP_HANDLE )
972: { printf("\n%s0x00000040 PROCESS_DUP_HANDLE ",ucIndentBitsBuf);
973: }
974: if ((dwSpecificBits & PROCESS_CREATE_PROCESS ) == PROCESS_CREATE_PROCESS )
975: { printf("\n%s0x00000080 PROCESS_CREATE_PROCESS ",ucIndentBitsBuf);
976: }
977: if ((dwSpecificBits & PROCESS_SET_INFORMATION ) == PROCESS_SET_INFORMATION )
978: { printf("\n%s0x00000200 PROCESS_SET_INFORMATION ",ucIndentBitsBuf);
979: }
980: if ((dwSpecificBits & PROCESS_QUERY_INFORMATION) == PROCESS_QUERY_INFORMATION)
981: { printf("\n%s0x00000400 PROCESS_QUERY_INFORMATION",ucIndentBitsBuf);
982: }
983:
984: if (((dwStandardBits | dwSpecificBits )
985: & PROCESS_ALL_ACCESS) == PROCESS_ALL_ACCESS)
986: { printf("\n%s0x001F0FFF PROCESS_ALL_ACCESS == (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x00000FFF) ",ucIndentBitsBuf);
987: }
988:
989: dwExtraBits = dwSpecificBits & ( ~( PROCESS_TERMINATE
990: | PROCESS_CREATE_THREAD
991: | PROCESS_VM_OPERATION
992: | PROCESS_VM_READ
993: | PROCESS_VM_WRITE
994: | PROCESS_DUP_HANDLE
995: | PROCESS_CREATE_PROCESS
996: | PROCESS_SET_INFORMATION
997: | PROCESS_QUERY_INFORMATION
998: | (PROCESS_ALL_ACCESS & SPECIFIC_RIGHTS_ALL) ) );
999: if (dwExtraBits)
1000: { printf("\n%sExtra specific bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
1001: }
1002: }
1003: else if (WindowStationAccessMask == kamKindOfMask)
1004: {
1005: if ((dwSpecificBits & WINSTA_ENUMDESKTOPS ) == WINSTA_ENUMDESKTOPS )
1006: { printf("\n%s0x00000001 WINSTA_ENUMDESKTOPS ",ucIndentBitsBuf);
1007: }
1008: if ((dwSpecificBits & WINSTA_READATTRIBUTES ) == WINSTA_READATTRIBUTES )
1009: { printf("\n%s0x00000002 WINSTA_READATTRIBUTES ",ucIndentBitsBuf);
1010: }
1011: if ((dwSpecificBits & WINSTA_ACCESSCLIPBOARD ) == WINSTA_ACCESSCLIPBOARD )
1012: { printf("\n%s0x00000004 WINSTA_ACCESSCLIPBOARD ",ucIndentBitsBuf);
1013: }
1014: if ((dwSpecificBits & WINSTA_CREATEDESKTOP ) == WINSTA_CREATEDESKTOP )
1015: { printf("\n%s0x00000008 WINSTA_CREATEDESKTOP ",ucIndentBitsBuf);
1016: }
1017: if ((dwSpecificBits & WINSTA_WRITEATTRIBUTES ) == WINSTA_WRITEATTRIBUTES )
1018: { printf("\n%s0x00000010 WINSTA_WRITEATTRIBUTES ",ucIndentBitsBuf);
1019: }
1020: if ((dwSpecificBits & WINSTA_ACCESSGLOBALATOMS) == WINSTA_ACCESSGLOBALATOMS)
1021: { printf("\n%s0x00000020 WINSTA_ACCESSGLOBALATOMS",ucIndentBitsBuf);
1022: }
1023: if ((dwSpecificBits & WINSTA_EXITWINDOWS ) == WINSTA_EXITWINDOWS )
1024: { printf("\n%s0x00000040 WINSTA_EXITWINDOWS ",ucIndentBitsBuf);
1025: }
1026: if ((dwSpecificBits & WINSTA_ENUMERATE ) == WINSTA_ENUMERATE )
1027: { printf("\n%s0x00000100 WINSTA_ENUMERATE ",ucIndentBitsBuf);
1028: }
1029: if ((dwSpecificBits & WINSTA_READSCREEN ) == WINSTA_READSCREEN )
1030: { printf("\n%s0x00000200 WINSTA_READSCREEN ",ucIndentBitsBuf);
1031: }
1032:
1033: dwExtraBits = dwSpecificBits & ( ~( WINSTA_ENUMDESKTOPS
1034: | WINSTA_READATTRIBUTES
1035: | WINSTA_ACCESSCLIPBOARD
1036: | WINSTA_CREATEDESKTOP
1037: | WINSTA_WRITEATTRIBUTES
1038: | WINSTA_ACCESSGLOBALATOMS
1039: | WINSTA_EXITWINDOWS
1040: | WINSTA_ENUMERATE
1041: | WINSTA_READSCREEN) );
1042: if (dwExtraBits)
1043: { printf("\n%sExtra specific bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
1044: }
1045: }
1046: else if (RegKeyAccessMask == kamKindOfMask)
1047: {
1048: if ((dwSpecificBits & KEY_QUERY_VALUE ) == KEY_QUERY_VALUE )
1049: { printf("\n%s0x00000001 KEY_QUERY_VALUE ",ucIndentBitsBuf);
1050: }
1051: if ((dwSpecificBits & KEY_SET_VALUE ) == KEY_SET_VALUE )
1052: { printf("\n%s0x00000002 KEY_SET_VALUE ",ucIndentBitsBuf);
1053: }
1054: if ((dwSpecificBits & KEY_CREATE_SUB_KEY ) == KEY_CREATE_SUB_KEY )
1055: { printf("\n%s0x00000004 KEY_CREATE_SUB_KEY ",ucIndentBitsBuf);
1056: }
1057: if ((dwSpecificBits & KEY_ENUMERATE_SUB_KEYS) == KEY_ENUMERATE_SUB_KEYS)
1058: { printf("\n%s0x00000008 KEY_ENUMERATE_SUB_KEYS",ucIndentBitsBuf);
1059: }
1060: if ((dwSpecificBits & KEY_NOTIFY ) == KEY_NOTIFY )
1061: { printf("\n%s0x00000010 KEY_NOTIFY ",ucIndentBitsBuf);
1062: }
1063: if ((dwSpecificBits & KEY_CREATE_LINK ) == KEY_CREATE_LINK )
1064: { printf("\n%s0x00000020 KEY_CREATE_LINK ",ucIndentBitsBuf);
1065: }
1066:
1067: if (((dwStandardBits | dwSpecificBits )
1068: & KEY_READ ) == KEY_READ )
1069: { printf("\n%s0x00020019 KEY_READ == ((STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE))",ucIndentBitsBuf);
1070: }
1071: if (((dwStandardBits | dwSpecificBits )
1072: & KEY_WRITE ) == KEY_WRITE )
1073: { printf("\n%s0x00020006 KEY_WRITE == ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE))",ucIndentBitsBuf);
1074: }
1075: if (((dwStandardBits | dwSpecificBits )
1076: & KEY_EXECUTE ) == KEY_EXECUTE )
1077: { printf("\n%s0x00020019 KEY_EXECUTE == ((KEY_READ) & (~SYNCHRONIZE))",ucIndentBitsBuf);
1078: }
1079: if (((dwStandardBits | dwSpecificBits )
1080: & KEY_ALL_ACCESS) == KEY_ALL_ACCESS)
1081: { printf("\n%s0x000F003F KEY_ALL_ACCESS == ((STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE))",ucIndentBitsBuf);
1082: }
1083:
1084: dwExtraBits = dwSpecificBits & ( ~( KEY_QUERY_VALUE
1085: | KEY_SET_VALUE
1086: | KEY_CREATE_SUB_KEY
1087: | KEY_ENUMERATE_SUB_KEYS
1088: | KEY_NOTIFY
1089: | KEY_CREATE_LINK
1090: | (KEY_READ & SPECIFIC_RIGHTS_ALL)
1091: | (KEY_WRITE & SPECIFIC_RIGHTS_ALL)
1092: | (KEY_EXECUTE & SPECIFIC_RIGHTS_ALL)
1093: | (KEY_ALL_ACCESS & SPECIFIC_RIGHTS_ALL) ) );
1094: if (dwExtraBits)
1095: { printf("\n%sExtra specific bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
1096: }
1097: }
1098: else if (ServiceAccessMask == kamKindOfMask)
1099: {
1100: if ((dwSpecificBits & SERVICE_QUERY_CONFIG ) == SERVICE_QUERY_CONFIG )
1101: { printf("\n%s0x00000001 SERVICE_QUERY_CONFIG ",ucIndentBitsBuf);
1102: }
1103: if ((dwSpecificBits & SERVICE_CHANGE_CONFIG ) == SERVICE_CHANGE_CONFIG )
1104: { printf("\n%s0x00000002 SERVICE_CHANGE_CONFIG ",ucIndentBitsBuf);
1105: }
1106: if ((dwSpecificBits & SERVICE_QUERY_STATUS ) == SERVICE_QUERY_STATUS )
1107: { printf("\n%s0x00000004 SERVICE_QUERY_STATUS ",ucIndentBitsBuf);
1108: }
1109: if ((dwSpecificBits & SERVICE_ENUMERATE_DEPENDENTS) == SERVICE_ENUMERATE_DEPENDENTS)
1110: { printf("\n%s0x00000008 SERVICE_ENUMERATE_DEPENDENTS",ucIndentBitsBuf);
1111: }
1112: if ((dwSpecificBits & SERVICE_START ) == SERVICE_START )
1113: { printf("\n%s0x00000010 SERVICE_START ",ucIndentBitsBuf);
1114: }
1115: if ((dwSpecificBits & SERVICE_STOP ) == SERVICE_STOP )
1116: { printf("\n%s0x00000020 SERVICE_STOP ",ucIndentBitsBuf);
1117: }
1118: if ((dwSpecificBits & SERVICE_PAUSE_CONTINUE ) == SERVICE_PAUSE_CONTINUE )
1119: { printf("\n%s0x00000040 SERVICE_PAUSE_CONTINUE ",ucIndentBitsBuf);
1120: }
1121: if ((dwSpecificBits & SERVICE_INTERROGATE ) == SERVICE_INTERROGATE )
1122: { printf("\n%s0x00000080 SERVICE_INTERROGATE ",ucIndentBitsBuf);
1123: }
1124: if ((dwSpecificBits & SERVICE_USER_DEFINED_CONTROL) == SERVICE_USER_DEFINED_CONTROL)
1125: { printf("\n%s0x00000100 SERVICE_USER_DEFINED_CONTROL",ucIndentBitsBuf,ucIndentBitsBuf);
1126: }
1127:
1128: if (((dwStandardBits | dwSpecificBits )
1129: & SERVICE_ALL_ACCESS) == SERVICE_ALL_ACCESS)
1130: { printf("\n%s0x000F01FF SERVICE_ALL_ACCESS == (STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | ", ucIndentBitsBuf );
1131: printf("%s", "SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL)" );
1132: }
1133:
1134: dwExtraBits = dwSpecificBits & ( ~( SERVICE_QUERY_CONFIG
1135: | SERVICE_CHANGE_CONFIG
1136: | SERVICE_QUERY_STATUS
1137: | SERVICE_ENUMERATE_DEPENDENTS
1138: | SERVICE_START
1139: | SERVICE_STOP
1140: | SERVICE_PAUSE_CONTINUE
1141: | SERVICE_INTERROGATE
1142: | SERVICE_USER_DEFINED_CONTROL
1143: | (SERVICE_ALL_ACCESS & SPECIFIC_RIGHTS_ALL) ) );
1144: if (dwExtraBits)
1145: { printf("\n%sExtra specific bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
1146: }
1147: }
1148: else if (DefaultDaclInAccessTokenAccessMask == kamKindOfMask)
1149: {
1150: printf("\n%sSpecific bits in default Dacl(s) in token not broken down into defines",ucIndentBitsBuf);
1151: }
1152: else
1153: { printf("\n%sYou will need to write some code (such as that directly",ucIndentBuf);
1154: printf("\n%s above the code that wrote out this message) to decode",ucIndentBuf);
1155: printf("\n%s this kind of access mask",ucIndentBuf);
1156: }
1157: }
1158:
1159: /**************************************************************************\
1160: *
1161: * Print then decode the ACCESS_SYSTEM_SECURITY bit
1162: *
1163: \**************************************************************************/
1164:
1165: printf("\n%sAccess System Security == 0x%.8x",ucIndentBuf,dwAccessSystemSecurityBit);
1166:
1167: /**************************************************************************\
1168: *
1169: * Print then decode the generic rights bits, which will rarely be on
1170: *
1171: * Generic bits are nearly always mapped by Windows NT before it tries to do
1172: * anything with them. You can ignore the fact that generic bits are
1173: * special in any way, although it helps to keep track of what the mappings
1174: * are so that you don't have any surprises
1175: *
1176: * The only time the generic bits are not mapped immediately is if they are
1177: * placed in an inheritable ACE in an ACL, or in an ACL that will be
1178: * assigned by default (such as the default DACL in an access token). In
1179: * that case they're mapped when the child object is created (or when the
1180: * default DACL is used at object creation time)
1181: *
1182: \**************************************************************************/
1183:
1184: printf("\n%sGeneric Rights == 0x%.8x",ucIndentBuf,dwGenericBits);
1185:
1186: if (dwGenericBits)
1187: {
1188: if ((dwGenericBits & GENERIC_READ ) == GENERIC_READ )
1189: { printf("\n%s0x80000000 GENERIC_READ ",ucIndentBitsBuf);
1190: }
1191: if ((dwGenericBits & GENERIC_WRITE ) == GENERIC_WRITE )
1192: { printf("\n%s0x40000000 GENERIC_WRITE ",ucIndentBitsBuf);
1193: }
1194: if ((dwGenericBits & GENERIC_EXECUTE) == GENERIC_EXECUTE)
1195: { printf("\n%s0x20000000 GENERIC_EXECUTE",ucIndentBitsBuf);
1196: }
1197: if ((dwGenericBits & GENERIC_ALL ) == GENERIC_ALL )
1198: { printf("\n%s0x10000000 GENERIC_ALL ",ucIndentBitsBuf);
1199: }
1200:
1201: dwExtraBits = dwGenericBits & ( ~( GENERIC_READ
1202: | GENERIC_WRITE
1203: | GENERIC_EXECUTE
1204: | GENERIC_ALL) );
1205: if (dwExtraBits)
1206: { printf("\n%sExtra generic bits == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
1207: }
1208: }
1209: }
1210:
1211: /****************************************************************************\
1212: *
1213: * FUNCTION: LookupSIDName
1214: *
1215: \****************************************************************************/
1216:
1217: BOOL LookupSIDName(PSID psidSID, LPTSTR lpszOldIndent)
1218: {
1219: UCHAR ucIndentBuf [SZ_INDENT_BUF] = "";
1220: #define SZ_ACCT_NAME_BUF 60
1221: UCHAR ucNameBuf [SZ_ACCT_NAME_BUF] = "";
1222: DWORD dwNameLength = SZ_ACCT_NAME_BUF;
1223: #define SZ_DMN_NAME_BUF 60
1224: UCHAR ucDomainNmBuf [SZ_DMN_NAME_BUF] = "";
1225: DWORD dwDNameLength = SZ_DMN_NAME_BUF;
1226: #define SZ_SID_STRING_BUF 150
1227: UCHAR ucSIDStringBuf [SZ_SID_STRING_BUF] = "";
1228: SID_NAME_USE peAcctNameUse = SidTypeInvalid;
1229: DWORD dwLookupStatus;
1230: BOOL bGotBadLookupThatIsNotLocalLogonSID;
1231:
1232: strcpy(ucIndentBuf,lpszOldIndent);
1233: strcat(ucIndentBuf," ");
1234:
1235: if (!IsValidSid(psidSID))
1236: { PERR("IsValidSid");
1237: return(FALSE);
1238: }
1239:
1240: if (!SIDStringName(psidSID,ucSIDStringBuf))
1241: { PERR("SIDStringName");
1242: return(FALSE);
1243: }
1244:
1245: if (!LookupAccountSid(
1246: (LPTSTR)"", // Look on local machine
1247: psidSID,
1248: (LPTSTR)&ucNameBuf,
1249: (LPDWORD)&dwNameLength,
1250: (LPTSTR)&ucDomainNmBuf,
1251: (LPDWORD)&dwDNameLength,
1252: (PSID_NAME_USE)&peAcctNameUse))
1253: {
1254: dwLookupStatus = GetLastError();
1255:
1256: /************************************************************************\
1257: *
1258: * Got a bad Lookup, so check is SID the Local Logon SID?
1259: *
1260: * The problem is that LookupAccountSid api will find all the well-known
1261: * SIDs except the Local Logon SID. The last two sub-authorities are
1262: * always different, so to check to see if the SID we're looking at is
1263: * the Local Logon SID, we take the psidLogonIdsSid variable we built at
1264: * initialization time, and blast into it's last two sub-authorities the
1265: * last two sub-authorities that we have. Then compare for EqualSid
1266: *
1267: \************************************************************************/
1268:
1269: // Must have same number of sub authorities
1270:
1271: bGotBadLookupThatIsNotLocalLogonSID = FALSE; // Assume the best :)
1272:
1273: if ( ( *(GetSidSubAuthorityCount(psidLogonIdsSid))) !=
1274: ( *(GetSidSubAuthorityCount(psidSID ))) )
1275: { // Not same number of sub-authorities, so can't be a match
1276: bGotBadLookupThatIsNotLocalLogonSID = TRUE;
1277: }
1278: else
1279: {
1280: // Force the last two sub-authorities to match
1281: *(GetSidSubAuthority( psidLogonIdsSid, 1 )) =
1282: *(GetSidSubAuthority( psidSID , 1 ));
1283: *(GetSidSubAuthority( psidLogonIdsSid, 2 )) =
1284: *(GetSidSubAuthority( psidSID , 2 ));
1285:
1286: /**********************************************************************\
1287: *
1288: * EqualPrefixSid could be used instead if we want to blast in all but
1289: * the last sub-authority. For demonstration purposes, as long as we
1290: * did one of the two previous assignment statements, we may as well to
1291: * the other and use EqualSID
1292: *
1293: \**********************************************************************/
1294:
1295: if (EqualSid(psidSID,psidLogonIdsSid))
1296: { printf("\n%sSID is the Local Logon SID %s",ucIndentBuf,ucSIDStringBuf);
1297: }
1298: else
1299: { bGotBadLookupThatIsNotLocalLogonSID = TRUE;
1300: }
1301: }
1302: if (bGotBadLookupThatIsNotLocalLogonSID)
1303: {
1304: /**********************************************************************\
1305: *
1306: * ERROR_NONE_MAPPED means account unknown. RegEdt32.exe will show
1307: * 1332-error-type accounts as Account Unknown, so we will also
1308: *
1309: \**********************************************************************/
1310:
1311: if (ERROR_NONE_MAPPED == dwLookupStatus)
1312: { printf("\n%sSID domain == %s, Name == %s (Account Unknown) %s",ucIndentBuf,ucDomainNmBuf,ucNameBuf,ucSIDStringBuf);
1313: }
1314: else
1315: { SetLastError(dwLookupStatus);
1316: PERR("LookupAccountSid");
1317: return(FALSE);
1318: }
1319: }
1320: }
1321: else
1322: { // Got good Lookup, so SID Is NOT the Local Logon SID
1323: printf("\n%sSID domain == %s, Name == %s %s",ucIndentBuf,ucDomainNmBuf,ucNameBuf,ucSIDStringBuf);
1324:
1325: /************************************************************************\
1326: *
1327: * For demonstration purposes see which well-known SID it might be
1328: * For demonstration purposes do a silly search demonstrating
1329: * no two well-known SIDs are equal
1330: *
1331: \************************************************************************/
1332:
1333: if (EqualSid(psidSID,psidNullSid))
1334: { printf("\n%sSID is the Null SID",ucIndentBuf);
1335: }
1336: if (EqualSid(psidSID,psidWorldSid))
1337: { printf("\n%sSID is the World SID",ucIndentBuf);
1338: }
1339: if (EqualSid(psidSID,psidLocalSid))
1340: { printf("\n%sSID is the Local SID",ucIndentBuf);
1341: }
1342: if (EqualSid(psidSID,psidCreatorOwnerSid))
1343: { printf("\n%sSID is the CreatorOwner SID",ucIndentBuf);
1344: }
1345: if (EqualSid(psidSID,psidCreatorGroupSid))
1346: { printf("\n%sSID is the CreatorGroup SID",ucIndentBuf);
1347: }
1348: if (EqualSid(psidSID,psidNtAuthoritySid))
1349: { printf("\n%sSID is the NtAuthority SID",ucIndentBuf);
1350: }
1351: if (EqualSid(psidSID,psidDialupSid))
1352: { printf("\n%sSID is the DialUp SID",ucIndentBuf);
1353: }
1354: if (EqualSid(psidSID,psidNetworkSid))
1355: { printf("\n%sSID is the Network SID",ucIndentBuf);
1356: }
1357: if (EqualSid(psidSID,psidBatchSid))
1358: { printf("\n%sSID is the Batch SID",ucIndentBuf);
1359: }
1360: if (EqualSid(psidSID,psidInteractiveSid))
1361: { printf("\n%sSID is the Interactive SID",ucIndentBuf);
1362: }
1363: if (EqualSid(psidSID,psidServiceSid))
1364: { printf("\n%sSID is the Service SID",ucIndentBuf);
1365: }
1366: if (EqualSid(psidSID,psidLocalSystemSid))
1367: { printf("\n%sSID is the LocalSystem SID",ucIndentBuf);
1368: }
1369: if (EqualSid(psidSID,psidBuiltinDomainSid))
1370: { printf("\n%sSID is the Builtin Domain SID",ucIndentBuf);
1371: }
1372: }
1373:
1374: switch (peAcctNameUse)
1375: { case SidTypeUser :
1376: printf("\n%sSID type is SidTypeUser" ,ucIndentBuf);
1377: break;
1378: case SidTypeGroup :
1379: printf("\n%sSID type is SidTypeGroup" ,ucIndentBuf);
1380: break;
1381: case SidTypeDomain :
1382: printf("\n%sSID type is SidTypeDomain" ,ucIndentBuf);
1383: break;
1384: case SidTypeAlias :
1385: printf("\n%sSID type is SidTypeAlias" ,ucIndentBuf);
1386: break;
1387: case SidTypeWellKnownGroup :
1388: printf("\n%sSID type is SidTypeWellKnownGroup",ucIndentBuf);
1389: break;
1390: case SidTypeDeletedAccount :
1391: printf("\n%sSID type is SidTypeDeletedAccount",ucIndentBuf);
1392: break;
1393: case SidTypeInvalid :
1394: printf("\n%sSID type is SidTypeInvalid" ,ucIndentBuf);
1395: break;
1396: case SidTypeUnknown :
1397: printf("\n%sSID type is SidTypeUnknown" ,ucIndentBuf);
1398: break;
1399: default :
1400: printf("\n%sSID type is IMPOSSIBLE!!!! Run debugger, see value!",ucIndentBuf);
1401: break;
1402: }
1403: }
1404:
1405: /****************************************************************************\
1406: *
1407: * FUNCTION: SIDStringName
1408: *
1409: \****************************************************************************/
1410:
1411: BOOL SIDStringName(PSID psidSID, LPTSTR lpszSIDStringName)
1412: {
1413: /**************************************************************************\
1414: *
1415: * Unfortunately there is no api to return the SID Revision, and the number
1416: * of bytes in the Identifier Authority must be expressed as a define
1417: * (since the == operator won't operate on structures so mempcy has to be
1418: * used for the identifier authority compares)
1419: *
1420: \**************************************************************************/
1421:
1422: DWORD dwNumSubAuthorities;
1423: DWORD dwLen;
1424: DWORD dwSubAuthorityI;
1425: #define BytesInIdentifierAuthority 6
1426: SID_IDENTIFIER_AUTHORITY siaSidAuthority;
1427: SID_IDENTIFIER_AUTHORITY siaNullSidAuthority = SECURITY_NULL_SID_AUTHORITY;
1428: SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
1429: SID_IDENTIFIER_AUTHORITY siaLocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
1430: SID_IDENTIFIER_AUTHORITY siaCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
1431: SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
1432:
1433: dwLen = sprintf(lpszSIDStringName,"S-%d-",SID_REVISION);
1434:
1435: if (SID_REVISION != ((PISID)psidSID)->Revision)
1436: { dwLen += sprintf(lpszSIDStringName+dwLen,"bad_revision==%d",((PISID)psidSID)->Revision);
1437: }
1438:
1439: siaSidAuthority = *(GetSidIdentifierAuthority(psidSID));
1440:
1441: if (0==memcmp(&siaSidAuthority,&siaNullSidAuthority ,BytesInIdentifierAuthority))
1442: { dwLen += sprintf(lpszSIDStringName+dwLen,"0");
1443: }
1444: else if (0==memcmp(&siaSidAuthority,&siaWorldSidAuthority ,BytesInIdentifierAuthority))
1445: { dwLen += sprintf(lpszSIDStringName+dwLen,"1");
1446: }
1447: else if (0==memcmp(&siaSidAuthority,&siaLocalSidAuthority ,BytesInIdentifierAuthority))
1448: { dwLen += sprintf(lpszSIDStringName+dwLen,"2");
1449: }
1450: else if (0==memcmp(&siaSidAuthority,&siaCreatorSidAuthority,BytesInIdentifierAuthority))
1451: { dwLen += sprintf(lpszSIDStringName+dwLen,"3");
1452: }
1453: else if (0==memcmp(&siaSidAuthority,&siaNtAuthority ,BytesInIdentifierAuthority))
1454: { dwLen += sprintf(lpszSIDStringName+dwLen,"5");
1455: }
1456: else
1457: { dwLen += sprintf(lpszSIDStringName+dwLen,"UnknownAuthority!");
1458: }
1459:
1460: dwNumSubAuthorities = (DWORD)( *(GetSidSubAuthorityCount(psidSID)) );
1461:
1462: for (dwSubAuthorityI=0; dwSubAuthorityI<dwNumSubAuthorities; dwSubAuthorityI++)
1463: { dwLen += sprintf(lpszSIDStringName+dwLen,"-%d",*(GetSidSubAuthority(psidSID,dwSubAuthorityI)));
1464: }
1465:
1466: return(TRUE);
1467: }
1468:
1469: /****************************************************************************\
1470: *
1471: * FUNCTION: ExamineAccessToken
1472: *
1473: \****************************************************************************/
1474:
1475: VOID ExamineAccessToken(HANDLE hAccessToken)
1476: { TOKEN_INFORMATION_CLASS ticInfoClass;
1477: #define SZ_TOK_INFO_BUF 2000
1478: UCHAR ucTokInfoBuf [SZ_TOK_INFO_BUF] = "";
1479: DWORD dwTokInfoBufSz;
1480: PTOKEN_USER ptuTokenUser = (PTOKEN_USER )&ucTokInfoBuf;
1481: PTOKEN_GROUPS ptgTokenGroups = (PTOKEN_GROUPS )&ucTokInfoBuf;
1482: PTOKEN_PRIVILEGES ptpTokenPrivileges = (PTOKEN_PRIVILEGES )&ucTokInfoBuf;
1483: PTOKEN_OWNER ptoTokenOwner = (PTOKEN_OWNER )&ucTokInfoBuf;
1484: PTOKEN_PRIMARY_GROUP ptgTokenPrimaryGroup = (PTOKEN_PRIMARY_GROUP)&ucTokInfoBuf;
1485: PTOKEN_DEFAULT_DACL ptdTokenDefaultDacl = (PTOKEN_DEFAULT_DACL )&ucTokInfoBuf;
1486: PTOKEN_SOURCE ptsTokenSource = (PTOKEN_SOURCE )&ucTokInfoBuf;
1487: PTOKEN_TYPE pttTokenType = (PTOKEN_TYPE )&ucTokInfoBuf;
1488: PSECURITY_IMPERSONATION_LEVEL psilSecurityImpersonationLevel = (PSECURITY_IMPERSONATION_LEVEL)&ucTokInfoBuf;
1489: PTOKEN_STATISTICS ptsTokenStatistics = (PTOKEN_STATISTICS )&ucTokInfoBuf;
1490: DWORD dwGroupI;
1491: DWORD dwPrivilegeI;
1492: #define SZ_PRIV_INFO_BUF 250
1493: UCHAR ucPrivInfoBuf[SZ_PRIV_INFO_BUF] = "";
1494: DWORD dwPrivInfoBufSz;
1495: DWORD dwExtraBits;
1496: UCHAR ucIndentBitsBuf[SZ_INDENT_BUF] = "";
1497:
1498: strcpy(ucIndentBitsBuf,"");
1499: strcat(ucIndentBitsBuf," ");
1500:
1501:
1502: if (!I_DO_NOT_WANT_THIS_CODE_TO_CLUTTER_THIS_PROGRAM_S_OUTPUT)
1503: {
1504: ticInfoClass = TokenUser;
1505: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1506:
1507: if (!GetTokenInformation(hAccessToken,
1508: ticInfoClass,
1509: ucTokInfoBuf,
1510: (DWORD)SZ_TOK_INFO_BUF,
1511: &dwTokInfoBufSz))
1512: { PERR("GetTokenInformation");
1513: return;
1514: }
1515:
1516: printf("\nToken's User SID");
1517: printf("\n (this is a SID that is used to compare to SIDs in DACL(s) and SACL(s)");
1518:
1519: if(!LookupSIDName( (*ptuTokenUser).User.Sid,""))
1520: { PERR("LookupSIDName failed");
1521: }
1522:
1523: printf("\nToken's User SID Attributes == 0x%.8x",(*ptuTokenUser).User.Attributes);
1524: printf("\n These should always be 0 - see \\mstools\\h\\winnt.h right after");
1525: printf("\n the defines such as SE_GROUP_LOGON_ID - there are no user");
1526: printf("\n attributes yet defined");
1527:
1528:
1529:
1530: ticInfoClass = TokenGroups;
1531: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1532:
1533: if (!GetTokenInformation(hAccessToken,
1534: ticInfoClass,
1535: ucTokInfoBuf,
1536: (DWORD)SZ_TOK_INFO_BUF,
1537: &dwTokInfoBufSz))
1538: { PERR("GetTokenInformation");
1539: return;
1540: }
1541:
1542: printf("\nToken groups (%d)",(*ptgTokenGroups).GroupCount);
1543: printf("\n (these SID(s) also are used to compare to SIDs in DACL(s) and SACL(s)");
1544:
1545: for (dwGroupI=0; dwGroupI<(*ptgTokenGroups).GroupCount; dwGroupI++)
1546: {
1547: DWORD dwAttributeBits = (*ptgTokenGroups).Groups[dwGroupI].Attributes;
1548: printf("\n Token group (%d)",dwGroupI);
1549:
1550: if(!LookupSIDName( (*ptgTokenGroups).Groups[dwGroupI].Sid," "))
1551: { PERR("LookupSIDName failed");
1552: }
1553: printf("\n Token's group (%d) attributes == 0x%.8x",dwGroupI,dwAttributeBits);
1554:
1555: if (dwAttributeBits)
1556: {
1557: if ((dwAttributeBits & SE_GROUP_MANDATORY ) == SE_GROUP_MANDATORY )
1558: { printf("\n%s0x00000001 SE_GROUP_MANDATORY ",ucIndentBitsBuf);
1559: }
1560: if ((dwAttributeBits & SE_GROUP_ENABLED_BY_DEFAULT) == SE_GROUP_ENABLED_BY_DEFAULT)
1561: { printf("\n%s0x00000002 SE_GROUP_ENABLED_BY_DEFAULT",ucIndentBitsBuf);
1562: }
1563: if ((dwAttributeBits & SE_GROUP_ENABLED ) == SE_GROUP_ENABLED )
1564: { printf("\n%s0x00000004 SE_GROUP_ENABLED ",ucIndentBitsBuf);
1565: }
1566: if ((dwAttributeBits & SE_GROUP_OWNER ) == SE_GROUP_OWNER )
1567: { printf("\n%s0x00000008 SE_GROUP_OWNER ",ucIndentBitsBuf);
1568: }
1569: if ((dwAttributeBits & SE_GROUP_LOGON_ID ) == SE_GROUP_LOGON_ID )
1570: { printf("\n%s0xC0000000 SE_GROUP_LOGON_ID ",ucIndentBitsBuf);
1571: }
1572:
1573: dwExtraBits = dwAttributeBits & ( ~( SE_GROUP_MANDATORY
1574: | SE_GROUP_ENABLED_BY_DEFAULT
1575: | SE_GROUP_ENABLED
1576: | SE_GROUP_OWNER
1577: | SE_GROUP_LOGON_ID) );
1578: if (0 != dwExtraBits)
1579: { printf("\n Extra attribute bits == 0x%.8x <-This is a problem, should be all 0s",dwExtraBits);
1580: }
1581: }
1582: }
1583:
1584:
1585:
1586: ticInfoClass = TokenPrivileges;
1587: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1588:
1589: if (!GetTokenInformation(hAccessToken,
1590: ticInfoClass,
1591: ucTokInfoBuf,
1592: (DWORD)SZ_TOK_INFO_BUF,
1593: &dwTokInfoBufSz))
1594: { PERR("GetTokenInformation");
1595: return;
1596: }
1597:
1598: printf("\nToken privileges (%d)",(*ptpTokenPrivileges).PrivilegeCount);
1599: printf("\n NOTE: Most token privileges are not enabled by default.");
1600: printf("\n For example the privilege to reboot or logoff is not.");
1601: printf("\n 0x00000000 for attributes implies the privilege is not enabled.");
1602: printf("\n Use care when enabling privileges. Enable only those needed,");
1603: printf("\n and leave them enabled only for as long as they are needed.");
1604:
1605: for (dwPrivilegeI=0; dwPrivilegeI<(*ptpTokenPrivileges).PrivilegeCount; dwPrivilegeI++)
1606: {
1607: LUID luidTokenLuid = (*ptpTokenPrivileges).Privileges[dwPrivilegeI].Luid;
1608: DWORD dwAttributeBits = (*ptpTokenPrivileges).Privileges[dwPrivilegeI].Attributes;
1609:
1610: dwPrivInfoBufSz = SZ_PRIV_INFO_BUF;
1611:
1612: if (!LookupPrivilegeName(NULL,
1613: (PLUID)&luidTokenLuid,
1614: (LPTSTR)ucPrivInfoBuf,
1615: (LPDWORD)&dwPrivInfoBufSz))
1616: { PERR("LookUpPrivilegeName");
1617: return;
1618: }
1619:
1620: printf("\n Token's privilege (%.2d) name == %s",dwPrivilegeI,ucPrivInfoBuf);
1621:
1622: printf("\n Token's privilege (%.2d) attributes == 0x%.8x",dwPrivilegeI,dwAttributeBits);
1623:
1624: if (dwAttributeBits)
1625: {
1626: if ((dwAttributeBits & SE_PRIVILEGE_ENABLED_BY_DEFAULT) == SE_PRIVILEGE_ENABLED_BY_DEFAULT)
1627: { printf("\n%s 0x00000001 SE_PRIVILEGE_ENABLED_BY_DEFAULT",ucIndentBitsBuf);
1628: }
1629: if ((dwAttributeBits & SE_PRIVILEGE_ENABLED ) == SE_PRIVILEGE_ENABLED )
1630: { printf("\n%s 0x00000002 SE_PRIVILEGE_ENABLED ",ucIndentBitsBuf);
1631: }
1632: if ((dwAttributeBits & SE_PRIVILEGE_USED_FOR_ACCESS ) == SE_PRIVILEGE_USED_FOR_ACCESS )
1633: { printf("\n%s 0x80000000 SE_PRIVILEGE_USED_FOR_ACCESS ",ucIndentBitsBuf);
1634: }
1635:
1636: dwExtraBits = dwAttributeBits & ( ~( SE_PRIVILEGE_ENABLED_BY_DEFAULT
1637: | SE_PRIVILEGE_ENABLED
1638: | SE_PRIVILEGE_USED_FOR_ACCESS ) );
1639: if (0 != dwExtraBits)
1640: { printf("\n Extra attribute bits == 0x%.8x <-This is a problem, should be all 0s",dwExtraBits);
1641: }
1642: }
1643: }
1644:
1645:
1646:
1647: ticInfoClass = TokenOwner;
1648: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1649:
1650: if (!GetTokenInformation(hAccessToken,
1651: ticInfoClass,
1652: ucTokInfoBuf,
1653: (DWORD)SZ_TOK_INFO_BUF,
1654: &dwTokInfoBufSz))
1655: { PERR("GetTokenInformation");
1656: return;
1657: }
1658:
1659: printf("\nToken's default-owner-SID for created objects");
1660: printf("\n (this is NOT a SID that is used to compare to SIDs in DACL(s) and SACL(s)");
1661:
1662: if(!LookupSIDName((*ptoTokenOwner).Owner,""))
1663: { PERR("LookupSIDName failed");
1664: }
1665:
1666:
1667:
1668: ticInfoClass = TokenPrimaryGroup;
1669: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1670:
1671: if (!GetTokenInformation(hAccessToken,
1672: ticInfoClass,
1673: ucTokInfoBuf,
1674: (DWORD)SZ_TOK_INFO_BUF,
1675: &dwTokInfoBufSz))
1676: { PERR("GetTokenInformation");
1677: return;
1678: }
1679:
1680: printf("\nToken's Primary Group SID");
1681: printf("\n (Current uses are Posix and Macintosh client support)");
1682:
1683: if(!LookupSIDName((*ptgTokenPrimaryGroup).PrimaryGroup,""))
1684: { PERR("LookupSIDName failed");
1685: }
1686:
1687:
1688:
1689: ticInfoClass = TokenDefaultDacl;
1690: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1691:
1692: if (!GetTokenInformation(hAccessToken,
1693: ticInfoClass,
1694: ucTokInfoBuf,
1695: (DWORD)SZ_TOK_INFO_BUF,
1696: &dwTokInfoBufSz))
1697: { PERR("GetTokenInformation");
1698: return;
1699: }
1700:
1701: if (NULL == (*ptdTokenDefaultDacl).DefaultDacl)
1702: { printf("\nToken has a NULL Default DACL explicitly specified (allows all access to");
1703: printf("\n Everyone, only on objects that are created where the object's Dacl is");
1704: printf("\n assigned by default from this default Dacl in this access token)");
1705: }
1706: else
1707: { printf("\nToken's default-DACL for created objects");
1708: if(!ExamineACL((*ptdTokenDefaultDacl).DefaultDacl,"",DefaultDaclInAccessTokenAccessMask))
1709: { PERR("ExamineACL failed");
1710: }
1711: }
1712:
1713:
1714:
1715: ticInfoClass = TokenSource;
1716: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1717:
1718: if (!GetTokenInformation(hAccessToken,
1719: ticInfoClass,
1720: ucTokInfoBuf,
1721: (DWORD)SZ_TOK_INFO_BUF,
1722: &dwTokInfoBufSz))
1723: { PERR("GetTokenInformation");
1724: return;
1725: }
1726:
1727: printf("\nToken's Source");
1728: printf("\n Source Name == %.8s",(*ptsTokenSource).SourceName);
1729: printf("\n Source Identifier == 0x%.8x%.8x",
1730: (*ptsTokenSource).SourceIdentifier.HighPart,
1731: (*ptsTokenSource).SourceIdentifier.LowPart);
1732:
1733:
1734:
1735: ticInfoClass = TokenType;
1736: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1737:
1738: if (!GetTokenInformation(hAccessToken,
1739: ticInfoClass,
1740: ucTokInfoBuf,
1741: (DWORD)SZ_TOK_INFO_BUF,
1742: &dwTokInfoBufSz))
1743: { PERR("GetTokenInformation");
1744: return;
1745: }
1746:
1747: switch (*pttTokenType)
1748: { case TokenPrimary :
1749: printf("\nToken's Type is TokenPrimary");
1750: break;
1751: case TokenImpersonation :
1752: printf("\nToken's Type is TokenImpersonation");
1753: printf("\n Hence the token's TokenImpersonationLevel can be examined");
1754:
1755: ticInfoClass = TokenImpersonationLevel;
1756: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1757:
1758: if (!GetTokenInformation(hAccessToken,
1759: ticInfoClass,
1760: ucTokInfoBuf,
1761: (DWORD)SZ_TOK_INFO_BUF,
1762: &dwTokInfoBufSz))
1763: { PERR("GetTokenInformation");
1764: return;
1765: }
1766:
1767: switch (*psilSecurityImpersonationLevel)
1768: { case SecurityAnonymous :
1769: printf("\n Token is a SecurityAnonymous impersonation token");
1770: break;
1771: case SecurityIdentification :
1772: printf("\n Token is a SecurityIdentification impersonation token");
1773: break;
1774: case SecurityImpersonation :
1775: printf("\n Token is a SecurityImpersonation impersonation token");
1776: break;
1777: case SecurityDelegation :
1778: printf("\n Token is a SecurityDelegation impersonation token");
1779: break;
1780: default :
1781: printf("\n Token is an ILLEGAL KIND OF impersonation token!!! == 0x%.8x",*psilSecurityImpersonationLevel);
1782: break;
1783: }
1784:
1785: default :
1786: printf("\nToken's Type is ILLEGAL!!! == 0x%.8x",*pttTokenType);
1787: break;
1788: }
1789:
1790:
1791:
1792: ticInfoClass = TokenStatistics;
1793: dwTokInfoBufSz = SZ_TOK_INFO_BUF;
1794:
1795: if (!GetTokenInformation(hAccessToken,
1796: ticInfoClass,
1797: ucTokInfoBuf,
1798: (DWORD)SZ_TOK_INFO_BUF,
1799: &dwTokInfoBufSz))
1800: { PERR("GetTokenInformation");
1801: return;
1802: }
1803:
1804: printf("\nToken's Statistics");
1805: printf("\n TokenId == 0x%.8x%.8x",
1806: (*ptsTokenStatistics).TokenId.HighPart,
1807: (*ptsTokenStatistics).TokenId.LowPart);
1808: printf("\n AuthenticationId == 0x%.8x%.8x",
1809: (*ptsTokenStatistics).AuthenticationId.HighPart,
1810: (*ptsTokenStatistics).AuthenticationId.LowPart);
1811: printf("\n ExpirationTime == (not supported in this release of Windows NT)");
1812: printf("\n TokenType == See token type above");
1813: printf("\n ImpersonationLevel == See impersonation level above (only if TokenType is not TokenPrimary)");
1814: printf("\n DynamicCharged == %ld",(*ptsTokenStatistics).DynamicCharged );
1815: printf("\n DynamicAvailable == %ld",(*ptsTokenStatistics).DynamicAvailable );
1816: printf("\n GroupCount == %d",(*ptsTokenStatistics).GroupCount );
1817: printf("\n PrivilegeCount == %d",(*ptsTokenStatistics).PrivilegeCount );
1818: printf("\n ModifiedId == 0x%.8x%.8x",
1819: (*ptsTokenStatistics).ModifiedId.HighPart,
1820: (*ptsTokenStatistics).ModifiedId.LowPart);
1821:
1822:
1823:
1824: printf("\n\n");
1825:
1826: }
1827: }
1828:
1829: /****************************************************************************\
1830: *
1831: * FUNCTION: SetPrivilegeInAccessToken
1832: *
1833: \****************************************************************************/
1834:
1835: BOOL SetPrivilegeInAccessToken(VOID)
1836: {
1837: HANDLE hProcess;
1838: HANDLE hAccessToken;
1839: LUID luidPrivilegeLUID;
1840: TOKEN_PRIVILEGES tpTokenPrivilege;
1841:
1842: hProcess = GetCurrentProcess();
1843: if (!hProcess)
1844: { PERR("GetCurrentProcess");
1845: return(FALSE);
1846: }
1847:
1848: if (!OpenProcessToken(hProcess,
1849: TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
1850: &hAccessToken))
1851: { PERR("OpenProcessToken");
1852: return(FALSE);
1853: }
1854:
1855: /**************************************************************************\
1856: *
1857: * Get LUID of SeSecurityPrivilege privilege
1858: *
1859: \**************************************************************************/
1860:
1861: if (!LookupPrivilegeValue(NULL,
1862: "SeSecurityPrivilege",
1863: &luidPrivilegeLUID))
1864: { PERR("LookupPrivilegeValue");
1865: printf("\nThe above error means you need to log on as an Administrator");
1866: return(FALSE);
1867: }
1868:
1869: /**************************************************************************\
1870: *
1871: * Enable the SeSecurityPrivilege privilege using the LUID just
1872: * obtained
1873: *
1874: \**************************************************************************/
1875:
1876: tpTokenPrivilege.PrivilegeCount = 1;
1877: tpTokenPrivilege.Privileges[0].Luid = luidPrivilegeLUID;
1878: tpTokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
1879:
1880: AdjustTokenPrivileges (hAccessToken,
1881: FALSE, // Do not disable all
1882: &tpTokenPrivilege,
1883: sizeof(TOKEN_PRIVILEGES),
1884: NULL, // Ignore previous info
1885: NULL); // Ignore previous info
1886:
1887: if ( GetLastError() != NO_ERROR )
1888: { PERR("AdjustTokenPrivileges");
1889: return(FALSE);
1890: }
1891:
1892: return(TRUE);
1893: }
1894:
1895: /****************************************************************************\
1896: *
1897: * FUNCTION: InitializeWellKnownSIDs
1898: *
1899: \****************************************************************************/
1900:
1901: VOID InitializeWellKnownSIDs(VOID)
1902: {
1903: DWORD dwSidWith0SubAuthorities;
1904: DWORD dwSidWith1SubAuthority;
1905: DWORD dwSidWith2SubAuthorities;
1906: DWORD dwSidWith3SubAuthorities;
1907: DWORD dwSidWith4SubAuthorities;
1908:
1909: SID_IDENTIFIER_AUTHORITY siaNullSidAuthority = SECURITY_NULL_SID_AUTHORITY;
1910: SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
1911: SID_IDENTIFIER_AUTHORITY siaLocalSidAuthority = SECURITY_LOCAL_SID_AUTHORITY;
1912: SID_IDENTIFIER_AUTHORITY siaCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
1913: SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
1914:
1915: // These SID sizes need to be allocated
1916:
1917: dwSidWith0SubAuthorities = GetSidLengthRequired( 0 );
1918: dwSidWith1SubAuthority = GetSidLengthRequired( 1 );
1919: dwSidWith2SubAuthorities = GetSidLengthRequired( 2 );
1920: dwSidWith3SubAuthorities = GetSidLengthRequired( 3 );
1921: dwSidWith4SubAuthorities = GetSidLengthRequired( 4 );
1922:
1923: // Allocate and initialize the universal SIDs
1924:
1925: psidNullSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1926: psidWorldSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1927: psidLocalSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1928: psidCreatorOwnerSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1929: psidCreatorGroupSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1930:
1931: InitializeSid( psidNullSid, &siaNullSidAuthority, 1 );
1932: InitializeSid( psidWorldSid, &siaWorldSidAuthority, 1 );
1933: InitializeSid( psidLocalSid, &siaLocalSidAuthority, 1 );
1934: InitializeSid( psidCreatorOwnerSid, &siaCreatorSidAuthority, 1 );
1935: InitializeSid( psidCreatorGroupSid, &siaCreatorSidAuthority, 1 );
1936:
1937: *(GetSidSubAuthority( psidNullSid, 0 )) = SECURITY_NULL_RID;
1938: *(GetSidSubAuthority( psidWorldSid, 0 )) = SECURITY_WORLD_RID;
1939: *(GetSidSubAuthority( psidLocalSid, 0 )) = SECURITY_LOCAL_RID;
1940: *(GetSidSubAuthority( psidCreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
1941: *(GetSidSubAuthority( psidCreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
1942:
1943: // Allocate and initialize the NT defined SIDs
1944:
1945: psidNtAuthoritySid = (PSID)LocalAlloc(LPTR,dwSidWith0SubAuthorities);
1946: psidDialupSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1947: psidNetworkSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1948: psidBatchSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1949: psidInteractiveSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1950: psidLogonIdsSid = (PSID)LocalAlloc(LPTR,dwSidWith3SubAuthorities);
1951: psidServiceSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1952: psidLocalSystemSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1953: psidBuiltinDomainSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
1954:
1955: InitializeSid( psidNtAuthoritySid, &siaNtAuthority, 0 );
1956: InitializeSid( psidDialupSid, &siaNtAuthority, 1 );
1957: InitializeSid( psidNetworkSid, &siaNtAuthority, 1 );
1958: InitializeSid( psidBatchSid, &siaNtAuthority, 1 );
1959: InitializeSid( psidInteractiveSid, &siaNtAuthority, 1 );
1960: InitializeSid( psidLogonIdsSid, &siaNtAuthority, 3 );
1961: InitializeSid( psidServiceSid, &siaNtAuthority, 1 );
1962: InitializeSid( psidLocalSystemSid, &siaNtAuthority, 1 );
1963: InitializeSid( psidBuiltinDomainSid, &siaNtAuthority, 1 );
1964:
1965: *(GetSidSubAuthority( psidDialupSid, 0 )) = SECURITY_DIALUP_RID;
1966: *(GetSidSubAuthority( psidNetworkSid, 0 )) = SECURITY_NETWORK_RID;
1967: *(GetSidSubAuthority( psidBatchSid, 0 )) = SECURITY_BATCH_RID;
1968: *(GetSidSubAuthority( psidInteractiveSid, 0 )) = SECURITY_INTERACTIVE_RID;
1969: *(GetSidSubAuthority( psidLogonIdsSid, 0 )) = SECURITY_LOGON_IDS_RID;
1970: *(GetSidSubAuthority( psidLogonIdsSid, 1 )) = 0; // Bogus!
1971: *(GetSidSubAuthority( psidLogonIdsSid, 2 )) = 0; // Also bogus!
1972: *(GetSidSubAuthority( psidServiceSid, 0 )) = SECURITY_SERVICE_RID;
1973: *(GetSidSubAuthority( psidLocalSystemSid, 0 )) = SECURITY_LOCAL_SYSTEM_RID;
1974: *(GetSidSubAuthority( psidBuiltinDomainSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
1975: }
1976:
1977: /****************************************************************************\
1978: *
1979: * FUNCTION: DisplayHelp
1980: *
1981: \****************************************************************************/
1982:
1983: VOID DisplayHelp(VOID)
1984: {
1985: printf("\nTo run type CHECK_SD and 0 or 1 parameters. Syntax:");
1986: printf("\n CHECK_SD");
1987: printf("\n or");
1988: printf("\n CHECK_SD filename");
1989: printf("\n filename is the name of the file that is passed");
1990: printf("\n to GetFileSecurity() to fetch the SD to examine");
1991: printf("\nExamples:");
1992: printf("\n CHECK_SD Checks the SD on A: (this is the default)");
1993: printf("\n CHECK_SD \\\\.\\A: Checks the SD on A:");
1994: printf("\n CHECK_SD d:\\a.fil Checks the SD on d:\a.fil");
1995: printf("\n CHECK_SD A: Checks the SD on the A: root, but that");
1996: printf("\n is not where the DACL is that controls");
1997: printf("\n access to the floppy, so don't do this");
1998: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.