Пример #1
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;
}
Пример #2
0
static int DOKAN_CALLBACK
MirrorGetFileSecurity(
	LPCWSTR					FileName,
	PSECURITY_INFORMATION	SecurityInformation,
	PSECURITY_DESCRIPTOR	SecurityDescriptor,
	ULONG				BufferLength,
	PULONG				LengthNeeded,
	PDOKAN_FILE_INFO	DokanFileInfo)
{
	HANDLE	handle;
	WCHAR	filePath[MAX_PATH];

	GetFilePath(filePath, MAX_PATH, FileName);

	DbgPrint(L"GetFileSecurity %s\n", filePath);

	handle = (HANDLE)DokanFileInfo->Context;
	if (!handle || handle == INVALID_HANDLE_VALUE) {
		DbgPrint(L"\tinvalid handle\n\n");
		return -1;
	}

	if (!GetUserObjectSecurity(handle, SecurityInformation, SecurityDescriptor,
			BufferLength, LengthNeeded)) {
		int error = GetLastError();
		if (error == ERROR_INSUFFICIENT_BUFFER) {
			DbgPrint(L"  GetUserObjectSecurity failed: ERROR_INSUFFICIENT_BUFFER\n");
			return error * -1;
		} else {
			DbgPrint(L"  GetUserObjectSecurity failed: %d\n", error);
			return -1;
		}
	}
	return 0;
}
Пример #3
0
int backupsec(HANDLE h, const char *f)
{
	PSECURITY_DESCRIPTOR sec;
	SECURITY_INFORMATION inf;
	DWORD rv;
	int r;

	if (!security_vbs) return 1;

	rv = 0;
#define ALL_SECURITY	DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION \
			| GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION
	inf = ALL_SECURITY;
	if (!GetUserObjectSecurity(h,
				&inf,
				(PSECURITY_DESCRIPTOR)buffer,
				sizeof(buffer),
				&rv)) {
		if (rv >= sizeof(buffer)) {
			sec = malloc(rv+64);
			inf = ALL_SECURITY;
			if (!GetUserObjectSecurity(h, &inf, sec, rv+64, &rv)) {
				win32_perror(f);
				set_backup_privs(0);
				if (s_flag) return 0;
			}
		} else {
			win32_perror(f);
			set_backup_privs(0);
			if (s_flag) return 0;
			return 1;
		}
		r = acprint(security_vbs, sec, f);
		free(sec);
	} else {
		r = acprint(security_vbs, (PSECURITY_DESCRIPTOR)buffer, f);
	}

	return r;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
static int
_win32_create_temp_file(_zip_source_win32_read_file_t *ctx)
{
    zip_uint32_t value;
    /*
    Windows has GetTempFileName(), but it closes the file after
    creation, leaving it open to a horrible race condition. So
    we reinvent the wheel.
    */
    int i;
    HANDLE th = INVALID_HANDLE_VALUE;
    void *temp = NULL;
    SECURITY_INFORMATION si;
    SECURITY_ATTRIBUTES sa;
    PSECURITY_DESCRIPTOR psd = NULL;
    PSECURITY_ATTRIBUTES psa = NULL;
    DWORD len;
    BOOL success;

    /*
    Read the DACL from the original file, so we can copy it to the temp file.
    If there is no original file, or if we can't read the DACL, we'll use the
    default security descriptor.
    */
    if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
	si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
	len = 0;
	success = GetUserObjectSecurity(ctx->h, &si, NULL, len, &len);
	if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
	    if ((psd = (PSECURITY_DESCRIPTOR)malloc(len)) == NULL) {
		zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
		return -1;
	    }
	    success = GetUserObjectSecurity(ctx->h, &si, psd, len, &len);
	}
	if (success) {
	    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	    sa.bInheritHandle = FALSE;
	    sa.lpSecurityDescriptor = psd;
	    psa = &sa;
	}
    }

    value = GetTickCount();
    for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
	th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
	if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
	    break;
    }

    if (th == INVALID_HANDLE_VALUE) {
	free(temp);
	free(psd);
	zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
	return -1;
    }

    free(psd);
    ctx->hout = th;
    ctx->tmpname = temp;

    return 0;
}
Пример #8
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;
}
Пример #9
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;

}
Пример #10
0
static NTSTATUS DOKAN_CALLBACK MirrorGetFileSecurity(
    LPCWSTR FileName, PSECURITY_INFORMATION SecurityInformation,
    PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG BufferLength,
    PULONG LengthNeeded, PDOKAN_FILE_INFO DokanFileInfo) {
  WCHAR filePath[MAX_PATH];

  UNREFERENCED_PARAMETER(DokanFileInfo);

  GetFilePath(filePath, MAX_PATH, FileName);

  DbgPrint(L"GetFileSecurity %s\n", filePath);

  MirrorCheckFlag(*SecurityInformation, FILE_SHARE_READ);
  MirrorCheckFlag(*SecurityInformation, OWNER_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, GROUP_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, DACL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, SACL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, LABEL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, ATTRIBUTE_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, SCOPE_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation,
                  PROCESS_TRUST_LABEL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, BACKUP_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, PROTECTED_DACL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, PROTECTED_SACL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, UNPROTECTED_DACL_SECURITY_INFORMATION);
  MirrorCheckFlag(*SecurityInformation, UNPROTECTED_SACL_SECURITY_INFORMATION);

  DbgPrint(L"  Opening new handle with READ_CONTROL access\n");
  HANDLE handle = CreateFile(
      filePath,
      READ_CONTROL | (((*SecurityInformation & SACL_SECURITY_INFORMATION) ||
                       (*SecurityInformation & BACKUP_SECURITY_INFORMATION))
                          ? ACCESS_SYSTEM_SECURITY
                          : 0),
      FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
      NULL, // security attribute
      OPEN_EXISTING,
      FILE_FLAG_BACKUP_SEMANTICS, // |FILE_FLAG_NO_BUFFERING,
      NULL);

  if (!handle || handle == INVALID_HANDLE_VALUE) {
    DbgPrint(L"\tinvalid handle\n\n");
    int error = GetLastError();
    return ToNtStatus(error);
  }

  if (!GetUserObjectSecurity(handle, SecurityInformation, SecurityDescriptor,
                             BufferLength, LengthNeeded)) {
    int error = GetLastError();
    if (error == ERROR_INSUFFICIENT_BUFFER) {
      DbgPrint(L"  GetUserObjectSecurity failed: ERROR_INSUFFICIENT_BUFFER\n");
      CloseHandle(handle);
      return STATUS_BUFFER_OVERFLOW;
    } else {
      DbgPrint(L"  GetUserObjectSecurity failed: %d\n", error);
      CloseHandle(handle);
      return ToNtStatus(error);
    }
  }
  CloseHandle(handle);

  return STATUS_SUCCESS;
}
Пример #11
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;
}