libnet_become_dc.c

来自「samba最新软件」· C语言 代码 · 共 2,239 行 · 第 1/5 页

C
2,239
字号
 *	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_context *libnet;	struct dom_sid zero_sid;	struct {		struct cldap_socket *sock;		struct cldap_netlogon io;		struct NETLOGON_SAM_LOGON_RESPONSE_EX netlogon;	} cldap;	struct becomeDC_ldap {		struct ldb_context *ldb;		const struct ldb_message *rootdse;	} ldap1, ldap2;	struct becomeDC_drsuapi {		struct libnet_BecomeDC_state *s;		struct dcerpc_binding *binding;		struct dcerpc_pipe *pipe;		DATA_BLOB gensec_skey;		struct drsuapi_DsBind bind_r;		struct GUID bind_guid;		struct drsuapi_DsBindInfoCtr bind_info_ctr;		struct drsuapi_DsBindInfo28 local_info28;		struct drsuapi_DsBindInfo28 remote_info28;		struct policy_handle bind_handle;	} drsuapi1, drsuapi2, drsuapi3;	struct libnet_BecomeDC_Domain domain;	struct libnet_BecomeDC_Forest forest;	struct libnet_BecomeDC_SourceDSA source_dsa;	struct libnet_BecomeDC_DestDSA dest_dsa;	struct libnet_BecomeDC_Partition schema_part, config_part, domain_part;	struct becomeDC_fsmo {		const char *dns_name;		const char *server_dn_str;		const char *ntds_dn_str;		struct GUID ntds_guid;	} infrastructure_fsmo;	struct becomeDC_fsmo rid_manager_fsmo;	struct libnet_BecomeDC_CheckOptions _co;	struct libnet_BecomeDC_PrepareDB _pp;	struct libnet_BecomeDC_StoreChunk _sc;	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.dest_port	= lp_cldap_port(s->libnet->lp_ctx);	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		= NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;	s->cldap.io.in.map_response	= true;	s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx, 					  lp_iconv_convenience(s->libnet->lp_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){	struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private,					  struct libnet_BecomeDC_state);	struct composite_context *c = s->creq;	c->status = cldap_netlogon_recv(req, s, &s->cldap.io);	if (!composite_is_ok(c)) return;	s->cldap.netlogon = s->cldap.io.out.netlogon.nt5_ex;	s->domain.dns_name		= s->cldap.netlogon.dns_domain;	s->domain.netbios_name		= s->cldap.netlogon.domain;	s->domain.guid			= s->cldap.netlogon.domain_uuid;	s->forest.dns_name		= s->cldap.netlogon.forest;	s->source_dsa.dns_name		= s->cldap.netlogon.pdc_dns_name;	s->source_dsa.netbios_name	= s->cldap.netlogon.pdc_name;	s->source_dsa.site_name		= s->cldap.netlogon.server_site;	s->dest_dsa.site_name		= s->cldap.netlogon.client_site;	becomeDC_connect_ldap1(s);}static NTSTATUS becomeDC_ldap_connect(struct libnet_BecomeDC_state *s, 				      struct becomeDC_ldap *ldap){	char *url;	url = talloc_asprintf(s, "ldap://%s/", s->source_dsa.dns_name);	NT_STATUS_HAVE_NO_MEMORY(url);	ldap->ldb = ldb_wrap_connect(s, s->libnet->event_ctx, s->libnet->lp_ctx, url,				     NULL,				     s->libnet->cred,				     0, NULL);	talloc_free(url);	if (ldap->ldb == NULL) {		return NT_STATUS_UNEXPECTED_NETWORK_ERROR;	}	return NT_STATUS_OK;}static NTSTATUS becomeDC_ldap1_rootdse(struct libnet_BecomeDC_state *s){	int ret;	struct ldb_result *r;	struct ldb_dn *basedn;	static const char *attrs[] = {		"*",		NULL	};	basedn = ldb_dn_new(s, s->ldap1.ldb, NULL);	NT_STATUS_HAVE_NO_MEMORY(basedn);	ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE, 			 "(objectClass=*)", attrs, &r);	talloc_free(basedn);	if (ret != LDB_SUCCESS) {		return NT_STATUS_LDAP(ret);	} else if (r->count != 1) {		talloc_free(r);		return NT_STATUS_INVALID_NETWORK_RESPONSE;	}	talloc_steal(s, r);	s->ldap1.rootdse = r->msgs[0];	s->domain.dn_str	= ldb_msg_find_attr_as_string(s->ldap1.rootdse, "defaultNamingContext", NULL);	if (!s->domain.dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;	s->forest.root_dn_str	= ldb_msg_find_attr_as_string(s->ldap1.rootdse, "rootDomainNamingContext", NULL);	if (!s->forest.root_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;	s->forest.config_dn_str	= ldb_msg_find_attr_as_string(s->ldap1.rootdse, "configurationNamingContext", NULL);	if (!s->forest.config_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;	s->forest.schema_dn_str	= ldb_msg_find_attr_as_string(s->ldap1.rootdse, "schemaNamingContext", NULL);	if (!s->forest.schema_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;	s->source_dsa.server_dn_str	= ldb_msg_find_attr_as_string(s->ldap1.rootdse, "serverName", NULL);	if (!s->source_dsa.server_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;	s->source_dsa.ntds_dn_str	= ldb_msg_find_attr_as_string(s->ldap1.rootdse, "dsServiceName", NULL);	if (!s->source_dsa.ntds_dn_str) return NT_STATUS_INVALID_NETWORK_RESPONSE;	return NT_STATUS_OK;}static NTSTATUS becomeDC_ldap1_crossref_behavior_version(struct libnet_BecomeDC_state *s){	int ret;	struct ldb_result *r;	struct ldb_dn *basedn;	static const char *attrs[] = {		"msDs-Behavior-Version",		NULL	};	basedn = ldb_dn_new(s, s->ldap1.ldb, s->forest.config_dn_str);	NT_STATUS_HAVE_NO_MEMORY(basedn);	ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_ONELEVEL,			 "(cn=Partitions)", attrs, &r);	talloc_free(basedn);	if (ret != LDB_SUCCESS) {		return NT_STATUS_LDAP(ret);	} else if (r->count != 1) {		talloc_free(r);		return NT_STATUS_INVALID_NETWORK_RESPONSE;	}	s->forest.crossref_behavior_version = ldb_msg_find_attr_as_uint(r->msgs[0], "msDs-Behavior-Version", 0);	talloc_free(r);	return NT_STATUS_OK;}static NTSTATUS becomeDC_ldap1_domain_behavior_version(struct libnet_BecomeDC_state *s){	int ret;	struct ldb_result *r;	struct ldb_dn *basedn;	static const char *attrs[] = {		"msDs-Behavior-Version",		NULL	};	basedn = ldb_dn_new(s, s->ldap1.ldb, s->domain.dn_str);	NT_STATUS_HAVE_NO_MEMORY(basedn);	ret = ldb_search(s->ldap1.ldb, basedn, LDB_SCOPE_BASE,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?