/*
 * FreeSD: Frees the memory of an absolute SD.
 */
void
vncAccessControl::FreeSD(PSECURITY_DESCRIPTOR pSD){
	PSID pOwnerSID = NULL;
	PSID pGroupSID = NULL;
	PACL pDACL = NULL;
	PACL pSACL = NULL;
	BOOL bOwnerDefaulted = FALSE;
	BOOL bGroupDefaulted = FALSE;
	BOOL bDaclPresent = FALSE;
	BOOL bDaclDefaulted = FALSE;
	BOOL bSaclPresent = FALSE;
	BOOL bSaclDefaulted = FALSE;
	
	if (pSD) {
		GetSecurityDescriptorOwner(pSD, &pOwnerSID, &bOwnerDefaulted);
		GetSecurityDescriptorGroup(pSD, &pGroupSID, &bGroupDefaulted);
		GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDACL, &bDaclDefaulted);
		GetSecurityDescriptorSacl(pSD, &bSaclPresent, &pSACL, &bSaclDefaulted);
	}
	// Clean up
	if (pSD)
		HeapFree(GetProcessHeap(), 0, pSD);
	if (bDaclPresent && pDACL)
		HeapFree(GetProcessHeap(), 0, pDACL);
	if (bSaclPresent && pSACL)
		HeapFree(GetProcessHeap(), 0, pSACL);
	if (pOwnerSID)
		HeapFree(GetProcessHeap(), 0, pOwnerSID);
	if (pGroupSID)
		HeapFree(GetProcessHeap(), 0, pGroupSID);

}
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
static void CallbackSdOwner(
    _In_ HANDLE hOutfile,
    _Inout_ PLDAP_RETRIEVED_DATA pLdapRetreivedData
    ) {
    BOOL bResult = FALSE;
    BOOL bDaclPresent = FALSE;
    BOOL bDaclDefaulted = FALSE;
    PACL pDacl = { 0 };
    PSECURITY_DESCRIPTOR pSd = (PSECURITY_DESCRIPTOR)pLdapRetreivedData->ppbData[0];

    if (!IsValidSecurityDescriptor(pSd)) {
        LOG(Err, _T("Invalid security descriptor"));
        return;
    }

    bResult = ControlWriteOwnerOutline(hOutfile, pSd, pLdapRetreivedData->tDN, CONTROL_AD_OWNER_KEYWORD);
    if (!bResult) {
        LOG(Err, _T("Cannot write owner control relation for <%s>"), pLdapRetreivedData->tDN);
    }

    bResult = GetSecurityDescriptorDacl(pSd, &bDaclPresent, &pDacl, &bDaclDefaulted);
    if (bResult == FALSE) {
        LOG(Err, _T("Failed to get DACL <%u>"), GetLastError());
        return;
    }

    if (bDaclPresent == FALSE || pDacl == NULL) {
        LOG(Info, "Null or no DACL for element <%s>", pLdapRetreivedData->tDN);
        bResult = ControlWriteOutline(hOutfile, gs_ptSidEveryone, pLdapRetreivedData->tDN, CONTROL_AD_NULL_DACL_KEYWORD);
        if (bResult == FALSE) {
            LOG(Err, _T("Cannot write null-dacl control relation for <%s>"), pLdapRetreivedData->tDN);
            return;
        }
    }
}
void DumpSD(PSECURITY_DESCRIPTOR pSD)
{
    DWORD dwSize = GetSecurityDescriptorLength(pSD);
    printf("\nSecurity Descriptor is of size %d", dwSize);

    BOOL DaclPresent, DaclDefaulted;
    PACL pDacl;
    if(GetSecurityDescriptorDacl(pSD, &DaclPresent,
                &pDacl, &DaclDefaulted) && DaclPresent)
    {

        // Dump the aces

        ACL_SIZE_INFORMATION inf;
        DWORD dwNumAces;
        if(GetAclInformation(
            pDacl,
            &inf,
            sizeof(ACL_SIZE_INFORMATION),
            AclSizeInformation
            ))
        {
            dwNumAces = inf.AceCount;
            printf("\nThe DACL has %d ACEs", dwNumAces);
            for(DWORD dwCnt = 0; dwCnt < dwNumAces; dwCnt++)
            {
                ACCESS_ALLOWED_ACE * pAce;
                if(GetAce(pDacl, dwCnt, (LPVOID *)&pAce))
                    DumpAce(pAce);
            }
        }
    }
}
Beispiel #4
0
HANDLE GetAnonymousToken()
{
  ImpersonateAnonymousToken(GetCurrentThread());
  HANDLE hToken;
  OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &hToken);
  RevertToSelf();
  
  PSECURITY_DESCRIPTOR pSD;
  ULONG sd_length;
  if (!ConvertStringSecurityDescriptorToSecurityDescriptor(L"D:(A;;GA;;;WD)(A;;GA;;;AN)", SDDL_REVISION_1, &pSD, &sd_length))
  {
    printf("Error converting SDDL: %d\n", GetLastError());
    exit(1);
  }

  TOKEN_DEFAULT_DACL dacl;
  BOOL bPresent;
  BOOL bDefaulted;
  PACL pDACL;
  GetSecurityDescriptorDacl(pSD, &bPresent, &pDACL, &bDefaulted);
  dacl.DefaultDacl = pDACL;

  if (!SetTokenInformation(hToken, TokenDefaultDacl, &dacl, sizeof(dacl)))
  {
    printf("Error setting default DACL: %d\n", GetLastError());
    exit(1);
  }

  return hToken;
}
Beispiel #5
0
DWORD GetObjectSecurityDescriptorDacl(
    IN HANDLE object,
    OUT SECURITY_DESCRIPTOR **sd,
    OUT BOOL *daclPresent,
    OUT ACL **dacl
    )
{
    DWORD status;
    SECURITY_INFORMATION si;
    DWORD sizeNeeded;
    BOOL daclDefaulted;

    if (!sd || !daclPresent || !dacl)
        return ERROR_INVALID_PARAMETER;

    si = DACL_SECURITY_INFORMATION;

    if (!GetUserObjectSecurity(
        object,
        &si,
        NULL,
        0,
        &sizeNeeded))
    {
        status = GetLastError();
        if (ERROR_INSUFFICIENT_BUFFER != status)
        {
            return perror("GetUserObjectSecurity");
        }
    }

    *sd = LocalAlloc(LPTR, sizeNeeded);
    if (*sd == NULL)
    {
        return perror("LocalAlloc");
    }

    if (!GetUserObjectSecurity(
        object,
        &si,
        *sd,
        sizeNeeded,
        &sizeNeeded))
    {
        return perror("GetUserObjectSecurity");
    }

    if (!GetSecurityDescriptorDacl(*sd, daclPresent, dacl, &daclDefaulted))
    {
        status = GetLastError();
        LocalFree(*sd);
        return perror2(status, "GetSecurityDescriptorDacl");
    }

    return ERROR_SUCCESS;
}
/*
 * SetSD: Changes the class variable pACL and the reg key.
 *        The ACL is the DACL of the provided SD.
 */
BOOL
vncAccessControl::SetSD(PSECURITY_DESCRIPTOR pSD){
	BOOL isOK = FALSE;
	BOOL bDaclPresent = FALSE;
	BOOL bDaclDefaulted = FALSE;
	PACL pDACL = NULL;

	GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDACL, &bDaclDefaulted);

	if (bDaclPresent && pDACL && IsValidAcl(pDACL) && StoreACL(pDACL))
		isOK = TRUE;
	return isOK;
}
Beispiel #7
0
/*
 * Returns pointer discretionary access-control list (ACL) from the security
 * descriptor of the specified file.
 */
static ACL* getFileDACL(JNIEnv* env, SECURITY_DESCRIPTOR* sd) {
    ACL *acl;
    int defaulted, present;

    if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
        JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorDacl failed");
        return NULL;
    }
    if (!present) {
        JNU_ThrowInternalError(env, "Security descriptor does not contain a DACL");
        return NULL;
    }
    return acl;
}
Beispiel #8
0
BOOL ValidateSecurity(uch *securitydata)
{
    PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata;
    PACL pAcl;
    PSID pSid;
    BOOL bAclPresent;
    BOOL bDefaulted;

    if(!IsWinNT()) return TRUE; /* don't do anything if not on WinNT */

    if(!IsValidSecurityDescriptor(sd)) return FALSE;

    /* verify Dacl integrity */

    if(!GetSecurityDescriptorDacl(sd, &bAclPresent, &pAcl, &bDefaulted))
        return FALSE;

    if(bAclPresent && pAcl!=NULL) {
        if(!IsValidAcl(pAcl)) return FALSE;
    }

    /* verify Sacl integrity */

    if(!GetSecurityDescriptorSacl(sd, &bAclPresent, &pAcl, &bDefaulted))
        return FALSE;

    if(bAclPresent && pAcl!=NULL) {
        if(!IsValidAcl(pAcl)) return FALSE;
    }

    /* verify owner integrity */

    if(!GetSecurityDescriptorOwner(sd, &pSid, &bDefaulted))
        return FALSE;

    if(pSid != NULL) {
        if(!IsValidSid(pSid)) return FALSE;
    }

    /* verify group integrity */

    if(!GetSecurityDescriptorGroup(sd, &pSid, &bDefaulted))
        return FALSE;

    if(pSid != NULL) {
        if(!IsValidSid(pSid)) return FALSE;
    }

    return TRUE;
}
Beispiel #9
0
DWORD
ListNamedValueSD (
    HKEY RootKey,
    LPTSTR KeyName,
    LPTSTR ValueName
    )
{
    DWORD               returnValue;
    SECURITY_DESCRIPTOR *sd;
    BOOL                present;
    BOOL                defaultDACL;
    PACL                dacl;
    BOOL                newSD = FALSE;

    returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);

    if ((returnValue != ERROR_SUCCESS) || (newSD == TRUE))
    {
        _tprintf (TEXT("<Using Default Permissions>\n"));
        free (sd);
        return returnValue;
    }

    if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
    {
        free (sd);
        return GetLastError();
    }

    if (!present)
    {
        _tprintf (TEXT("<Access is denied to everyone>\n"));
        free (sd);
        return ERROR_SUCCESS;
    }

    ListACL (dacl);

    free (sd);

    return ERROR_SUCCESS;
}
/*---------------------------------------------------------------------------*\
 * NAME: ListNamedValueSD 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Displays the designated security descriptor.
\*---------------------------------------------------------------------------*/
DWORD ListNamedValueSD (
    HKEY hkeyRoot,
    LPTSTR tszKeyName,
    LPTSTR tszValueName,
    DWORD dwSDType
    )
{
    DWORD               dwReturnValue = ERROR_SUCCESS;
    SECURITY_DESCRIPTOR *pSD          = NULL;
    BOOL                fPresent      = FALSE;
    BOOL                fDefaultDACL  = FALSE;
    PACL                dacl          = NULL;

    dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, NULL);

    if (dwReturnValue != ERROR_SUCCESS)
    {
        _tprintf (_T("<Using Default Permissions>\n"));
        goto CLEANUP;
    }

    if (!GetSecurityDescriptorDacl (pSD, &fPresent, &dacl, &fDefaultDACL))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    if (!fPresent)
    {
        _tprintf (_T("<Access is denied to everyone>\n"));
        goto CLEANUP;
    }

    ListACL (dacl, dwSDType);

CLEANUP:

    if(pSD) free (pSD);

    return dwReturnValue;
}
Beispiel #11
0
/*
(in) PSECURITY_DESCRIPTOR file or directory handle
(in/out) struct acl * acl 
*/
int get_file_acl(PSECURITY_DESCRIPTOR pSD,struct acl * acl)
{
  DWORD dwLastError;
  PACL pDacl;
  PSID pOwnerSid,pGroupSid;
  SID_NAME_USE eUse;
  BOOL  bPresent;
  BOOL bDef;
  int i;


  
  if (0 == GetSecurityDescriptorOwner(pSD,
				      &pOwnerSid,
				      &bDef)){
    return (-1);
  }
  if (0 == GetSecurityDescriptorGroup(pSD,
				      &pGroupSid,
				      &bDef)){
    return(-1);
  }
  if (0 == GetSecurityDescriptorDacl(pSD,&bPresent,&pDacl,&bDef)){
    return(-1);
  }

  if (get_account_sid(pOwnerSid,acl->owner,MAX_LEN,&eUse) == -1){
    return (-1);
  }
  if (get_account_sid(pGroupSid,acl->group,MAX_LEN,&eUse) == -1){
    return (-1);
  }

  if (pDacl != NULL)
    get_ace(pDacl,acl,&eUse);


  return (0);
}
Beispiel #12
0
/**
 * This function adjusts the specified WindowStation to include the specfied
 *   user.
 *
 * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx
 **/
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
   ACCESS_ALLOWED_ACE   *pace = NULL;
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl = NULL;
   PACL                 pNewAcl = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   try
   {
      // Obtain the DACL for the window station.

      if (!GetUserObjectSecurity(
             hwinsta,
             &si,
             psd,
             dwSidSize,
             &dwSdSizeNeeded)
      )
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psd == NULL)
            throw;

         psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psdNew == NULL)
            throw;

         dwSidSize = dwSdSizeNeeded;

         if (!GetUserObjectSecurity(
               hwinsta,
               &si,
               psd,
               dwSidSize,
               &dwSdSizeNeeded)
         )
            throw;
      }
      else
         throw;

      // Create a new DACL.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         throw;

      // Get the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         throw;

      // Initialize the ACL.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if the DACL is not NULL.

      if (pacl != NULL)
      {
         // get the file ACL size info
         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            throw;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));

      // Allocate memory for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         throw;

      // Initialize the new DACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         throw;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  throw;

               // Add the ACE to the new ACL.
               if (!AddAce(
                     pNewAcl,
                     ACL_REVISION,
                     MAXDWORD,
                     pTempAce,
                    ((PACE_HEADER)pTempAce)->AceSize)
               )
                  throw;
            }
         }
      }

      // Add the first ACE to the window station.

      pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)
      );

      if (pace == NULL)
         throw;

      pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
      pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
                              INHERIT_ONLY_ACE |
                              OBJECT_INHERIT_ACE;
      pace->Header.AceSize  = (WORD)sizeof(ACCESS_ALLOWED_ACE) + 
                              (WORD)GetLengthSid(psid) - 
                              (WORD)sizeof(DWORD);
      pace->Mask            = GENERIC_ALL;

      if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
         throw;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         throw;

      // Add an ACE to the window station.

      pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
      pace->Mask            = GENERIC_ALL;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         throw;

      // Set a new DACL for the security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         throw;

      // Set the new security descriptor for the window station.

      if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
         throw;

      // Indicate success.

      bSuccess = TRUE;
   }
   catch(...)
   {
      // Free the allocated buffers.

      if (pace != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pace);

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;

}
Beispiel #13
0
BOOL Process::AddAceToProc(DWORD mask,PSID psid){//Здесь происходит очень сильная магия. И я не разобрался до конца почему тут косяки
	//Смысл в том, что нельзя просто так добавить ACE в DACL. 
	//Придется создать DACL бОльшего размера чем предыдущий, и скопировать все в новый из старого.
	//Потом вручную насоздавть структур и сохранить их. 
	//Проблема в том, что почему-то не сохраняется нужный RID. ВЫдается ошибка, что сессия уже используется.
	printf("Adding ace\n");
	BOOL				 bSuccess = FALSE;
	ACCESS_ALLOWED_ACE	*pAce = NULL;
	ACL_SIZE_INFORMATION aclSizeInfo;
	PACL				 pacl;
	PACL				 pNewAcl = NULL;
	PSECURITY_DESCRIPTOR psd = NULL;
	PSECURITY_DESCRIPTOR psdNew = NULL;
	PVOID				 pTemAce;
	SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
	DWORD				 dwSidSize = 0;
	DWORD				 dwSidSizeNeeded;
	DWORD				 dwNewAclSize;
	BOOL				 bDaclPresent;
	BOOL				 bDaclExist;
	
	__try{
		if (!GetUserObjectSecurity(
			_handle,
			&si,
			psd,
			dwSidSize,
			&dwSidSizeNeeded)
		)
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
			psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSidSizeNeeded);

			if (psd == NULL){
				printf("psd: %d\n",GetLastError());
				__leave;
			}

			psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSidSizeNeeded);

			if (psdNew == NULL){
				printf("psdNew : %d\n",GetLastError());
				__leave;
			}

			dwSidSize = dwSidSizeNeeded;

			if (!GetUserObjectSecurity(
				_handle,
				&si,
				psd,
				dwSidSize,
				&dwSidSizeNeeded)
			){
				printf("GetUserObjectSEcurity: %d\n",GetLastError());
				__leave;
			}
		}else{
			printf("Some thing else: %d\n",GetLastError());
			__leave;
		}
		

		if (!InitializeSecurityDescriptor(
			psdNew,
			SECURITY_DESCRIPTOR_REVISION)
		){
			printf("init secur descr: %d\n",GetLastError());
			__leave;
		}

		if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
		){
			printf("get dacl: %d\n",GetLastError());
			__leave;
		}

		ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
		aclSizeInfo.AclBytesInUse = sizeof(ACL);

		if (pacl != NULL){
			if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
			){
				printf("get acl info -size : %d\n",GetLastError());
				__leave;
			}
		}
		
		dwNewAclSize = aclSizeInfo.AclBytesInUse +
			(2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));
		pNewAcl = (PACL)HeapAlloc(
			GetProcessHeap(),
			HEAP_ZERO_MEMORY,
			dwNewAclSize);
		if (pNewAcl == NULL)
			__leave;
		if (!InitializeAcl(pNewAcl,dwNewAclSize,ACL_REVISION)){
			printf("init new acl : %d \n",GetLastError());
			__leave;
		}

		if (bDaclPresent){
         // Copy the ACEs to the new ACL.
			if (aclSizeInfo.AceCount){
				for (DWORD i=0; i < aclSizeInfo.AceCount; i++){
				// Get an ACE.
					if (!GetAce(pacl, i, &pTemAce))
						__leave;
					// Add the ACE to the new ACL.
					if (!AddAce(
					 pNewAcl,
				     ACL_REVISION,
                     MAXDWORD,
					 pTemAce,
					 ((PACE_HEADER)pTemAce)->AceSize)
					){
						printf("add ace in filling: %d",GetLastError());
						__leave;
					}
				}
			}
		}

		pAce = (ACCESS_ALLOWED_ACE *)HeapAlloc(
			GetProcessHeap(),
			HEAP_ZERO_MEMORY,
			sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD));
		if (pAce==NULL)
			__leave;

		pAce->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
		pAce->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
		pAce->Header.AceSize = LOWORD(sizeof(ACCESS_ALLOWED_ACE)+GetLengthSid(psid)-sizeof(DWORD));
		pAce->Mask = mask;
//		if(!CopySid(GetLengthSid(psid), &pAce->SidStart, psid)){ //official way to save sid in ace, but strange
//			printf("copy sid : %d\n",GetLastError());
//			__leave;
//		}
		pAce->SidStart = parseRID(psid);
		if(!AddAce(
			pNewAcl,
			ACL_REVISION,
			MAXDWORD,
			(LPVOID)pAce,
			pAce->Header.AceSize)
			)
		{
			printf("add new ace %d\n",GetLastError()); 
			__leave;
		}
		printf("WAIT!!! %d %u     %d\n",pAce->SidStart,pAce->Mask,parseRID(psid));
		if(!SetSecurityDescriptorDacl(
			psdNew,
			TRUE,
			pNewAcl,
			FALSE)
			)
		{
			printf("set dacl %d\n",GetLastError());
			__leave;
		}
		if(!SetKernelObjectSecurity(_handle,si,psdNew)){
			printf("set obj secur %d\n",GetLastError());
			__leave;
		}
		bSuccess = TRUE;		
		printf("Success. added %u for %d\n",pAce->Mask,pAce->SidStart);
	}
	__finally{
		if (pAce != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)pAce);

		if (pNewAcl != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

		if (psd != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

		if (psdNew != NULL)
			HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
	} 
	return bSuccess;
}
int _changeAccess(LPCTSTR lpServiceName){
	
	int returnValue = 0;
	
	SC_HANDLE schSCManager;
	SC_HANDLE schService;
	
	schSCManager = OpenSCManager(NULL,
								 SERVICES_ACTIVE_DATABASE, 
								 SC_MANAGER_ALL_ACCESS);
	
	if(!schSCManager){
		returnValue = GetLastError();
	}else{
		schService = OpenService(schSCManager, 
								 lpServiceName,  
								 READ_CONTROL|WRITE_DAC);
		
		if(!schService){	
			returnValue = GetLastError();
		}else{	
			
			PSECURITY_DESCRIPTOR psd = NULL;
			DWORD dwSize, dwBytesNeeded  = 0;
			
			if(!QueryServiceObjectSecurity(schService,
										   DACL_SECURITY_INFORMATION, 
										   &psd,           // using NULL does not work on all versions
										   0, 
										   &dwBytesNeeded)){
				
				dwSize = dwBytesNeeded;
				
				std::vector<unsigned int> buf(dwSize);
				
				psd = (PSECURITY_DESCRIPTOR)&buf[0];
				
				if(!QueryServiceObjectSecurity(schService,
											   DACL_SECURITY_INFORMATION, 
											   psd, 
											   dwSize, 
											   &dwBytesNeeded)){
					returnValue = GetLastError();
				}else{
					
					BOOL bDaclPresent = FALSE;
					PACL pacl = NULL;
					PACL pNewAcl = NULL;
					BOOL bDaclDefaulted = FALSE;
					
					if(!GetSecurityDescriptorDacl(psd, 
												  &bDaclPresent, 
												  &pacl,
												  &bDaclDefaulted)){
						returnValue = GetLastError();
					}else{
						EXPLICIT_ACCESS ea;
						
						BuildExplicitAccessWithName(&ea, 
													L"GUEST",
													SERVICE_START|SERVICE_STOP|
													SERVICE_CHANGE_CONFIG|SERVICE_QUERY_CONFIG|DELETE,
													SET_ACCESS, 
													NO_INHERITANCE);
						
						if(SetEntriesInAcl(1, &ea, pacl, &pNewAcl)!=ERROR_SUCCESS){
							returnValue = GetLastError();
						}else{
							SECURITY_DESCRIPTOR  sd;
							if(!InitializeSecurityDescriptor(&sd, 
															 SECURITY_DESCRIPTOR_REVISION)){
								returnValue = GetLastError();
							}else{
								if(SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)){
									if(!SetServiceObjectSecurity(schService, 
																 DACL_SECURITY_INFORMATION, 
																 &sd)){
										returnValue = GetLastError();	
									}
								}
							}
							LocalFree((HLOCAL)pNewAcl);
						}
					}
				}					
			}
			
			CloseServiceHandle(schService);	
			
		}
		
		CloseServiceHandle(schSCManager);	
		
	}	
	
	return returnValue;
}
Beispiel #15
0
//
// get_permissions:  1 = yes, 0 = no, -1 = unknown/error
//
int perm::get_permissions( const char *file_name, ACCESS_MASK &AccessRights ) {
	DWORD retVal;
	PACL pacl;
	
	PSECURITY_DESCRIPTOR pSD;
	DWORD pSD_length = 0;
	DWORD pSD_length_needed = 0;
	BOOL acl_present = FALSE;
	BOOL acl_defaulted = FALSE;
	
	// Do the call first to find out how much space is needed.
	
	pSD = NULL;
	
	GetFileSecurity(
		file_name,					// address of string for file name
		DACL_SECURITY_INFORMATION,	// requested information
		pSD,						// address of security descriptor
		pSD_length, 				// size of security descriptor buffer
		&pSD_length_needed			// address of required size of buffer
		);
	
	if( pSD_length_needed <= 0 ) {					// Find out how much space is needed, if <=0 then error
		if ( (GetLastError() == ERROR_FILE_NOT_FOUND) || 
			(GetLastError() == ERROR_PATH_NOT_FOUND) ) {
			
			// Here we have the tricky part of walking up the directory path
			// Typically it works like this:  If the filename exists, great, we'll
			//	 get the permissions on that.  If the filename does not exist, then
			//	 we pop the filename part off the file_name and look at the
			//	 directory.  If that directory should be (for some odd reason) non-
			//	 existant, then we just pop that off, until either we find something
			//	 thats will give us a permissions bitmask, or we run out of places
			//	 to look (which shouldn't happen since c:\ should always give us
			//	 SOMETHING...
			int i = strlen( file_name ) - 1;
			while ( i >= 0 && ( file_name[i] != '\\' && file_name[i] != '/' ) ) {
				i--;
			}
			if ( i < 0 ) {	// We've nowhere else to look, and this is bad.
				return -1;	// Its not a no, its an unknown
			}
			char *new_file_name = new char[i+1];
			strncpy(new_file_name, file_name, i);
			new_file_name[i]= '\0';
			
			// Now that we've chopped off more of the filename, call get_permissions
			// again...
			retVal = get_permissions( new_file_name, AccessRights );
			delete[] new_file_name;
			
			// ... and return what it returns. (after deleting the string that was
			// allocated.
			
			return retVal;
		}
		dprintf(D_ALWAYS, "perm::GetFileSecurity failed (err=%d)\n", GetLastError());
		return -1;
	}
	
	pSD_length = pSD_length_needed + 2; 	// Add 2 for safety.
	pSD_length_needed = 0;
	pSD = new BYTE[pSD_length];
	
	// Okay, now that we've found something, and know how large of an SD we need,
	// call the thing for real and lets get ON WITH IT ALREADY...
	
	if( !GetFileSecurity(
		file_name,					// address of string for file name
		DACL_SECURITY_INFORMATION,	// requested information
		pSD,						// address of security descriptor
		pSD_length, 				// size of security descriptor buffer
		&pSD_length_needed			// address of required size of buffer
		) ) {
		dprintf(D_ALWAYS, "perm::GetFileSecurity(%s) failed (err=%d)\n", file_name, GetLastError());
		delete[] pSD;
		return -1;
	}
	
	// Now, get the ACL from the security descriptor
	if( !GetSecurityDescriptorDacl(
		pSD,							// address of security descriptor
		&acl_present,					// address of flag for presence of disc. ACL
		&pacl,							// address of pointer to ACL
		&acl_defaulted					// address of flag for default disc. ACL
		) ) {
		dprintf(D_ALWAYS, "perm::GetSecurityDescriptorDacl failed (file=%s err=%d)\n", file_name, GetLastError());
		delete[] pSD;
		return -1;
	}
	
	// This is the workaround for the broken API GetEffectiveRightsFromAcl().
	// It should be guaranteed to work on all versions of NT and 2000 but be aware
	// that nested global group permissions are not supported.
	// C. Stolley - June 2001

	ACL_SIZE_INFORMATION acl_info;
		// Structure contains the following members:
		//  DWORD   AceCount; 
		//  DWORD   AclBytesInUse; 
		//  DWORD   AclBytesFree; 



	// first get the number of ACEs in the ACL
		if (! GetAclInformation( pacl,		// acl to get info from
								&acl_info,	// buffer to receive info
								sizeof(acl_info),  // size in bytes of buffer
								AclSizeInformation // class of info to retrieve
								) ) {
			dprintf(D_ALWAYS, "Perm::GetAclInformation failed with error %d\n", GetLastError() );
			return -1;
		}

		ACCESS_MASK allow = 0x0;
		ACCESS_MASK deny = 0x0;

		unsigned int aceCount = acl_info.AceCount;
		
		int result;
		
		// now look at each ACE in the ACL and see if it contains the user we're looking for
		for (unsigned int i=0; i < aceCount; i++) {
			LPVOID current_ace;

			if (! GetAce(	pacl,	// pointer to ACL 
							i,		// index of ACE we want
							&current_ace	// pointer to ACE
							) ) {
				dprintf(D_ALWAYS, "Perm::GetAce() failed! Error code %d\n", GetLastError() );
				return -1;
			}

			dprintf(D_FULLDEBUG, "Calling Perm::userInAce() for %s\\%s\n",
				   (Domain_name) ? Domain_name : "NULL",
				   (Account_name) ? Account_name : "NULL" );
			result = userInAce ( current_ace, Account_name, Domain_name );		
			
			if (result == 1) {
				switch ( ( (PACE_HEADER) current_ace)->AceType ) {				
				case ACCESS_ALLOWED_ACE_TYPE:
				case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
					allow |= ( (ACCESS_ALLOWED_ACE*) current_ace)->Mask;
					break;
				case ACCESS_DENIED_ACE_TYPE:
				case ACCESS_DENIED_OBJECT_ACE_TYPE:
					deny |= ( (ACCESS_DENIED_ACE*) current_ace)->Mask;
					break;
				}
			}
		}
		
		AccessRights = allow;
		AccessRights &= ~deny;

	// and now if we've made this far everything's happy so return true
	return 1;
}
Beispiel #16
0
/**
 * Sets the access control list for user access for the specified service.
 *
 * @param  hService  The service to set the access control list on
 * @param  pNewAcl   The out param ACL which should be freed by caller
 * @param  psd       out param security descriptor, should be freed by caller
 * @return ERROR_SUCCESS if successful
 */
DWORD
SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl, 
                         PSECURITY_DESCRIPTOR psd)
{
  // Get the current security descriptor needed size
  DWORD needed = 0;
  if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, 
                                  &psd, 0, &needed)) {
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
      LOG(("Warning: Could not query service object security size.  (%d)\n", 
           GetLastError()));
      return GetLastError();
    }

    DWORD size = needed;
    psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size);
    if (!psd) {
      LOG(("Warning: Could not allocate security descriptor.  (%d)\n", 
           GetLastError()));
      return ERROR_INSUFFICIENT_BUFFER;
    }

    // Get the actual security descriptor now
    if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, 
                                    psd, size, &needed)) {
      LOG(("Warning: Could not allocate security descriptor.  (%d)\n", 
           GetLastError()));
      return GetLastError();
    }
  }

  // Get the current DACL from the security descriptor.
  PACL pacl = NULL;
  BOOL bDaclPresent = FALSE;
  BOOL bDaclDefaulted = FALSE;
  if ( !GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, 
                                  &bDaclDefaulted)) {
    LOG(("Warning: Could not obtain DACL.  (%d)\n", GetLastError()));
    return GetLastError();
  }

  PSID sid;
  DWORD SIDSize = SECURITY_MAX_SID_SIZE;
  sid = LocalAlloc(LMEM_FIXED, SIDSize);
  if (!sid) {
    LOG(("Could not allocate SID memory.  (%d)\n", GetLastError()));
    return GetLastError();
  }

  if (!CreateWellKnownSid(WinBuiltinUsersSid, NULL, sid, &SIDSize)) {
    DWORD lastError = GetLastError();
    LOG(("Could not create well known SID.  (%d)\n", lastError));
    LocalFree(sid);
    return lastError;
  }

  // Lookup the account name, the function fails if you don't pass in
  // a buffer for the domain name but it's not used since we're using
  // the built in account Sid.
  SID_NAME_USE accountType;
  WCHAR accountName[UNLEN + 1] = { L'\0' };
  WCHAR domainName[DNLEN + 1] = { L'\0' };
  DWORD accountNameSize = UNLEN + 1;
  DWORD domainNameSize = DNLEN + 1;
  if (!LookupAccountSidW(NULL, sid, accountName, 
                         &accountNameSize, 
                         domainName, &domainNameSize, &accountType)) {
    LOG(("Warning: Could not lookup account Sid, will try Users.  (%d)\n",
         GetLastError()));
    wcsncpy(accountName, L"Users", UNLEN);
  }

  // We already have the group name so we can get rid of the SID
  FreeSid(sid);
  sid = NULL;

  // Build the ACE, BuildExplicitAccessWithName cannot fail so it is not logged.
  EXPLICIT_ACCESS ea;
  BuildExplicitAccessWithNameW(&ea, accountName, 
                              SERVICE_START | SERVICE_STOP | GENERIC_READ, 
                              SET_ACCESS, NO_INHERITANCE);
  DWORD lastError = SetEntriesInAclW(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl);
  if (ERROR_SUCCESS != lastError) {
    LOG(("Warning: Could not set entries in ACL.  (%d)\n", lastError));
    return lastError;
  }

  // Initialize a new security descriptor.
  SECURITY_DESCRIPTOR sd;
  if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
    LOG(("Warning: Could not initialize security descriptor.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Set the new DACL in the security descriptor.
  if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) {
    LOG(("Warning: Could not set security descriptor DACL.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Set the new security descriptor for the service object.
  if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd)) {
    LOG(("Warning: Could not set object security.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Woohoo, raise the roof
  LOG(("User access was set successfully on the service.\n"));
  return ERROR_SUCCESS;
}
Beispiel #17
0
/**
 * This function adjusts the specified Desktop to include the specfied
 *   user.
 *
 * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx
 **/
BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
{
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl = NULL;
   PACL                 pNewAcl = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   try
   {
      // Obtain the security descriptor for the desktop object.

      if (!GetUserObjectSecurity(
            hdesk,
            &si,
            psd,
            dwSidSize,
            &dwSdSizeNeeded))
      {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         {
            psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded );

            if (psd == NULL)
               throw;

            psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded);

            if (psdNew == NULL)
               throw;

            dwSidSize = dwSdSizeNeeded;

            if (!GetUserObjectSecurity(
                  hdesk,
                  &si,
                  psd,
                  dwSidSize,
                  &dwSdSizeNeeded)
            )
               throw;
         }
         else
            throw;
      }

      // Create a new security descriptor.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         throw;

      // Obtain the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         throw;

      // Initialize.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if NULL DACL.

      if (pacl != NULL)
      {
         // Determine the size of the ACL information.

         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            throw;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psid) - sizeof(DWORD);

      // Allocate buffer for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         throw;

      // Initialize the new ACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         throw;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  throw;

               // Add the ACE to the new ACL.
               if (!AddAce(
                  pNewAcl,
                  ACL_REVISION,
                  MAXDWORD,
                  pTempAce,
                  ((PACE_HEADER)pTempAce)->AceSize)
               )
                  throw;
            }
         }
      }

      // Add ACE to the DACL.

      if (!AddAccessAllowedAce(
            pNewAcl,
            ACL_REVISION,
            GENERIC_ALL,
            psid)
      )
         throw;

      // Set new DACL to the new security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         throw;

      // Set the new security descriptor for the desktop object.

      if (!SetUserObjectSecurity(hdesk, &si, psdNew))
         throw;

      // Indicate success.

      bSuccess = TRUE;
   }
   catch(...)
   {
      // Free buffers.

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;
}
void changeServiceAccess(const char* szName)
{
	gcAssert(szName);

	SC_HANDLE scm = nullptr;
	SC_HANDLE Service = nullptr;

	BOOL                 bDaclPresent   = FALSE;
	BOOL                 bDaclDefaulted = FALSE;
	DWORD                dwSize         = 0;
	EXPLICIT_ACCESS      ea;
	PACL                 pacl           = nullptr;
	PACL                 pNewAcl        = nullptr;
	PSECURITY_DESCRIPTOR psd            = nullptr;
	SECURITY_DESCRIPTOR  sd;


	//open connection to SCM
	scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);

	if (!scm)
		throw gcException(ERR_NULLSCMANAGER, GetLastError(), "Failed to open the Service Control Manager");

	gcWString wName(szName);

	try
	{
		//open service
		Service = OpenService(scm, wName.c_str(), READ_CONTROL|WRITE_DAC);
		if (!Service)
			throw gcException(ERR_NULLSERVICE, GetLastError(), gcString("Failed to open service: {0}", szName));


		// Get the current security descriptor.
		if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, 0, &dwSize))
		{
			if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
			{
				psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);

				if (!psd)
					throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName));

				//get securtty info
				if (!QueryServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize))
					throw gcException(ERR_SERVICE, GetLastError(), gcString("QueryServiceObjectSecurity failed for service: {0}", szName));
			}
		}

		if (!psd)
			throw gcException(ERR_SERVICE, gcString("Failed heap allocation for service service: {0}", szName));

		// Get the DACL.
		if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, &bDaclDefaulted))		
			throw gcException(ERR_SERVICE, GetLastError(), gcString("GetSecurityDescriptorDacl failed for service: {0}", szName));


		DWORD SidSize;
		PSID TheSID;

		SidSize = SECURITY_MAX_SID_SIZE;
		// Allocate enough memory for the largest possible SID.
		if(!(TheSID = LocalAlloc(LMEM_FIXED, SidSize)))
		{    
			LocalFree(TheSID);
			throw gcException(ERR_SERVICE, GetLastError(), gcString("LocalAlloc failed for  service: {0}", szName));
		}

		if(!CreateWellKnownSid(WinWorldSid, nullptr, TheSID, &SidSize))
		{
			LocalFree(TheSID);
			throw gcException(ERR_SERVICE, GetLastError(), gcString("CreateWellKnownSid failed for  service: {0}", szName));
		}

		wchar_t everyone[255];
		wchar_t domain[255];
		DWORD eSize = 255;
		DWORD dSize = 255;
		SID_NAME_USE rSidNameUse;

		if (!LookupAccountSid(nullptr, TheSID, everyone, &eSize, domain, &dSize, &rSidNameUse))
		{
			LocalFree(TheSID);
			throw gcException(ERR_SERVICE, GetLastError(), gcString("LookupAccountSid failed for  service: {0}", szName));
		}

		LocalFree(TheSID);

		// Build the ACE.
		BuildExplicitAccessWithName(&ea, everyone, SERVICE_START|SERVICE_STOP|READ_CONTROL|SERVICE_QUERY_STATUS|PROCESS_QUERY_INFORMATION, SET_ACCESS, NO_INHERITANCE);

		if (SetEntriesInAcl(1, &ea, pacl, &pNewAcl) != ERROR_SUCCESS)
		{
			throw gcException(ERR_SERVICE, GetLastError(), gcString("SetEntriesInAcl failed for  service: {0}", szName));
		}

		// Initialize a NEW Security Descriptor.
		if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))			
			throw gcException(ERR_SERVICE, GetLastError(), gcString("InitializeSecurityDescriptor failed for  service: {0}", szName));

		// Set the new DACL in the Security Descriptor.
		if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))						
			throw gcException(ERR_SERVICE, GetLastError(), gcString("SetSecurityDescriptorDacl failed for  service: {0}", szName));

		// Set the new DACL for the service object.
		if (!SetServiceObjectSecurity(Service, DACL_SECURITY_INFORMATION, &sd))		
			throw gcException(ERR_SERVICE, GetLastError(), gcString("SetServiceObjectSecurity failed for  service: {0}", szName));

	}
	catch (gcException &e)
	{
		if (Service)
			CloseServiceHandle(Service);

		if (scm)
			CloseServiceHandle(scm);

		// Free buffers.
		LocalFree((HLOCAL)pNewAcl);
		HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

		throw e;
	}

	CloseServiceHandle(scm);
	CloseServiceHandle(Service);

	// Free buffers.
	LocalFree((HLOCAL)pNewAcl);
	HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
}
/*---------------------------------------------------------------------------*\
 * 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;
}
BOOL RemoveAceFromDesktop(HDESK hdesk, PSID psid)
{
    // Obtain the security descriptor for the desktop object.
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    DWORD sd_size = 0;
    if (!GetUserObjectSecurity(hdesk, &si, NULL, 0, &sd_size)) {
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
            return FALSE;
         }
    }
    auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_size);
    if (!GetUserObjectSecurity(hdesk, &si, psd.get(), sd_size, &sd_size)) {
        printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Create a new security descriptor.
    auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_size);
    if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) {
        printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Obtain the DACL from the security descriptor.
    BOOL bDaclPresent;
    PACL pacl;
    BOOL bDaclExist;
    if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) {
        printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Initialize.
    ACL_SIZE_INFORMATION aclSizeInfo = {};
    aclSizeInfo.AclBytesInUse = sizeof(ACL);
    if (pacl != NULL) {
        // Determine the size of the ACL information.
        if (!GetAclInformation(pacl, (LPVOID)&aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) {
            printf("GetAclInformation() failed: %d\n", GetLastError());
            return FALSE;
        }
    }

    // Allocate buffer for the new ACL.
    DWORD dwNewAclSize = aclSizeInfo.AclBytesInUse -
                         (sizeof(ACCESS_ALLOWED_ACE) +
                          GetLengthSid(psid) - sizeof(DWORD));
    auto_buffer<PACL> new_acl(dwNewAclSize);

    // Initialize the new ACL.
    if (!InitializeAcl(new_acl.get(), dwNewAclSize, ACL_REVISION)) {
        printf("InitializeAcl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // If DACL is present, copy it to a new DACL.
    if (bDaclPresent) {
        // Copy the ACEs to the new ACL.
        for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) {
            // Get an ACE.
            ACCESS_ALLOWED_ACE* pace;
            if (!GetAce(pacl, i, (void**)&pace)) {
                printf("GetAce() failed: %d\n", GetLastError());
                return FALSE;
            }
            if (!EqualSid(psid, &pace->SidStart)) {
                // Add the ACE to the new ACL.
                if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, pace,
                            pace->Header.AceSize)) {
                    printf("AddAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
            }
        }
    }

    // Set new DACL to the new security descriptor.
    if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) {
        printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set the new security descriptor for the desktop object.
    if (!SetUserObjectSecurity(hdesk, &si, psd_new.get())) {
        printf("SetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }
    
    return TRUE;
}
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
    // Obtain the DACL for the window station.
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    DWORD sd_length = 0;
    if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
            return FALSE;
        }
    }
    auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length);
    if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) {
        printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Create a new DACL.
    auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length);
    if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) {
        printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Get the DACL from the security descriptor.
    BOOL bDaclPresent;
    PACL pacl;
    BOOL bDaclExist;
    if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) {
        printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }
    
    // Initialize the ACL.
    ACL_SIZE_INFORMATION aclSizeInfo = {};
    aclSizeInfo.AclBytesInUse = sizeof(ACL);
    if (NULL != pacl) {
        // get the file ACL size info
        if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) {
            printf("GetAclInformation() failed: %d\n", GetLastError());
            return FALSE;
        }
    }

    // Compute the size of the new ACL.
    DWORD new_acl_size = aclSizeInfo.AclBytesInUse +
                         (2 * sizeof(ACCESS_ALLOWED_ACE)) + 
                         (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD));
    auto_buffer<PACL> new_acl(new_acl_size);

    // Initialize the new DACL.
    if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) {
        printf("InitializeAcl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // If DACL is present, copy it to a new DACL.
    if (bDaclPresent) {
        // Copy the ACEs to the new ACL.
        if (aclSizeInfo.AceCount) {
            for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) {
                LPVOID pTempAce;
                if (!GetAce(pacl, i, &pTempAce)) {
                    printf("GetAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
                if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD,
                            pTempAce, ((PACE_HEADER)pTempAce)->AceSize)) {
                    printf("AddAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
            }
        }
    }

    // Add the first ACE to the window station.
    auto_buffer<ACCESS_ALLOWED_ACE*> ace(sizeof(ACCESS_ALLOWED_ACE) +
                                         GetLengthSid(psid) -
                                         sizeof(DWORD));
    ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
    ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
    ace->Header.AceSize = (WORD) (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD));
    ace->Mask = GENERIC_ACCESS;
    if (!CopySid(GetLengthSid(psid), &ace->SidStart, psid)) {
        printf("CopySid() failed: %d\n", GetLastError());
        return FALSE;
    }
    if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, ace.get(), ace->Header.AceSize)) {
        printf("AddAce() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Add the second ACE to the window station.
    ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
    ace->Mask = WINSTA_ALL;
    if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, ace.get(), ace->Header.AceSize)) {
        printf("AddAce() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set a new DACL for the security descriptor.
    if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) {
        printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set the new security descriptor for the window station.
    if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) {
        printf("SetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    return TRUE;
}
Beispiel #22
0
HRESULT COpcSecurity::Attach(PSECURITY_DESCRIPTOR pSelfRelativeSD)
{
	PACL    pDACL = NULL;
	PACL    pSACL = NULL;
	BOOL    bDACLPresent, bSACLPresent;
	BOOL    bDefaulted;
	PACL    m_pDACL = NULL;
	ACCESS_ALLOWED_ACE* pACE;
	HRESULT hr;
	PSID    pUserSid;
	PSID    pGroupSid;

	hr = Initialize();
	if(FAILED(hr))
		return hr;

	// get the existing DACL.
	if (!GetSecurityDescriptorDacl(pSelfRelativeSD, &bDACLPresent, &pDACL, &bDefaulted))
		goto failed;

	if (bDACLPresent)
	{
		if (pDACL)
		{
			// allocate new DACL.
			m_pDACL = (PACL) malloc(pDACL->AclSize);
			if (m_pDACL == NULL)
			{
				hr = E_OUTOFMEMORY;
				goto failedMemory;
			}

			// initialize the DACL
			if (!InitializeAcl(m_pDACL, pDACL->AclSize, ACL_REVISION))
				goto failed;

			// copy the ACES
			for (int i = 0; i < pDACL->AceCount; i++)
			{
				if (!GetAce(pDACL, i, (void **)&pACE))
					goto failed;

				if (!AddAccessAllowedAce(m_pDACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
					goto failed;
			}

			if (!IsValidAcl(m_pDACL))
				goto failed;
		}

		// set the DACL
		if (!SetSecurityDescriptorDacl(m_pSD, m_pDACL ? TRUE : FALSE, m_pDACL, bDefaulted))
			goto failed;
	}

	// get the existing SACL.
	if (!GetSecurityDescriptorSacl(pSelfRelativeSD, &bSACLPresent, &pSACL, &bDefaulted))
		goto failed;

	if (bSACLPresent)
	{
		if (pSACL)
		{
			// allocate new SACL.
			m_pSACL = (PACL) malloc(pSACL->AclSize);
			if (m_pSACL == NULL)
			{
				hr = E_OUTOFMEMORY;
				goto failedMemory;
			}

			// initialize the SACL
			if (!InitializeAcl(m_pSACL, pSACL->AclSize, ACL_REVISION))
				goto failed;

			// copy the ACES
			for (int i = 0; i < pSACL->AceCount; i++)
			{
				if (!GetAce(pSACL, i, (void **)&pACE))
					goto failed;

				if (!AddAccessAllowedAce(m_pSACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart)))
					goto failed;
			}

			if (!IsValidAcl(m_pSACL))
				goto failed;
		}

		// set the SACL
		if (!SetSecurityDescriptorSacl(m_pSD, m_pSACL ? TRUE : FALSE, m_pSACL, bDefaulted))
			goto failed;
	}

	if (!GetSecurityDescriptorOwner(m_pSD, &pUserSid, &bDefaulted))
		goto failed;

	if (FAILED(SetOwner(pUserSid, bDefaulted)))
		goto failed;

	if (!GetSecurityDescriptorGroup(m_pSD, &pGroupSid, &bDefaulted))
		goto failed;

	if (FAILED(SetGroup(pGroupSid, bDefaulted)))
		goto failed;

	if (!IsValidSecurityDescriptor(m_pSD))
		goto failed;

	return hr;

failed:
	hr = HRESULT_FROM_WIN32(hr);

failedMemory:
	if (m_pDACL)
	{
		free(m_pDACL);
		m_pDACL = NULL;
	}
	if (m_pSD)
	{
		free(m_pSD);
		m_pSD = NULL;
	}
	return hr;
}
BOOL RemoveAceFromWindowStation(HWINSTA hwinsta, PSID psid)
{
    // Obtain the DACL for the window station.
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    DWORD sd_length = 0;
    if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
            return FALSE;
        }
    }
    auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length);
    if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) {
        printf("GetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Create a new DACL.
    auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length);
    if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) {
        printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Get the DACL from the security descriptor.
    BOOL bDaclPresent;
    PACL pacl;
    BOOL bDaclExist;
    if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) {
        printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }
    
    // Initialize the ACL.
    ACL_SIZE_INFORMATION aclSizeInfo = {};
    aclSizeInfo.AclBytesInUse = sizeof(ACL);
    if (NULL != pacl) {
        // get the file ACL size info
        if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) {
            printf("GetAclInformation() failed: %d\n", GetLastError());
            return FALSE;
        }
    }

    // Compute the size of the new ACL.
    DWORD new_acl_size = aclSizeInfo.AclBytesInUse -
                         ((2 * sizeof(ACCESS_ALLOWED_ACE)) + 
                          (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD)));
    auto_buffer<PACL> new_acl(new_acl_size);

    // Initialize the new DACL.
    if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) {
        printf("InitializeAcl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // If DACL is present, copy it to a new DACL.
    if (bDaclPresent) {
        // Copy the ACEs to the new ACL.
        for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) {
            ACCESS_ALLOWED_ACE* pace;
            if (!GetAce(pacl, i, (void**)&pace)) {
                printf("GetAce() failed: %d\n", GetLastError());
                return FALSE;
            }
            if (!EqualSid(psid, &pace->SidStart)) {
                if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD,
                            pace, pace->Header.AceSize)) {
                    printf("AddAce() failed: %d\n", GetLastError());
                    return FALSE;
                }
            }
        }
    }

    // Set a new DACL for the security descriptor.
    if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) {
        printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError());
        return FALSE;
    }

    // Set the new security descriptor for the window station.
    if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) {
        printf("SetUserObjectSecurity() failed: %d\n", GetLastError());
        return FALSE;
    }

    return TRUE;
}
/*---------------------------------------------------------------------------*\
 * NAME: UpdatePrincipalInNamedValueSD 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Retrieves the designated security descriptor from the
 * registry and updates all ACLs that belong to the named principal.
\*---------------------------------------------------------------------------*/
DWORD UpdatePrincipalInNamedValueSD (
    HKEY hkeyRoot,
    LPTSTR tszKeyName,
    LPTSTR tszValueName,
    LPTSTR tszPrincipal,
    DWORD dwAccessMask,
    BOOL fRemove,
    DWORD fAceType
    )
{
    DWORD               dwReturnValue    = ERROR_SUCCESS;
    SECURITY_DESCRIPTOR *pSD             = NULL;
    SECURITY_DESCRIPTOR *psdSelfRelative = NULL;
    SECURITY_DESCRIPTOR *psdAbsolute     = NULL;
    DWORD               cbSecurityDesc   = 0;
    BOOL                fPresent         = FALSE;
    BOOL                fDefaultDACL     = FALSE;
    PACL                pDacl            = NULL;


    // Get security descriptor from registry
    dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, NULL);


    if (dwReturnValue != ERROR_SUCCESS)
    {
        if(dwReturnValue == ERROR_FILE_NOT_FOUND && fRemove)
        {
            dwReturnValue = ERROR_SUCCESS;
        }
        goto CLEANUP;
    }

    if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Update the tszPrincipal that the caller wants to change
    dwReturnValue = UpdatePrincipalInACL (pDacl, tszPrincipal, dwAccessMask, fRemove, fAceType);
    if(dwReturnValue == ERROR_FILE_NOT_FOUND)
    {
        dwReturnValue = ERROR_SUCCESS;
        goto CLEANUP;
    }
    else if (dwReturnValue != ERROR_SUCCESS)
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Make the security descriptor absolute 
    dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute); 
    if (dwReturnValue != ERROR_SUCCESS)  goto CLEANUP;

    // Set the discretionary ACL on the security descriptor
    if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    //Now ensure consistency of the SD
    dwReturnValue = CanonicalizeSD(psdAbsolute);
    if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP;

    // Make the security descriptor self-relative so that we can
    // store it in the registry
    cbSecurityDesc = 0;
    MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc);

    psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc);


    if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Store the security descriptor in the registry
    dwReturnValue = SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative);

CLEANUP:

    if(pSD) free (pSD);
    if(psdSelfRelative) free (psdSelfRelative);
    if(psdAbsolute) free (psdAbsolute);

    return dwReturnValue;
}
/*---------------------------------------------------------------------------*\
 * NAME: RemovePrincipalFromNamedValueSD 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Retrieves the designated security descriptor from the
 * registry and removes all ACLs that belong to the named principal.
\*---------------------------------------------------------------------------*/
DWORD RemovePrincipalFromNamedValueSD (
    HKEY hkeyRoot,
    LPTSTR tszKeyName,
    LPTSTR tszValueName,
    LPTSTR tszPrincipal,
    DWORD fAceType
    )
{
    DWORD               dwReturnValue    = ERROR_SUCCESS;
    SECURITY_DESCRIPTOR *pSD             = NULL;
    SECURITY_DESCRIPTOR *psdSelfRelative = NULL;
    SECURITY_DESCRIPTOR *psdAbsolute     = NULL;
    DWORD               cbSecurityDesc   = 0;
    BOOL                fPresent         = FALSE;
    BOOL                fDefaultDACL     = FALSE;
    PACL                pDacl            = NULL;

    dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, NULL);

    // Get security descriptor from registry or create a new one
    if (dwReturnValue != ERROR_SUCCESS)
    {
        if(dwReturnValue == ERROR_FILE_NOT_FOUND)
        {
            dwReturnValue = ERROR_SUCCESS;
        }
        goto CLEANUP;
    }

    if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Remove the tszPrincipal that the caller wants removed
    dwReturnValue = RemovePrincipalFromACL (pDacl, tszPrincipal, fAceType);
    if(dwReturnValue == ERROR_FILE_NOT_FOUND)
    {
        dwReturnValue = ERROR_SUCCESS;
        goto CLEANUP;
    }
    else if (dwReturnValue != ERROR_SUCCESS)
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Make the security descriptor absolute if it isn't new
    dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute); 
    if (dwReturnValue != ERROR_SUCCESS)  goto CLEANUP;

    // Set the discretionary ACL on the security descriptor
    if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Make the security descriptor self-relative so that we can
    // store it in the registry
    cbSecurityDesc = 0;
    MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc);

    psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc);


    if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Store the security descriptor in the registry
    dwReturnValue = SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative);

CLEANUP:

    if(pSD) free (pSD);
    if(psdSelfRelative) free (psdSelfRelative);
    if(psdAbsolute) free (psdAbsolute);

    return dwReturnValue;
}
/*---------------------------------------------------------------------------*\
 * NAME: AddPrincipalToNamedValueSD 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Retrieves the designated security descriptor from the
 * registry and adds an ACE for the designated principal.
\*---------------------------------------------------------------------------*/
DWORD AddPrincipalToNamedValueSD (
    HKEY hkeyRoot,
    LPTSTR tszKeyName,
    LPTSTR tszValueName,
    LPTSTR tszPrincipal,
    BOOL fPermit,
    DWORD dwAccessMask,
    DWORD dwSDType
    )
{
    DWORD               dwReturnValue    = ERROR_SUCCESS;
    SECURITY_DESCRIPTOR *pSD             = NULL;
    SECURITY_DESCRIPTOR *psdSelfRelative = NULL;
    SECURITY_DESCRIPTOR *psdAbsolute     = NULL;
    DWORD               cbSecurityDesc   = 0;
    BOOL                fPresent         = FALSE;
    BOOL                fDefaultDACL     = FALSE;
    PACL                pDacl            = NULL;
    BOOL                fNewSD           = FALSE;

    dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, &fNewSD);

    // Get security descriptor from registry or create a new one
    if (dwReturnValue != ERROR_SUCCESS)  goto CLEANUP;

    if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    if (fNewSD)
    {
        dwReturnValue = SetAclDefaults(&pDacl, dwSDType);
        if (dwReturnValue != ERROR_SUCCESS)  goto CLEANUP;
    }

    // Add the tszPrincipal that the caller wants added
    if (fPermit)
    {
        dwReturnValue = AddAccessAllowedACEToACL (&pDacl, dwAccessMask, tszPrincipal);
    }
    else
    {
        dwReturnValue = AddAccessDeniedACEToACL (&pDacl, dwAccessMask, tszPrincipal);
    }

    if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP;

    // Make the security descriptor absolute if it isn't new
    if (!fNewSD)
    {
        dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute);
        if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP;
    }
    else
    {
        psdAbsolute = pSD;
    }

    // Set the discretionary ACL on the security descriptor
    if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
     }

    //Now ensure consistency of the SD
    dwReturnValue = CanonicalizeSD(psdAbsolute);
    if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP;

    // Make the security descriptor self-relative so that we can
    // store it in the registry
    cbSecurityDesc = 0;

    MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc);

    psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc);

    if(!psdSelfRelative)
    {
        dwReturnValue = ERROR_OUTOFMEMORY;
        goto CLEANUP;
    }

    if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Store the security descriptor in the registry
    SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative);

CLEANUP:

    if(pSD) free (pSD);
    if(psdSelfRelative) free (psdSelfRelative);
    if(psdAbsolute && pSD != psdAbsolute) free (psdAbsolute);

    return dwReturnValue;
}
/*---------------------------------------------------------------------------*\
 * NAME: MakeSDAbsolute 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Takes a self-relative security descriptor and returns a
 * newly created absolute security descriptor.
\*---------------------------------------------------------------------------*/
DWORD MakeSDAbsolute (
    PSECURITY_DESCRIPTOR psidOld,
    PSECURITY_DESCRIPTOR *psidNew
    )
{
    PSECURITY_DESCRIPTOR  pSid           = NULL;
    DWORD                 cbDescriptor   = 0;
    DWORD                 cbDacl         = 0;
    DWORD                 cbSacl         = 0;
    DWORD                 cbOwnerSID     = 0;
    DWORD                 cbGroupSID     = 0;
    PACL                  pDacl          = NULL;
    PACL                  pSacl          = NULL;
    PSID                  psidOwner      = NULL;
    PSID                  psidGroup      = NULL;
    BOOL                  fPresent       = FALSE;
    BOOL                  fSystemDefault = FALSE;
    DWORD                 dwReturnValue  = ERROR_SUCCESS;

    // Get SACL
    if (!GetSecurityDescriptorSacl (psidOld, &fPresent, &pSacl, &fSystemDefault))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    if (pSacl && fPresent)
    {
        cbSacl = pSacl->AclSize;
    } 

    // Get DACL
    if (!GetSecurityDescriptorDacl (psidOld, &fPresent, &pDacl, &fSystemDefault))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    if (pDacl && fPresent)
    {
        cbDacl = pDacl->AclSize;
    } 

    // Get Owner
    if (!GetSecurityDescriptorOwner (psidOld, &psidOwner, &fSystemDefault))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    cbOwnerSID = GetLengthSid (psidOwner);

    // Get Group
    if (!GetSecurityDescriptorGroup (psidOld, &psidGroup, &fSystemDefault))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    cbGroupSID = GetLengthSid (psidGroup);

    // Do the conversion
    cbDescriptor = 0;

    MakeAbsoluteSD (psidOld, pSid, &cbDescriptor, pDacl, &cbDacl, pSacl,
                    &cbSacl, psidOwner, &cbOwnerSID, psidGroup,
                    &cbGroupSID);

    pSid = (PSECURITY_DESCRIPTOR) malloc(cbDescriptor);
    if(!pSid)
    {
        dwReturnValue = ERROR_OUTOFMEMORY;
        goto CLEANUP;
    }

    ZeroMemory(pSid, cbDescriptor);
    
    if (!InitializeSecurityDescriptor (pSid, SECURITY_DESCRIPTOR_REVISION))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    if (!MakeAbsoluteSD (psidOld, pSid, &cbDescriptor, pDacl, &cbDacl, pSacl,
                         &cbSacl, psidOwner, &cbOwnerSID, psidGroup,
                         &cbGroupSID))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

CLEANUP:

    if(dwReturnValue != ERROR_SUCCESS && pSid)
    {
        free(pSid);
        pSid = NULL;
    }

    *psidNew = pSid;

    return dwReturnValue;
}
Beispiel #28
0
// https://ru.wikipedia.org/wiki/DACL + https://github.com/hfiref0x/WinObjEx64/tree/master/Source
BOOL AddAllowSidForDevice(PWCHAR wchPath, PSID lpSid, DWORD dwSidLength) {
	OBJECT_ATTRIBUTES ObjAtt;
	RtlZeroMemory(&ObjAtt, sizeof(ObjAtt));

	UNICODE_STRING UserModeDeviceName;

	WCHAR PathBuffer[MAX_PATH] = { 0 };

	wcscpy_s(PathBuffer, L"\\??\\");
	wcscat_s(PathBuffer, wchPath);

	UserModeDeviceName.Buffer = PathBuffer;
	UserModeDeviceName.Length = (USHORT)(wcslen(PathBuffer) * sizeof(WCHAR));
	UserModeDeviceName.MaximumLength = (USHORT)(UserModeDeviceName.Length + sizeof(WCHAR));
	InitializeObjectAttributes(&ObjAtt, &UserModeDeviceName, 0, 0, 0);

	HANDLE hFile;
	IO_STATUS_BLOCK IoStatusBlock;
	NTSTATUS status = ntdll_ZwOpenFile(&hFile, WRITE_DAC | READ_CONTROL, &ObjAtt, &IoStatusBlock, 0, 0);
	if (status != STATUS_SUCCESS) {
		DebugOut("ZwOpenFile(..., %S,...) failed! (status=%x)\n", wchPath, status);
		return FALSE;
	}

	DWORD LastError;
	SECURITY_DESCRIPTOR *lpSd = NULL;	// адрес дескриптора безопасности
	DWORD dwSdLength = 0;				// длина SD
	if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, NULL, dwSdLength, &dwSdLength)) {
		LastError = GetLastError();
		if (LastError == ERROR_INSUFFICIENT_BUFFER) {
			dwSdLength += 1000; // !! FIX_ME
			lpSd = (SECURITY_DESCRIPTOR*)malloc(dwSdLength);
			if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, lpSd, dwSdLength, &dwSdLength)) {
				DebugOut("GetKernelObjectSecurity[2](...) failed! (LastError=0x%x)\n", GetLastError());
				CloseHandle(hFile);
				return FALSE;
			}
		} else {
			DebugOut("GetKernelObjectSecurity[1](...) failed! (LastError=0x%x)\n", LastError);
			CloseHandle(hFile);
			return FALSE;
		}
	}
	ACL* lpOldDacl;						// указатель на старый DACL
	BOOL bDaclPresent;					// признак присутствия списка DACL
	BOOL bDaclDefaulted;				// признак списка DACL по умолчанию
	if (!GetSecurityDescriptorDacl(lpSd, &bDaclPresent, &lpOldDacl, &bDaclDefaulted)) { // получаем список DACL из дескриптора безопасности
		DebugOut("GetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError());
		CloseHandle(hFile);
		return FALSE;
	}
	DWORD dwDaclLength = lpOldDacl->AclSize + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + dwSidLength; // определяем длину нового DACL
	ACL* lpNewDacl = (ACL*)malloc(dwDaclLength);
	if (!InitializeAcl(lpNewDacl, dwDaclLength, ACL_REVISION)) { // инициализируем новый DACL
		DebugOut("InitializeAcl(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	if (!AddAccessAllowedAce(lpNewDacl, ACL_REVISION,ACCOUNT_ALLOW_RIGHTS, lpSid)) { // добавляем новый элемент в новый DACL
		DebugOut("AddAccessAllowedAce(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	LPVOID lpAce;						// указатель на элемент ACE
	if (!GetAce(lpOldDacl, 0, &lpAce)) { // получаем адрес первого ACE в старом списке DACL
		DebugOut("GetAce(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	// переписываем элементы из старого DACL в новый DACL
	if (bDaclPresent) {
		if (!AddAce(lpNewDacl, ACL_REVISION, MAXDWORD, lpAce, lpOldDacl->AclSize - sizeof(ACL))) {
			DebugOut("AddAce(...) failed! (LastError=0x%x)\n", GetLastError());
			free(lpNewDacl);
			CloseHandle(hFile);
			return FALSE;
		}
	}
	if (!IsValidAcl(lpNewDacl)) { // проверяем достоверность DACL
		DebugOut("IsValidAcl(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	SECURITY_DESCRIPTOR sdAbsoluteSd;	// абсолютный формат SD
	if (!InitializeSecurityDescriptor(&sdAbsoluteSd, SECURITY_DESCRIPTOR_REVISION)) { // создаем новый дескриптор безопасности в абсолютной форме
		DebugOut("InitializeSecurityDescriptor(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	if (!SetSecurityDescriptorDacl(&sdAbsoluteSd, TRUE, lpNewDacl, FALSE)) { // устанавливаем DACL  в новый дескриптор безопасности
		DebugOut("SetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}

	// проверяем структуру дескриптора безопасности
	if (!IsValidSecurityDescriptor(&sdAbsoluteSd)) {
		DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	
	if (!SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, &sdAbsoluteSd)) { // устанавливаем новый дескриптор безопасности
		DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	free(lpNewDacl);
	CloseHandle(hFile);

	DebugOut("ACL Rules applyed to \"%S\"\n", PathBuffer);

	return TRUE;
}
Beispiel #29
-1
static int
TestplatformChmod(
    const char *nativePath,
    int pmode)
{
    static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION
	    | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
    static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE
	    | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA
	    | FILE_WRITE_DATA | DELETE;

    /*
     * References to security functions (only available on NT and later).
     */

    const BOOL set_readOnly = !(pmode & 0222);
    BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted;
    SID_IDENTIFIER_AUTHORITY userSidAuthority = {
	SECURITY_WORLD_SID_AUTHORITY
    };
    BYTE *secDesc = 0;
    DWORD secDescLen, attr, newAclSize;
    ACL_SIZE_INFORMATION ACLSize;
    PACL curAcl, newAcl = 0;
    WORD j;
    SID *userSid = 0;
    char *userDomain = 0;
    int res = 0;

    /*
     * Process the chmod request.
     */

    attr = GetFileAttributesA(nativePath);

    /*
     * nativePath not found
     */

    if (attr == 0xffffffff) {
	res = -1;
	goto done;
    }

    /*
     * If nativePath is not a directory, there is no special handling.
     */

    if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
	goto done;
    }

    /*
     * Set the result to error, if the ACL change is successful it will be
     * reset to 0.
     */

    res = -1;

    /*
     * Read the security descriptor for the directory. Note the first call
     * obtains the size of the security descriptor.
     */

    if (!GetFileSecurityA(nativePath, infoBits, NULL, 0, &secDescLen)) {
	DWORD secDescLen2 = 0;

	if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
	    goto done;
	}

	secDesc = (BYTE *) ckalloc(secDescLen);
	if (!GetFileSecurityA(nativePath, infoBits,
		(PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2)
		|| (secDescLen < secDescLen2)) {
	    goto done;
	}
    }

    /*
     * Get the World SID.
     */

    userSid = (SID *) ckalloc(GetSidLengthRequired((UCHAR) 1));
    InitializeSid(userSid, &userSidAuthority, (BYTE) 1);
    *(GetSidSubAuthority(userSid, 0)) = SECURITY_WORLD_RID;

    /*
     * If curAclPresent == false then curAcl and curAclDefaulted not valid.
     */

    if (!GetSecurityDescriptorDacl((PSECURITY_DESCRIPTOR) secDesc,
	    &curAclPresent, &curAcl, &curAclDefaulted)) {
	goto done;
    }
    if (!curAclPresent || !curAcl) {
	ACLSize.AclBytesInUse = 0;
	ACLSize.AceCount = 0;
    } else if (!GetAclInformation(curAcl, &ACLSize, sizeof(ACLSize),
	    AclSizeInformation)) {
	goto done;
    }

    /*
     * Allocate memory for the new ACL.
     */

    newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE)
	    + GetLengthSid(userSid) - sizeof(DWORD);
    newAcl = (ACL *) ckalloc(newAclSize);

    /*
     * Initialize the new ACL.
     */

    if (!InitializeAcl(newAcl, newAclSize, ACL_REVISION)) {
	goto done;
    }

    /*
     * Add denied to make readonly, this will be known as a "read-only tag".
     */

    if (set_readOnly && !AddAccessDeniedAce(newAcl, ACL_REVISION,
	    readOnlyMask, userSid)) {
	goto done;
    }

    acl_readOnly_found = FALSE;
    for (j = 0; j < ACLSize.AceCount; j++) {
	LPVOID pACE2;
	ACE_HEADER *phACE2;

	if (!GetAce(curAcl, j, &pACE2)) {
	    goto done;
	}

	phACE2 = (ACE_HEADER *) pACE2;

	/*
	 * Do NOT propagate inherited ACEs.
	 */

	if (phACE2->AceFlags & INHERITED_ACE) {
	    continue;
	}

	/*
	 * Skip the "read-only tag" restriction (either added above, or it is
	 * being removed).
	 */

	if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) {
	    ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2;

	    if (pACEd->Mask == readOnlyMask
		    && EqualSid(userSid, (PSID) &pACEd->SidStart)) {
		acl_readOnly_found = TRUE;
		continue;
	    }
	}

	/*
	 * Copy the current ACE from the old to the new ACL.
	 */

	if (!AddAce(newAcl, ACL_REVISION, MAXDWORD, (PACL *) pACE2,
		((PACE_HEADER) pACE2)->AceSize)) {
	    goto done;
	}
    }

    /*
     * Apply the new ACL.
     */

    if (set_readOnly == acl_readOnly_found || SetNamedSecurityInfoA(
	    (LPSTR) nativePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
	    NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) {
	res = 0;
    }

  done:
    if (secDesc) {
	ckfree((char *) secDesc);
    }
    if (newAcl) {
	ckfree((char *) newAcl);
    }
    if (userSid) {
	ckfree((char *) userSid);
    }
    if (userDomain) {
	ckfree((char *) userDomain);
    }

    if (res != 0) {
	return res;
    }

    /*
     * Run normal chmod command.
     */

    return chmod(nativePath, pmode);
}
HRESULT CSecurityInformation::SetSecurity(
			SECURITY_INFORMATION SecurityInformation,
			PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
	HRESULT hr = 1;

	// Get the Dacl
	PACL pDACL = NULL;
	BOOL fPresent, fDefaulted;
	GetSecurityDescriptorDacl(pSecurityDescriptor, &fPresent, &pDACL, &fDefaulted);

	// Get the SACL
	PACL pSACL = NULL;
	GetSecurityDescriptorSacl(pSecurityDescriptor, &fPresent, &pSACL, &fDefaulted);

	// Get the owner
	PSID psidOwner = NULL;
	GetSecurityDescriptorOwner(pSecurityDescriptor, &psidOwner, &fDefaulted);

	// Get the group
	PSID psidGroup = NULL;
	GetSecurityDescriptorOwner(pSecurityDescriptor, &psidGroup, &fDefaulted);

	// Find out if DACL and SACL inherit from parent objects
	SECURITY_DESCRIPTOR_CONTROL sdCtrl = NULL;
	ULONG ulRevision;
	GetSecurityDescriptorControl(pSecurityDescriptor, &sdCtrl, &ulRevision);

	if ((sdCtrl & SE_DACL_PROTECTED) != SE_DACL_PROTECTED)
		SecurityInformation  |= UNPROTECTED_DACL_SECURITY_INFORMATION;
	else
		SecurityInformation  |= PROTECTED_DACL_SECURITY_INFORMATION;

	if ((sdCtrl & SE_SACL_PROTECTED) != SE_SACL_PROTECTED)
		SecurityInformation  |= UNPROTECTED_SACL_SECURITY_INFORMATION;
	else
		SecurityInformation  |= PROTECTED_SACL_SECURITY_INFORMATION;

	// Set the security
	ULONG lErr;
	if (m_Info.m_szName[0] != 0) // Is it named
	{
		lErr = SetNamedSecurityInfo(m_Info.m_szName, 
					m_Type.m_objSecurType, SecurityInformation, psidOwner, 
					psidGroup, pDACL, pSACL);
	}
	else
	{
		// Is it a handle case
		lErr = SetSecurityInfo(m_Info.m_hHandle, m_Type.m_objSecurType,
					SecurityInformation, psidOwner, psidGroup, pDACL, pSACL);
	}

	// Report error
	if (lErr != ERROR_SUCCESS)
	{
		MessageBox(NULL,
			TEXT("An error occurred saving security information for this object,\n")
			TEXT("possibly due to insufficient access rights.\n"),
			TEXT("Security Notice"), MB_OK);
	}
	else
	{
		hr = S_OK;
	}

	return(hr);
}