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