Samba_4_SID_Allocation_using_DNA_Plugin#
Overview#
A security identifier (SID) is a unique value of variable length that is used to identify a security principal or security group in Active Directory/Samba. Each domain has an SID which is generated during setup. Each user/group has an SID which is generated when the user/group is created. The user/group SID is created by concatenating the domain SID with a relative identifier (RID).
A domain may contain multiple domain controllers (DC). To guarantee uniqueness across the entire domain, the RID must be obtained from an integer pool which is maintained by the DC where the user/group is being created.
Active Directory uses an RID Manager which resides on the master DC. The RID Manager is responsible for distributing non-overlapping RID pools to the DC’s. When a DC is running out of entries in its pool, it will request for a new pool from the RID Manager.
Currently Samba doesn’t have such RID Manager. Basically each Samba instances has a large pool but the range overlaps with other pools in other instances, meaning that SID conflicts can occur.
One solution is to implement an RID Manager similar to Active Directory, but this could take some time.
A faster solution is using the DNA plugin in Fedora DS to generate unique SID’s across DS instances. Unlike RID Manager, the DNA plugin doesn’t rely on a single master server.
SID Formats#
SID has both binary and string (human readable) formats. SID is stored in the directory in its binary format (i.e. objectSid attribute) but should be displayed in UI in its string format.
SID binary format:
<revision> <sub-authority count> <identifier authority> <sub-authority>*
revision: 1 byte
sub-authority count: 1 byte
identifier authority: 6 bytes (big-endian)
sub-authority: 4 bytes (little-endian)
SID string format:
S - <revision> - <identifier authority> [ - <sub-authority> ]*
revision: decimal
identifier authority: decimal
sub-authority: decimal
Consider the following domain SID in binaries:
01 04 00 00 00 00 00 05 15 00 00 00 01 d2 f9 89 aa 27 ba fc d8 a2 6c ff
S-1-5-21-2314850817-4240058282-4285309656
The following user SID is generated by adding an RID (e.g. 1158) to the above domain SID:
01 05 00 00 00 00 00 05 15 00 00 00 01 d2 f9 89 aa 27 ba fc d8 a2 6c ff 86 04 00 00
S-1-5-21-2314850817-4240058282-4285309656-1158
DNA Plugin#
DNA plugin provides a way to generate integer values that are unique across DS instances. These values are called managed values. A prefix can be specified so that it will be prepended to all managed values.
The DNA plugin can be used to generate SID values by splitting the SID in two parts:
prefix: domain SID (e.g. S-1-5-21-2314850817-4240058282-4285309656)
managed value: RID (e.g. 1158)
When a new user is added into the DS, the plugin will automatically assign a full SID value which consists of the domain SID and the RID.
Current Code#
SAM LDB Module#
Currently the SAM LDB module generates SID values for new users. The code is located in source4/dsdb/samdb/ldb_modules/samldb.c:
static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
{
// check entry SID
ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
if ( ! ac->sid) { // no entry SID specified
// generate entry SID from domain SID and (next RID + 1)
samldb_add_step(ac, samldb_new_sid);
} else { // new entry contains SID
// find domain object and next RID based on entry SID
samldb_add_step(ac, samldb_get_sid_domain);
}
// increment next RID in the domain object
samldb_add_step(ac, samldb_notice_sid);
}
Proposed Changes#
Samba Configuration#
A new parameter should be added into smb.conf to control how the SID will be generated:
[globals]
sid generator = backend
Valid values:
internal: Samba will generate the SID and add it to the backend
backend: Backend will generate the SID
If the paramater is not specified, the default value should be “internal”.
The parameter should be defined in source4/param/loadparm.c:
enum sid_generator {
SID_GENERATOR_INTERNAL=0,
SID_GENERATOR_BACKEND=1
};
struct loadparm_global
{
enum sid_generator sid_generator;
}
static const struct enum_list enum_sid_generator[] = {
{SID_GENERATOR_INTERNAL, "internal"},
{SID_GENERATOR_BACKEND, "backend"},
{-1, NULL}
};
static struct parm_struct parm_table[] = {
{"sid generator", P_ENUM, P_GLOBAL, GLOBAL_VAR(sid_generator), NULL, enum_sid_generator},
_PUBLIC_ FN_GLOBAL_INTEGER(lp_sid_generator, sid_generator)
SAM LDB Module#
The module should generate the SID values only when the “sid generator” parameter is set to “internal”:
static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
{
sid_generator = lp_sid_generator(lp_ctx);
if (sid_generator == SID_GENERATOR_INTERNAL) {
// check entry SID
ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
if ( ! ac->sid) { // no entry SID specified
// generate entry SID from domain SID and (next RID + 1)
samldb_add_step(ac, samldb_new_sid);
} else { // new entry contains SID
// find domain object and next RID based on entry SID
samldb_add_step(ac, samldb_get_sid_domain);
}
// increment next RID in the domain object
samldb_add_step(ac, samldb_notice_sid);
}
}
Provisioning Tool#
The provisioning tool should generate the following configuration:
dn: cn=Samba SIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
objectClass: top
objectClass: extensibleObject
cn: Samba SIDs
dnaType: sambaSID
dnaMaxValue: 10000
dnaMagicRegen: 0
dnaFilter: (|(objectClass=user)(objectClass=group))
dnaScope: ${DOMAINDN}
dnaNextValue: 1000
dnaSharedCfgDn: cn=Samba SIDs,ou=Ranges,${SAMBADN}
dnaPrefix: ${DOMAINSID}-
The plugin should be enabled:
dn: cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
changetype: modify
replace: nsslapd-pluginEnabled
nsslapd-pluginEnabled: on
The provisioning tool should also add a container entry for sharing SID ranges among multiple DS instances.
dn: ou=Ranges,${SAMBADN}
objectClass: top
objectClass: organizationalUnit
ou: Ranges
dn: ou=Ranges,${SAMBADN}
dn: cn=Samba SIDs,ou=Ranges,${SAMBADN}
objectClass: top
objectClass: nsContainer
cn: Object SIDs
Issues#
Samba currently stores the SID in DS in its binary format. However, the DNA plugin currently only supports generating integer and string attributes. The options are:
Patches#
The following patch has been applied to the source repository:
References#
Well-known security identifiers in Windows operating systems
[http://technet.microsoft.com/en-us/library/cc779144(WS.10).aspx How Security Principals Work]