Annotation of q_a/samples/check_sd/check_sd.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.