Changeset 988 for vendor/current/libcli/cldap/cldap.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/libcli/cldap/cldap.c
r746 r988 62 62 bool connected; 63 63 64 /*65 * we allow sync requests only, if the caller66 * did not pass an event context to cldap_socket_init()67 */68 struct {69 bool allow_poll;70 struct tevent_context *ctx;71 } event;72 73 64 /* the queue for outgoing dgrams */ 74 65 struct tevent_queue *send_queue; … … 87 78 /* what to do with incoming request packets */ 88 79 struct { 80 struct tevent_context *ev; 89 81 void (*handler)(struct cldap_socket *, 90 82 void *private_data, … … 98 90 99 91 struct { 92 struct tevent_context *ev; 100 93 struct cldap_socket *cldap; 101 94 } caller; … … 137 130 static bool cldap_recvfrom_setup(struct cldap_socket *c) 138 131 { 132 struct tevent_context *ev; 133 139 134 if (c->recv_subreq) { 140 135 return true; … … 145 140 } 146 141 147 c->recv_subreq = tdgram_recvfrom_send(c, c->event.ctx, c->sock); 142 ev = c->incoming.ev; 143 if (ev == NULL) { 144 ev = c->searches.list->caller.ev; 145 } 146 147 c->recv_subreq = tdgram_recvfrom_send(c, ev, c->sock); 148 148 if (!c->recv_subreq) { 149 149 return false; … … 213 213 talloc_free(subreq); 214 214 talloc_free(in); 215 /*TODO: call a dead socket handler */216 return;217 215 } 218 216 … … 223 221 struct cldap_incoming *in) 224 222 { 225 DATA_BLOB blob;226 223 struct asn1_data *asn1; 227 224 void *p; … … 233 230 } 234 231 235 blob = data_blob_const(in->buf, in->len);236 237 232 asn1 = asn1_init(in); 238 233 if (!asn1) { … … 240 235 } 241 236 242 if (!asn1_load(asn1, blob)) { 243 goto nomem; 244 } 237 asn1_load_nocopy(asn1, in->buf, in->len); 245 238 246 239 in->ldap_msg = talloc(in, struct ldap_message); … … 259 252 if (p == NULL) { 260 253 if (!c->incoming.handler) { 261 goto done; 254 TALLOC_FREE(in); 255 return true; 262 256 } 263 257 … … 267 261 } 268 262 269 search = talloc_get_type (p, struct cldap_search_state);263 search = talloc_get_type_abort(p, struct cldap_search_state); 270 264 search->response.in = talloc_move(search, &in); 265 271 266 search->response.asn1 = asn1; 272 search->response.asn1->ofs = 0; 267 268 asn1_load_nocopy(search->response.asn1, 269 search->response.in->buf, search->response.in->len); 273 270 274 271 DLIST_REMOVE(c->searches.list, search); 275 272 276 cldap_recvfrom_setup(c); 277 273 if (cldap_recvfrom_setup(c)) { 274 tevent_req_done(search->req); 275 return true; 276 } 277 278 /* 279 * This request was ok, just defer the notify of the caller 280 * and then just fail the next request if needed 281 */ 282 tevent_req_defer_callback(search->req, search->caller.ev); 278 283 tevent_req_done(search->req); 279 return true; 280 284 285 status = NT_STATUS_NO_MEMORY; 286 /* in is NULL it this point */ 287 goto nterror; 281 288 nomem: 282 289 in->recv_errno = ENOMEM; 283 290 error: 284 status = map_nt_error_from_unix (in->recv_errno);291 status = map_nt_error_from_unix_common(in->recv_errno); 285 292 nterror: 286 293 TALLOC_FREE(in); … … 288 295 if (!c->connected) { 289 296 /* otherwise we just ignore the error */ 290 goto done;297 return false; 291 298 } 292 299 if (!c->searches.list) { 293 goto done; 294 } 295 cldap_recvfrom_setup(c); 300 return false; 301 } 302 /* 303 * We might called tevent_req_done() for a successful 304 * search before, so we better deliver the failure 305 * after the success, that is why we better also 306 * use tevent_req_defer_callback() here. 307 */ 308 tevent_req_defer_callback(c->searches.list->req, 309 c->searches.list->caller.ev); 296 310 tevent_req_nterror(c->searches.list->req, status); 297 return true;298 done:299 TALLOC_FREE(in);300 311 return false; 301 312 } … … 305 316 */ 306 317 NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx, 307 struct tevent_context *ev,308 318 const struct tsocket_address *local_addr, 309 319 const struct tsocket_address *remote_addr, … … 341 351 } 342 352 343 if (!ev) {344 ev = tevent_context_init(c);345 if (!ev) {346 goto nomem;347 }348 c->event.allow_poll = true;349 }350 c->event.ctx = ev;351 352 353 if (!local_addr) { 353 354 /* … … 362 363 &any); 363 364 if (ret != 0) { 364 status = map_nt_error_from_unix (errno);365 status = map_nt_error_from_unix_common(errno); 365 366 goto nterror; 366 367 } … … 376 377 c, &c->sock); 377 378 if (ret != 0) { 378 status = map_nt_error_from_unix (errno);379 status = map_nt_error_from_unix_common(errno); 379 380 goto nterror; 380 381 } … … 406 407 */ 407 408 NTSTATUS cldap_set_incoming_handler(struct cldap_socket *c, 409 struct tevent_context *ev, 408 410 void (*handler)(struct cldap_socket *, 409 411 void *private_data, … … 415 417 } 416 418 417 /* if sync requests are allowed, we don't allow an incoming handler */ 418 if (c->event.allow_poll) { 419 return NT_STATUS_INVALID_PIPE_STATE; 420 } 421 419 c->incoming.ev = ev; 422 420 c->incoming.handler = handler; 423 421 c->incoming.private_data = private_data; … … 453 451 } 454 452 453 if (cldap->incoming.ev == NULL) { 454 return NT_STATUS_INVALID_PIPE_STATE; 455 } 456 455 457 if (!io->dest) { 456 458 return NT_STATUS_INVALID_ADDRESS; … … 505 507 506 508 subreq = tdgram_sendto_queue_send(state, 507 cldap-> event.ctx,509 cldap->incoming.ev, 508 510 cldap->sock, 509 511 cldap->send_queue, … … 558 560 */ 559 561 struct tevent_req *cldap_search_send(TALLOC_CTX *mem_ctx, 560 struct cldap_socket *cldap, 561 const struct cldap_search *io) 562 struct tevent_context *ev, 563 struct cldap_socket *cldap, 564 const struct cldap_search *io) 562 565 { 563 566 struct tevent_req *req, *subreq; … … 576 579 } 577 580 ZERO_STRUCTP(state); 581 state->caller.ev = ev; 578 582 state->req = req; 579 583 state->caller.cldap = cldap; … … 651 655 end = now; 652 656 for (i = 0; i < state->request.count; i++) { 653 end = tevent_timeval_add(&end, 0, state->request.delay); 654 } 655 656 if (!tevent_req_set_endtime(req, state->caller.cldap->event.ctx, end)) { 657 tevent_req_nomem(NULL, req); 657 end = tevent_timeval_add(&end, state->request.delay / 1000000, 658 state->request.delay % 1000000); 659 } 660 661 if (!tevent_req_set_endtime(req, state->caller.ev, end)) { 662 tevent_req_oom(req); 658 663 goto post; 659 664 } 660 665 661 666 subreq = tdgram_sendto_queue_send(state, 662 state->caller. cldap->event.ctx,667 state->caller.ev, 663 668 state->caller.cldap->sock, 664 669 state->caller.cldap->send_queue, … … 671 676 tevent_req_set_callback(subreq, cldap_search_state_queue_done, req); 672 677 673 DLIST_ADD_END(cldap->searches.list, state , struct cldap_search_state *);678 DLIST_ADD_END(cldap->searches.list, state); 674 679 675 680 return req; 676 681 677 682 post: 678 return tevent_req_post(req, cldap->event.ctx);683 return tevent_req_post(req, state->caller.ev); 679 684 } 680 685 … … 693 698 if (ret == -1) { 694 699 NTSTATUS status; 695 status = map_nt_error_from_unix (sys_errno);700 status = map_nt_error_from_unix_common(sys_errno); 696 701 DLIST_REMOVE(state->caller.cldap->searches.list, state); 697 702 ZERO_STRUCT(state->caller.cldap); … … 704 709 /* wait for incoming traffic */ 705 710 if (!cldap_recvfrom_setup(state->caller.cldap)) { 706 tevent_req_ nomem(NULL,req);711 tevent_req_oom(req); 707 712 return; 708 713 } … … 713 718 } 714 719 715 next = tevent_timeval_current_ofs(0, state->request.delay); 720 next = tevent_timeval_current_ofs(state->request.delay / 1000000, 721 state->request.delay % 1000000); 716 722 subreq = tevent_wakeup_send(state, 717 state->caller. cldap->event.ctx,723 state->caller.ev, 718 724 next); 719 725 if (tevent_req_nomem(subreq, req)) { … … 739 745 740 746 subreq = tdgram_sendto_queue_send(state, 741 state->caller. cldap->event.ctx,747 state->caller.ev, 742 748 state->caller.cldap->sock, 743 749 state->caller.cldap->send_queue, … … 828 834 struct cldap_search *io) 829 835 { 836 TALLOC_CTX *frame; 830 837 struct tevent_req *req; 838 struct tevent_context *ev; 831 839 NTSTATUS status; 832 833 if (!cldap->event.allow_poll) {834 return NT_STATUS_INVALID_PIPE_STATE;835 }836 840 837 841 if (cldap->searches.list) { … … 839 843 } 840 844 841 req = cldap_search_send(mem_ctx, cldap, io); 842 NT_STATUS_HAVE_NO_MEMORY(req); 843 844 if (!tevent_req_poll(req, cldap->event.ctx)) { 845 talloc_free(req); 846 return NT_STATUS_INTERNAL_ERROR; 845 if (cldap->incoming.handler) { 846 return NT_STATUS_INVALID_PIPE_STATE; 847 } 848 849 frame = talloc_stackframe(); 850 851 ev = samba_tevent_context_init(frame); 852 if (ev == NULL) { 853 TALLOC_FREE(frame); 854 return NT_STATUS_NO_MEMORY; 855 } 856 857 req = cldap_search_send(mem_ctx, ev, cldap, io); 858 if (req == NULL) { 859 TALLOC_FREE(frame); 860 return NT_STATUS_NO_MEMORY; 861 } 862 863 if (!tevent_req_poll(req, ev)) { 864 status = map_nt_error_from_unix_common(errno); 865 TALLOC_FREE(frame); 866 return status; 847 867 } 848 868 849 869 status = cldap_search_recv(req, mem_ctx, io); 850 talloc_free(req); 851 852 return status; 870 if (!NT_STATUS_IS_OK(status)) { 871 TALLOC_FREE(frame); 872 return status; 873 } 874 875 TALLOC_FREE(frame); 876 return NT_STATUS_OK; 853 877 } 854 878 … … 857 881 }; 858 882 883 char *cldap_netlogon_create_filter(TALLOC_CTX *mem_ctx, 884 const struct cldap_netlogon *io) 885 { 886 char *filter; 887 888 filter = talloc_asprintf(mem_ctx, "(&(NtVer=%s)", 889 ldap_encode_ndr_uint32(mem_ctx, io->in.version)); 890 if (filter == NULL) 891 return NULL; 892 893 if (io->in.user) { 894 filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user); 895 if (filter == NULL) { 896 return NULL; 897 } 898 } 899 if (io->in.host) { 900 filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host); 901 if (filter == NULL) { 902 return NULL; 903 } 904 } 905 if (io->in.realm) { 906 filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm); 907 if (filter == NULL) { 908 return NULL; 909 } 910 } 911 if (io->in.acct_control != -1) { 912 filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)", 913 ldap_encode_ndr_uint32(mem_ctx, io->in.acct_control)); 914 if (filter == NULL) { 915 return NULL; 916 } 917 } 918 if (io->in.domain_sid) { 919 struct dom_sid *sid = dom_sid_parse_talloc(mem_ctx, io->in.domain_sid); 920 921 filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)", 922 ldap_encode_ndr_dom_sid(mem_ctx, sid)); 923 if (filter == NULL) { 924 return NULL; 925 } 926 } 927 if (io->in.domain_guid) { 928 struct GUID guid; 929 GUID_from_string(io->in.domain_guid, &guid); 930 931 filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)", 932 ldap_encode_ndr_GUID(mem_ctx, &guid)); 933 if (filter == NULL) { 934 return NULL; 935 } 936 } 937 filter = talloc_asprintf_append_buffer(filter, ")"); 938 939 return filter; 940 } 941 859 942 static void cldap_netlogon_state_done(struct tevent_req *subreq); 860 943 /* … … 862 945 */ 863 946 struct tevent_req *cldap_netlogon_send(TALLOC_CTX *mem_ctx, 864 struct cldap_socket *cldap, 865 const struct cldap_netlogon *io) 947 struct tevent_context *ev, 948 struct cldap_socket *cldap, 949 const struct cldap_netlogon *io) 866 950 { 867 951 struct tevent_req *req, *subreq; … … 876 960 } 877 961 878 filter = talloc_asprintf(state, "(&(NtVer=%s)", 879 ldap_encode_ndr_uint32(state, io->in.version)); 880 if (tevent_req_nomem(filter, req)) { 881 goto post; 882 } 883 if (io->in.user) { 884 filter = talloc_asprintf_append_buffer(filter, "(User=%s)", io->in.user); 885 if (tevent_req_nomem(filter, req)) { 886 goto post; 887 } 888 } 889 if (io->in.host) { 890 filter = talloc_asprintf_append_buffer(filter, "(Host=%s)", io->in.host); 891 if (tevent_req_nomem(filter, req)) { 892 goto post; 893 } 894 } 895 if (io->in.realm) { 896 filter = talloc_asprintf_append_buffer(filter, "(DnsDomain=%s)", io->in.realm); 897 if (tevent_req_nomem(filter, req)) { 898 goto post; 899 } 900 } 901 if (io->in.acct_control != -1) { 902 filter = talloc_asprintf_append_buffer(filter, "(AAC=%s)", 903 ldap_encode_ndr_uint32(state, io->in.acct_control)); 904 if (tevent_req_nomem(filter, req)) { 905 goto post; 906 } 907 } 908 if (io->in.domain_sid) { 909 struct dom_sid *sid = dom_sid_parse_talloc(state, io->in.domain_sid); 910 if (tevent_req_nomem(sid, req)) { 911 goto post; 912 } 913 filter = talloc_asprintf_append_buffer(filter, "(domainSid=%s)", 914 ldap_encode_ndr_dom_sid(state, sid)); 915 if (tevent_req_nomem(filter, req)) { 916 goto post; 917 } 918 } 919 if (io->in.domain_guid) { 920 struct GUID guid; 921 NTSTATUS status; 922 status = GUID_from_string(io->in.domain_guid, &guid); 923 if (tevent_req_nterror(req, status)) { 924 goto post; 925 } 926 filter = talloc_asprintf_append_buffer(filter, "(DomainGuid=%s)", 927 ldap_encode_ndr_GUID(state, &guid)); 928 if (tevent_req_nomem(filter, req)) { 929 goto post; 930 } 931 } 932 filter = talloc_asprintf_append_buffer(filter, ")"); 962 filter = cldap_netlogon_create_filter(state, io); 933 963 if (tevent_req_nomem(filter, req)) { 934 964 goto post; … … 951 981 state->search.in.retries = 2; 952 982 953 subreq = cldap_search_send(state, cldap, &state->search);983 subreq = cldap_search_send(state, ev, cldap, &state->search); 954 984 if (tevent_req_nomem(subreq, req)) { 955 985 goto post; … … 959 989 return req; 960 990 post: 961 return tevent_req_post(req, cldap->event.ctx);991 return tevent_req_post(req, ev); 962 992 } 963 993 … … 989 1019 struct cldap_netlogon_state *state = tevent_req_data(req, 990 1020 struct cldap_netlogon_state); 991 NTSTATUS status ;1021 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 992 1022 DATA_BLOB *data; 993 1023 … … 1033 1063 struct cldap_netlogon *io) 1034 1064 { 1065 TALLOC_CTX *frame; 1035 1066 struct tevent_req *req; 1067 struct tevent_context *ev; 1036 1068 NTSTATUS status; 1037 1038 if (!cldap->event.allow_poll) {1039 return NT_STATUS_INVALID_PIPE_STATE;1040 }1041 1069 1042 1070 if (cldap->searches.list) { … … 1044 1072 } 1045 1073 1046 req = cldap_netlogon_send(mem_ctx, cldap, io); 1047 NT_STATUS_HAVE_NO_MEMORY(req); 1048 1049 if (!tevent_req_poll(req, cldap->event.ctx)) { 1050 talloc_free(req); 1051 return NT_STATUS_INTERNAL_ERROR; 1074 if (cldap->incoming.handler) { 1075 return NT_STATUS_INVALID_PIPE_STATE; 1076 } 1077 1078 frame = talloc_stackframe(); 1079 1080 ev = samba_tevent_context_init(frame); 1081 if (ev == NULL) { 1082 TALLOC_FREE(frame); 1083 return NT_STATUS_NO_MEMORY; 1084 } 1085 1086 req = cldap_netlogon_send(mem_ctx, ev, cldap, io); 1087 if (req == NULL) { 1088 TALLOC_FREE(frame); 1089 return NT_STATUS_NO_MEMORY; 1090 } 1091 1092 if (!tevent_req_poll(req, ev)) { 1093 status = map_nt_error_from_unix_common(errno); 1094 TALLOC_FREE(frame); 1095 return status; 1052 1096 } 1053 1097 1054 1098 status = cldap_netlogon_recv(req, mem_ctx, io); 1055 talloc_free(req); 1056 1057 return status; 1099 if (!NT_STATUS_IS_OK(status)) { 1100 TALLOC_FREE(frame); 1101 return status; 1102 } 1103 1104 TALLOC_FREE(frame); 1105 return NT_STATUS_OK; 1058 1106 } 1059 1107
Note:
See TracChangeset
for help on using the changeset viewer.