Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-5684

Windows ADSI User and Group exists? checks are invalid

    Details

    • Template:
    • Story Points:
      2
    • Sprint:
      Windows 2016-01-13
    • Release Notes:
      Bug Fix
    • Release Notes Summary:
      Puppet may have internally considered a Windows User or Group to exist when it does not, preventing the User / Group from being created. Based on how this code was used however, this likely had no user facing impact.

      Description

      Puppet::Util::Windows::ADSI::User and Puppet::Util::Windows::ADSI::Group both implement an exists member something like:

      def self.exists?(name)
        Puppet::Util::Windows::ADSI.connectable?(Group.uri(name))
      end
      

      See https://github.com/puppetlabs/puppet/blob/d26bfd2e9ba08f092114348ebad5e4421270f315/lib/puppet/util/windows/adsi.rb#L324-L326 and https://github.com/puppetlabs/puppet/blob/d26bfd2e9ba08f092114348ebad5e4421270f315/lib/puppet/util/windows/adsi.rb#L467-L469

      This code is actually incorrect, because a uri like WinNT://<SID> might be errantly built inside the uri method and consumed by the exists? method. Such a WinNT:// style URI is technically valid, but only for very specific use cases; it cannot be used as a moniker to resolve a user or group when calling WIN32OLE.connect. So a COM object that is returned when calling WIN32OLE.connect('WinNT://<SID>') implements IADs but not IADsGroup or IADsUser. When retrieving the .Class property, the value is always going to be "Domain" (even though the object returned is not an IADsDomain.

      This was discovered during the testing of PUP-5538, and should be fixed prior to that PR being merged.

      [37] pry(main)> admins_by_name = WIN32OLE.connect('WinNT://./Administrators,group')
      => #<WIN32OLE:0x00000008f260e0>
      [38] pry(main)> admins_by_name.Class
      => "Group"
      [39] pry(main)> admins_by_name.objectSID
      => [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0]
       
       
      [40] pry(main)> admins_by_sid = WIN32OLE.connect('WinNT://S-1-5-32-544')
      => #<WIN32OLE:0x000000088429b8>
      [41] pry(main)> admins_by_sid.Class
      => "Domain"
      [42] pry(main)> admins_by_sid.objectSID
      NoMethodError: unknown property or method: `objectSID'
          HRESULT error code:0x80020006
            Unknown name.
      from (pry):42:in `method_missing'
      

      The methods sid_uri and sid_uri_safe should *only be used* to generate a SID style uri when adding members to a group via IADsGroup::Add

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                ethan Ethan Brown
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:

                  Zendesk Support