Mapping of RIDs to uid_t and gid_t
Jeremy Allison
jallison at whistle.com
Fri Apr 3 01:51:14 GMT 1998
I have been doing some thinking of late on the
mapping of UNIX uid_t's and gid_t's to NT domain
32 bit RID's. Here are my thoughts so far.
Comments are welcome, as I'm going to be coding
these up for Samba soon :-).
The problem:
The last component of an NT SID is a 32bit
unsigned 'RID' - or relative ID. Both users
groups, aliases (whatever *they* are :-) and
machine accounts in an NT SAM map into this
space, and NT has some 'well known' numbers
that must be the same across different domains
- they're hard-coded into the include files for
NT (just to be helpful :-).
The possible different types of RID are :
User, Group, Domain, Alias, WellKnownGroup,
Deleted, Invalid and Unknown.
The 'well known' numbers are:
Well known user id's
--------------------
Administrator - 500
Guest - 501
Well known group id's
---------------------
Administrators - 544
Users - 545
Guests - 546
Well known aliases (what *exactly* are these ?)
-----------------------------------------------
Administrators - 544
Users - 545
Guests - 546
Power users - 547
Account operators - 548
System operators - 549
Printer operators - 550
Backup operators - 551
Replicator - 552
Note that I am not covering the
'local' well known users such as
'creator owner' etc, as these have
a fixed SID in their entirity,
not just a fixed RID.
Also note that all these numbers are
below 1000.
The solution
------------
We need to map UNIX uid_t, gid_t and
machine accounts (which don't have a
unix uid) into the 32 bit RID, in such
a way that when recieving this RID
back from an NT box we can do a reverse
mapping unabiguously into a uid_t or
gid_t.
To do this we first treat the 'well
known' RID values specially - we use a
lookup mapping table for them.
Next we allocate bits for the
various account types :
User = 1
Group = 2
Domain (machine account) = 3
Alias = 4
WellKnownGroup = 5
Deleted = 6 \
Invalid = 7 |-- we never generate these.
Unknown = 8 /
Next we map the 32 bit RID space into
the following bits :
4 bits account type | 28 bits account number.
We then map a uid_t into a RID as follows :
(User << 28) | ((uid_t + 1000) & 0xFFFFFFF)
A gid_t to a RID as follows :
(Group << 28) | ((gid_t + 1000) & 0xFFFFFFF)
etc. (you get the picture).
This is nice and reversible, and is
unambiguous when recieving a RID
back, so is easy to map into the
uid_t, gid_t or machine account
case.
We store the RID's for a user in the
domain and the RID for their primary
group in the vuser struct, along with
their uid_t and primary gid_t, for
speed.
To generate new machine accounts, we
junk the algorithm I'm using at the
moment and create them starting at
2^28 - 1001
going down.
Problems
--------
All this works very nicely for systems
where sizeof(uid_t) and sizeof(gid_t) = 16,
but is problematic for 32 bit uid_t, gid_t
systems.
I propose that, as most systems will
be using uid_t's and gid_t's in the
range 0 - (2^28 - 1001) we simply
generate an error for 32 bit uid_t
systems that have allocated users
out of that range (comments please ?).
We also add a 'groupname map' file
parameter to smb.conf that allows us
to do the name translation between
Administrators and the wheel group
etc. This gives UNIX admins a much
more familiar space in which to play
than having a new group config file.
Speak soon, or I'm gonna start coding
up this sucker :-).
Jeremy.
--
--------------------------------------------------------
Buying an operating system without source is like buying
a self-assembly Space Shuttle with no instructions.
--------------------------------------------------------
More information about the samba-technical
mailing list