nTSecurityDescriptor inheritance - work in progress

Nadezhda Ivanova nadezhda.ivanova at postpath.com
Wed Jul 1 09:32:51 GMT 2009

Hi Samba,
Attached is my work in progress regarding the implementation of nTSecurityDescriptor creation and inheritance. create_descriptor.c contains the descriptor creation algorithm as described in MS-DTYP 2.5.2. Details about the data structures used and the meaning of flags and controls can be found in the same document. Still work in progress, haven't even run it yet, but it gives the general idea.
That is the generic algorithm for the creation of a new security descriptor, based on the descriptor of the object's parent and the descriptor provided by the user at the object's creation or modification. It is generic in the sense that it should be used by all resource managers that use SECURITY DESCRIPTOR type structure to handle access rights, such as Directory Service, File System and Registry. The difference between the security managers is in the arguments provided to the algorithm. How the createDescriptor routine should be invoked is described in the corresponding document for each resource manager. I have only researched AD at this point, so all the examples will relate to AD at this point. The rules of use of the createDescriptor by AD are described in MS-ADTS 7.1.3.

In order to use the createDescriptor routine, each resource manager needs to have an implementation of:
	1.	a generic mapping routine. This serves to map the generic access rights in an access mask (GA. GE, GW, GR) to specific access rights. Since the last 16 bits of a mask are manager-specific, the mappings are different for each manager. A sample generic mapping for AD is in create_descriptor.c
	2.	a routine for calculating default ownership and group, used when owner and group are not provided by the user. There are different defaulting rules for each manager. In the case of AD, they depend on the user account and the naming context where the object is located. Haven'n implemented that yet.
	3. 	ACL revision checks. The algorithm is revision independent and it appears it is the responsibility of the caller to verify that the revision is correct before invoking createDescriptor.
	4. 	ACE ordering function createDescriptor does not seem to deal with ordering rules, which are different between managers and even between pre 2000 and post 2000 Active Directory.

The createDescriptor returns a descriptor for the object being created or a new descriptor if one is being modified, based on the following:
	1. Security descriptor of the objects parent. Used to calculate the ACE's that are to be inherited by the new object, whether active or inherited only. Can be null if the object has no parent.
	2. Security descriptor provided by the user. In the case of AD, this is the nTSecurityDescriptor attribute from the incoming LDAP request. If no such descriptor is provided, then the defaultSecurityDescriptor of the object class for the new object is used. Can be NULL.
	3. IsContainerObject - true if the object is a container - can have children. In AD this is always set to true, which saves us some object class checking :).
	4. ObjectTypes - this is a list of the GUIDs of the object types relevant to the new object. IN AD case, these are the objects allowed attributes/attribute sets, and maybe the allowed access control rights. This is used to determine if an inherited object specific ACE is to be applied to the object or mark as inherited only. My guess is this is only relevant for AD, and should be NULL for fr/registry.
	5. AutoInheritFlags - a set of flags that govern descriptor inheritance. The meaning of each is described in MS-DTYP page 67. In AD, this is always DACL_AUTO_INHERIT|SACL_AUTO_INHERIT, which means thet inheritable ACE's from the parent are always inherited unless the NO_PROPAGATE flag is set.
	6. Token - contains the default security information. Basically this is the owner/group to be used for the new descriptor if such are not provided by the user. They should be calculated according to the defaulting rules. In addition, it also contains a default DACL, which in the case of AD is used as a DACL for the new object if none is provided by the user and there is no defaultSecurityDescriptor for its object class. We do not have this in Samba now. I wasn't able to find any info in the docs on how this is determined, whether it depends on the user account or somenthing else. Eill be writing to MS forum about it, left it NULL for now.
	7. generic mapping - a pointer to the above mentioned generic access rights mapping routine.

I will not be describing createDescriptor in much detail, its best to look at the pseudo code, but basically it first determines which ACE's from the parent are inheritable. Makes a list of those and sets their flags to inherited, and inherit only if necessary. It then deals with the user provided descriptor, ignoring any ACE's that are marked as inherited, and adds the rest to the list. Finally, the mapping function is used to set the access rights correctly if they have been specified as generic, and applies the correct owner/group.

In the case of directory service, we need to invoke the createDescriptor when an object is added or its descriptor is modified, bearing in mind the SD_FLAGS_CONTROL. Also, recalculation is necessary when an object is moved under a new parent. Not sure if we have to recalculate the descriptors of all children if the descriptor of a parent is modified, will check this, but my guess is that we do. I intend to try enhancing the object_class ldb module to handle this, and also will have to think of python and other tests if each routine.

Sorry for the "War and Peace" length of the mail :). Tried to keep it short as possible. Any questions or feedback will be appreciated.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Initial-implementation-of-security-descriptor-creati.patch
Type: application/octet-stream
Size: 12492 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20090701/2005ded2/0001-Initial-implementation-of-security-descriptor-creati.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-Added-create_descriptor.c-to-make-file.patch
Type: application/octet-stream
Size: 912 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20090701/2005ded2/0002-Added-create_descriptor.c-to-make-file.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-Added-default-DACL-to-the-security-token-structure.patch
Type: application/octet-stream
Size: 2221 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20090701/2005ded2/0003-Added-default-DACL-to-the-security-token-structure.obj

More information about the samba-technical mailing list