Ensuring MDM management stack initialization is done (#9928)

This relates to #9310 


This PR introduces changes to ensure that MDM management stack is ready
(required for first-time exec on brand-new machines). The PR also removes unnecessary info on the error messages
This commit is contained in:
Marcos Oviedo 2023-02-20 11:43:35 -03:00 committed by GitHub
parent 03a588d65d
commit 88a9d67e8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -31,16 +31,17 @@ var (
modmdmlocalmgmt = windows.NewLazySystemDLL("mdmlocalmanagement.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procIsDeviceRegisteredWithManagement = modmdmregistration.NewProc("IsDeviceRegisteredWithManagement")
procSendSyncMLcommand = modmdmlocalmgmt.NewProc("ApplyLocalManagementSyncML")
proclstrlenW = modkernel32.NewProc("lstrlenW")
procRtlMoveMemory = modkernel32.NewProc("RtlMoveMemory")
procIsDeviceRegisteredWithManagement = modmdmregistration.NewProc("IsDeviceRegisteredWithManagement")
procSendSyncMLcommand = modmdmlocalmgmt.NewProc("ApplyLocalManagementSyncML")
procRegisterDeviceWithLocalManagement = modmdmlocalmgmt.NewProc("RegisterDeviceWithLocalManagement")
proclstrlenW = modkernel32.NewProc("lstrlenW")
procRtlMoveMemory = modkernel32.NewProc("RtlMoveMemory")
// Synchronization mutex
mu sync.Mutex
// SMBIOS UUID SHA256 hash generation executor
uuidHashGeneration sync.Once
// MDM Management stack initialization executor
mdmManagementStackInit sync.Once
// SHA256 hash of device SMBIOS UUID
uuidHash []byte
@ -389,9 +390,12 @@ func executeMDMcommand(inputCMD string) (string, error) {
}
// MDM stack is ready to receive commands
// The code below is just using returnCode to determine if call was successul or not. The err
// variable returns status above call dispatching so it not needed and actually introduce
// confusion about the status of the call.
var outputStrBuffer *uint16
if returnCode, _, err := procSendSyncMLcommand.Call(uintptr(unsafe.Pointer(&inputCmdPtr[0])), uintptr(unsafe.Pointer(&outputStrBuffer))); returnCode != uintptr(windows.ERROR_SUCCESS) {
return "", fmt.Errorf("there was an error calling ApplyLocalManagementSyncML(): %s (0x%X)", err, returnCode)
if returnCode, _, _ := procSendSyncMLcommand.Call(uintptr(unsafe.Pointer(&inputCmdPtr[0])), uintptr(unsafe.Pointer(&outputStrBuffer))); returnCode != uintptr(windows.ERROR_SUCCESS) {
return "", fmt.Errorf("there was an error calling ApplyLocalManagementSyncML(): (0x%X)", err, returnCode)
}
// converting windows MDM UTF16 output string into go string
@ -541,13 +545,30 @@ func getUUIDhash() ([]byte, error) {
// enableCmdExecution initializes the registry flags required for OS MDM execution
func enableCmdExecution() error {
// generating SHA256 hash of SMBIOS UUID
// initialize MDM stack management by generating SHA256 hash of SMBIOS UUID and calling RegisterDeviceWithLocalManagement()
// this is wrapped by sync.Once so it only executes once
uuidHashGeneration.Do(func() {
mdmManagementStackInit.Do(func() {
// making sure that COM is initialized
// this is a best effort call as COM stack could have been initialized already by other components
err := windows.CoInitializeEx(0, windows.COINIT_MULTITHREADED)
if err != nil {
log.Error().Msgf("there was an error calling CoInitializeEx(): (%s)", err)
}
// calling RegisterDeviceWithLocalManagement() to initialize the MDM stack
// The code below is just using returnCode to determine if call was successul or not. The err
// variable returns status above call dispatching so it not needed and actually introduce
// confusion about the status of the call.
if returnCode, _, _ := procRegisterDeviceWithLocalManagement.Call(uintptr(unsafe.Pointer(nil))); returnCode != uintptr(windows.ERROR_SUCCESS) {
log.Error().Msgf("there was an error calling RegisterDeviceWithLocalManagement(): (0x%X)", returnCode)
return
}
// generate SHA256 hash of UUID bytes
workHash, err := getUUIDhash()
if err != nil {
log.Debug().Err(err).Msg("there was an issue generating the UUID hash")
log.Error().Err(err).Msg("there was an issue generating the UUID hash")
return
}
// making the UUID hash to be globally accessible