url="http://wiki.samba.org/index.php/Samba4/HOWTO">Samba4
HOWTO</ulink></para>
+ <para><anchor id="IPA-DC"/><emphasis>SERVER ROLE = IPA DOMAIN CONTROLLER</emphasis></para>
+
+ <para>This mode of operation runs Samba in a hybrid mode for IPA
+ domain controller, providing forest trust to Active Directory.
+ This role requires special configuration performed by IPA installers
+ and should not be used manually by any administrator.
+ </para>
</description>
<related>security</related>
{ ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
{ ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
{ ROLE_ACTIVE_DIRECTORY_DC, "ROLE_ACTIVE_DIRECTORY_DC" },
+ { ROLE_IPA_DC, "ROLE_IPA_DC"},
{ 0, NULL }
};
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
case ROLE_ACTIVE_DIRECTORY_DC:
+ case ROLE_IPA_DC:
if (security == SEC_USER) {
valid = true;
}
{ROLE_ACTIVE_DIRECTORY_DC, "active directory domain controller"},
{ROLE_ACTIVE_DIRECTORY_DC, "domain controller"},
{ROLE_ACTIVE_DIRECTORY_DC, "dc"},
+ {ROLE_IPA_DC, "IPA primary domain controller"},
{-1, NULL}
};
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
case ROLE_ACTIVE_DIRECTORY_DC:
+ case ROLE_IPA_DC:
return lpcfg_workgroup(lp_ctx);
default:
return lpcfg_netbios_name(lp_ctx);
if (ndr->offset < ndr->data_size) {
TALLOC_FREE(ndr);
/*
- * We need to handle a bug in FreeIPA (at least <= 4.1.2).
+ * We need to handle a bug in IPA (at least <= 4.1.2).
*
* They include the ip address information without setting
* NETLOGON_NT_VERSION_5EX_WITH_IP, while using
/* not in samr.idl */
ROLE_ACTIVE_DIRECTORY_DC = 4,
+ ROLE_IPA_DC = 5,
/* To determine the role automatically, this is not a valid role */
ROLE_AUTO = 100
break;
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
+ case ROLE_IPA_DC:
role = "'DC'";
methods = "anonymous sam winbind sam_ignoredomain";
break;
switch (lp_server_role()) {
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
+ case ROLE_IPA_DC:
methods = "sam_netlogon3 winbind";
break;
case ROLE_DOMAIN_MEMBER:
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
+ case ROLE_IPA_DC:
methods = "sam";
break;
case ROLE_ACTIVE_DIRECTORY_DC:
break;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
if (!is_local_name && !is_my_domain) {
/* If we are running on a DC that has PASSDB module with domain
* information, check if DNS forest name is matching the domain
- * name. This is the case of FreeIPA domain controller when
- * trusted AD DCs attempt to authenticate FreeIPA users using
- * the forest root domain (which is the only domain in FreeIPA).
+ * name. This is the case of IPA domain controller when
+ * trusted AD DCs attempt to authenticate IPA users using
+ * the forest root domain (which is the only domain in IPA).
*/
struct pdb_domain_info *dom_info = NULL;
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
break;
default:
DBG_ERR("Invalid server role\n");
if (!is_my_domain) {
/* If we are running on a DC that has PASSDB module with domain
* information, check if DNS forest name is matching the domain
- * name. This is the case of FreeIPA domain controller when
- * trusted AD DCs attempt to authenticate FreeIPA users using
- * the forest root domain (which is the only domain in FreeIPA).
+ * name. This is the case of IPA domain controller when
+ * trusted AD DCs attempt to authenticate IPA users using
+ * the forest root domain (which is the only domain in IPA).
*/
struct pdb_domain_info *dom_info = NULL;
dom_info = pdb_get_domain_info(mem_ctx);
Check to see if we are a DC for this domain
*****************************************************************************/
-#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
+#define IS_DC (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC || lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_server_role() == ROLE_IPA_DC)
#define IS_AD_DC (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
/*
case ROLE_DOMAIN_MEMBER:
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
*r->out.name_type = NetSetupDomainName;
break;
case ROLE_STANDALONE:
default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
break;
case ROLE_DOMAIN_PDC:
+ case ROLE_IPA_DC:
default_server_announce |= SV_TYPE_DOMAIN_CTRL;
break;
case ROLE_DOMAIN_BDC:
bool lp_domain_master(void)
{
if (Globals._domain_master == Auto)
- return (lp_server_role() == ROLE_DOMAIN_PDC);
+ return (lp_server_role() == ROLE_DOMAIN_PDC ||
+ lp_server_role() == ROLE_IPA_DC);
return (bool)Globals._domain_master;
}
/* If we are running on a DC that has PASSDB module with domain
* information, check if DNS forest name is matching the domain
- * name. This is the case of FreeIPA domain controller when
+ * name. This is the case of IPA domain controller when
* trusted AD DC looks up users found in a Global Catalog of
* the forest root domain. */
if (!check_global_sam && (IS_DC)) {
dyn_guid = (struct GUID *)secrets_fetch(key, &size);
if (!dyn_guid) {
- if (lp_server_role() == ROLE_DOMAIN_PDC) {
+ if (lp_server_role() == ROLE_DOMAIN_PDC ||
+ lp_server_role() == ROLE_IPA_DC) {
new_guid = GUID_random();
if (!secrets_store_domain_guid(domain, &new_guid))
return False;
enum netr_SchannelType get_default_sec_channel(void)
{
- if (lp_server_role() == ROLE_DOMAIN_BDC ||
- lp_server_role() == ROLE_DOMAIN_PDC ||
- lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+ if (IS_DC) {
return SEC_CHAN_BDC;
} else {
return SEC_CHAN_WKSTA;
switch (lp_server_role()) {
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
value_ascii = "LanmanNT";
break;
case ROLE_STANDALONE:
basic->domain = get_global_sam_name();
break;
case ROLE_DOMAIN_PDC:
+ case ROLE_IPA_DC:
basic->role = DS_ROLE_PRIMARY_DC;
basic->domain = get_global_sam_name();
break;
exit_daemon("smbd can not open secrets.tdb", EACCES);
}
- if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
+ if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC || lp_server_role() == ROLE_IPA_DC) {
struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
if (!open_schannel_session_store(NULL, lp_ctx)) {
exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
case SEC_CHAN_BDC: {
int role = lp_server_role();
- if (role == ROLE_DOMAIN_PDC) {
+ if (role == ROLE_DOMAIN_PDC || role == ROLE_IPA_DC) {
s = talloc_strdup(mem_ctx, "PDC");
if (s == NULL) {
return NULL;
secure_channel_type = SEC_CHAN_LOCAL;
}
- status = add_trusted_domain(get_global_sam_name(),
- NULL,
- get_global_sam_sid(),
- LSA_TRUST_TYPE_DOWNLEVEL,
- trust_flags,
- 0, /* trust_attribs */
- secure_channel_type,
- NULL,
- &domain);
+ if ((pdb_domain_info != NULL) && (role == ROLE_IPA_DC)) {
+ /* This is IPA DC that presents itself as
+ * an Active Directory domain controller to trusted AD
+ * forests but in fact is a classic domain controller.
+ */
+ trust_flags = NETR_TRUST_FLAG_PRIMARY;
+ trust_flags |= NETR_TRUST_FLAG_IN_FOREST;
+ trust_flags |= NETR_TRUST_FLAG_NATIVE;
+ trust_flags |= NETR_TRUST_FLAG_OUTBOUND;
+ trust_flags |= NETR_TRUST_FLAG_TREEROOT;
+ status = add_trusted_domain(pdb_domain_info->name,
+ pdb_domain_info->dns_domain,
+ &pdb_domain_info->sid,
+ LSA_TRUST_TYPE_UPLEVEL,
+ trust_flags,
+ LSA_TRUST_ATTRIBUTE_WITHIN_FOREST,
+ secure_channel_type,
+ NULL,
+ &domain);
+ TALLOC_FREE(pdb_domain_info);
+ } else {
+ status = add_trusted_domain(get_global_sam_name(),
+ NULL,
+ get_global_sam_sid(),
+ LSA_TRUST_TYPE_DOWNLEVEL,
+ trust_flags,
+ 0, /* trust_attribs */
+ secure_channel_type,
+ NULL,
+ &domain);
+ }
if (!NT_STATUS_IS_OK(status)) {
DBG_ERR("Failed to add local SAM to "
"domain to winbindd's internal list\n");
case ROLE_DOMAIN_BDC:
case ROLE_DOMAIN_PDC:
case ROLE_ACTIVE_DIRECTORY_DC:
+ case ROLE_IPA_DC:
auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
break;
}
return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
task_server_terminate(
task, "Cannot start KDC as a 'classic Samba' DC", false);
return NT_STATUS_INVALID_DOMAIN_ROLE;
break;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
case ROLE_AUTO:
return NT_STATUS_INTERNAL_ERROR;
case ROLE_DOMAIN_MEMBER:
break;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
+ case ROLE_IPA_DC:
case ROLE_AUTO:
return NT_STATUS_INTERNAL_ERROR;
case ROLE_DOMAIN_MEMBER: