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

Heesob Park phasis at gmail.com
Wed Jul 9 00:35:50 EDT 2008


2008/7/9 Daniel Berger <djberg96 at gmail.com>:
> 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?
>
That looks good.

I think the SID detection code
 if account =~ /\W+/
can be something like
 if account[0] < 10


Regards,

Park Heesob


More information about the win32utils-devel mailing list