[Win32utils-devel] Some more win32-security: SID.create

Daniel Berger djberg96 at gmail.com
Wed Jul 9 00:11:59 EDT 2008


On Tue, Jul 8, 2008 at 9:12 PM, Heesob Park <phasis at gmail.com> wrote:
> Hi,
>
> 2008/7/9 Berger, Daniel <Daniel.Berger at qwest.com>:
>> Hi all,
>>
>> How does this look as a general approach to a SID.create method:
>>
>> # Creates and initializes
>> def self.create(authority, *sub_authorities)
>>   if sub_authorities.length > 8
>>      raise ArgumentError, 'maximum of 8 subauthorities allowed'
>>   end
>>
>>   authorities = Array.new(8, 0)
>>   authorities.replace(sub_authorities)
>>   count = authorities.select{ |e| e > 0 }.size
>>
>>   if count == 0
>>      # Use InitializeSid()
>>   else
>>      # Use AllocateAndInitializeSid()
>>   end
>> end
>>
>> Any help actually implementing this method would also be greatly
>> appreciated, as my attempts were not working out so well.
>>
> Here is an working code:
>
> def self.create(authority, *sub_authorities)
>
>  if sub_authorities.length > 8
>     raise ArgumentError, "maximum of 8 subauthorities allowed"
>  end
>
>  sid = 0.chr * GetSidLengthRequired(sub_authorities.length+1)
>
>  if [0,1,2,3,5].include?(authority)
>      auth = 0.chr * 5 + authority.chr
>      bool = InitializeSid(sid, auth, sub_authorities.length+1)
>      unless bool
>       raise Error, get_last_error
>      end
>      sub_authorities.each_index do |i|
>         value = [sub_authorities[i]].pack('L')
>         auth_ptr = GetSidSubAuthority(sid, i)
>         memcpy(auth_ptr,value,4)
>      end
>  end
>  sid
> end
>
>
> Above code works with GetSidSubAuthority definition like this:
> API.new('GetSidSubAuthority', 'PL', 'L', 'advapi32')

Excellent, thanks. I've modified GetSidSubAuthority() as you suggest,
and made a few other functions that I had previously returning
pointers return longs instead - easier to deal with.

Your code gave me an idea, too. What do you think of modifying SID.new
so that it accepts either an account name or a sid? Behind the scenes
it just calls LookupAccountSid or LookupAccountName, depending on the
content of the first argument. That would allow SID.create to return a
full SID object.

Here's a proposed implementation:

def self.create(authority, *sub_authorities)
   # Code same as before except for the return value
   return self.new(sid)
end

def initialize(account, host=Socket.gethostname)
   sid    = 0.chr * 28
   sid_cb = [sid.size].pack('L')

   domain_buf = 0.chr * 80
   domain_cch = [domain_buf.size].pack('L')

   sid_name_use = 0.chr * 4

    # If the account includes non-alpha characters, assume it's a SID.
     if account =~ /\W+/ # Unicode concerns?
        bool = LookupAccountSid(
           host,
           [account].pack('p*').unpack('L')[0],
            sid,
            sid_cb,
            domain_buf,
            domain_cch,
            sid_name_use
         )

         @sid = account
         @name = sid.strip
     else
         bool = LookupAccountName(
            host,
            account,
            sid,
            sid_cb,
            domain_buf,
            domain_cch,
            sid_name_use
         )

         @sid = sid.strip
         @account = account
   end

   unless bool
      raise Error, get_last_error
   end

   @host    = host
   @domain  = domain_buf.strip

   @account_type = get_account_type(sid_name_use.unpack('L')[0])

   sid
end

How does that look?

Regards,

Dan


More information about the win32utils-devel mailing list