summaryrefslogtreecommitdiff
path: root/source4/libnet/libnet_become_dc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libnet/libnet_become_dc.c')
-rw-r--r--source4/libnet/libnet_become_dc.c643
1 files changed, 643 insertions, 0 deletions
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index dc1b064eb0..a0cce15cff 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -34,6 +34,649 @@
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "auth/gensec/gensec.h"
+/*****************************************************************************
+ * Windows 2003 (w2k3) does the following steps when changing the server role
+ * from domain member to domain controller
+ *
+ * We mostly do the same.
+ *****************************************************************************/
+
+/*
+ * lookup DC:
+ * - using nbt name<1C> request and a samlogon mailslot request
+ * or
+ * - using a DNS SRV _ldap._tcp.dc._msdcs. request and a CLDAP netlogon request
+ *
+ * see: becomeDC_recv_cldap() and becomeDC_send_cldap()
+ */
+
+/*
+ * Open 1st LDAP connection to the DC using admin credentials
+ *
+ * see: becomeDC_connect_ldap1() and becomeDC_ldap_connect()
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_rootdse()
+ *
+ * Request:
+ * basedn: ""
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: *
+ * Result:
+ * ""
+ * currentTime: 20061202155100.0Z
+ * subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,<domain_partition>
+ * dsServiceName: CN=<netbios_name>,CN=Servers,CN=<site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * namingContexts: <domain_partition>
+ * CN=Configuration,<domain_partition>
+ * CN=Schema,CN=Configuration,<domain_partition>
+ * defaultNamingContext: <domain_partition>
+ * schemaNamingContext: CN=Schema,CN=Configuration,<domain_partition>
+ * configurationNamingContext:CN=Configuration,<domain_partition>
+ * rootDomainNamingContext:<domain_partition>
+ * supportedControl: ...
+ * supportedLDAPVersion: 3
+ * 2
+ * supportedLDAPPolicies: ...
+ * highestCommitedUSN: ...
+ * supportedSASLMechanisms:GSSAPI
+ * GSS-SPNEGO
+ * EXTERNAL
+ * DIGEST-MD5
+ * dnsHostName: <dns_host_name>
+ * ldapServiceName: <domain_dns_name>:<netbios_name>$@<REALM>
+ * serverName: CN=Servers,CN=<site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * supportedCapabilities: ...
+ * isSyncronized: TRUE
+ * isGlobalCatalogReady: TRUE
+ * domainFunctionality: 0
+ * forestFunctionality: 0
+ * domainControllerFunctionality: 2
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_crossref_behavior_version()
+ *
+ * Request:
+ * basedn: CN=Configuration,<domain_partition>
+ * scope: one
+ * filter: (cn=Partitions)
+ * attrs: msDS-Behavior-Version
+ * Result:
+ * CN=Partitions,CN=Configuration,<domain_partition>
+ * msDS-Behavior-Version: 0
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * NOTE: this seems to be a bug! as the messageID of the LDAP message is corrupted!
+ *
+ * not implemented here
+ *
+ * Request:
+ * basedn: CN=Schema,CN=Configuration,<domain_partition>
+ * scope: one
+ * filter: (cn=Partitions)
+ * attrs: msDS-Behavior-Version
+ * Result:
+ * <none>
+ *
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_domain_behavior_version()
+ *
+ * Request:
+ * basedn: <domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: msDS-Behavior-Version
+ * Result:
+ * <domain_partition>
+ * msDS-Behavior-Version: 0
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_schema_object_version()
+ *
+ * Request:
+ * basedn: CN=Schema,CN=Configuration,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: objectVersion
+ * Result:
+ * CN=Schema,CN=Configuration,<domain_partition>
+ * objectVersion: 30
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * not implemented, because the information is already there
+ *
+ * Request:
+ * basedn: ""
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: defaultNamingContext
+ * dnsHostName
+ * Result:
+ * ""
+ * defaultNamingContext: <domain_partition>
+ * dnsHostName: <dns_host_name>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_infrastructure_fsmo()
+ *
+ * Request:
+ * basedn: <WKGUID=2fbac1870ade11d297c400c04fd8d5cd,domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: 1.1
+ * Result:
+ * CN=Infrastructure,<domain_partition>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_w2k3_update_revision()
+ *
+ * Request:
+ * basedn: CN=Windows2003Update,CN=DomainUpdates,CN=System,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: revision
+ * Result:
+ * CN=Windows2003Update,CN=DomainUpdates,CN=System,<domain_partition>
+ * revision: 8
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_infrastructure_fsmo()
+ *
+ * Request:
+ * basedn: CN=Infrastructure,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: fSMORoleOwner
+ * Result:
+ * CN=Infrastructure,<domain_partition>
+ * fSMORoleOwner: CN=NTDS Settings,<infrastructure_fsmo_server_object>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_infrastructure_fsmo()
+ *
+ * Request:
+ * basedn: <infrastructure_fsmo_server_object>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: dnsHostName
+ * Result:
+ * <infrastructure_fsmo_server_object>
+ * dnsHostName: <dns_host_name>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_infrastructure_fsmo()
+ *
+ * Request:
+ * basedn: CN=NTDS Settings,<infrastructure_fsmo_server_object>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: objectGUID
+ * Result:
+ * CN=NTDS Settings,<infrastructure_fsmo_server_object>
+ * objectGUID: <object_guid>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_rid_manager_fsmo()
+ *
+ * Request:
+ * basedn: <domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: rIDManagerReference
+ * Result:
+ * <domain_partition>
+ * rIDManagerReference: CN=RID Manager$,CN=System,<domain_partition>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_rid_manager_fsmo()
+ *
+ * Request:
+ * basedn: CN=RID Manager$,CN=System,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: fSMORoleOwner
+ * Result:
+ * CN=Infrastructure,<domain_partition>
+ * fSMORoleOwner: CN=NTDS Settings,<rid_manager_fsmo_server_object>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_rid_manager_fsmo()
+ *
+ * Request:
+ * basedn: <rid_manager_fsmo_server_object>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: dnsHostName
+ * Result:
+ * <rid_manager_fsmo_server_object>
+ * dnsHostName: <dns_host_name>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_rid_manager_fsmo()
+ *
+ * Request:
+ * basedn: CN=NTDS Settings,<rid_manager_fsmo_server_object>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: msDs-ReplicationEpoch
+ * Result:
+ * CN=NTDS Settings,<rid_manager_fsmo_server_object>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_site_object()
+ *
+ * Request:
+ * basedn: CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs:
+ * Result:
+ * CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * objectClass: top
+ * site
+ * cn: <new_dc_site_name>
+ * distinguishedName:CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * instanceType: 4
+ * whenCreated: ...
+ * whenChanged: ...
+ * uSNCreated: ...
+ * uSNChanged: ...
+ * showInAdvancedViewOnly: TRUE
+ * name: <new_dc_site_name>
+ * objectGUID: <object_guid>
+ * systemFlags: 1107296256 <0x42000000>
+ * objectCategory: CN=Site,C=Schema,CN=Configuration,<domain_partition>
+ */
+
+/***************************************************************
+ * Add this stage we call the check_options() callback function
+ * of the caller, to see if he wants us to continue
+ *
+ * see: becomeDC_check_options()
+ ***************************************************************/
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_computer_object()
+ *
+ * Request:
+ * basedn: <domain_partition>
+ * scope: sub
+ * filter: (&(|(objectClass=user)(objectClass=computer))(sAMAccountName=<new_dc_account_name>))
+ * attrs: distinguishedName
+ * userAccountControl
+ * Result:
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * distinguishedName: CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * userAccoountControl: 4096 <0x1000>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_server_object_1()
+ *
+ * Request:
+ * basedn: CN=<new_dc_netbios_name>,CN=Servers,CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs:
+ * Result:
+ * <noSuchObject>
+ * <matchedDN:CN=Servers,CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_server_object_2()
+ *
+ * Request:
+ * basedn: CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: serverReferenceBL
+ * typesOnly: TRUE!!!
+ * Result:
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ */
+
+/*
+ * LDAP add 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_server_object_add()
+ *
+ * Request:
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * objectClass: server
+ * systemFlags: 50000000 <0x2FAF080>
+ * serverReference:CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * Result:
+ * <success>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * not implemented, maybe we can add that later
+ *
+ * Request:
+ * basedn: CN=NTDS Settings,CN=<new_dc_netbios_name>,CN=Servers,CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs:
+ * Result:
+ * <noSuchObject>
+ * <matchedDN:CN=<new_dc_netbios_name>,CN=Servers,CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>>
+ */
+
+/*
+ * LDAP search 1st LDAP connection:
+ *
+ * not implemented because it gives no new information
+ *
+ * Request:
+ * basedn: CN=Partitions,CN=Configuration,<domain_partition>
+ * scope: sub
+ * filter: (nCName=<domain_partition>)
+ * attrs: nCName
+ * dnsRoot
+ * controls: LDAP_SERVER_EXTENDED_DN_OID:critical=false
+ * Result:
+ * <GUID=<hex_guid>>;CN=<domain_netbios_name>,CN=Partitions,<domain_partition>>
+ * nCName: <GUID=<hex_guid>>;<SID=<hex_sid>>;<domain_partition>>
+ * dnsRoot: <domain_dns_name>
+ */
+
+/*
+ * LDAP modify 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_server_object_modify()
+ *
+ * Request (add):
+ * CN=<new_dc_netbios_name>,CN=Servers,CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>>
+ * serverReference:CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * Result:
+ * <attributeOrValueExist>
+ */
+
+/*
+ * LDAP modify 1st LDAP connection:
+ *
+ * see: becomeDC_ldap1_server_object_modify()
+ *
+ * Request (replace):
+ * CN=<new_dc_netbios_name>,CN=Servers,CN=<new_dc_site_name>,CN=Sites,CN=Configuration,<domain_partition>>
+ * serverReference:CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * Result:
+ * <success>
+ */
+
+/*
+ * Open 1st DRSUAPI connection to the DC using admin credentials
+ * DsBind with DRSUAPI_DS_BIND_GUID_W2K3 ("6afab99c-6e26-464a-975f-f58f105218bc")
+ * (w2k3 does 2 DsBind() calls here..., where is first is unused and contains garbage at the end)
+ *
+ * see: becomeDC_drsuapi_connect_send(), becomeDC_drsuapi1_connect_recv(),
+ * becomeDC_drsuapi_bind_send(), becomeDC_drsuapi_bind_recv() and becomeDC_drsuapi1_bind_recv()
+ */
+
+/*
+ * DsAddEntry to create the CN=NTDS Settings,CN=<machine_name>,CN=Servers,CN=Default-First-Site-Name, ...
+ * on the 1st DRSUAPI connection
+ *
+ * see: becomeDC_drsuapi1_add_entry_send() and becomeDC_drsuapi1_add_entry_recv()
+ */
+
+/***************************************************************
+ * Add this stage we call the prepare_db() callback function
+ * of the caller, to see if he wants us to continue
+ *
+ * see: becomeDC_prepare_db()
+ ***************************************************************/
+
+/*
+ * Open 2nd and 3rd DRSUAPI connection to the DC using admin credentials
+ * - a DsBind with DRSUAPI_DS_BIND_GUID_W2K3 ("6afab99c-6e26-464a-975f-f58f105218bc")
+ * on the 2nd connection
+ *
+ * see: becomeDC_drsuapi_connect_send(), becomeDC_drsuapi2_connect_recv(),
+ * becomeDC_drsuapi_bind_send(), becomeDC_drsuapi_bind_recv(), becomeDC_drsuapi2_bind_recv()
+ * and becomeDC_drsuapi3_connect_recv()
+ */
+
+/*
+ * replicate CN=Schema,CN=Configuration,...
+ * on the 3rd DRSUAPI connection and the bind_handle from the 2nd connection
+ *
+ * see: becomeDC_drsuapi_pull_partition_send(), becomeDC_drsuapi_pull_partition_recv(),
+ * becomeDC_drsuapi3_pull_schema_send() and becomeDC_drsuapi3_pull_schema_recv()
+ *
+ ***************************************************************
+ * Add this stage we call the schema_chunk() callback function
+ * for each replication message
+ ***************************************************************/
+
+/*
+ * replicate CN=Configuration,...
+ * on the 3rd DRSUAPI connection and the bind_handle from the 2nd connection
+ *
+ * see: becomeDC_drsuapi_pull_partition_send(), becomeDC_drsuapi_pull_partition_recv(),
+ * becomeDC_drsuapi3_pull_config_send() and becomeDC_drsuapi3_pull_config_recv()
+ *
+ ***************************************************************
+ * Add this stage we call the config_chunk() callback function
+ * for each replication message
+ ***************************************************************/
+
+/*
+ * LDAP unbind on the 1st LDAP connection
+ *
+ * not implemented, because it's not needed...
+ */
+
+/*
+ * Open 2nd LDAP connection to the DC using admin credentials
+ *
+ * see: becomeDC_connect_ldap2() and becomeDC_ldap_connect()
+ */
+
+/*
+ * LDAP search 2nd LDAP connection:
+ *
+ * not implemented because it gives no new information
+ * same as becomeDC_ldap1_computer_object()
+ *
+ * Request:
+ * basedn: <domain_partition>
+ * scope: sub
+ * filter: (&(|(objectClass=user)(objectClass=computer))(sAMAccountName=<new_dc_account_name>))
+ * attrs: distinguishedName
+ * userAccountControl
+ * Result:
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * distinguishedName: CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * userAccoountControl: 4096 <0x00001000>
+ */
+
+/*
+ * LDAP search 2nd LDAP connection:
+ *
+ * not implemented because it gives no new information
+ * same as becomeDC_ldap1_computer_object()
+ *
+ * Request:
+ * basedn: CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: userAccountControl
+ * Result:
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * userAccoountControl: 4096 <0x00001000>
+ */
+
+/*
+ * LDAP modify 2nd LDAP connection:
+ *
+ * see: becomeDC_ldap2_modify_computer()
+ *
+ * Request (replace):
+ * CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * userAccoountControl: 532480 <0x82000>
+ * Result:
+ * <success>
+ */
+
+/*
+ * LDAP search 2nd LDAP connection:
+ *
+ * see: becomeDC_ldap2_move_computer()
+ *
+ * Request:
+ * basedn: <WKGUID=2fbac1870ade11d297c400c04fd8d5cd,<domain_partition>>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: 1.1
+ * Result:
+ * CN=Domain Controllers,<domain_partition>
+ */
+
+/*
+ * LDAP search 2nd LDAP connection:
+ *
+ * not implemented because it gives no new information
+ *
+ * Request:
+ * basedn: CN=Domain Controllers,<domain_partition>
+ * scope: base
+ * filter: (objectClass=*)
+ * attrs: distinguishedName
+ * Result:
+ * CN=Domain Controller,<domain_partition>
+ * distinguishedName: CN=Domain Controllers,<domain_partition>
+ */
+
+/*
+ * LDAP modifyRDN 2nd LDAP connection:
+ *
+ * see: becomeDC_ldap2_move_computer()
+ *
+ * Request:
+ * entry: CN=<new_dc_netbios_name>,CN=Computers,<domain_partition>
+ * newrdn: CN=<new_dc_netbios_name>
+ * deleteoldrdn: TRUE
+ * newparent: CN=Domain Controllers,<domain_partition>
+ * Result:
+ * <success>
+ */
+
+/*
+ * LDAP unbind on the 2nd LDAP connection
+ *
+ * not implemented, because it's not needed...
+ */
+
+/*
+ * replicate Domain Partition
+ * on the 3rd DRSUAPI connection and the bind_handle from the 2nd connection
+ *
+ * see: becomeDC_drsuapi_pull_partition_send(), becomeDC_drsuapi_pull_partition_recv(),
+ * becomeDC_drsuapi3_pull_domain_send() and becomeDC_drsuapi3_pull_domain_recv()
+ *
+ ***************************************************************
+ * Add this stage we call the domain_chunk() callback function
+ * for each replication message
+ ***************************************************************/
+
+/* call DsReplicaUpdateRefs() for all partitions like this:
+ * req1: struct drsuapi_DsReplicaUpdateRefsRequest1
+ *
+ * naming_context: struct drsuapi_DsReplicaObjectIdentifier
+ * __ndr_size : 0x000000ae (174)
+ * __ndr_size_sid : 0x00000000 (0)
+ * guid : 00000000-0000-0000-0000-000000000000
+ * sid : S-0-0
+ * dn : 'CN=Schema,CN=Configuration,DC=w2k3,DC=vmnet1,DC=vm,DC=base'
+ *
+ * dest_dsa_dns_name : '4a0df188-a0b8-47ea-bbe5-e614723f16dd._msdcs.w2k3.vmnet1.vm.base'
+ * dest_dsa_guid : 4a0df188-a0b8-47ea-bbe5-e614723f16dd
+ * options : 0x0000001c (28)
+ * 0: DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION
+ * 0: DRSUAPI_DS_REPLICA_UPDATE_WRITEABLE
+ * 1: DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE
+ * 1: DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE
+ * 1: DRSUAPI_DS_REPLICA_UPDATE_0x00000010
+ *
+ * 4a0df188-a0b8-47ea-bbe5-e614723f16dd is the objectGUID the DsAddEntry() returned for the
+ * CN=NTDS Settings,CN=<machine_name>,CN=Servers,CN=Default-First-Site-Name, ...
+ * on the 2nd!!! DRSUAPI connection
+ *
+ * see: becomeDC_drsuapi_update_refs_send(), becomeDC_drsuapi2_update_refs_schema_recv(),
+ * becomeDC_drsuapi2_update_refs_config_recv() and becomeDC_drsuapi2_update_refs_domain_recv()
+ */
+
+/*
+ * Windows does opens the 4th and 5th DRSUAPI connection...
+ * and does a DsBind() with the objectGUID from DsAddEntry() as bind_guid
+ * on the 4th connection
+ *
+ * and then 2 full replications of the domain partition on the 5th connection
+ * with the bind_handle from the 4th connection
+ *
+ * not implemented because it gives no new information
+ */
+
struct libnet_BecomeDC_state {
struct composite_context *creq;