Brève présentation puisqu'il s'agit de mon premier post :
Je développe de façon ponctuelle depuis une quinzaine d'années pour m'aider dans mon quotidien d'admin réseaux. Jusqu'à présent j'utilisais AutoIt et pour des raisons de compilation et détection Antivirus (faux positif) j'ai décidé de tester PureBasic.
Pour en revenir à mon soucis, je bascule à l'heure actuel un outil qui me permet d'interroger des postes distants via des requêtes WMI. Sous Autoit, une partie des fonctions nécessaires sont intégrées et invisibles, ce qui fait que très peu de code est nécessaire pour exécuter ces requêtes. Mais sous PureBasic j'ai dû pas mal fouiner sur le forum, et je n'ai pas trouver grand chose de "frais".
J'ai testé un code fonctionnel pour des requêtes locales mais dès que je modifie les paramètres de la méthode ConnectServer en y ajoutant l'identifiant et mot de passe du compte admin local distant, les requêtes (pas la connexion) sont en erreur.
Il y a beaucoup de paramètres qui me dépasse dans les fonctions CoInitializeSecurity_ ou CoSetProxyBlanket_ et j'ai l'impression que, même si l'erreur vient de ExecQuery, il s'agit malgré tout d'un problème de sécurité. Après tout en local, la requête fonctionne.
J'ai aussi récupéré la librairie COMate.pbi mais cette dernière ne permet pas de se connecter en indiquant un compte utilisateur.
Le code que j'utilise :
Code : Tout sélectionner
; #WBEM_INFINITE = $FFFFFFFF
#COINIT_MULTITHREADED = 0
#RPC_C_AUTHN_LEVEL_CONNECT = 2 ;Authenticates the credentials of the client only when the client establishes a relationship with the server.
#RPC_C_AUTHN_LEVEL_CALL = 3 ;Authenticates only at the beginning of each remote procedure call when the server receives the request.
#EOAC_NONE = 0 ;No Authentication capability flags are set
#RPC_C_AUTHN_WINNT = 10 ;Use the Microsoft NT LAN Manager (NTLM) SSP.
#RPC_C_AUTHZ_NONE = 0 ;The server performs no authorization. Currently, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_GSS_SCHANNEL, And RPC_C_AUTHN_GSS_KERBEROS all use only RPC_C_AUTHZ_NONE.
#RPC_C_IMP_LEVEL_IMPERSONATE = 3 ;The server process can impersonate the client's security context while acting on behalf of the client. When impersonating at this level, the impersonation token can only be passed across one machine boundary (can be used to access local resources such as files).
#wbemFlagReturnImmediately = 16 ;Causes the call to return immediately.
#wbemFlagForwardOnly = 32 ;Causes a forward-only enumerator to be returned. Forward-only enumerators are generally much faster and use less memory than conventional enumerators, but they do not allow calls to SWbemObject.Clone_.
#CLSCTX_INPROC_SERVER = $1
CompilerIf #PB_Compiler_OS = #PB_Compiler_Unicode
Macro ptr(String) : @String : EndMacro
CompilerElse
Macro ptr(String) : ansi2bstr(String) : EndMacro
CompilerEndIf
;=======================================
Procedure.i ansi2bstr(String$)
size.i = MultiByteToWideChar_(#CP_ACP, 0, String$, Len(String$), 0, 0)
If Size
Dim unicode.w(size)
MultiByteToWideChar_(#CP_ACP, 0, String$, Len(String$), unicode(), size) ;#CP_ACP
For Counter.i = 0 To size
tmp.s + Hex(unicode(Counter), #PB_Unicode)
Next
EndIf
ProcedureReturn SysAllocString_(@unicode())
EndProcedure
;=======================================
Procedure.i bstr2string(bstr.i)
Shared result.s
result = PeekS(bstr, -1, #PB_Unicode)
ProcedureReturn @result
EndProcedure
;=======================================
Procedure.s WMI_GetProcessOwner(Servername$, Processname$, user$, pass$)
Result$ = ""
Select Servername$
Case "" : Namespace$ = "\\.\root\CIMV2"
Default : Namespace$ = "\\" + RemoveString(Servername$, "\") + "\root\CIMV2"
EndSelect
;
If CoInitializeEx_(0, #COINIT_MULTITHREADED) = 0
If CoInitializeSecurity_(0, -1, 0, 0, #RPC_C_AUTHN_LEVEL_CONNECT, #RPC_C_IMP_LEVEL_IMPERSONATE, 0, #EOAC_NONE, 0) = 0
If CoCreateInstance_(?CLSID_WbemLocator, 0, #CLSCTX_INPROC_SERVER, ?IID_IWbemLocator, @pLocator.IWbemLocator) = 0
If pLocator\ConnectServer(ptr(Namespace$), @user$, @pass$, 0, 0, 0, 0, @pService.IWbemServices) = 0
If CoSetProxyBlanket_(pService, #RPC_C_AUTHN_WINNT, #RPC_C_AUTHZ_NONE, 0, #RPC_C_AUTHN_LEVEL_CALL, #RPC_C_IMP_LEVEL_IMPERSONATE, 0, #EOAC_NONE) = 0
pService\queryinterface(?IID_IUnknown,@pUnknown.IUnknown)
If CoSetProxyBlanket_(pUnknown, #RPC_C_AUTHN_WINNT, #RPC_C_AUTHZ_NONE, 0, #RPC_C_AUTHN_LEVEL_CALL, #RPC_C_IMP_LEVEL_IMPERSONATE, 0, #EOAC_NONE) = 0
If pService\ExecQuery(ptr("WQL"), ptr("SELECT * FROM Win32_Process"), #wbemFlagReturnImmediately|#wbemFlagForwardOnly, 0, @pEnumerator.IEnumWbemClassObject) = 0
pEnumerator\reset()
NbrReturned.i = 1
While NbrReturned
pEnumerator\Next(#WBEM_INFINITE, 1, @pclsObj.IWbemClassObject, @NbrReturned)
;Get Processname
If pclsObj\Get(ptr("Name"), 0, @vtReturn.VARIANT, 0, 0) = 0 ;Debug PeekS(bstr2string(vtReturn\bstrVal))
Found.i = #False
If LCase(PeekS(bstr2string(vtReturn\bstrVal))) = Processname$
Found = #True
;Get Processpath
If pclsObj\Get(ptr("__PATH"), 0, @vtPath.VARIANT, 0, 0) = 0 ;Debug PeekS(bstr2string(vtPath\bstrVal))
;Get Processowner
If pService\ExecMethod(vtPath\bstrVal, ptr("GetOwner"), 0, 0, 0, @pResult.IWbemClassObject, 0) = 0
If pResult\Get(ptr("User"), 0, @vtUser.VARIANT, 0, 0) = 0
Result$ = PeekS(bstr2string(vtUser\bstrVal))
VariantClear_(vtUser)
EndIf
pResult\release()
EndIf
VariantClear_(vtPath)
EndIf
Break
EndIf
VariantClear_(vtReturn)
If Found = #False : Result$ = "Error - Unable to find the process" : EndIf
EndIf
Wend
pclsObj\release()
Else
Result$ = "Error - Unable to retrieve the objects"
EndIf
pUnknown\release()
Else
Result$ = "Error - Unable to set the IUnknown security"
EndIf
Else
Result$ = "Error - Unable to set the proxy security"
EndIf
pService\release()
Else
Result$ = "Error - Unable to connect to CIMV2"
EndIf
pLocator\release()
Else
Result$ = "Error - Unable to create a WbemLocator"
EndIf
Else
Result$ = "Error - Unable to set the security values for the process"
EndIf
CoUninitialize_()
Else
Result$ = "Error - Unable to launch COM"
EndIf
ProcedureReturn Result$
DataSection
CLSID_IEnumWbemClassObject:
Data.l $1B1CAD8C : Data.w $2DAB, $11D2 : Data.b $B6, $04, $00, $10, $4B, $70, $3E, $FD
IID_IEnumWbemClassObject:
Data.l $7C857801 : Data.w $7381, $11CF : Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24
CLSID_WbemLocator:
Data.l $4590F811 : Data.w $1D3A, $11D0 : Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24
IID_IWbemLocator:
Data.l $DC12A687 : Data.w $737F, $11CF : Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24
IID_IUnknown:
Data.l $00000000 : Data.w $0000, $0000 : Data.b $C0, $00, $00, $00, $00, $00, $00, $46
IID_IWbemRefresher:
Data.l $49353C99 : Data.w $516B, $11D1 : Data.b $AE, $A6, $00, $C0, $4F, $B6, $88, $20
CLSID_WbemRefresher:
Data.l $C71566F2 : Data.w $561E, $11D1 : Data.b $AD, $87, $00, $C0, $4F, $D8, $FD, $FF
IID_IWbemConfigureRefresher:
Data.l $49353C92 : Data.w $516B, $11D1 : Data.b $AE, $A6, $00, $C0, $4F, $B6, $88, $20
IID_IWbemObjectAccess:
Data.l $49353C9A : Data.w $516B, $11D1 : Data.b $AE, $A6, $00, $C0, $4F, $B6, $88, $20
EndDataSection
EndProcedure
;=======================================
;=======================================
;=======================================
Servername$ = "remote_pc"
Processname$ = "smss.exe"
Debug WMI_GetProcessOwner(Servername$, Processname$, "user", "password")