libnet_become_dc.c

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

C
2,239
字号
	}	talloc_free(r);	return NT_STATUS_OK;}static NTSTATUS becomeDC_ldap1_server_object_add(struct libnet_BecomeDC_state *s){	int ret;	struct ldb_message *msg;	char *server_dn_str;	/* if the server_dn_str has a valid value, we skip this lookup */	if (s->dest_dsa.server_dn_str) return NT_STATUS_OK;	msg = ldb_msg_new(s);	NT_STATUS_HAVE_NO_MEMORY(msg);	msg->dn = ldb_dn_new_fmt(msg, s->ldap1.ldb, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",				 s->dest_dsa.netbios_name,				 s->dest_dsa.site_name,				 s->forest.config_dn_str);	NT_STATUS_HAVE_NO_MEMORY(msg->dn);	ret = ldb_msg_add_string(msg, "objectClass", "server");	if (ret != 0) {		talloc_free(msg);		return NT_STATUS_NO_MEMORY;	}	ret = ldb_msg_add_string(msg, "systemFlags", "50000000");	if (ret != 0) {		talloc_free(msg);		return NT_STATUS_NO_MEMORY;	}	ret = ldb_msg_add_string(msg, "serverReference", s->dest_dsa.computer_dn_str);	if (ret != 0) {		talloc_free(msg);		return NT_STATUS_NO_MEMORY;	}	server_dn_str = ldb_dn_alloc_linearized(s, msg->dn);	NT_STATUS_HAVE_NO_MEMORY(server_dn_str);	ret = ldb_add(s->ldap1.ldb, msg);	talloc_free(msg);	if (ret != LDB_SUCCESS) {		talloc_free(server_dn_str);		return NT_STATUS_LDAP(ret);	}	s->dest_dsa.server_dn_str = server_dn_str;	return NT_STATUS_OK;}static NTSTATUS becomeDC_ldap1_server_object_modify(struct libnet_BecomeDC_state *s){	int ret;	struct ldb_message *msg;	uint32_t i;	/* make a 'modify' msg, and only for serverReference */	msg = ldb_msg_new(s);	NT_STATUS_HAVE_NO_MEMORY(msg);	msg->dn = ldb_dn_new(msg, s->ldap1.ldb, s->dest_dsa.server_dn_str);	NT_STATUS_HAVE_NO_MEMORY(msg->dn);	ret = ldb_msg_add_string(msg, "serverReference", s->dest_dsa.computer_dn_str);	if (ret != 0) {		talloc_free(msg);		return NT_STATUS_NO_MEMORY;	}	/* mark all the message elements (should be just one)	   as LDB_FLAG_MOD_ADD */	for (i=0;i<msg->num_elements;i++) {		msg->elements[i].flags = LDB_FLAG_MOD_ADD;	}	ret = ldb_modify(s->ldap1.ldb, msg);	if (ret == LDB_SUCCESS) {		talloc_free(msg);		return NT_STATUS_OK;	} else if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {		/* retry with LDB_FLAG_MOD_REPLACE */	} else {		talloc_free(msg);		return NT_STATUS_LDAP(ret);	}	/* mark all the message elements (should be just one)	   as LDB_FLAG_MOD_REPLACE */	for (i=0;i<msg->num_elements;i++) {		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;	}	ret = ldb_modify(s->ldap1.ldb, msg);	talloc_free(msg);	if (ret != LDB_SUCCESS) {		return NT_STATUS_LDAP(ret);	}	return NT_STATUS_OK;}static void becomeDC_drsuapi_connect_send(struct libnet_BecomeDC_state *s,					  struct becomeDC_drsuapi *drsuapi,					  void (*recv_fn)(struct composite_context *req));static void becomeDC_drsuapi1_connect_recv(struct composite_context *req);static void becomeDC_connect_ldap2(struct libnet_BecomeDC_state *s);static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s){	struct composite_context *c = s->creq;	c->status = becomeDC_ldap_connect(s, &s->ldap1);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_rootdse(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_crossref_behavior_version(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_domain_behavior_version(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_schema_object_version(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_w2k3_update_revision(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_infrastructure_fsmo(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_rid_manager_fsmo(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_site_object(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_check_options(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_computer_object(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_server_object_1(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_server_object_2(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_server_object_add(s);	if (!composite_is_ok(c)) return;	c->status = becomeDC_ldap1_server_object_modify(s);	if (!composite_is_ok(c)) return;	becomeDC_drsuapi_connect_send(s, &s->drsuapi1, becomeDC_drsuapi1_connect_recv);}static void becomeDC_drsuapi_connect_send(struct libnet_BecomeDC_state *s,					  struct becomeDC_drsuapi *drsuapi,					  void (*recv_fn)(struct composite_context *req)){	struct composite_context *c = s->creq;	struct composite_context *creq;	char *binding_str;	drsuapi->s = s;	if (!drsuapi->binding) {		if (lp_parm_bool(s->libnet->lp_ctx, NULL, "become_dc", "print", false)) {			binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[print,seal]", s->source_dsa.dns_name);			if (composite_nomem(binding_str, c)) return;		} else {			binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[seal]", s->source_dsa.dns_name);			if (composite_nomem(binding_str, c)) return;		}		c->status = dcerpc_parse_binding(s, binding_str, &drsuapi->binding);		talloc_free(binding_str);		if (!composite_is_ok(c)) return;	}	creq = dcerpc_pipe_connect_b_send(s, drsuapi->binding, &ndr_table_drsuapi,					  s->libnet->cred, s->libnet->event_ctx,					  s->libnet->lp_ctx);	composite_continue(c, creq, recv_fn, s);}static void becomeDC_drsuapi_bind_send(struct libnet_BecomeDC_state *s,				       struct becomeDC_drsuapi *drsuapi,				       void (*recv_fn)(struct rpc_request *req));static void becomeDC_drsuapi1_bind_recv(struct rpc_request *req);static void becomeDC_drsuapi1_connect_recv(struct composite_context *req){	struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,					  struct libnet_BecomeDC_state);	struct composite_context *c = s->creq;	c->status = dcerpc_pipe_connect_b_recv(req, s, &s->drsuapi1.pipe);	if (!composite_is_ok(c)) return;	c->status = gensec_session_key(s->drsuapi1.pipe->conn->security_state.generic_state,				       &s->drsuapi1.gensec_skey);	if (!composite_is_ok(c)) return;	becomeDC_drsuapi_bind_send(s, &s->drsuapi1, becomeDC_drsuapi1_bind_recv);}static void becomeDC_drsuapi_bind_send(struct libnet_BecomeDC_state *s,				       struct becomeDC_drsuapi *drsuapi,				       void (*recv_fn)(struct rpc_request *req)){	struct composite_context *c = s->creq;	struct rpc_request *req;	struct drsuapi_DsBindInfo28 *bind_info28;	GUID_from_string(DRSUAPI_DS_BIND_GUID_W2K3, &drsuapi->bind_guid);	bind_info28				= &drsuapi->local_info28;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_BASE;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;	if (s->domain.behavior_version == 2) {		/* TODO: find out how this is really triggered! */		bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;	}	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_00100000;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;#if 0 /* we don't support XPRESS compression yet */	bind_info28->supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;#endif	bind_info28->site_guid			= s->dest_dsa.site_guid;	if (s->domain.behavior_version == 2) {		/* TODO: find out how this is really triggered! */		bind_info28->u1				= 528;	} else {		bind_info28->u1				= 516;	}	bind_info28->repl_epoch			= 0;	drsuapi->bind_info_ctr.length		= 28;	drsuapi->bind_info_ctr.info.info28	= *bind_info28;	drsuapi->bind_r.in.bind_guid = &drsuapi->bind_guid;	drsuapi->bind_r.in.bind_info = &drsuapi->bind_info_ctr;	drsuapi->bind_r.out.bind_handle = &drsuapi->bind_handle;	req = dcerpc_drsuapi_DsBind_send(drsuapi->pipe, s, &drsuapi->bind_r);	composite_continue_rpc(c, req, recv_fn, s);}static WERROR becomeDC_drsuapi_bind_recv(struct libnet_BecomeDC_state *s,					 struct becomeDC_drsuapi *drsuapi){	if (!W_ERROR_IS_OK(drsuapi->bind_r.out.result)) {		return drsuapi->bind_r.out.result;	}	ZERO_STRUCT(drsuapi->remote_info28);	if (drsuapi->bind_r.out.bind_info) {		switch (drsuapi->bind_r.out.bind_info->length) {		case 24: {			struct drsuapi_DsBindInfo24 *info24;			info24 = &drsuapi->bind_r.out.bind_info->info.info24;			drsuapi->remote_info28.supported_extensions	= info24->supported_extensions;			drsuapi->remote_info28.site_guid		= info24->site_guid;			drsuapi->remote_info28.u1			= info24->u1;			drsuapi->remote_info28.repl_epoch		= 0;			break;		}		case 28:			drsuapi->remote_info28 = drsuapi->bind_r.out.bind_info->info.info28;			break;		}	}	return WERR_OK;}static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s);static void becomeDC_drsuapi1_bind_recv(struct rpc_request *req){	struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,					  struct libnet_BecomeDC_state);	struct composite_context *c = s->creq;	WERROR status;	bool print = false;	if (req->p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {		print = true;	}	c->status = dcerpc_ndr_request_recv(req);	if (!composite_is_ok(c)) return;	if (print) {		NDR_PRINT_OUT_DEBUG(drsuapi_DsBind, &s->drsuapi1.bind_r);	}	status = becomeDC_drsuapi_bind_recv(s, &s->drsuapi1);	if (!W_ERROR_IS_OK(status)) {		composite_error(c, werror_to_ntstatus(status));		return;	}	becomeDC_drsuapi1_add_entry_send(s);}static void becomeDC_drsuapi1_add_entry_recv(struct rpc_request *req);static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s){	struct composite_context *c = s->creq;	struct rpc_request *req;	struct drsuapi_DsAddEntry *r;	struct drsuapi_DsReplicaObjectIdentifier *identifier;	uint32_t num_attrs, i = 0;	struct drsuapi_DsReplicaAttribute *attrs;	struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(s->libnet->lp_ctx);	enum ndr_err_code ndr_err;	bool w2k3;	/* choose a random invocationId */	s->dest_dsa.invocation_id = GUID_random();	/*	 * if the schema version indicates w2k3, then	 * also send some w2k3 specific attributes	 */	if (s->forest.schema_object_version >= 30) {		w2k3 = true;	} else {		w2k3 = false;	}	r = talloc_zero(s, struct drsuapi_DsAddEntry);	if (composite_nomem(r, c)) return;	/* setup identifier */	identifier		= talloc(r, struct drsuapi_DsReplicaObjectIdentifier);	if (composite_nomem(identifier, c)) return;	identifier->guid	= GUID_zero();	identifier->sid		= s->zero_sid;	identifier->dn		= talloc_asprintf(identifier, "CN=NTDS Settings,%s",						  s->dest_dsa.server_dn_str);	if (composite_nomem(identifier->dn, c)) return;	/* allocate attribute array */	num_attrs	= 11;	attrs		= talloc_array(r, struct drsuapi_DsReplicaAttribute, num_attrs);	if (composite_nomem(attrs, c)) return;	/* ntSecurityDescriptor */	{		struct drsuapi_DsAttributeValue *vs;		DATA_BLOB *vd;		struct security_descriptor *v;		struct dom_sid *domain_admins_sid;		const char *domain_admins_sid_str;		vs = talloc_array(attrs, struct drsuapi_DsAttributeValue, 1);		if (composite_nomem(vs, c)) return;		vd = talloc_array(vs, DATA_BLOB, 1);		if (composite_nomem(vd, c)) return;		domain_admins_sid = dom_sid_add_rid(vs, s->domain.sid, DOMAIN_RID_ADMINS);		if (composite_nomem(domain_admins_sid, c)) return;		domain_admins_sid_str = dom_sid_string(domain_admins_sid, domain_admins_sid);		if (composite_nomem(domain_admins_sid_str, c)) return;		v = security_descriptor_dacl_create(vd,					       0,					       /* owner: domain admins */					       domain_admins_sid_str,					       /* owner group: domain admins */					       domain_admins_sid_str,					       /* authenticated users */					       SID_NT_AUTHENTICATED_USERS,					       SEC_ACE_TYPE_ACCESS_ALLOWED,					       SEC_STD_READ_CONTROL |					       SEC_ADS_LIST |					       SEC_ADS_READ_PROP |					       SEC_ADS_LIST_OBJECT,					       0,					       /* domain admins */					       domain_admins_sid_str,					       SEC_ACE_TYPE_ACCESS_ALLOWED,					       SEC_STD_REQUIRED |					       SEC_ADS_CREATE_CHILD |					       SEC_ADS_LIST |					       SEC_ADS_SELF_WRITE |					       SEC_ADS_READ_PROP |					       SEC_ADS_WRITE_PROP |					       SEC_ADS_DELETE_TREE |					       SEC_ADS_LIST_OBJECT |					       SEC_ADS_CONTROL_ACCESS,					       0,					       /* system */					       SID_NT_SYSTEM,					       SEC_ACE_TYPE_ACCESS_ALLOWED,					       SEC_STD_REQUIRED |					       SEC_ADS_CREATE_CHILD |					       SEC_ADS_DELETE_CHILD |					       SEC_ADS_LIST |					       SEC_ADS_SELF_WRITE |					       SEC_ADS_READ_PROP |					       SEC_ADS_WRITE_PROP |					       SEC_ADS_DELETE_TREE |					       SEC_ADS_LIST_OBJECT |					       SEC_ADS_CONTROL_ACCESS,					       0,					       /* end */					       NULL);		if (composite_nomem(v, c)) return;		ndr_err = ndr_push_struct_blob(&vd[0], vd, iconv_convenience, v,(ndr_push_flags_fn_t)ndr_push_security_descriptor);

⌨️ 快捷键说明

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