/*---------------------------------------------------------------------------*\
 * NAME: DisplayAccess                                                       *
 * --------------------------------------------------------------------------*
 * DESCRIPTION: 
\*---------------------------------------------------------------------------*/
void DisplayAccess(
    DWORD dwAccessMask, 
    DWORD dwSDType, 
    LPCTSTR tszAccessType, 
    LPCTSTR tszUser, 
    LPCTSTR tszDomain
    )
{

    BOOL fLegacy = IsLegacySecurityModel();

    if(!fLegacy)
    {
        WarnIfGlobalPolicySet();
    }

    if(dwSDType & SDTYPE_ACCESS)
    {
        BOOL fLocalAccess = (dwAccessMask & COM_RIGHTS_EXECUTE_LOCAL  ) ||
                             ((dwAccessMask & COM_RIGHTS_EXECUTE) && 
                              !(dwAccessMask & COM_RIGHTS_EXECUTE_REMOTE));

        BOOL fRemoteAccess = (dwAccessMask & COM_RIGHTS_EXECUTE_REMOTE  ) ||
                             ((dwAccessMask & COM_RIGHTS_EXECUTE) && 
                              !(dwAccessMask & COM_RIGHTS_EXECUTE_LOCAL));

        if(fLegacy && dwAccessMask & COM_RIGHTS_EXECUTE)
        {
            _tprintf (_T("Access %s to %s\\%s.\n"), 
                      tszAccessType,
                      tszDomain, tszUser);

        }
        else if(!fLegacy && (fLocalAccess || fRemoteAccess))
        {

            _tprintf (_T("%s access %s to %s\\%s.\n"), 
                      fLocalAccess ? 
                      fRemoteAccess ? 
                      _T("Remote and Local") : _T("Local") : _T("Remote") ,
                      tszAccessType,
                      tszDomain, tszUser);
         }
    }
    else
    {

        BOOL fLocalLaunchAccess = (dwAccessMask & COM_RIGHTS_EXECUTE_LOCAL  ) ||
                             ((dwAccessMask & COM_RIGHTS_EXECUTE) && 
                             !(dwAccessMask & (COM_RIGHTS_EXECUTE_REMOTE  |
                                               COM_RIGHTS_ACTIVATE_REMOTE |
                                               COM_RIGHTS_ACTIVATE_LOCAL)));

        BOOL fRemoteLaunchAccess = (dwAccessMask & COM_RIGHTS_EXECUTE_REMOTE  ) ||
                             ((dwAccessMask & COM_RIGHTS_EXECUTE) && 
                             !(dwAccessMask & (COM_RIGHTS_EXECUTE_LOCAL   |
                                               COM_RIGHTS_ACTIVATE_REMOTE |
                                               COM_RIGHTS_ACTIVATE_LOCAL)));

        BOOL fLocalActivateAccess = (dwAccessMask & COM_RIGHTS_ACTIVATE_LOCAL) ||
                             ((dwAccessMask & COM_RIGHTS_EXECUTE) && 
                             !(dwAccessMask & (COM_RIGHTS_EXECUTE_LOCAL  |
                                               COM_RIGHTS_EXECUTE_REMOTE |
                                               COM_RIGHTS_ACTIVATE_REMOTE)));

        BOOL fRemoteActivateAccess = (dwAccessMask & COM_RIGHTS_ACTIVATE_REMOTE) ||
                             ((dwAccessMask & COM_RIGHTS_EXECUTE) && 
                             !(dwAccessMask & (COM_RIGHTS_EXECUTE_LOCAL  |
                                               COM_RIGHTS_EXECUTE_REMOTE |
                                               COM_RIGHTS_ACTIVATE_LOCAL)));

        if(fLegacy && dwAccessMask & COM_RIGHTS_EXECUTE)
        {
            _tprintf (_T("Launch %s to %s\\%s.\n"), 
                      tszAccessType,
                      tszDomain, tszUser);

        }
        else 
        {
            if(!fLegacy && (fLocalLaunchAccess || fRemoteLaunchAccess))
            {

                _tprintf (_T("%s launch %s to %s\\%s.\n"), 
                          fLocalLaunchAccess ? 
                          fRemoteLaunchAccess ? 
                          _T("Remote and Local") : _T("Local") : _T("Remote") ,
                          tszAccessType,
                          tszDomain, tszUser);
             }
             if(!fLegacy && (fLocalActivateAccess || fRemoteActivateAccess))
             {

                _tprintf (_T("%s activation %s to %s\\%s.\n"), 
                          fLocalActivateAccess ? 
                          fRemoteActivateAccess ? 
                          _T("Remote and Local") : _T("Local") : _T("Remote"),
                          tszAccessType,
                          tszDomain, tszUser);
             }

         }

    }

}
/*---------------------------------------------------------------------------*\
 * NAME: CanonicalizeSD 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Ensures the entire security descriptor is consistent with the new permission
 * format.
\*---------------------------------------------------------------------------*/
DWORD CanonicalizeSD(PSECURITY_DESCRIPTOR pSD)
{
    BOOL fSuccess = FALSE, fACLPresent = FALSE, fDefaulted = FALSE;
    ACL* pACL = NULL;

    if(IsLegacySecurityModel()) return ERROR_SUCCESS;
 
    fSuccess = GetSecurityDescriptorDacl(pSD, &fACLPresent, &pACL, &fDefaulted);
    if (fSuccess == FALSE)
    {
        return GetLastError();
    }
 
    ACCESS_MASK dwOtherRights = COM_RIGHTS_EXECUTE_LOCAL |
                                COM_RIGHTS_EXECUTE_REMOTE |
                                COM_RIGHTS_ACTIVATE_LOCAL |
                                COM_RIGHTS_ACTIVATE_REMOTE;
 
    DWORD dwSizeOfACL = sizeof(ACL);
    ULONG_PTR ulptrACL = (ULONG_PTR)pACL;
    PACE_HEADER pAceHeader = (PACE_HEADER)(ulptrACL + dwSizeOfACL);
    PACCESS_MASK pAccessMask = (PACCESS_MASK)((ULONG_PTR)pAceHeader+sizeof(ACE_HEADER));
 
    // Iterate through the ACE's in the ACL and canonicalize the representation
    // Each ACE has a header and Mask Field as a minimum.
 
    if ( pACL )
    {
        for ( int i = 0; i < pACL->AceCount ; i++)
        {
            DWORD dwError = NULL;
            void* pNewAcl = NULL;
       
            // Protect against bad ACL structure 
            if (((ULONG_PTR)pAceHeader-(ULONG_PTR)pACL) >= (pACL->AclSize-sizeof(ACCESS_MASK)))
           {
                return ERROR_INVALID_PARAMETER;
            }
      
            DWORD dwAceSize = pAceHeader->AceSize;
 
            // Ensure minimum size ACE
            if (dwAceSize < (sizeof(ACE_HEADER)+sizeof(ACCESS_MASK)))
            {
                return ERROR_INVALID_PARAMETER;
            }
 
            // Canonicalize AccessMask
            if (*pAccessMask & COM_RIGHTS_EXECUTE)
            {
                // When COM_RIGHTS_EXECUTE is set but no other RIGHTS
                // This means grant all other RIGHTS
                if ((*pAccessMask & dwOtherRights) == 0)
                {
                    *pAccessMask |= dwOtherRights;
                }
            }
            else
            {
                // COM_RIGHTS_EXECUTE Not Set so clear all other RIGHTS bits
                *pAccessMask &= ~dwOtherRights;
            }
 
            ulptrACL = (ULONG_PTR)pAceHeader;
            pAceHeader = (PACE_HEADER)(ulptrACL + dwAceSize);
            pAccessMask = (PACCESS_MASK)((ULONG_PTR)pAceHeader+sizeof(ACE_HEADER));
        }
 
    }
 
    return ERROR_SUCCESS;
}
DWORD COxtSecurityHelper::SetACLDefaults(PACL *ppDacl, DWORD dwSDType)
{
	DWORD dwReturnValue = ERROR_BAD_ARGUMENTS;

	if (IsLegacySecurityModel())
		return SetLegacyACLDefaults(ppDacl, dwSDType);

	switch (dwSDType)
	{
	case SDTYPE_APPLICATION_LAUNCH:
		{
		dwReturnValue = AddAccessAllowedACEToACL(ppDacl,
												 COM_RIGHTS_ACTIVATE_LOCAL |
												 COM_RIGHTS_EXECUTE_LOCAL |
												 COM_RIGHTS_EXECUTE,
												 g_ptszPrincipals[1]); // SYSTEM

		if (dwReturnValue != ERROR_SUCCESS)
			break;

		dwReturnValue = AddAccessAllowedACEToACL(ppDacl,
												 COM_RIGHTS_ACTIVATE_LOCAL |
												 COM_RIGHTS_EXECUTE_LOCAL |
												 COM_RIGHTS_EXECUTE,
												 g_ptszPrincipals[2]); // Administrators

		if (dwReturnValue != ERROR_SUCCESS)
			break;

		dwReturnValue = AddAccessAllowedACEToACL(ppDacl,
												 COM_RIGHTS_ACTIVATE_LOCAL |
												 COM_RIGHTS_EXECUTE_LOCAL |
												 COM_RIGHTS_EXECUTE,
												 g_ptszPrincipals[0]); // INTERACTIVE
		break;
		}
	case SDTYPE_APPLICATION_ACCESS:
		{
		dwReturnValue = AddAccessAllowedACEToACL(ppDacl,
												 COM_RIGHTS_EXECUTE_LOCAL |
												 COM_RIGHTS_EXECUTE,
												 g_ptszPrincipals[1]); // SYSTEM

		if (dwReturnValue != ERROR_SUCCESS)
			break;

		dwReturnValue = AddAccessAllowedACEToACL(ppDacl,
												 COM_RIGHTS_EXECUTE_LOCAL |
												 COM_RIGHTS_EXECUTE,
												 g_ptszPrincipals[2]); // Administrators

		if (dwReturnValue != ERROR_SUCCESS)
			break;

		dwReturnValue = AddAccessAllowedACEToACL(ppDacl,
												 COM_RIGHTS_EXECUTE_LOCAL |
												 COM_RIGHTS_EXECUTE,
												 g_ptszPrincipals[0]); // INTERACTIVE

		break;
		}
	default:
		break;
	}

	return dwReturnValue;
}
bool COxtSecurityHelper::DenyCheckUser(DWORD dwAccessMask,
									   DWORD dwSDType,
									   LPCTSTR tszUser,
									   LPCTSTR tszDomain,
									   BOOL bPermit)
{

	if (IsLegacySecurityModel())
	{
		// We don't really support anything lower than XPSP3 so we will just
		// drop out on the legacy check.
		// NOTE: removed check for WarnIfGlobalPolicySet()
		return true;
	}

	// All local access is fine and this check is not concerned with whether
	// everything has been denied. So the only case that is bad is permitting
	// remote access.

	if (dwSDType & SDTYPE_APPLICATION_ACCESS)
	{
		BOOL bRemoteAccess = (dwAccessMask & COM_RIGHTS_EXECUTE_REMOTE  ) ||
							 ((dwAccessMask & COM_RIGHTS_EXECUTE) &&
							  !(dwAccessMask & COM_RIGHTS_EXECUTE_LOCAL));

		if ((bPermit)&&(bRemoteAccess))
		{
			m_pclOxtSvc->LogEventTypeId(ctxLS(IDS_DENY_REMOTE_CHECK_FOR_zS_DETECTE_OXTSECURITYHELPER_1279),
									 EVENTLOG_ERROR_TYPE, EVMSG_SECURITY_FAILURE,
									 _T("AccessPermission"));
			return false;
		}
	}

	if (dwSDType & SDTYPE_APPLICATION_LAUNCH)
	{
		BOOL bRemoteLaunchAccess = (dwAccessMask & COM_RIGHTS_EXECUTE_REMOTE  ) ||
							 ((dwAccessMask & COM_RIGHTS_EXECUTE) &&
							 !(dwAccessMask & (COM_RIGHTS_EXECUTE_LOCAL   |
											   COM_RIGHTS_ACTIVATE_REMOTE |
											   COM_RIGHTS_ACTIVATE_LOCAL)));

		BOOL bRemoteActivateAccess = (dwAccessMask & COM_RIGHTS_ACTIVATE_REMOTE) ||
							 ((dwAccessMask & COM_RIGHTS_EXECUTE) &&
							 !(dwAccessMask & (COM_RIGHTS_EXECUTE_LOCAL  |
											   COM_RIGHTS_EXECUTE_REMOTE |
											   COM_RIGHTS_ACTIVATE_LOCAL)));
		if ((bPermit)&&(bRemoteLaunchAccess))
		{
			m_pclOxtSvc->LogEventTypeId(ctxLS(IDS_DENY_REMOTE_CHECK_FOR_zS_DETECTE_OXTSECURITYHELPER_1301),
									 EVENTLOG_ERROR_TYPE, EVMSG_SECURITY_FAILURE,
									 _T("LaunchPermission-Launch"));
			return false;
		}

		if ((bPermit)&&(bRemoteActivateAccess))
		{
			m_pclOxtSvc->LogEventTypeId(ctxLS(IDS_DENY_REMOTE_CHECK_FOR_zS_DETECTE_OXTSECURITYHELPER_1309),
									 EVENTLOG_ERROR_TYPE, EVMSG_SECURITY_FAILURE,
									 _T("LaunchPermission-Activate"));
			return false;
		}
	}

	return true;
}
void HandleApplicationLaunchAndActivateOption (
    int cArgs,
    TCHAR **pptszArgv
    )
{
    DWORD dwReturnValue                 = ERROR_SUCCESS;
    HKEY  hkeyRegistry                  = NULL;
    TCHAR tszAppID [SIZE_NAME_BUFFER]   = {0};
    TCHAR tszKeyName [SIZE_NAME_BUFFER] = {0};

    DWORD dwAccessMask = COM_RIGHTS_EXECUTE;
    
    if (cArgs < 4) ShowUsage (_T("Invalid number of arguments."));

    if (_tcsicmp (pptszArgv[3], _T("LIST")) == 0)
    {
        if (cArgs < 4) ShowUsage (_T("Invalid number of arguments.\n"));

        _tprintf (_T("Launch permission list for AppID %s:\n\n"), pptszArgv[2]);
        ListAppIDLaunchACL (pptszArgv[2]);
        return;
    }

    if (_tcsicmp (pptszArgv[3], _T("DEFAULT")) == 0)
    {


        _stprintf_s (tszAppID, RTL_NUMBER_OF(tszAppID), pptszArgv [2][0] == '{' ? _T("%s") : _T("{%s}"), pptszArgv [2]);
        _stprintf_s (tszKeyName, RTL_NUMBER_OF(tszKeyName), _T("APPID\\%s"), tszAppID);


        dwReturnValue = RegOpenKeyEx (HKEY_CLASSES_ROOT, tszKeyName, 0, KEY_ALL_ACCESS, &hkeyRegistry);
        if (dwReturnValue != ERROR_SUCCESS && dwReturnValue != ERROR_FILE_NOT_FOUND)
        {
            Error (_T("ERROR: Cannot open AppID registry key."), dwReturnValue);
        }

        dwReturnValue = RegDeleteValue (hkeyRegistry, _T("LaunchPermission"));
        if (dwReturnValue != ERROR_SUCCESS && dwReturnValue != ERROR_FILE_NOT_FOUND)
        {
            Error (_T("ERROR: Cannot delete LaunchPermission value."), dwReturnValue);
        }

        if(hkeyRegistry) RegCloseKey (hkeyRegistry);

        _tprintf (_T("Successfully set the Application Launch to the machine default.\n"));

        return;
    }

    if (cArgs < 5) ShowUsage (_T("Invalid number of arguments."));

    if (_tcsicmp (pptszArgv [3], _T("SET")) == 0)
    {
        if (cArgs < 6) ShowUsage (_T("Invalid number of arguments."));

        if(cArgs == 7) 
        {
            SetAccessMaskFromCommandLine(pptszArgv[6], &dwAccessMask, SDTYPE_APPLICATION_LAUNCH);
        }
        else if(!IsLegacySecurityModel())
        {
            _tprintf (_T("WARNING: Default access flags designated on a system with an enhanced security model.\n"));
        }

        if (_tcsicmp (pptszArgv [5], _T("PERMIT")) == 0)
        {
            dwReturnValue = ChangeAppIDLaunchAndActivateACL (pptszArgv[2], pptszArgv [4], TRUE, TRUE, dwAccessMask);
        }
        else if (_tcsicmp (pptszArgv [5], _T("DENY")) == 0)
        {
            dwReturnValue = ChangeAppIDLaunchAndActivateACL (pptszArgv[2], pptszArgv [4], TRUE, FALSE, dwAccessMask);
        }
        else
        {
            ShowUsage (_T("You can only set a user's permissions to \"permit\" or \"deny\".\n\n"));
        }

        if (dwReturnValue != ERROR_SUCCESS)
            Error (_T("ERROR: Cannot add user to application launch ACL."), dwReturnValue);
    } 
    else if (_tcsicmp (pptszArgv [3], _T("REMOVE")) == 0)
    {
        dwReturnValue = ChangeAppIDLaunchAndActivateACL (pptszArgv[2], pptszArgv[4], FALSE, FALSE, dwAccessMask);

        if (dwReturnValue != ERROR_SUCCESS)
        {
            Error (_T("ERROR: Cannot remove user from application launch ACL."), dwReturnValue);
        }
    } 
    else
    {
        ShowUsage (_T("You can only \"set\" or \"remove\" a user."));
    }

     _tprintf (_T("Successfully set the Application Launch ACL.\n"));

    ListAppIDLaunchACL(pptszArgv[2]);
}
/*---------------------------------------------------------------------------*\
 * NAME: HandleDefaultLaunchOption                                           *
 * --------------------------------------------------------------------------*
 * DESCRIPTION: 
\*---------------------------------------------------------------------------*/
void HandleDefaultLaunchOption (
    int cArgs,
    TCHAR **pptszArgv
    )
{
    DWORD dwReturnValue = ERROR_SUCCESS;
    DWORD dwAccessMask = COM_RIGHTS_EXECUTE;

    if (cArgs < 3) ShowUsage (_T("Invalid number of arguments."));

    if (_tcsicmp (pptszArgv [2], _T("LIST")) == 0)
    {
        _tprintf (_T("Default launch permission list:\n\n"));
        dwReturnValue = ListDefaultLaunchACL();

        if (dwReturnValue != ERROR_SUCCESS)
        {
            Error (_T("ERROR: Cannot list default launch ACL."), dwReturnValue);
        }

        return;
    }

    if (cArgs < 4) ShowUsage (_T("Invalid number of arguments."));

    if (_tcsicmp (pptszArgv [2], _T("SET")) == 0)
    {
        if (cArgs < 5) ShowUsage (_T("Invalid number of arguments."));

        if(cArgs == 6) 
        {
            SetAccessMaskFromCommandLine(pptszArgv[5], &dwAccessMask, SDTYPE_DEFAULT_LAUNCH);
        }
        else if(!IsLegacySecurityModel())
        {
            _tprintf (_T("WARNING: Default access flags designated on a system with an enhanced security model.\n"));
        }

        if (_tcsicmp (pptszArgv [4], _T("PERMIT")) == 0)
        {
            dwReturnValue = ChangeDefaultLaunchAndActivateACL (pptszArgv [3], TRUE, TRUE, dwAccessMask); 
        }
        else if (_tcsicmp (pptszArgv [4], _T("DENY")) == 0)
        {
            dwReturnValue = ChangeDefaultLaunchAndActivateACL (pptszArgv [3], TRUE, FALSE, dwAccessMask); 
        }
        else
        {
            ShowUsage (_T("You can only set a user's permissions to \"permit\" or \"deny\".\n\n"));
        }

        if (dwReturnValue != ERROR_SUCCESS)
        {
            Error (_T("ERROR: Cannot add user to default launch ACL."), dwReturnValue);
        }

    } 
    else if (_tcsicmp (pptszArgv [2], _T("REMOVE")) == 0)
    {
        dwReturnValue = ChangeDefaultLaunchAndActivateACL (pptszArgv[3], FALSE, FALSE, dwAccessMask);

        if (dwReturnValue != ERROR_SUCCESS)
        {
            Error (_T("ERROR: Cannot remove user from default launch ACL."), dwReturnValue);
        }
    } 
    else
    {
        ShowUsage (_T("You can only \"set\" or \"remove\" a user."));
    }

     _tprintf (_T("Successfully set the Default Launch ACL.\n"));

    ListDefaultLaunchACL();
}
/*---------------------------------------------------------------------------*\
 * NAME: HandleDefaultLaunchOption                                           *
 * --------------------------------------------------------------------------*
 * DESCRIPTION: 
\*---------------------------------------------------------------------------*/
void ShowUsage (
    LPTSTR tszErrorString
    )
{

    BOOL fLegacy = IsLegacySecurityModel();

    _tprintf (_T("%s\n"), tszErrorString);
    _tprintf (_T("Syntax: dcomperm <option> [...]\n\n"));

    _tprintf (_T("Options:\n"));

    if(!fLegacy)
    {
        _tprintf (_T("   -ma <\"set\" or \"remove\"> <Principal Name> [\"permit\" or \"deny\"] [\"level:l,r\"]\n"));
        _tprintf (_T("   -ma list\n"));
        _tprintf (_T("       Modify or list the machine access permission list\n\n"));

        _tprintf (_T("   -ml <\"set\" or \"remove\"> <Principal Name> [\"permit\" or \"deny\"] [\"level:l,r,ll,la,rl,ra\"]\n"));
        _tprintf (_T("   -ml list\n"));
        _tprintf (_T("       Modify or list the machine launch permission list\n\n"));
    }

    _tprintf (_T("   -da <\"set\" or \"remove\"> <Principal Name> [\"permit\" or \"deny\"] "));
    if(!fLegacy) _tprintf (_T("[\"level:l,r\"]\n")); else _tprintf (_T("\n"));
    
    _tprintf (_T("   -da list\n"));
    _tprintf (_T("       Modify or list the default access permission list\n\n"));

    _tprintf (_T("   -dl <\"set\" or \"remove\"> <Principal Name> [\"permit\" or \"deny\"] "));
    if(!fLegacy) _tprintf (_T("[\"level:l,r,ll,la,rl,ra\"]\n")); else _tprintf (_T("\n"));
    _tprintf (_T("   -dl list\n"));
    _tprintf (_T("       Modify or list the default launch permission list\n\n"));

    _tprintf (_T("   -aa <AppID> <\"set\" or \"remove\"> <Principal Name> [\"permit\" or \"deny\"] "));
    if(!fLegacy) _tprintf (_T("[\"level:l,r\"]\n")); else _tprintf (_T("\n"));
    _tprintf (_T("   -aa <AppID> default\n"));
    _tprintf (_T("   -aa <AppID> list\n"));
    _tprintf (_T("       Modify or list the access permission list for a specific AppID\n\n"));

    _tprintf (_T("   -al <AppID> <\"set\" or \"remove\"> <Principal Name> [\"permit\" or \"deny\"] "));
    if(!fLegacy) _tprintf (_T("[\"level:l,r,ll,la,rl,ra\"]\n")); else _tprintf (_T("\n"));
    _tprintf (_T("   -al <AppID> default\n"));
    _tprintf (_T("   -al <AppID> list\n"));
    _tprintf (_T("       Modify or list the launch permission list for a specific AppID\n\n"));

    if(!fLegacy)
    {
        _tprintf (_T("level: \n"));
        _tprintf (_T("\tll - local launch (only applies to {ml, dl, al} options)  \n"));
        _tprintf (_T("\trl - remote launch (only applies to {ml, dl, al} options)  \n"));
        _tprintf (_T("\tla - local activate (only applies to {ml, dl, al} options)  \n"));
        _tprintf (_T("\tra - remote activate (only applies to {ml, dl, al} options)  \n"));
        _tprintf (_T("\tl  - local (local access - means launch and activate when used with {ml, dl, al} options)  \n"));
        _tprintf (_T("\tr  - remote (remote access - means launch and activate when used with {ml, dl, al} options)  \n\n"));
    }

    _tprintf (_T("Press any key to continue. . ."));
    _getch();
    _tprintf (_T("\r                               \r"));

    _tprintf (_T("   -runas <AppID> <Principal Name> <Password>\n"));
    _tprintf (_T("   -runas <AppID> \"Interactive User\"\n"));
    _tprintf (_T("   -runas <AppID> \"Launching User\"\n"));
    _tprintf (_T("       Set the RunAs information for a specific AppID\n\n"));

    _tprintf (_T("Examples:\n"));
    _tprintf (_T("   dcomperm -da set redmond\\t-miken permit"));
    if(!fLegacy) _tprintf (_T(" level:r\n")); else _tprintf (_T("\n"));
    _tprintf (_T("   dcomperm -dl set redmond\\jdoe deny"));
    if(!fLegacy) _tprintf (_T(" level:rl,ra\n")); else _tprintf (_T("\n"));
    _tprintf (_T("   dcomperm -aa {12345678-1234-1234-1234-00aa00bbf7c7} list\n"));
    _tprintf (_T("   dcomperm -al {12345678-1234-1234-1234-00aa00bbf7c7} remove redmond\\t-miken\n"));
    _tprintf (_T("   dcomperm -runas {12345678-1234-1234-1234-00aa00bbf7c7} redmond\\jdoe password\n"));

    exit (0);
}