cldap.c

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

C
740
字号
	struct cldap_request *req;	DATA_BLOB blob1, blob2;	NTSTATUS status = NT_STATUS_NO_MEMORY;	req = talloc_zero(cldap, struct cldap_request);	if (req == NULL) goto failed;	req->cldap       = cldap;	req->state       = CLDAP_REQUEST_SEND;	req->is_reply    = true;	req->asn1        = asn1_init(req);	if (!req->asn1) {		goto failed;	}	req->dest        = io->dest;	if (talloc_reference(req, io->dest) == NULL) goto failed;	talloc_set_destructor(req, cldap_request_destructor);	msg = talloc(req, struct ldap_message);	if (msg == NULL) goto failed;	msg->messageid       = io->messageid;	msg->controls        = NULL;		if (io->response) {		msg->type = LDAP_TAG_SearchResultEntry;		msg->r.SearchResultEntry = *io->response;		if (!ldap_encode(msg, &blob1, req)) {			DEBUG(0,("Failed to encode cldap message to %s:%d\n",				 req->dest->addr, req->dest->port));			status = NT_STATUS_INVALID_PARAMETER;			goto failed;		}	} else {		blob1 = data_blob(NULL, 0);	}	msg->type = LDAP_TAG_SearchResultDone;	msg->r.SearchResultDone = *io->result;	if (!ldap_encode(msg, &blob2, req)) {		DEBUG(0,("Failed to encode cldap message to %s:%d\n",			 req->dest->addr, req->dest->port));		status = NT_STATUS_INVALID_PARAMETER;		goto failed;	}	req->encoded = data_blob_talloc(req, NULL, blob1.length + blob2.length);	if (req->encoded.data == NULL) goto failed;	memcpy(req->encoded.data, blob1.data, blob1.length);	memcpy(req->encoded.data+blob1.length, blob2.data, blob2.length);	DLIST_ADD_END(cldap->send_queue, req, struct cldap_request *);	EVENT_FD_WRITEABLE(cldap->fde);	return NT_STATUS_OK;failed:	talloc_free(req);	return status;}/*  receive a cldap reply*/NTSTATUS cldap_search_recv(struct cldap_request *req, 			   TALLOC_CTX *mem_ctx, 			   struct cldap_search *io){	struct ldap_message *ldap_msg;	NTSTATUS status;	if (req == NULL) {		return NT_STATUS_NO_MEMORY;	}	while (req->state < CLDAP_REQUEST_DONE) {		if (event_loop_once(req->cldap->event_ctx) != 0) {			talloc_free(req);			return NT_STATUS_UNEXPECTED_NETWORK_ERROR;		}	}	if (req->state == CLDAP_REQUEST_ERROR) {		status = req->status;		talloc_free(req);		return status;	}	ldap_msg = talloc(mem_ctx, struct ldap_message);	NT_STATUS_HAVE_NO_MEMORY(ldap_msg);	status = ldap_decode(req->asn1, ldap_msg);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status)));		talloc_free(req);		return status;	}	ZERO_STRUCT(io->out);	/* the first possible form has a search result in first place */	if (ldap_msg->type == LDAP_TAG_SearchResultEntry) {		io->out.response = talloc(mem_ctx, struct ldap_SearchResEntry);		NT_STATUS_HAVE_NO_MEMORY(io->out.response);		*io->out.response = ldap_msg->r.SearchResultEntry;		/* decode the 2nd part */		status = ldap_decode(req->asn1, ldap_msg);		if (!NT_STATUS_IS_OK(status)) {			DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status)));			talloc_free(req);			return status;		}	}	if (ldap_msg->type != LDAP_TAG_SearchResultDone) {		talloc_free(req);		return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);	}	io->out.result = talloc(mem_ctx, struct ldap_Result);	NT_STATUS_HAVE_NO_MEMORY(io->out.result);	*io->out.result = ldap_msg->r.SearchResultDone;	talloc_free(req);	if (io->out.result->resultcode != LDAP_SUCCESS) {		return NT_STATUS_LDAP(io->out.result->resultcode);	}	return NT_STATUS_OK;}/*  synchronous cldap search*/NTSTATUS cldap_search(struct cldap_socket *cldap, 		      TALLOC_CTX *mem_ctx, 		      struct cldap_search *io){	struct cldap_request *req = cldap_search_send(cldap, io);	return cldap_search_recv(req, mem_ctx, io);}/*  queue a cldap netlogon for send*/struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap, 					  struct cldap_netlogon *io){	struct cldap_search search;	char *filter;	struct cldap_request *req;	const char *attr[] = { "NetLogon", NULL };	TALLOC_CTX *tmp_ctx = talloc_new(cldap);	filter = talloc_asprintf(tmp_ctx, "(&(NtVer=%s)", 				 ldap_encode_ndr_uint32(tmp_ctx, io->in.version));	if (filter == NULL) goto failed;	if (io->in.user) {		filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user);		if (filter == NULL) goto failed;	}	if (io->in.host) {		filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host);		if (filter == NULL) goto failed;	}	if (io->in.realm) {		filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm);		if (filter == NULL) goto failed;	}	if (io->in.acct_control != -1) {		filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)", 						ldap_encode_ndr_uint32(tmp_ctx, io->in.acct_control));		if (filter == NULL) goto failed;	}	if (io->in.domain_sid) {		struct dom_sid *sid = dom_sid_parse_talloc(tmp_ctx, io->in.domain_sid);		if (sid == NULL) goto failed;		filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)",						ldap_encode_ndr_dom_sid(tmp_ctx, sid));		if (filter == NULL) goto failed;	}	if (io->in.domain_guid) {		struct GUID guid;		NTSTATUS status;		status = GUID_from_string(io->in.domain_guid, &guid);		if (!NT_STATUS_IS_OK(status)) goto failed;		filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)",						ldap_encode_ndr_GUID(tmp_ctx, &guid));		if (filter == NULL) goto failed;	}	filter = talloc_asprintf_append_buffer(filter, ")");	if (filter == NULL) goto failed;	search.in.dest_address = io->in.dest_address;	search.in.dest_port    = io->in.dest_port;	search.in.filter       = filter;	search.in.attributes   = attr;	search.in.timeout      = 2;	search.in.retries      = 2;	req = cldap_search_send(cldap, &search);	talloc_free(tmp_ctx);	return req;failed:	talloc_free(tmp_ctx);	return NULL;}/*  receive a cldap netlogon reply*/NTSTATUS cldap_netlogon_recv(struct cldap_request *req, 			     TALLOC_CTX *mem_ctx, 			     struct cldap_netlogon *io){	NTSTATUS status;	struct cldap_search search;	struct cldap_socket *cldap;	DATA_BLOB *data;	cldap = req->cldap;	status = cldap_search_recv(req, mem_ctx, &search);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	if (search.out.response == NULL) {		return NT_STATUS_NOT_FOUND;	}	if (search.out.response->num_attributes != 1 ||	    strcasecmp(search.out.response->attributes[0].name, "netlogon") != 0 ||	    search.out.response->attributes[0].num_values != 1 ||	    search.out.response->attributes[0].values->length < 2) {		return NT_STATUS_UNEXPECTED_NETWORK_ERROR;	}	data = search.out.response->attributes[0].values;	status = pull_netlogon_samlogon_response(data, mem_ctx, req->cldap->iconv_convenience,						 &io->out.netlogon);	if (!NT_STATUS_IS_OK(status)) {		return status;	}		if (io->in.map_response) {		map_netlogon_samlogon_response(&io->out.netlogon);	}	return NT_STATUS_OK;}/*  sync cldap netlogon search*/NTSTATUS cldap_netlogon(struct cldap_socket *cldap, 			TALLOC_CTX *mem_ctx, struct cldap_netlogon *io){	struct cldap_request *req = cldap_netlogon_send(cldap, io);	return cldap_netlogon_recv(req, mem_ctx, io);}/*  send an empty reply (used on any error, so the client doesn't keep waiting  or send the bad request again)*/NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, 			   uint32_t message_id,			   struct socket_address *src){	NTSTATUS status;	struct cldap_reply reply;	struct ldap_Result result;	reply.messageid    = message_id;	reply.dest         = src;	reply.response     = NULL;	reply.result       = &result;	ZERO_STRUCT(result);	status = cldap_reply_send(cldap, &reply);	return status;}/*  send an error reply (used on any error, so the client doesn't keep waiting  or send the bad request again)*/NTSTATUS cldap_error_reply(struct cldap_socket *cldap, 			   uint32_t message_id,			   struct socket_address *src,			   int resultcode,			   const char *errormessage){	NTSTATUS status;	struct cldap_reply reply;	struct ldap_Result result;	reply.messageid    = message_id;	reply.dest         = src;	reply.response     = NULL;	reply.result       = &result;	ZERO_STRUCT(result);	result.resultcode	= resultcode;	result.errormessage	= errormessage;	status = cldap_reply_send(cldap, &reply);	return status;}/*  send a netlogon reply */NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, 			      uint32_t message_id,			      struct socket_address *src,			      uint32_t version,			      struct netlogon_samlogon_response *netlogon){	NTSTATUS status;	struct cldap_reply reply;	struct ldap_SearchResEntry response;	struct ldap_Result result;	TALLOC_CTX *tmp_ctx = talloc_new(cldap);	DATA_BLOB blob;	status = push_netlogon_samlogon_response(&blob, tmp_ctx, cldap->iconv_convenience,						 netlogon);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	reply.messageid    = message_id;	reply.dest         = src;	reply.response     = &response;	reply.result       = &result;	ZERO_STRUCT(result);	response.dn = "";	response.num_attributes = 1;	response.attributes = talloc(tmp_ctx, struct ldb_message_element);	NT_STATUS_HAVE_NO_MEMORY(response.attributes);	response.attributes->name = "netlogon";	response.attributes->num_values = 1;	response.attributes->values = &blob;	status = cldap_reply_send(cldap, &reply);	talloc_free(tmp_ctx);	return status;}

⌨️ 快捷键说明

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