smb2_server: call smbXsrv_connection_disconnect_transport() early on network errors
[gd/samba-autobuild/.git] / source3 / smbd / message.c
index 347370e40c47490f65692802790d37e9ba399149..b97289468893f4b16aa3b56ceca1fd26230b3b4b 100644 (file)
 
 
 #include "includes.h"
+#include "system/filesys.h"
+#include "smbd/smbd.h"
+#include "smbd/globals.h"
+#include "smbprofile.h"
 
 extern userdom_struct current_user_info;
 
@@ -32,8 +36,6 @@ struct msg_state {
        char *msg;
 };
 
-static struct msg_state *smbd_msg_state;
-
 /****************************************************************************
  Deliver the message.
 ****************************************************************************/
@@ -41,6 +43,8 @@ static struct msg_state *smbd_msg_state;
 static void msg_deliver(struct msg_state *state)
 {
        TALLOC_CTX *frame = talloc_stackframe();
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        char *name = NULL;
        int i;
        int fd;
@@ -49,8 +53,9 @@ static void msg_deliver(struct msg_state *state)
        ssize_t sz;
        fstring alpha_buf;
        char *s;
+       mode_t mask;
 
-       if (! (*lp_msg_command())) {
+       if (! (*lp_message_command(frame, lp_sub))) {
                DEBUG(1,("no messaging command specified\n"));
                goto done;
        }
@@ -60,7 +65,9 @@ static void msg_deliver(struct msg_state *state)
        if (!name) {
                goto done;
        }
-       fd = smb_mkstemp(name);
+       mask = umask(S_IRWXO | S_IRWXG);
+       fd = mkstemp(name);
+       umask(mask);
 
        if (fd == -1) {
                DEBUG(1, ("can't open message file %s: %s\n", name,
@@ -74,7 +81,7 @@ static void msg_deliver(struct msg_state *state)
 
        if (!convert_string_talloc(talloc_tos(), CH_DOS, CH_UNIX, state->msg,
                                   talloc_get_size(state->msg), (void *)&msg,
-                                  &len, true)) {
+                                  &len)) {
                DEBUG(3, ("Conversion failed, delivering message in DOS "
                          "codepage format\n"));
                msg = state->msg;
@@ -95,7 +102,7 @@ static void msg_deliver(struct msg_state *state)
        close(fd);
 
        /* run the command */
-       s = talloc_strdup(talloc_tos(), lp_msg_command());
+       s = lp_message_command(frame, lp_sub);
        if (s == NULL) {
                goto done;
        }
@@ -124,7 +131,7 @@ static void msg_deliver(struct msg_state *state)
        if (s == NULL) {
                goto done;
        }
-       smbrun(s,NULL);
+       smbrun(s, NULL, NULL);
 
  done:
        TALLOC_FREE(frame);
@@ -138,22 +145,24 @@ static void msg_deliver(struct msg_state *state)
 
 void reply_sends(struct smb_request *req)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        struct msg_state *state;
        int len;
-       const char *msg;
-       const char *p;
+       const uint8_t *msg;
+       const uint8_t *p;
 
        START_PROFILE(SMBsends);
 
-       if (!(*lp_msg_command())) {
-               reply_doserror(req, ERRSRV, ERRmsgoff);
+       if (!(*lp_message_command(talloc_tos(), lp_sub))) {
+               reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
                END_PROFILE(SMBsends);
                return;
        }
 
        state = talloc(talloc_tos(), struct msg_state);
 
-       p = (const char *)req->buf + 1;
+       p = req->buf + 1;
        p += srvstr_pull_req_talloc(
                state, req, &state->from, p, STR_ASCII|STR_TERMINATE) + 1;
        p += srvstr_pull_req_talloc(
@@ -162,7 +171,7 @@ void reply_sends(struct smb_request *req)
        msg = p;
 
        len = SVAL(msg,0);
-       len = MIN(len, smb_bufrem(req->inbuf, msg+2));
+       len = MIN(len, smbreq_bufrem(req, msg+2));
 
        state->msg = talloc_array(state, char, len);
 
@@ -189,36 +198,42 @@ void reply_sends(struct smb_request *req)
 
 void reply_sendstrt(struct smb_request *req)
 {
-       const char *p;
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
+       struct smbXsrv_connection *xconn = req->xconn;
+       const uint8_t *p;
 
        START_PROFILE(SMBsendstrt);
 
-       if (!(*lp_msg_command())) {
-               reply_doserror(req, ERRSRV, ERRmsgoff);
+       if (!(*lp_message_command(talloc_tos(), lp_sub))) {
+               reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
                END_PROFILE(SMBsendstrt);
                return;
        }
 
-       TALLOC_FREE(smbd_msg_state);
+       TALLOC_FREE(xconn->smb1.msg_state);
 
-       smbd_msg_state = TALLOC_ZERO_P(NULL, struct msg_state);
+       xconn->smb1.msg_state = talloc_zero(xconn, struct msg_state);
 
-       if (smbd_msg_state == NULL) {
+       if (xconn->smb1.msg_state == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
                END_PROFILE(SMBsendstrt);
                return;
        }
 
-       p = (const char *)req->buf+1;
+       p = req->buf+1;
        p += srvstr_pull_req_talloc(
-               smbd_msg_state, req, &smbd_msg_state->from, p,
+               xconn->smb1.msg_state, req,
+               &xconn->smb1.msg_state->from, p,
                STR_ASCII|STR_TERMINATE) + 1;
        p += srvstr_pull_req_talloc(
-               smbd_msg_state, req, &smbd_msg_state->to, p,
+               xconn->smb1.msg_state, req,
+               &xconn->smb1.msg_state->to, p,
                STR_ASCII|STR_TERMINATE) + 1;
 
-       DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", smbd_msg_state->from,
-                   smbd_msg_state->to ) );
+       DEBUG(3, ("SMBsendstrt (from %s to %s)\n",
+                 xconn->smb1.msg_state->from,
+                 xconn->smb1.msg_state->to));
 
        reply_outbuf(req, 0, 0);
 
@@ -233,6 +248,9 @@ void reply_sendstrt(struct smb_request *req)
 
 void reply_sendtxt(struct smb_request *req)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
+       struct smbXsrv_connection *xconn = req->xconn;
        int len;
        const char *msg;
        char *tmp;
@@ -240,13 +258,13 @@ void reply_sendtxt(struct smb_request *req)
 
        START_PROFILE(SMBsendtxt);
 
-       if (! (*lp_msg_command())) {
-               reply_doserror(req, ERRSRV, ERRmsgoff);
+       if (! (*lp_message_command(talloc_tos(), lp_sub))) {
+               reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
                END_PROFILE(SMBsendtxt);
                return;
        }
 
-       if (smbd_msg_state == NULL) {
+       if ((xconn->smb1.msg_state == NULL) || (req->buflen < 3)) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBsendtxt);
                return;
@@ -254,12 +272,13 @@ void reply_sendtxt(struct smb_request *req)
 
        msg = (const char *)req->buf + 1;
 
-       old_len = talloc_get_size(smbd_msg_state->msg);
+       old_len = talloc_get_size(xconn->smb1.msg_state->msg);
 
-       len = MIN(SVAL(msg, 0), smb_bufrem(req->inbuf, msg+2));
+       len = MIN(SVAL(msg, 0), smbreq_bufrem(req, msg+2));
 
-       tmp = TALLOC_REALLOC_ARRAY(smbd_msg_state, smbd_msg_state->msg,
-                                  char, old_len + len);
+       tmp = talloc_realloc(xconn->smb1.msg_state,
+                            xconn->smb1.msg_state->msg,
+                            char, old_len + len);
 
        if (tmp == NULL) {
                reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -267,9 +286,9 @@ void reply_sendtxt(struct smb_request *req)
                return;
        }
 
-       smbd_msg_state->msg = tmp;
+       xconn->smb1.msg_state->msg = tmp;
 
-       memcpy(&smbd_msg_state->msg[old_len], msg+2, len);
+       memcpy(&xconn->smb1.msg_state->msg[old_len], msg+2, len);
 
        DEBUG( 3, ( "SMBsendtxt\n" ) );
 
@@ -286,19 +305,28 @@ void reply_sendtxt(struct smb_request *req)
 
 void reply_sendend(struct smb_request *req)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
+       struct smbXsrv_connection *xconn = req->xconn;
        START_PROFILE(SMBsendend);
 
-       if (! (*lp_msg_command())) {
-               reply_doserror(req, ERRSRV, ERRmsgoff);
+       if (! (*lp_message_command(talloc_tos(), lp_sub))) {
+               reply_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED);
+               END_PROFILE(SMBsendend);
+               return;
+       }
+
+       if (xconn->smb1.msg_state == NULL) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
                END_PROFILE(SMBsendend);
                return;
        }
 
        DEBUG(3,("SMBsendend\n"));
 
-       msg_deliver(smbd_msg_state);
+       msg_deliver(xconn->smb1.msg_state);
 
-       TALLOC_FREE(smbd_msg_state);
+       TALLOC_FREE(xconn->smb1.msg_state);
 
        reply_outbuf(req, 0, 0);