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 + -
显示快捷键?