]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smb2_ioctl: implement FSCTL_PIPE_WAIT
authorStefan Metzmacher <metze@samba.org>
Thu, 11 Jun 2026 12:40:13 +0000 (14:40 +0200)
committerVolker Lendecke <vl@samba.org>
Fri, 24 Jul 2026 13:33:36 +0000 (13:33 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/smbd/smb2_ioctl_named_pipe.c

index 4c1967cca67a0502b05b79c69b5673af7b6a43b5..7787a0e6e52b9ab2927800b0fa78b68786d936a7 100644 (file)
 #include "smbd/globals.h"
 #include "../libcli/smb/smb_common.h"
 #include "../lib/util/tevent_ntstatus.h"
+#include "../lib/util/util_str_escape.h"
 #include "rpc_server/srv_pipe_hnd.h"
 #include "include/ntioctl.h"
+#include "librpc/gen_ndr/ndr_ioctl.h"
 #include "smb2_ioctl_private.h"
 
 #undef DBGC_CLASS
@@ -32,6 +34,7 @@
 
 static void smbd_smb2_ioctl_pipe_write_done(struct tevent_req *subreq);
 static void smbd_smb2_ioctl_pipe_read_done(struct tevent_req *subreq);
+static void smbd_smb2_ioctl_pipe_wait_done(struct tevent_req *subreq);
 
 struct tevent_req *smb2_ioctl_named_pipe(uint32_t ctl_code,
                                         struct tevent_context *ev,
@@ -42,7 +45,43 @@ struct tevent_req *smb2_ioctl_named_pipe(uint32_t ctl_code,
        uint8_t *out_data = NULL;
        uint32_t out_data_len = 0;
 
-       if (ctl_code == FSCTL_PIPE_TRANSCEIVE) {
+       if (ctl_code == FSCTL_PIPE_WAIT) {
+               struct connection_struct *conn = state->smbreq->conn;
+               struct fsctl_pipe_wait wait_request = { .pipe_name = NULL, };
+               enum ndr_err_code err;
+               struct tevent_req *subreq = NULL;
+
+               if (!IS_IPC(conn)) {
+                       tevent_req_nterror(req,
+                                       NT_STATUS_INVALID_DEVICE_REQUEST);
+                       return tevent_req_post(req, ev);
+               }
+
+               err = ndr_pull_struct_blob(&state->in_input,
+                               state, &wait_request,
+                               (ndr_pull_flags_fn_t)ndr_pull_fsctl_pipe_wait);
+               if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
+                       tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+                       return tevent_req_post(req, ev);
+               }
+
+               DBG_DEBUG("Handling FSCTL_PIPE_WAIT: %s\n",
+                         log_escape(state, wait_request.pipe_name));
+
+               subreq = np_wait_exists_send(state,
+                                            ev,
+                                            wait_request.pipe_name,
+                                            conn->sconn->remote_address,
+                                            conn->sconn->local_address,
+                                            conn->session_info);
+               if (tevent_req_nomem(subreq, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               tevent_req_set_callback(subreq,
+                                       smbd_smb2_ioctl_pipe_wait_done,
+                                       req);
+               return req;
+       } else if (ctl_code == FSCTL_PIPE_TRANSCEIVE) {
                struct tevent_req *subreq;
 
                if (!IS_IPC(state->smbreq->conn)) {
@@ -188,3 +227,9 @@ static void smbd_smb2_ioctl_pipe_read_done(struct tevent_req *subreq)
 
        tevent_req_done(req);
 }
+
+static void smbd_smb2_ioctl_pipe_wait_done(struct tevent_req *subreq)
+{
+       NTSTATUS status = np_wait_exists_recv(subreq);
+       tevent_req_simple_finish_ntstatus(subreq, status);
+}