WMI win32process Method GetOwnerSid

Developers
2013-04-05
2013-04-06
  • Paul Higgins
    Paul Higgins
    2013-04-05

    Under Windows 8 I am trying to execute a method GetOwnerSid in WMI process win32_process. Here is my code:

    WMIObject = .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")
    do process over WMIObject~InstancesOf("win32_process")
    sid = 9999
    sid_rc = process~GetOwnerSid(sid)
    say process~processid process~name' rc=' sid_rc' SID='sid
    end
    exit
    ::requires "OREXXOLE.CLS"
    ================================================
    The output for sid is always 999. The sid_rc is either 0 (Success) or 2 (Access denied)
    An example in VB that supposedly works (haven't tried it) is:
    ===============================================
    strServer = "."

    Set objWMI = GetObject("winmgmts:\" & strServer & "\root\cimv2")

    strWQL = "select * from Win32_Process"
    Set objInstances = objWMI.ExecQuery(strWQL,,48)

    For Each objInstance in objInstances
    p_Sid = "Value" ' byReference, content may change!

    ' Uncomment next line to actually execute the method!
    ' intResult = objInstance.GetOwnerSid(p_Sid)
    
    Select case intResult
        Case 0 : WScript.Echo "Successful completion"
        Case 2 : WScript.Echo "Access denied"
        Case 3 : WScript.Echo "Insufficient privilege"
        Case 8 : WScript.Echo "Unknown failure"
        Case 9 : WScript.Echo "Path not found"
        Case 21 : WScript.Echo "Invalid parameter"
    End Select
    

    Next

    How do I get the output of GetOwnerSid() using oorexx?

    Thanks

     
    • Mark Miesfeld
      Mark Miesfeld
      2013-04-05

      ERROR! The markdown supplied could not be parsed correctly. Did you forget to surround a code snippet with "~~~~"?

      Paul,
      
      You probably need to use an OleVariant object.  I'm on Linux right now and
      don't have access to the OleObject docs, so this may be off a little,
      because I can't look it up.
      
      I think what you want to do is create an OleVariant object with a
      byRefernce setting and use that in your
      
       sid = 9999
         sid_rc = process~GetOwnerSid(sid)
      
      code.  Something like:
      
       sid = .OleVariant~new(9999, byRefence)
      
         sid_rc = process~GetOwnerSid(sid)
      
      say 'value of sid now:'  sid~value
      
      You need to look up the details in the reference manual.
      
      --
      Mark Miesfeld
      
      
      
      On Fri, Apr 5, 2013 at 10:55 AM, Paul Higgins <phigginsph99@users.sf.net>wrote:
      
      > Under Windows 8 I am trying to execute a method GetOwnerSid in  WMI
      > process win32_process.  Here is my code:
      > ==========================================================
      > WMIObject =
      > .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")
      > do process over WMIObject~InstancesOf("win32_process")
      >     sid = 9999
      >    sid_rc = process~GetOwnerSid(sid)
      >    say process~processid process~name' rc=' sid_rc' SID='sid
      > end
      > exit
      > ::requires "OREXXOLE.CLS"
      > ================================================
      > The output for sid is always 999. The sid_rc is either 0 (Success)  or 2
      > (Access denied)
      > An example in VB that supposedly works (haven't tried it) is:
      > ===============================================
      > strServer = "."
      >
      > Set objWMI = GetObject("winmgmts:\\" & strServer & "\root\cimv2")
      >
      > strWQL = "select * from Win32_Process"
      > Set objInstances = objWMI.ExecQuery(strWQL,,48)
      >
      > For Each objInstance in objInstances
      >         p_Sid = "Value" ' byReference, content may change!
      >
      >         ' Uncomment next line to actually execute the method!
      >         ' intResult = objInstance.GetOwnerSid(p_Sid)
      >
      >         Select case intResult
      >                 Case 0 : WScript.Echo "Successful completion"
      >                 Case 2 : WScript.Echo "Access denied"
      >                 Case 3 : WScript.Echo "Insufficient privilege"
      >                 Case 8 : WScript.Echo "Unknown failure"
      >                 Case 9 : WScript.Echo "Path not found"
      >                 Case 21 : WScript.Echo "Invalid parameter"
      >         End Select
      > Next
      > ======================
      > How do I get the output of GetOwnerSid() using oorexx?
      >
      > Thanks
      >
      >
      >
      > ---
      > [WMI  win32process Method GetOwnerSid](
      > https://sourceforge.net/p/oorexx/discussion/408479/thread/57ce3f89/?limit=25#5a7e
      > )
      >
      > ---
      >
      > Sent from sourceforge.net because you indicated interest in <
      > https://sourceforge.net/p/oorexx/discussion/408479/>
      >
      > To unsubscribe from further messages, please visit <
      > https://sourceforge.net/auth/subscriptions/>
      >
      
       
      • Paul Higgins
        Paul Higgins
        2013-04-06

        That helped a lot and I now have the GetOwnerSid working but got stuck again. Here is my code now:

        WMIObject = .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")
        do process over WMIObject~InstancesOf("win32_process")
        param = .OleVariant~new(9999, "VT_DECIMAL,VT_BYREF","OUT")
        sid_rc = process~GetOwnerSid(param)
        if sid_rc == 0 then do
        strSID = param~!varValue_
        say 'strSID='strSID
        array = .array~new()
        param_array = .OleVariant~new(9999, "VT_DECIMAL,VT_ARRAY","IN")
        param_array = WMIObject~Get("Win32_SID='"strSID"'")
        array = param_array~!varValue_
        if sid_rc == 0 then say process~processid process~name' param_array~items='param_array~items' strSID='strSID ' type = ' param~!varType_
        end
        end
        exit
        ::requires "OREXXOLE.CLS"

        The strSID has:S-1-5-21-1523768696-3292311931-3688940087-1000
        which is some sort of string that you have to feed into WMIObject~Get and the output is put into an array parm_array which I defined as a .OlVariant array.
        I then try to put the parm_array into a rexx array and it fails:
        28 - array = param_array~!varValue_
        Error 97 running C:\PCOMM\process_id.rex line 28: Object method not found
        Error 97.1: Object "an OLEObject" does not understand message "!VARVALUE_"

        Do you have any idea how to get it into a rexx array?

         
        • Mark Miesfeld
          Mark Miesfeld
          2013-04-06

          On Sat, Apr 6, 2013 at 6:51 AM, Paul Higgins phigginsph99@users.sf.netwrote:

          That helped a lot and I now have the GetOwnerSid working but got stuck
          again.

          Wow - better than I did. I fooled with it a bit last night, but couldn't
          get the VT_ type correct. How did you know to use VT_DECIMAL?

          Here is my code now:

          WMIObject =
          .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")
          do process over WMIObject~InstancesOf("win32_process")
          param = .OleVariant~new(9999, "VT_DECIMAL,VT_BYREF","OUT")
          sid_rc = process~GetOwnerSid(param)
          if sid_rc == 0 then do
          strSID = param~!varValue_
          say 'strSID='strSID

          This next is an incorrect approach. An .OleVariant will never be returned.
          It can only be used as an argument in a method call of an OleObject.

          A guiding principle is "never use an OleVariant." ;-)

          Which means you really only want to use an OleVariant as a last result.
          You almost never need them.

            array = .array~new()
            param_array = .OleVariant~new(9999, "VT_DECIMAL,VT_ARRAY","IN")
            param_array = WMIObject~Get("Win32_SID='"strSID"'")
          

          Your code should be more like:

            retObj = WMIObject~Get("Win32_SID='"strSID"'")
          
            say 'retObj:' retObj 'items:' retObj~items
          

          That doesn't work for me, I get:

          SID: S-1-5-18
          13 - retObj = WMIObject~Get("Win32_SID='"strSID"'")
          Error 92 running C:\work.ooRexx\help.requests\paul.higgins\test.rex line
          13: OLE error
          Error 92.906: OLE exception: Code: 80070539 Source: SWbemServicesEx
          Description: The security ID structure is invalid.

          So, my argument to Get() is incorrect. (Which I just got from your code.)

          Looking up Get(), this is all I could find:

          The Get method of the
          SWbemServiceshttp://msdn.microsoft.com/en-us/library/windows/desktop/aa393854(v=vs.85).aspx
          object
          retrieves an object, that is either a class definition or an instance,
          based on the object path.

          objWbemObject = .Get(

          [ ByVal strObjectPath ],

          [ ByVal iFlags ],

          [ ByVal objWbemNamedValueSet ]

          )

          So, I'm stuck there. Which is why I dislike the whole OleObject stuff
          to begin with. ;-( It works okay if you can luck out and stumble
          across what the underlying COM object expects. But, when it doesn't
          work it is extremely frustrating.

            array = param_array~!varValue_
            if sid_rc == 0 then say process~processid process~name'
          

          param_array~items='param_array~items' strSID='strSID ' type = '
          param~!varType_
          end
          end
          exit
          ::requires "OREXXOLE.CLS"

          The strSID has:S-1-5-21-1523768696-3292311931-3688940087-1000
          which is some sort of string that you have to feed into WMIObject~Get and
          the output is put into an array

          In general, if the output from a method invocation is an array, OleObject
          will return an array.

          If you can point me to some example that you are working from so that I can
          get some idea of what the Get() method is mean to do, I can maybe help
          further.

          What I see for Get() does not have any arrays in the picture.

          --
          Mark Miesfeld

           
      • Paul Higgins
        Paul Higgins
        2013-04-06

        • Mark Miesfeld
          Mark Miesfeld
          2013-04-06

          On Sat, Apr 6, 2013 at 11:02 AM, Paul Higgins phigginsph99@users.sf.netwrote:

          I was working from the samples in the book:

          Okay Paul, this works for me:

          WMIObject =
          .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")

          count = 0
          do process over WMIObject~InstancesOf("win32_process")
          count += 1
          sid = '9999'
          param = .OLEVariant~new(sid, "VT_DECIMAL,VT_BYREF", "OUT")
          sid_rc = process~GetOwnerSid(param)

           say 'pid:' process~processid 'name:' process~name' rc:' sid_rc
           if sid_rc == 0 then do
               strSID = param~!varValue_
               say '  SID:' strSID
          
               retObj = WMIObject~Get("Win32_SID.SID='"strSID"'")
               say 'result:' retObj
           end
          

          end
          exit

          At least the returned object is an OleObject, which is what you want. I
          didn't take it further.

          pid: 3156 name: chrome.exe rc: 0
          SID: S-1-5-21-591256499-3866207021-4263410417-500
          result: an OLEObject
          pid: 1148 name: chrome.exe rc: 0
          SID: S-1-5-21-591256499-3866207021-4263410417-500
          result: an OLEObject

          The returned object should be a Win32_SID COM object.

          --
          Mark Miesfeld

           
          • Mark Miesfeld
            Mark Miesfeld
            2013-04-06

            On Sat, Apr 6, 2013 at 11:39 AM, Mark Miesfeld miesfeld@users.sf.netwrote:

            Okay Paul, this works for me:

            WMIObject =
            .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")

            count = 0

            Ignore or take out this count variable, it was left over from some
            debugging I was doing.

            --
            Mark Miesfeld

             
          • Mark Miesfeld
            Mark Miesfeld
            2013-04-06

            On Sat, Apr 6, 2013 at 11:39 AM, Mark Miesfeld miesfeld@gmail.com wrote:

            At least the returned object is an OleObject, which is what you want. I
            didn't take it further.

            Okay, here is a more complete example that shows we do get back a Win32_SID
            object. Watch for wrapped lines:

            WMIObject =
            .OLEObject~GetObject("winmgmts:{impersonationLevel=impersonate}")

            do process over WMIObject~InstancesOf("win32_process")
            sid = '9999'
            param = .OLEVariant~new(sid, "VT_DECIMAL,VT_BYREF", "OUT")
            sid_rc = process~GetOwnerSid(param)

             say 'pid:' process~processid 'name:' process~name' rc:' sid_rc
             if sid_rc == 0 then do
                 strSID = param~!varValue_
                 say '  SID:' strSID
            
                 retObj = WMIObject~Get("Win32_SID.SID='"strSID"'")
                 say 'SID account name:' retObj~accountName 'domain:'
            

            retObj~referencedDomainName 'sid length:' retObj~sidLength
            intArray = retObj~BinaryRepresentation
            if intArray~isA(.array) then do n over intArray
            say n
            end
            end
            end
            exit

            The 'BinaryRepresentation' is the actual numeric SID, as opposed to its
            string representation. It is returned as an array of 8 bit numbers

            Interesting problem here. As I hinted at earlier, the OLE stuff is kind of
            cool when it works. Frustrating when it doesn't.

            --
            Mark Miesfeld

             
            • Paul Higgins
              Paul Higgins
              2013-04-06

              Thanks very much Mark, as usual you made the extra effort, much appreciated.