s3-talloc Change TALLOC_ARRAY() to talloc_array()
[samba.git] / source3 / smbd / ipc.c
index f20c8512975c573c6987896ce42fb36630aba271..b452000e13921ddbac3689d39d32cfaacf28d5b9 100644 (file)
    */
 
 #include "includes.h"
    */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "smbd/globals.h"
 #include "smbd/globals.h"
+#include "smbprofile.h"
+#include "rpc_server/srv_pipe_hnd.h"
 
 #define NERR_notsupported 50
 
 
 #define NERR_notsupported 50
 
@@ -93,6 +96,8 @@ void send_trans_reply(connection_struct *conn,
 
        int ldata  = rdata  ? rdata_len : 0;
        int lparam = rparam ? rparam_len : 0;
 
        int ldata  = rdata  ? rdata_len : 0;
        int lparam = rparam ? rparam_len : 0;
+       struct smbd_server_connection *sconn = req->sconn;
+       int max_send = sconn->smb1.sessions.max_send;
 
        if (buffer_too_large)
                DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata ));
 
        if (buffer_too_large)
                DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata ));
@@ -133,7 +138,8 @@ void send_trans_reply(connection_struct *conn,
        }
 
        show_msg((char *)req->outbuf);
        }
 
        show_msg((char *)req->outbuf);
-       if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+       if (!srv_send_smb(sconn, (char *)req->outbuf,
+                         true, req->seqnum+1,
                          IS_CONN_ENCRYPTED(conn), &req->pcd)) {
                exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
        }
                          IS_CONN_ENCRYPTED(conn), &req->pcd)) {
                exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
        }
@@ -170,6 +176,9 @@ void send_trans_reply(connection_struct *conn,
                                           rparam, tot_param_sent, this_lparam,
                                           rdata, tot_data_sent, this_ldata);
 
                                           rparam, tot_param_sent, this_lparam,
                                           rdata, tot_data_sent, this_ldata);
 
+               SSVAL(req->outbuf,smb_vwv0,lparam);
+               SSVAL(req->outbuf,smb_vwv1,ldata);
+
                SSVAL(req->outbuf,smb_vwv3,this_lparam);
                SSVAL(req->outbuf,smb_vwv4,
                      smb_offset(smb_buf(req->outbuf)+1,req->outbuf));
                SSVAL(req->outbuf,smb_vwv3,this_lparam);
                SSVAL(req->outbuf,smb_vwv4,
                      smb_offset(smb_buf(req->outbuf)+1,req->outbuf));
@@ -189,7 +198,8 @@ void send_trans_reply(connection_struct *conn,
                }
 
                show_msg((char *)req->outbuf);
                }
 
                show_msg((char *)req->outbuf);
-               if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+               if (!srv_send_smb(sconn, (char *)req->outbuf,
+                                 true, req->seqnum+1,
                                  IS_CONN_ENCRYPTED(conn), &req->pcd))
                        exit_server_cleanly("send_trans_reply: srv_send_smb "
                                            "failed.");
                                  IS_CONN_ENCRYPTED(conn), &req->pcd))
                        exit_server_cleanly("send_trans_reply: srv_send_smb "
                                            "failed.");
@@ -220,12 +230,23 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
 {
        struct tevent_req *subreq;
        struct dcerpc_cmd_state *state;
 {
        struct tevent_req *subreq;
        struct dcerpc_cmd_state *state;
+       bool busy;
 
        if (!fsp_is_np(fsp)) {
                api_no_reply(conn, req);
                return;
        }
 
 
        if (!fsp_is_np(fsp)) {
                api_no_reply(conn, req);
                return;
        }
 
+       /*
+        * Trans requests are only allowed
+        * if no other Trans or Read is active
+        */
+       busy = np_read_in_progress(fsp->fake_file_handle);
+       if (busy) {
+               reply_nterror(req, NT_STATUS_PIPE_BUSY);
+               return;
+       }
+
        state = talloc(req, struct dcerpc_cmd_state);
        if (state == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
        state = talloc(req, struct dcerpc_cmd_state);
        if (state == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -247,7 +268,7 @@ static void api_dcerpc_cmd(connection_struct *conn, struct smb_request *req,
        state->num_data = length;
        state->max_read = max_read;
 
        state->num_data = length;
        state->max_read = max_read;
 
-       subreq = np_write_send(state, smbd_event_context(), state->handle,
+       subreq = np_write_send(state, server_event_context(), state->handle,
                               state->data, length);
        if (subreq == NULL) {
                TALLOC_FREE(state);
                               state->data, length);
        if (subreq == NULL) {
                TALLOC_FREE(state);
@@ -277,14 +298,14 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
                goto send;
        }
 
                goto send;
        }
 
-       state->data = TALLOC_REALLOC_ARRAY(state, state->data, uint8_t,
+       state->data = talloc_realloc(state, state->data, uint8_t,
                                           state->max_read);
        if (state->data == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                goto send;
        }
 
                                           state->max_read);
        if (state->data == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                goto send;
        }
 
-       subreq = np_read_send(req->conn, smbd_event_context(),
+       subreq = np_read_send(req->conn, server_event_context(),
                              state->handle, state->data, state->max_read);
        if (subreq == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                              state->handle, state->data, state->max_read);
        if (subreq == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -295,10 +316,12 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq)
 
  send:
        if (!srv_send_smb(
 
  send:
        if (!srv_send_smb(
-                   smbd_server_fd(), (char *)req->outbuf,
+                   req->sconn, (char *)req->outbuf,
+                   true, req->seqnum+1,
                    IS_CONN_ENCRYPTED(req->conn) || req->encrypted,
                    &req->pcd)) {
                    IS_CONN_ENCRYPTED(req->conn) || req->encrypted,
                    &req->pcd)) {
-               exit_server_cleanly("construct_reply: srv_send_smb failed.");
+               exit_server_cleanly("api_dcerpc_cmd_write_done: "
+                                   "srv_send_smb failed.");
        }
        TALLOC_FREE(req);
 }
        }
        TALLOC_FREE(req);
 }
@@ -321,11 +344,12 @@ static void api_dcerpc_cmd_read_done(struct tevent_req *subreq)
                           nt_errstr(status)));
                reply_nterror(req, status);
 
                           nt_errstr(status)));
                reply_nterror(req, status);
 
-               if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+               if (!srv_send_smb(req->sconn, (char *)req->outbuf,
+                                 true, req->seqnum+1,
                                  IS_CONN_ENCRYPTED(req->conn)
                                  ||req->encrypted, &req->pcd)) {
                                  IS_CONN_ENCRYPTED(req->conn)
                                  ||req->encrypted, &req->pcd)) {
-                       exit_server_cleanly("construct_reply: srv_send_smb "
-                                           "failed.");
+                       exit_server_cleanly("api_dcerpc_cmd_read_done: "
+                                           "srv_send_smb failed.");
                }
                TALLOC_FREE(req);
                return;
                }
                TALLOC_FREE(req);
                return;
@@ -448,7 +472,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
        }
 
        DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n",
        }
 
        DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n",
-                subcommand, fsp->fsp_name, pnum));
+                subcommand, fsp_str_dbg(fsp), pnum));
 
        DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt));
 
 
        DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt));
 
@@ -718,7 +742,7 @@ void reply_trans(struct smb_request *req)
                        goto bad_param;
                }
 
                        goto bad_param;
                }
 
-               if((state->setup = TALLOC_ARRAY(
+               if((state->setup = talloc_array(
                            state, uint16, state->setup_count)) == NULL) {
                        DEBUG(0,("reply_trans: setup malloc fail for %u "
                                 "bytes !\n", (unsigned int)
                            state, uint16, state->setup_count)) == NULL) {
                        DEBUG(0,("reply_trans: setup malloc fail for %u "
                                 "bytes !\n", (unsigned int)
@@ -750,6 +774,8 @@ void reply_trans(struct smb_request *req)
                return;
        }
 
                return;
        }
 
+       talloc_steal(talloc_tos(), state);
+
        handle_trans(conn, req, state);
 
        SAFE_FREE(state->data);
        handle_trans(conn, req, state);
 
        SAFE_FREE(state->data);
@@ -782,7 +808,7 @@ void reply_transs(struct smb_request *req)
 
        START_PROFILE(SMBtranss);
 
 
        START_PROFILE(SMBtranss);
 
-       show_msg((char *)req->inbuf);
+       show_msg((const char *)req->inbuf);
 
        if (req->wct < 8) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
 
        if (req->wct < 8) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -848,6 +874,8 @@ void reply_transs(struct smb_request *req)
                return;
        }
 
                return;
        }
 
+       talloc_steal(talloc_tos(), state);
+
        handle_trans(conn, req, state);
 
        DLIST_REMOVE(conn->pending_trans, state);
        handle_trans(conn, req, state);
 
        DLIST_REMOVE(conn->pending_trans, state);