/*
Unix SMB/CIFS implementation.
- Copyright (C) Stefan Metzmacher 2006
+ Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "auth/gensec/gensec.h"
+#include "param/param.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;
struct libnet_BecomeDC_Callbacks callbacks;
};
+static void becomeDC_recv_cldap(struct cldap_request *req);
+
+static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
+{
+ struct composite_context *c = s->creq;
+ struct cldap_request *req;
+
+ s->cldap.io.in.dest_address = s->source_dsa.address;
+ s->cldap.io.in.realm = s->domain.dns_name;
+ s->cldap.io.in.host = s->dest_dsa.netbios_name;
+ s->cldap.io.in.user = NULL;
+ s->cldap.io.in.domain_guid = NULL;
+ s->cldap.io.in.domain_sid = NULL;
+ s->cldap.io.in.acct_control = -1;
+ s->cldap.io.in.version = 6;
+
+ s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx);
+ if (composite_nomem(s->cldap.sock, c)) return;
+
+ req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
+ if (composite_nomem(req, c)) return;
+ req->async.fn = becomeDC_recv_cldap;
+ req->async.private = s;
+}
+
static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s);
static void becomeDC_recv_cldap(struct cldap_request *req)
becomeDC_connect_ldap1(s);
}
-static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
-{
- struct composite_context *c = s->creq;
- struct cldap_request *req;
-
- s->cldap.io.in.dest_address = s->source_dsa.address;
- s->cldap.io.in.realm = s->domain.dns_name;
- s->cldap.io.in.host = s->dest_dsa.netbios_name;
- s->cldap.io.in.user = NULL;
- s->cldap.io.in.domain_guid = NULL;
- s->cldap.io.in.domain_sid = NULL;
- s->cldap.io.in.acct_control = -1;
- s->cldap.io.in.version = 6;
-
- s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx);
- if (composite_nomem(s->cldap.sock, c)) return;
-
- req = cldap_netlogon_send(s->cldap.sock, &s->cldap.io);
- if (composite_nomem(req, c)) return;
- req->async.fn = becomeDC_recv_cldap;
- req->async.private = s;
-}
-
static NTSTATUS becomeDC_ldap_connect(struct libnet_BecomeDC_state *s, struct becomeDC_ldap *ldap)
{
char *url;
if (!composite_is_ok(c)) return;
}
- creq = dcerpc_pipe_connect_b_send(s, drsuapi->binding, &dcerpc_table_drsuapi,
+ creq = dcerpc_pipe_connect_b_send(s, drsuapi->binding, &ndr_table_drsuapi,
s->libnet->cred, s->libnet->event_ctx);
composite_continue(c, creq, recv_fn, s);
}
static void becomeDC_drsuapi1_bind_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
WERROR status;
v[0].sid = s->zero_sid;
v[0].dn = talloc_asprintf(vd, "CN=NTDS-DSA,%s",
s->forest.schema_dn_str);
- if (composite_nomem(v->dn, c)) return;
+ if (composite_nomem(v[0].dn, c)) return;
c->status = ndr_push_struct_blob(&vd[0], vd, &v[0],
(ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
static void becomeDC_drsuapi1_add_entry_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsAddEntry *r = talloc_get_type(req->ndr.struct_ptr,
struct drsuapi_DsAddEntry);
+ char *binding_str;
bool print = false;
if (req->p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
c->status = becomeDC_prepare_db(s);
if (!composite_is_ok(c)) return;
+ /* this avoids the epmapper lookup on the 2nd connection */
+ binding_str = dcerpc_binding_string(s, s->drsuapi1.binding);
+ if (composite_nomem(binding_str, c)) return;
+
+ c->status = dcerpc_parse_binding(s, binding_str, &s->drsuapi2.binding);
+ talloc_free(binding_str);
+ if (!composite_is_ok(c)) return;
+
+ /* w2k3 uses the same assoc_group_id as on the first connection, so we do */
+ s->drsuapi2.binding->assoc_group_id = s->drsuapi1.pipe->assoc_group_id;
+
becomeDC_drsuapi_connect_send(s, &s->drsuapi2, becomeDC_drsuapi2_connect_recv);
}
static void becomeDC_drsuapi2_bind_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
char *binding_str;
return;
}
- /* this avoids the epmapper lookup on the 2nd connection */
- binding_str = dcerpc_binding_string(s, s->drsuapi2.binding);
+ /* this avoids the epmapper lookup on the 3rd connection */
+ binding_str = dcerpc_binding_string(s, s->drsuapi1.binding);
if (composite_nomem(binding_str, c)) return;
c->status = dcerpc_parse_binding(s, binding_str, &s->drsuapi3.binding);
talloc_free(binding_str);
if (!composite_is_ok(c)) return;
+ /* w2k3 uses the same assoc_group_id as on the first connection, so we do */
+ s->drsuapi3.binding->assoc_group_id = s->drsuapi1.pipe->assoc_group_id;
+ /* w2k3 uses the concurrent multiplex feature on the 3rd connection, so we do */
+ s->drsuapi3.binding->flags |= DCERPC_CONCURRENT_MULTIPLEX;
+
becomeDC_drsuapi_connect_send(s, &s->drsuapi3, becomeDC_drsuapi3_connect_recv);
}
* are needed for it. Or the same KRB5 TGS is needed on both
* connections.
*/
- req = dcerpc_drsuapi_DsGetNCChanges_send(drsuapi_h->pipe, r, r);
+ req = dcerpc_drsuapi_DsGetNCChanges_send(drsuapi_p->pipe, r, r);
composite_continue_rpc(c, req, recv_fn, s);
}
* we need to use the drsuapi_p->gensec_skey here,
* when we use drsuapi_p->pipe in the for this request
*/
- s->_sc.gensec_skey = &drsuapi_h->gensec_skey;
+ s->_sc.gensec_skey = &drsuapi_p->gensec_skey;
nt_status = partition->store_chunk(s->callbacks.private_data, &s->_sc);
if (!NT_STATUS_IS_OK(nt_status)) {
static void becomeDC_drsuapi3_pull_schema_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsGetNCChanges *r = talloc_get_type(req->ndr.struct_ptr,
static void becomeDC_drsuapi3_pull_config_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsGetNCChanges *r = talloc_get_type(req->ndr.struct_ptr,
static void becomeDC_drsuapi3_pull_domain_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsGetNCChanges *r = talloc_get_type(req->ndr.struct_ptr,
static void becomeDC_drsuapi2_update_refs_schema_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsReplicaUpdateRefs *r = talloc_get_type(req->ndr.struct_ptr,
static void becomeDC_drsuapi2_update_refs_config_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsReplicaUpdateRefs *r = talloc_get_type(req->ndr.struct_ptr,
static void becomeDC_drsuapi2_update_refs_domain_recv(struct rpc_request *req)
{
- struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,
+ struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
struct drsuapi_DsReplicaUpdateRefs *r = talloc_get_type(req->ndr.struct_ptr,