2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2009
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "system/network.h"
22 #include "../util/tevent_unix.h"
23 #include "../lib/tsocket/tsocket.h"
24 #include "../lib/tsocket/tsocket_internal.h"
25 #include "../librpc/gen_ndr/ndr_named_pipe_auth.h"
26 #include "../libcli/named_pipe_auth/npa_tstream.h"
27 #include "../libcli/smb/smb_constants.h"
29 static const struct tstream_context_ops tstream_npa_ops;
32 struct tstream_context *unix_stream;
39 struct tstream_npa_connect_state {
41 struct tevent_context *ev;
44 const char *unix_path;
45 struct tsocket_address *unix_laddr;
46 struct tsocket_address *unix_raddr;
47 struct tstream_context *unix_stream;
49 struct named_pipe_auth_req auth_req;
50 DATA_BLOB auth_req_blob;
51 struct iovec auth_req_iov;
53 struct named_pipe_auth_rep auth_rep;
54 DATA_BLOB auth_rep_blob;
57 static void tstream_npa_connect_unix_done(struct tevent_req *subreq);
59 struct tevent_req *tstream_npa_connect_send(TALLOC_CTX *mem_ctx,
60 struct tevent_context *ev,
61 const char *directory,
63 const struct tsocket_address *remote_client_addr,
64 const char *remote_client_name_in,
65 const struct tsocket_address *local_server_addr,
66 const char *local_server_name,
67 const struct auth_session_info_transport *session_info)
69 struct tevent_req *req;
70 struct tstream_npa_connect_state *state;
71 struct tevent_req *subreq;
73 enum ndr_err_code ndr_err;
74 char *lower_case_npipe;
75 struct named_pipe_auth_req_info4 *info4;
77 req = tevent_req_create(mem_ctx, &state,
78 struct tstream_npa_connect_state);
83 state->caller.ev = ev;
85 lower_case_npipe = strlower_talloc(state, npipe);
86 if (tevent_req_nomem(lower_case_npipe, req)) {
90 state->unix_path = talloc_asprintf(state, "%s/%s",
93 talloc_free(lower_case_npipe);
94 if (tevent_req_nomem(state->unix_path, req)) {
98 ret = tsocket_address_unix_from_path(state,
102 tevent_req_error(req, errno);
106 ret = tsocket_address_unix_from_path(state,
110 tevent_req_error(req, errno);
114 ZERO_STRUCT(state->auth_req);
116 if (!local_server_addr) {
117 tevent_req_error(req, EINVAL);
121 state->auth_req.level = 4;
122 info4 = &state->auth_req.info.info4;
124 info4->remote_client_name = remote_client_name_in;
125 info4->remote_client_addr = tsocket_address_inet_addr_string(remote_client_addr,
127 if (!info4->remote_client_addr) {
128 /* errno might be EINVAL */
129 tevent_req_error(req, errno);
132 info4->remote_client_port = tsocket_address_inet_port(remote_client_addr);
133 if (!info4->remote_client_name) {
134 info4->remote_client_name = info4->remote_client_addr;
137 info4->local_server_addr = tsocket_address_inet_addr_string(local_server_addr,
139 if (!info4->local_server_addr) {
140 /* errno might be EINVAL */
141 tevent_req_error(req, errno);
144 info4->local_server_port = tsocket_address_inet_port(local_server_addr);
145 if (!info4->local_server_name) {
146 info4->local_server_name = info4->local_server_addr;
149 info4->session_info = discard_const_p(struct auth_session_info_transport, session_info);
152 NDR_PRINT_DEBUG(named_pipe_auth_req, &state->auth_req);
155 ndr_err = ndr_push_struct_blob(&state->auth_req_blob,
156 state, &state->auth_req,
157 (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
158 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
159 tevent_req_error(req, EINVAL);
163 state->auth_req_iov.iov_base = (char *) state->auth_req_blob.data;
164 state->auth_req_iov.iov_len = state->auth_req_blob.length;
166 subreq = tstream_unix_connect_send(state,
170 if (tevent_req_nomem(subreq, req)) {
173 tevent_req_set_callback(subreq, tstream_npa_connect_unix_done, req);
178 tevent_req_post(req, ev);
182 static void tstream_npa_connect_writev_done(struct tevent_req *subreq);
184 static void tstream_npa_connect_unix_done(struct tevent_req *subreq)
186 struct tevent_req *req =
187 tevent_req_callback_data(subreq,
189 struct tstream_npa_connect_state *state =
191 struct tstream_npa_connect_state);
195 ret = tstream_unix_connect_recv(subreq, &sys_errno,
196 state, &state->unix_stream);
199 tevent_req_error(req, sys_errno);
203 subreq = tstream_writev_send(state,
206 &state->auth_req_iov, 1);
207 if (tevent_req_nomem(subreq, req)) {
210 tevent_req_set_callback(subreq, tstream_npa_connect_writev_done, req);
213 static int tstream_npa_connect_next_vector(struct tstream_context *unix_stream,
216 struct iovec **_vector,
218 static void tstream_npa_connect_readv_done(struct tevent_req *subreq);
220 static void tstream_npa_connect_writev_done(struct tevent_req *subreq)
222 struct tevent_req *req =
223 tevent_req_callback_data(subreq,
225 struct tstream_npa_connect_state *state =
227 struct tstream_npa_connect_state);
231 ret = tstream_writev_recv(subreq, &sys_errno);
234 tevent_req_error(req, sys_errno);
238 state->auth_rep_blob = data_blob_const(NULL, 0);
240 subreq = tstream_readv_pdu_send(state, state->caller.ev,
242 tstream_npa_connect_next_vector,
244 if (tevent_req_nomem(subreq, req)) {
247 tevent_req_set_callback(subreq, tstream_npa_connect_readv_done, req);
250 static int tstream_npa_connect_next_vector(struct tstream_context *unix_stream,
253 struct iovec **_vector,
256 struct tstream_npa_connect_state *state = talloc_get_type_abort(private_data,
257 struct tstream_npa_connect_state);
258 struct iovec *vector;
262 if (state->auth_rep_blob.length == 0) {
263 state->auth_rep_blob = data_blob_talloc(state, NULL, 4);
264 if (!state->auth_rep_blob.data) {
267 } else if (state->auth_rep_blob.length == 4) {
272 msg_len = RIVAL(state->auth_rep_blob.data, 0);
274 if (msg_len > 0x00FFFFFF) {
286 state->auth_rep_blob.data = talloc_realloc(state,
287 state->auth_rep_blob.data,
289 if (!state->auth_rep_blob.data) {
292 state->auth_rep_blob.length = msg_len;
299 /* we need to get a message header */
300 vector = talloc_array(mem_ctx, struct iovec, 1);
304 vector[0].iov_base = (char *) (state->auth_rep_blob.data + ofs);
305 vector[0].iov_len = state->auth_rep_blob.length - ofs;
313 static void tstream_npa_connect_readv_done(struct tevent_req *subreq)
315 struct tevent_req *req =
316 tevent_req_callback_data(subreq,
318 struct tstream_npa_connect_state *state =
320 struct tstream_npa_connect_state);
323 enum ndr_err_code ndr_err;
325 ret = tstream_readv_pdu_recv(subreq, &sys_errno);
328 tevent_req_error(req, sys_errno);
332 DEBUG(10,("name_pipe_auth_rep(client)[%u]\n",
333 (uint32_t)state->auth_rep_blob.length));
334 dump_data(11, state->auth_rep_blob.data, state->auth_rep_blob.length);
336 ndr_err = ndr_pull_struct_blob(
337 &state->auth_rep_blob, state,
339 (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep);
341 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
342 DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n",
343 ndr_map_error2string(ndr_err)));
344 tevent_req_error(req, EIO);
349 NDR_PRINT_DEBUG(named_pipe_auth_rep, &state->auth_rep);
352 if (state->auth_rep.length < 16) {
353 DEBUG(0, ("req invalid length: %u < 16\n",
354 state->auth_rep.length));
355 tevent_req_error(req, EIO);
359 if (strcmp(NAMED_PIPE_AUTH_MAGIC, state->auth_rep.magic) != 0) {
360 DEBUG(0, ("req invalid magic: %s != %s\n",
361 state->auth_rep.magic, NAMED_PIPE_AUTH_MAGIC));
362 tevent_req_error(req, EIO);
366 if (!NT_STATUS_IS_OK(state->auth_rep.status)) {
367 DEBUG(0, ("req failed: %s\n",
368 nt_errstr(state->auth_rep.status)));
369 tevent_req_error(req, EACCES);
373 if (state->auth_rep.level != state->auth_req.level) {
374 DEBUG(0, ("req invalid level: %u != %u\n",
375 state->auth_rep.level, state->auth_req.level));
376 tevent_req_error(req, EIO);
380 tevent_req_done(req);
383 int _tstream_npa_connect_recv(struct tevent_req *req,
386 struct tstream_context **_stream,
387 uint16_t *_file_type,
388 uint16_t *_device_state,
389 uint64_t *_allocation_size,
390 const char *location)
392 struct tstream_npa_connect_state *state =
394 struct tstream_npa_connect_state);
395 struct tstream_context *stream;
396 struct tstream_npa *npas;
397 uint16_t device_state = 0;
398 uint64_t allocation_size = 0;
400 if (tevent_req_is_unix_error(req, perrno)) {
401 tevent_req_received(req);
405 stream = tstream_context_create(mem_ctx,
412 tevent_req_received(req);
417 npas->unix_stream = talloc_move(stream, &state->unix_stream);
418 switch (state->auth_rep.level) {
420 npas->file_type = state->auth_rep.info.info4.file_type;
421 device_state = state->auth_rep.info.info4.device_state;
422 allocation_size = state->auth_rep.info.info4.allocation_size;
427 *_file_type = npas->file_type;
428 *_device_state = device_state;
429 *_allocation_size = allocation_size;
430 tevent_req_received(req);
434 static ssize_t tstream_npa_pending_bytes(struct tstream_context *stream)
436 struct tstream_npa *npas = tstream_context_data(stream,
440 if (!npas->unix_stream) {
445 switch (npas->file_type) {
446 case FILE_TYPE_BYTE_MODE_PIPE:
447 ret = tstream_pending_bytes(npas->unix_stream);
450 case FILE_TYPE_MESSAGE_MODE_PIPE:
451 ret = npas->pending.iov_len;
461 struct tstream_npa_readv_state {
462 struct tstream_context *stream;
464 struct iovec *vector;
467 /* the header for message mode */
474 static void tstream_npa_readv_byte_mode_handler(struct tevent_req *subreq);
475 static int tstream_npa_readv_next_vector(struct tstream_context *stream,
478 struct iovec **_vector,
480 static void tstream_npa_readv_msg_mode_handler(struct tevent_req *subreq);
482 static struct tevent_req *tstream_npa_readv_send(TALLOC_CTX *mem_ctx,
483 struct tevent_context *ev,
484 struct tstream_context *stream,
485 struct iovec *vector,
488 struct tevent_req *req;
489 struct tstream_npa_readv_state *state;
490 struct tstream_npa *npas = tstream_context_data(stream, struct tstream_npa);
491 struct tevent_req *subreq;
496 req = tevent_req_create(mem_ctx, &state,
497 struct tstream_npa_readv_state);
502 state->stream = stream;
505 if (!npas->unix_stream) {
506 tevent_req_error(req, ENOTCONN);
510 switch (npas->file_type) {
511 case FILE_TYPE_BYTE_MODE_PIPE:
512 state->vector = vector;
513 state->count = count;
515 subreq = tstream_readv_send(state,
520 if (tevent_req_nomem(subreq,req)) {
523 tevent_req_set_callback(subreq,
524 tstream_npa_readv_byte_mode_handler,
529 case FILE_TYPE_MESSAGE_MODE_PIPE:
531 * we make a copy of the vector and prepend a header
534 state->vector = talloc_array(state, struct iovec, count);
535 if (tevent_req_nomem(state->vector, req)) {
538 memcpy(state->vector, vector, sizeof(struct iovec)*count);
539 state->count = count;
542 * copy the pending buffer first
545 left = npas->pending.iov_len;
546 pbase = (uint8_t *)npas->pending.iov_base;
548 while (left > 0 && state->count > 0) {
550 base = (uint8_t *)state->vector[0].iov_base;
551 if (left < state->vector[0].iov_len) {
552 memcpy(base, pbase + ofs, left);
555 state->vector[0].iov_base = (char *) base;
556 state->vector[0].iov_len -= left;
561 ZERO_STRUCT(npas->pending);
564 memcpy(base, pbase + ofs, state->vector[0].iov_len);
566 ofs += state->vector[0].iov_len;
567 left -= state->vector[0].iov_len;
573 ZERO_STRUCT(npas->pending);
579 memmove(pbase, pbase + ofs, left);
580 npas->pending.iov_base = (char *) pbase;
581 npas->pending.iov_len = left;
583 * this cannot fail and even if it
584 * fails we can handle it
586 pbase = talloc_realloc(npas, pbase, uint8_t, left);
588 npas->pending.iov_base = (char *) pbase;
595 if (state->count == 0) {
596 tevent_req_done(req);
600 ZERO_STRUCT(state->hdr);
601 state->wait_for_hdr = false;
603 subreq = tstream_readv_pdu_send(state,
606 tstream_npa_readv_next_vector,
608 if (tevent_req_nomem(subreq, req)) {
611 tevent_req_set_callback(subreq,
612 tstream_npa_readv_msg_mode_handler,
618 /* this can't happen */
619 tevent_req_error(req, EINVAL);
623 tevent_req_post(req, ev);
627 static void tstream_npa_readv_byte_mode_handler(struct tevent_req *subreq)
629 struct tevent_req *req = tevent_req_callback_data(subreq,
631 struct tstream_npa_readv_state *state = tevent_req_data(req,
632 struct tstream_npa_readv_state);
636 ret = tstream_readv_recv(subreq, &sys_errno);
639 tevent_req_error(req, sys_errno);
645 tevent_req_done(req);
648 static int tstream_npa_readv_next_vector(struct tstream_context *unix_stream,
651 struct iovec **_vector,
654 struct tstream_npa_readv_state *state = talloc_get_type_abort(private_data,
655 struct tstream_npa_readv_state);
656 struct tstream_npa *npas = tstream_context_data(state->stream,
658 struct iovec *vector;
663 if (state->count == 0) {
669 if (!state->wait_for_hdr) {
670 /* we need to get a message header */
671 vector = talloc_array(mem_ctx, struct iovec, 1);
675 ZERO_STRUCT(state->hdr);
676 vector[0].iov_base = (char *) state->hdr;
677 vector[0].iov_len = sizeof(state->hdr);
681 state->wait_for_hdr = true;
688 /* and now fill the callers buffers and maybe the pending buffer */
689 state->wait_for_hdr = false;
691 msg_len = SVAL(state->hdr, 0);
698 state->wait_for_hdr = false;
700 /* +1 because we may need to fill the pending buffer */
701 vector = talloc_array(mem_ctx, struct iovec, state->count + 1);
708 while (left > 0 && state->count > 0) {
709 if (left < state->vector[0].iov_len) {
711 base = (uint8_t *)state->vector[0].iov_base;
712 vector[count].iov_base = (char *) base;
713 vector[count].iov_len = left;
716 state->vector[0].iov_base = (char *) base;
717 state->vector[0].iov_len -= left;
720 vector[count] = state->vector[0];
722 left -= state->vector[0].iov_len;
729 * if the message is longer than the buffers the caller
730 * requested, we need to consume the rest of the message
731 * into the pending buffer, where the next readv can
734 npas->pending.iov_base = talloc_array(npas, char, left);
735 if (!npas->pending.iov_base) {
738 npas->pending.iov_len = left;
740 vector[count] = npas->pending;
744 state->ret += (msg_len - left);
751 static void tstream_npa_readv_msg_mode_handler(struct tevent_req *subreq)
753 struct tevent_req *req = tevent_req_callback_data(subreq,
758 ret = tstream_readv_pdu_recv(subreq, &sys_errno);
761 tevent_req_error(req, sys_errno);
766 * we do not set state->ret here as ret includes the headr size.
767 * we set it in tstream_npa_readv_pdu_next_vector()
770 tevent_req_done(req);
773 static int tstream_npa_readv_recv(struct tevent_req *req,
776 struct tstream_npa_readv_state *state = tevent_req_data(req,
777 struct tstream_npa_readv_state);
780 ret = tsocket_simple_int_recv(req, perrno);
785 tevent_req_received(req);
789 struct tstream_npa_writev_state {
790 const struct iovec *vector;
793 /* the header for message mode */
800 static void tstream_npa_writev_handler(struct tevent_req *subreq);
802 static struct tevent_req *tstream_npa_writev_send(TALLOC_CTX *mem_ctx,
803 struct tevent_context *ev,
804 struct tstream_context *stream,
805 const struct iovec *vector,
808 struct tevent_req *req;
809 struct tstream_npa_writev_state *state;
810 struct tstream_npa *npas = tstream_context_data(stream, struct tstream_npa);
811 struct tevent_req *subreq;
814 struct iovec *new_vector;
816 req = tevent_req_create(mem_ctx, &state,
817 struct tstream_npa_writev_state);
824 if (!npas->unix_stream) {
825 tevent_req_error(req, ENOTCONN);
829 switch (npas->file_type) {
830 case FILE_TYPE_BYTE_MODE_PIPE:
831 state->hdr_used = false;
832 state->vector = vector;
833 state->count = count;
836 case FILE_TYPE_MESSAGE_MODE_PIPE:
838 * we make a copy of the vector and prepend a header
841 new_vector = talloc_array(state, struct iovec, count + 1);
842 if (tevent_req_nomem(new_vector, req)) {
845 new_vector[0].iov_base = (char *) state->hdr;
846 new_vector[0].iov_len = sizeof(state->hdr);
847 memcpy(new_vector + 1, vector, sizeof(struct iovec)*count);
849 state->hdr_used = true;
850 state->vector = new_vector;
851 state->count = count + 1;
854 for (i=0; i < count; i++) {
855 msg_len += vector[i].iov_len;
858 if (msg_len > UINT16_MAX) {
859 tevent_req_error(req, EMSGSIZE);
863 SSVAL(state->hdr, 0, msg_len);
867 subreq = tstream_writev_send(state,
872 if (tevent_req_nomem(subreq, req)) {
875 tevent_req_set_callback(subreq, tstream_npa_writev_handler, req);
880 tevent_req_post(req, ev);
884 static void tstream_npa_writev_handler(struct tevent_req *subreq)
886 struct tevent_req *req = tevent_req_callback_data(subreq,
888 struct tstream_npa_writev_state *state = tevent_req_data(req,
889 struct tstream_npa_writev_state);
893 ret = tstream_writev_recv(subreq, &sys_errno);
896 tevent_req_error(req, sys_errno);
901 * in message mode we need to hide the length
902 * of the hdr from the caller
904 if (state->hdr_used) {
905 ret -= sizeof(state->hdr);
910 tevent_req_done(req);
913 static int tstream_npa_writev_recv(struct tevent_req *req,
916 struct tstream_npa_writev_state *state = tevent_req_data(req,
917 struct tstream_npa_writev_state);
920 ret = tsocket_simple_int_recv(req, perrno);
925 tevent_req_received(req);
929 struct tstream_npa_disconnect_state {
930 struct tstream_context *stream;
933 static void tstream_npa_disconnect_handler(struct tevent_req *subreq);
935 static struct tevent_req *tstream_npa_disconnect_send(TALLOC_CTX *mem_ctx,
936 struct tevent_context *ev,
937 struct tstream_context *stream)
939 struct tstream_npa *npas = tstream_context_data(stream, struct tstream_npa);
940 struct tevent_req *req;
941 struct tstream_npa_disconnect_state *state;
942 struct tevent_req *subreq;
944 req = tevent_req_create(mem_ctx, &state,
945 struct tstream_npa_disconnect_state);
950 state->stream = stream;
952 if (!npas->unix_stream) {
953 tevent_req_error(req, ENOTCONN);
957 subreq = tstream_disconnect_send(state,
960 if (tevent_req_nomem(subreq, req)) {
963 tevent_req_set_callback(subreq, tstream_npa_disconnect_handler, req);
968 tevent_req_post(req, ev);
972 static void tstream_npa_disconnect_handler(struct tevent_req *subreq)
974 struct tevent_req *req = tevent_req_callback_data(subreq,
976 struct tstream_npa_disconnect_state *state = tevent_req_data(req,
977 struct tstream_npa_disconnect_state);
978 struct tstream_context *stream = state->stream;
979 struct tstream_npa *npas = tstream_context_data(stream, struct tstream_npa);
983 ret = tstream_disconnect_recv(subreq, &sys_errno);
986 tevent_req_error(req, sys_errno);
990 TALLOC_FREE(npas->unix_stream);
992 tevent_req_done(req);
995 static int tstream_npa_disconnect_recv(struct tevent_req *req,
1000 ret = tsocket_simple_int_recv(req, perrno);
1002 tevent_req_received(req);
1006 static const struct tstream_context_ops tstream_npa_ops = {
1009 .pending_bytes = tstream_npa_pending_bytes,
1011 .readv_send = tstream_npa_readv_send,
1012 .readv_recv = tstream_npa_readv_recv,
1014 .writev_send = tstream_npa_writev_send,
1015 .writev_recv = tstream_npa_writev_recv,
1017 .disconnect_send = tstream_npa_disconnect_send,
1018 .disconnect_recv = tstream_npa_disconnect_recv,
1021 int _tstream_npa_existing_socket(TALLOC_CTX *mem_ctx,
1024 struct tstream_context **_stream,
1025 const char *location)
1027 struct tstream_context *stream;
1028 struct tstream_npa *npas;
1031 switch (file_type) {
1032 case FILE_TYPE_BYTE_MODE_PIPE:
1034 case FILE_TYPE_MESSAGE_MODE_PIPE:
1041 stream = tstream_context_create(mem_ctx,
1051 npas->file_type = file_type;
1053 ret = tstream_bsd_existing_socket(stream, fd,
1054 &npas->unix_stream);
1056 int saved_errno = errno;
1057 talloc_free(stream);
1058 errno = saved_errno;
1067 struct tstream_npa_accept_state {
1068 struct tevent_context *ev;
1069 struct tstream_context *plain;
1071 uint16_t device_state;
1072 uint64_t alloc_size;
1075 struct iovec out_iov;
1078 NTSTATUS accept_status;
1079 struct tsocket_address *remote_client_addr;
1080 char *remote_client_name;
1081 struct tsocket_address *local_server_addr;
1082 char *local_server_name;
1083 struct auth_session_info_transport *session_info;
1086 static int tstream_npa_accept_next_vector(struct tstream_context *unix_stream,
1088 TALLOC_CTX *mem_ctx,
1089 struct iovec **_vector,
1091 static void tstream_npa_accept_existing_reply(struct tevent_req *subreq);
1092 static void tstream_npa_accept_existing_done(struct tevent_req *subreq);
1094 struct tevent_req *tstream_npa_accept_existing_send(TALLOC_CTX *mem_ctx,
1095 struct tevent_context *ev,
1096 struct tstream_context *plain,
1098 uint16_t device_state,
1099 uint64_t allocation_size)
1101 struct tstream_npa_accept_state *state;
1102 struct tevent_req *req, *subreq;
1104 req = tevent_req_create(mem_ctx, &state,
1105 struct tstream_npa_accept_state);
1110 switch (file_type) {
1111 case FILE_TYPE_BYTE_MODE_PIPE:
1113 case FILE_TYPE_MESSAGE_MODE_PIPE:
1116 tevent_req_error(req, EINVAL);
1120 ZERO_STRUCTP(state);
1123 state->plain = plain;
1124 state->file_type = file_type;
1125 state->device_state = device_state;
1126 state->alloc_size = allocation_size;
1129 * The named pipe pdu's have the length as 8 byte (initial_read_size),
1130 * named_pipe_full_request provides the pdu length then.
1132 subreq = tstream_readv_pdu_send(state, ev, plain,
1133 tstream_npa_accept_next_vector,
1135 if (tevent_req_nomem(subreq, req)) {
1139 tevent_req_set_callback(subreq,
1140 tstream_npa_accept_existing_reply, req);
1145 tevent_req_post(req, ev);
1149 static int tstream_npa_accept_next_vector(struct tstream_context *unix_stream,
1151 TALLOC_CTX *mem_ctx,
1152 struct iovec **_vector,
1155 struct tstream_npa_accept_state *state =
1156 talloc_get_type_abort(private_data,
1157 struct tstream_npa_accept_state);
1158 struct iovec *vector;
1162 if (state->npa_blob.length == 0) {
1163 state->npa_blob = data_blob_talloc(state, NULL, 4);
1164 if (!state->npa_blob.data) {
1167 } else if (state->npa_blob.length == 4) {
1172 msg_len = RIVAL(state->npa_blob.data, 0);
1174 if (msg_len > 0x00FFFFFF) {
1186 state->npa_blob.data = talloc_realloc(state,
1187 state->npa_blob.data,
1189 if (!state->npa_blob.data) {
1192 state->npa_blob.length = msg_len;
1194 if (memcmp(&state->npa_blob.data[4],
1195 NAMED_PIPE_AUTH_MAGIC, 4) != 0) {
1196 DEBUG(0, ("Wrong protocol\n"));
1197 #if defined(EPROTONOSUPPORT)
1198 errno = EPROTONOSUPPORT;
1199 #elif defined(EPROTO)
1211 /* we need to get a message header */
1212 vector = talloc_array(mem_ctx, struct iovec, 1);
1216 vector[0].iov_base = (char *) (state->npa_blob.data + ofs);
1217 vector[0].iov_len = state->npa_blob.length - ofs;
1225 static void tstream_npa_accept_existing_reply(struct tevent_req *subreq)
1227 struct tevent_req *req =
1228 tevent_req_callback_data(subreq, struct tevent_req);
1229 struct tstream_npa_accept_state *state =
1230 tevent_req_data(req, struct tstream_npa_accept_state);
1231 struct named_pipe_auth_req *pipe_request;
1232 struct named_pipe_auth_rep pipe_reply;
1233 struct named_pipe_auth_req_info4 i4;
1234 enum ndr_err_code ndr_err;
1239 ret = tstream_readv_pdu_recv(subreq, &sys_errno);
1240 TALLOC_FREE(subreq);
1242 tevent_req_error(req, sys_errno);
1246 DEBUG(10, ("Received packet of length %lu\n",
1247 (long)state->npa_blob.length));
1248 dump_data(11, state->npa_blob.data, state->npa_blob.length);
1250 ZERO_STRUCT(pipe_reply);
1251 pipe_reply.level = 0;
1252 pipe_reply.status = NT_STATUS_INTERNAL_ERROR;
1254 * TODO: check it's a root (uid == 0) pipe
1257 pipe_request = talloc(state, struct named_pipe_auth_req);
1258 if (!pipe_request) {
1259 DEBUG(0, ("Out of memory!\n"));
1263 /* parse the passed credentials */
1264 ndr_err = ndr_pull_struct_blob_all(
1265 &state->npa_blob, pipe_request, pipe_request,
1266 (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req);
1267 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1268 pipe_reply.status = ndr_map_error2ntstatus(ndr_err);
1269 DEBUG(2, ("Could not unmarshall named_pipe_auth_req: %s\n",
1270 nt_errstr(pipe_reply.status)));
1275 NDR_PRINT_DEBUG(named_pipe_auth_req, pipe_request);
1280 if (pipe_request->level != 4) {
1281 DEBUG(0, ("Unknown level %u\n", pipe_request->level));
1282 pipe_reply.level = 0;
1283 pipe_reply.status = NT_STATUS_INVALID_LEVEL;
1287 pipe_reply.level = 4;
1288 pipe_reply.status = NT_STATUS_OK;
1289 pipe_reply.info.info4.file_type = state->file_type;
1290 pipe_reply.info.info4.device_state = state->device_state;
1291 pipe_reply.info.info4.allocation_size = state->alloc_size;
1293 i4 = pipe_request->info.info4;
1294 if (i4.local_server_addr == NULL) {
1295 pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
1296 DEBUG(2, ("Missing local server address\n"));
1299 if (i4.remote_client_addr == NULL) {
1300 pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
1301 DEBUG(2, ("Missing remote client address\n"));
1305 state->local_server_name = discard_const_p(char,
1307 &i4.local_server_name));
1308 ret = tsocket_address_inet_from_strings(state, "ip",
1309 i4.local_server_addr,
1310 i4.local_server_port,
1311 &state->local_server_addr);
1313 DEBUG(2, ("Invalid local server address[%s:%u] - %s\n",
1314 i4.local_server_addr, i4.local_server_port,
1316 pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
1320 state->remote_client_name = discard_const_p(char,
1322 &i4.remote_client_name));
1323 ret = tsocket_address_inet_from_strings(state, "ip",
1324 i4.remote_client_addr,
1325 i4.remote_client_port,
1326 &state->remote_client_addr);
1328 DEBUG(2, ("Invalid remote client address[%s:%u] - %s\n",
1329 i4.remote_client_addr, i4.remote_client_port,
1331 pipe_reply.status = NT_STATUS_INVALID_ADDRESS;
1335 state->session_info = talloc_move(state, &i4.session_info);
1337 /* create the output */
1338 ndr_err = ndr_push_struct_blob(&out, state, &pipe_reply,
1339 (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep);
1340 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1341 DEBUG(2, ("Error encoding structure: %s",
1342 ndr_map_error2string(ndr_err)));
1343 tevent_req_error(req, EIO);
1347 DEBUG(10, ("named_pipe_auth reply[%u]\n", (unsigned)out.length));
1348 dump_data(11, out.data, out.length);
1351 NDR_PRINT_DEBUG(named_pipe_auth_rep, &pipe_reply);
1354 state->accept_status = pipe_reply.status;
1356 state->out_iov.iov_base = (char *) out.data;
1357 state->out_iov.iov_len = out.length;
1359 subreq = tstream_writev_send(state, state->ev,
1361 &state->out_iov, 1);
1362 if (tevent_req_nomem(subreq, req)) {
1363 DEBUG(0, ("no memory for tstream_writev_send"));
1367 tevent_req_set_callback(subreq, tstream_npa_accept_existing_done, req);
1370 static void tstream_npa_accept_existing_done(struct tevent_req *subreq)
1372 struct tevent_req *req =
1373 tevent_req_callback_data(subreq, struct tevent_req);
1377 ret = tstream_writev_recv(subreq, &sys_errno);
1378 TALLOC_FREE(subreq);
1380 tevent_req_error(req, sys_errno);
1384 tevent_req_done(req);
1387 int _tstream_npa_accept_existing_recv(struct tevent_req *req,
1389 TALLOC_CTX *mem_ctx,
1390 struct tstream_context **stream,
1391 struct tsocket_address **remote_client_addr,
1392 char **_remote_client_name,
1393 struct tsocket_address **local_server_addr,
1394 char **local_server_name,
1395 struct auth_session_info_transport **session_info,
1396 const char *location)
1398 struct tstream_npa_accept_state *state =
1399 tevent_req_data(req, struct tstream_npa_accept_state);
1400 struct tstream_npa *npas;
1403 ret = tsocket_simple_int_recv(req, perrno);
1405 DEBUG(2, ("Failed to accept named pipe connection: %s\n",
1406 strerror(*perrno)));
1407 tevent_req_received(req);
1411 if (!NT_STATUS_IS_OK(state->accept_status)) {
1412 #if defined(EPROTONOSUPPORT)
1413 *perrno = EPROTONOSUPPORT;
1414 #elif defined(EPROTO)
1419 DEBUG(2, ("Failed to accept named pipe connection: %s => %s\n",
1420 nt_errstr(state->accept_status),
1421 strerror(*perrno)));
1422 tevent_req_received(req);
1426 *stream = tstream_context_create(mem_ctx,
1433 tevent_req_received(req);
1437 npas->unix_stream = state->plain;
1438 npas->file_type = state->file_type;
1440 *remote_client_addr = talloc_move(mem_ctx, &state->remote_client_addr);
1441 *_remote_client_name = talloc_move(mem_ctx, &state->remote_client_name);
1442 *local_server_addr = talloc_move(mem_ctx, &state->local_server_addr);
1443 *local_server_name = talloc_move(mem_ctx, &state->local_server_name);
1444 *session_info = talloc_move(mem_ctx, &state->session_info);
1446 tevent_req_received(req);
1451 /* SOCKETPAIR for internal rpc communication */
1453 /* file_type is FILE_TYPE_BYTE_MODE_PIPE or FILE_TYPE_MESSAGE_MODE_PIPE */
1454 int _tstream_npa_socketpair(uint16_t file_type,
1455 TALLOC_CTX *mem_ctx1,
1456 struct tstream_context **pstream1,
1457 TALLOC_CTX *mem_ctx2,
1458 struct tstream_context **pstream2,
1459 const char *location)
1461 struct tstream_context *stream1 = NULL;
1462 struct tstream_context *stream2 = NULL;
1469 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
1476 ok = smb_set_close_on_exec(fd1);
1481 ok = smb_set_close_on_exec(fd2);
1486 rc = set_blocking(fd1, false);
1491 rc = set_blocking(fd2, false);
1496 rc = _tstream_npa_existing_socket(mem_ctx1,
1505 rc = _tstream_npa_existing_socket(mem_ctx2,
1511 int sys_errno = errno;
1512 talloc_free(stream1);
1518 *pstream1 = stream1;
1519 *pstream2 = stream2;
1525 int sys_errno = errno;