LCOV - code coverage report
Current view: top level - source3/smbd - smb1_nttrans.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 1224 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 23 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    SMB NT transaction handling
       4             :    Copyright (C) Jeremy Allison                 1994-2007
       5             :    Copyright (C) Stefan (metze) Metzmacher      2003
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/filesys.h"
      23             : #include "smbd/smbd.h"
      24             : #include "smbd/globals.h"
      25             : #include "fake_file.h"
      26             : #include "../libcli/security/security.h"
      27             : #include "../librpc/gen_ndr/ndr_security.h"
      28             : #include "passdb/lookup_sid.h"
      29             : #include "auth.h"
      30             : #include "smbprofile.h"
      31             : #include "libsmb/libsmb.h"
      32             : #include "lib/util_ea.h"
      33             : #include "librpc/gen_ndr/ndr_quota.h"
      34             : #include "librpc/gen_ndr/ndr_security.h"
      35             : 
      36           0 : static char *nttrans_realloc(char **ptr, size_t size)
      37             : {
      38           0 :         if (ptr==NULL) {
      39           0 :                 smb_panic("nttrans_realloc() called with NULL ptr");
      40             :         }
      41             : 
      42           0 :         *ptr = (char *)SMB_REALLOC(*ptr, size);
      43           0 :         if(*ptr == NULL) {
      44           0 :                 return NULL;
      45             :         }
      46           0 :         memset(*ptr,'\0',size);
      47           0 :         return *ptr;
      48             : }
      49             : 
      50             : /****************************************************************************
      51             :  Send the required number of replies back.
      52             :  We assume all fields other than the data fields are
      53             :  set correctly for the type of call.
      54             :  HACK ! Always assumes smb_setup field is zero.
      55             : ****************************************************************************/
      56             : 
      57           0 : static void send_nt_replies(connection_struct *conn,
      58             :                             struct smb_request *req, NTSTATUS nt_error,
      59             :                             char *params, int paramsize,
      60             :                             char *pdata, int datasize)
      61             : {
      62           0 :         int data_to_send = datasize;
      63           0 :         int params_to_send = paramsize;
      64             :         int useable_space;
      65           0 :         char *pp = params;
      66           0 :         char *pd = pdata;
      67             :         int params_sent_thistime, data_sent_thistime, total_sent_thistime;
      68           0 :         int alignment_offset = 1;
      69           0 :         int data_alignment_offset = 0;
      70           0 :         struct smbXsrv_connection *xconn = req->xconn;
      71           0 :         int max_send = xconn->smb1.sessions.max_send;
      72             : 
      73             :         /*
      74             :          * If there genuinely are no parameters or data to send just send
      75             :          * the empty packet.
      76             :          */
      77             : 
      78           0 :         if(params_to_send == 0 && data_to_send == 0) {
      79           0 :                 reply_smb1_outbuf(req, 18, 0);
      80           0 :                 if (NT_STATUS_V(nt_error)) {
      81           0 :                         error_packet_set((char *)req->outbuf,
      82             :                                          0, 0, nt_error,
      83             :                                          __LINE__,__FILE__);
      84             :                 }
      85           0 :                 show_msg((char *)req->outbuf);
      86           0 :                 if (!smb1_srv_send(xconn,
      87           0 :                                 (char *)req->outbuf,
      88           0 :                                 true, req->seqnum+1,
      89           0 :                                 IS_CONN_ENCRYPTED(conn),
      90             :                                 &req->pcd)) {
      91           0 :                         exit_server_cleanly("send_nt_replies: smb1_srv_send failed.");
      92             :                 }
      93           0 :                 TALLOC_FREE(req->outbuf);
      94           0 :                 return;
      95             :         }
      96             : 
      97             :         /*
      98             :          * When sending params and data ensure that both are nicely aligned.
      99             :          * Only do this alignment when there is also data to send - else
     100             :          * can cause NT redirector problems.
     101             :          */
     102             : 
     103           0 :         if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
     104           0 :                 data_alignment_offset = 4 - (params_to_send % 4);
     105             :         }
     106             : 
     107             :         /*
     108             :          * Space is bufsize minus Netbios over TCP header minus SMB header.
     109             :          * The alignment_offset is to align the param bytes on a four byte
     110             :          * boundary (2 bytes for data len, one byte pad).
     111             :          * NT needs this to work correctly.
     112             :          */
     113             : 
     114           0 :         useable_space = max_send - (smb_size
     115             :                                     + 2 * 18 /* wct */
     116           0 :                                     + alignment_offset
     117           0 :                                     + data_alignment_offset);
     118             : 
     119           0 :         if (useable_space < 0) {
     120           0 :                 char *msg = talloc_asprintf(
     121           0 :                         talloc_tos(),
     122             :                         "send_nt_replies failed sanity useable_space = %d!!!",
     123             :                         useable_space);
     124           0 :                 DEBUG(0, ("%s\n", msg));
     125           0 :                 exit_server_cleanly(msg);
     126             :         }
     127             : 
     128           0 :         while (params_to_send || data_to_send) {
     129             : 
     130             :                 /*
     131             :                  * Calculate whether we will totally or partially fill this packet.
     132             :                  */
     133             : 
     134           0 :                 total_sent_thistime = params_to_send + data_to_send;
     135             : 
     136             :                 /*
     137             :                  * We can never send more than useable_space.
     138             :                  */
     139             : 
     140           0 :                 total_sent_thistime = MIN(total_sent_thistime, useable_space);
     141             : 
     142           0 :                 reply_smb1_outbuf(req, 18,
     143           0 :                              total_sent_thistime + alignment_offset
     144           0 :                              + data_alignment_offset);
     145             : 
     146             :                 /*
     147             :                  * Set total params and data to be sent.
     148             :                  */
     149             : 
     150           0 :                 SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
     151           0 :                 SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
     152             : 
     153             :                 /*
     154             :                  * Calculate how many parameters and data we can fit into
     155             :                  * this packet. Parameters get precedence.
     156             :                  */
     157             : 
     158           0 :                 params_sent_thistime = MIN(params_to_send,useable_space);
     159           0 :                 data_sent_thistime = useable_space - params_sent_thistime;
     160           0 :                 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
     161             : 
     162           0 :                 SIVAL(req->outbuf, smb_ntr_ParameterCount,
     163             :                       params_sent_thistime);
     164             : 
     165           0 :                 if(params_sent_thistime == 0) {
     166           0 :                         SIVAL(req->outbuf,smb_ntr_ParameterOffset,0);
     167           0 :                         SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0);
     168             :                 } else {
     169             :                         /*
     170             :                          * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
     171             :                          * parameter bytes, however the first 4 bytes of outbuf are
     172             :                          * the Netbios over TCP header. Thus use smb_base() to subtract
     173             :                          * them from the calculation.
     174             :                          */
     175             : 
     176           0 :                         SIVAL(req->outbuf,smb_ntr_ParameterOffset,
     177             :                               ((smb_buf(req->outbuf)+alignment_offset)
     178             :                                - smb_base(req->outbuf)));
     179             :                         /*
     180             :                          * Absolute displacement of param bytes sent in this packet.
     181             :                          */
     182             : 
     183           0 :                         SIVAL(req->outbuf, smb_ntr_ParameterDisplacement,
     184             :                               pp - params);
     185             :                 }
     186             : 
     187             :                 /*
     188             :                  * Deal with the data portion.
     189             :                  */
     190             : 
     191           0 :                 SIVAL(req->outbuf, smb_ntr_DataCount, data_sent_thistime);
     192             : 
     193           0 :                 if(data_sent_thistime == 0) {
     194           0 :                         SIVAL(req->outbuf,smb_ntr_DataOffset,0);
     195           0 :                         SIVAL(req->outbuf,smb_ntr_DataDisplacement, 0);
     196             :                 } else {
     197             :                         /*
     198             :                          * The offset of the data bytes is the offset of the
     199             :                          * parameter bytes plus the number of parameters being sent this time.
     200             :                          */
     201             : 
     202           0 :                         SIVAL(req->outbuf, smb_ntr_DataOffset,
     203             :                               ((smb_buf(req->outbuf)+alignment_offset) -
     204             :                                smb_base(req->outbuf))
     205             :                               + params_sent_thistime + data_alignment_offset);
     206           0 :                         SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
     207             :                 }
     208             : 
     209             :                 /*
     210             :                  * Copy the param bytes into the packet.
     211             :                  */
     212             : 
     213           0 :                 if(params_sent_thistime) {
     214           0 :                         if (alignment_offset != 0) {
     215           0 :                                 memset(smb_buf(req->outbuf), 0,
     216             :                                        alignment_offset);
     217             :                         }
     218           0 :                         memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
     219             :                                params_sent_thistime);
     220             :                 }
     221             : 
     222             :                 /*
     223             :                  * Copy in the data bytes
     224             :                  */
     225             : 
     226           0 :                 if(data_sent_thistime) {
     227           0 :                         if (data_alignment_offset != 0) {
     228           0 :                                 memset((smb_buf(req->outbuf)+alignment_offset+
     229             :                                         params_sent_thistime), 0,
     230             :                                        data_alignment_offset);
     231             :                         }
     232           0 :                         memcpy(smb_buf(req->outbuf)+alignment_offset
     233           0 :                                +params_sent_thistime+data_alignment_offset,
     234             :                                pd,data_sent_thistime);
     235             :                 }
     236             : 
     237           0 :                 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
     238             :                         params_sent_thistime, data_sent_thistime, useable_space));
     239           0 :                 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
     240             :                         params_to_send, data_to_send, paramsize, datasize));
     241             : 
     242           0 :                 if (NT_STATUS_V(nt_error)) {
     243           0 :                         error_packet_set((char *)req->outbuf,
     244             :                                          0, 0, nt_error,
     245             :                                          __LINE__,__FILE__);
     246             :                 }
     247             : 
     248             :                 /* Send the packet */
     249           0 :                 show_msg((char *)req->outbuf);
     250           0 :                 if (!smb1_srv_send(xconn,
     251           0 :                                 (char *)req->outbuf,
     252           0 :                                 true, req->seqnum+1,
     253           0 :                                 IS_CONN_ENCRYPTED(conn),
     254             :                                 &req->pcd)) {
     255           0 :                         exit_server_cleanly("send_nt_replies: smb1_srv_send failed.");
     256             :                 }
     257             : 
     258           0 :                 TALLOC_FREE(req->outbuf);
     259             : 
     260           0 :                 pp += params_sent_thistime;
     261           0 :                 pd += data_sent_thistime;
     262             : 
     263           0 :                 params_to_send -= params_sent_thistime;
     264           0 :                 data_to_send -= data_sent_thistime;
     265             : 
     266             :                 /*
     267             :                  * Sanity check
     268             :                  */
     269             : 
     270           0 :                 if(params_to_send < 0 || data_to_send < 0) {
     271           0 :                         DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
     272             :                                 params_to_send, data_to_send));
     273           0 :                         exit_server_cleanly("send_nt_replies: internal error");
     274             :                 }
     275             :         }
     276             : }
     277             : 
     278             : /****************************************************************************
     279             :  Reply to an NT create and X call on a pipe
     280             : ****************************************************************************/
     281             : 
     282           0 : static void nt_open_pipe(char *fname, connection_struct *conn,
     283             :                          struct smb_request *req, uint16_t *ppnum)
     284             : {
     285             :         files_struct *fsp;
     286             :         NTSTATUS status;
     287             : 
     288           0 :         DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
     289             : 
     290             :         /* Strip \\ off the name if present. */
     291           0 :         while (fname[0] == '\\') {
     292           0 :                 fname++;
     293             :         }
     294             : 
     295           0 :         status = open_np_file(req, fname, &fsp);
     296           0 :         if (!NT_STATUS_IS_OK(status)) {
     297           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     298           0 :                         reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
     299             :                                         ERRDOS, ERRbadpipe);
     300           0 :                         return;
     301             :                 }
     302           0 :                 reply_nterror(req, status);
     303           0 :                 return;
     304             :         }
     305             : 
     306           0 :         *ppnum = fsp->fnum;
     307           0 :         return;
     308             : }
     309             : 
     310             : /****************************************************************************
     311             :  Reply to an NT create and X call for pipes.
     312             : ****************************************************************************/
     313             : 
     314           0 : static void do_ntcreate_pipe_open(connection_struct *conn,
     315             :                                   struct smb_request *req)
     316             : {
     317           0 :         char *fname = NULL;
     318           0 :         uint16_t pnum = FNUM_FIELD_INVALID;
     319           0 :         char *p = NULL;
     320           0 :         uint32_t flags = IVAL(req->vwv+3, 1);
     321           0 :         TALLOC_CTX *ctx = talloc_tos();
     322             : 
     323           0 :         srvstr_pull_req_talloc(ctx, req, &fname, req->buf, STR_TERMINATE);
     324             : 
     325           0 :         if (!fname) {
     326           0 :                 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
     327             :                                 ERRDOS, ERRbadpipe);
     328           0 :                 return;
     329             :         }
     330           0 :         nt_open_pipe(fname, conn, req, &pnum);
     331             : 
     332           0 :         if (req->outbuf) {
     333             :                 /* error reply */
     334           0 :                 return;
     335             :         }
     336             : 
     337             :         /*
     338             :          * Deal with pipe return.
     339             :          */
     340             : 
     341           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     342             :                 /* This is very strange. We
     343             :                  * return 50 words, but only set
     344             :                  * the wcnt to 42 ? It's definitely
     345             :                  * what happens on the wire....
     346             :                  */
     347           0 :                 reply_smb1_outbuf(req, 50, 0);
     348           0 :                 SCVAL(req->outbuf,smb_wct,42);
     349             :         } else {
     350           0 :                 reply_smb1_outbuf(req, 34, 0);
     351             :         }
     352             : 
     353           0 :         SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
     354           0 :         SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
     355             : 
     356           0 :         p = (char *)req->outbuf + smb_vwv2;
     357           0 :         p++;
     358           0 :         SSVAL(p,0,pnum);
     359           0 :         p += 2;
     360           0 :         SIVAL(p,0,FILE_WAS_OPENED);
     361           0 :         p += 4;
     362           0 :         p += 32;
     363           0 :         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
     364           0 :         p += 20;
     365             :         /* File type. */
     366           0 :         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
     367             :         /* Device state. */
     368           0 :         SSVAL(p,2, 0x5FF); /* ? */
     369           0 :         p += 4;
     370             : 
     371           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     372           0 :                 p += 25;
     373           0 :                 SIVAL(p,0,FILE_GENERIC_ALL);
     374             :                 /*
     375             :                  * For pipes W2K3 seems to return
     376             :                  * 0x12019B next.
     377             :                  * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
     378             :                  */
     379           0 :                 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
     380             :         }
     381             : 
     382           0 :         DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
     383             : }
     384             : 
     385             : struct case_semantics_state {
     386             :         connection_struct *conn;
     387             :         bool case_sensitive;
     388             :         bool case_preserve;
     389             :         bool short_case_preserve;
     390             : };
     391             : 
     392             : /****************************************************************************
     393             :  Restore case semantics.
     394             : ****************************************************************************/
     395             : 
     396           0 : static int restore_case_semantics(struct case_semantics_state *state)
     397             : {
     398           0 :         state->conn->case_sensitive = state->case_sensitive;
     399           0 :         state->conn->case_preserve = state->case_preserve;
     400           0 :         state->conn->short_case_preserve = state->short_case_preserve;
     401           0 :         return 0;
     402             : }
     403             : 
     404             : /****************************************************************************
     405             :  Save case semantics.
     406             : ****************************************************************************/
     407             : 
     408           0 : static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx,
     409             :                                                 connection_struct *conn)
     410             : {
     411             :         struct case_semantics_state *result;
     412             : 
     413           0 :         if (!(result = talloc(mem_ctx, struct case_semantics_state))) {
     414           0 :                 return NULL;
     415             :         }
     416             : 
     417           0 :         result->conn = conn;
     418           0 :         result->case_sensitive = conn->case_sensitive;
     419           0 :         result->case_preserve = conn->case_preserve;
     420           0 :         result->short_case_preserve = conn->short_case_preserve;
     421             : 
     422             :         /* Set to POSIX. */
     423           0 :         conn->case_sensitive = True;
     424           0 :         conn->case_preserve = True;
     425           0 :         conn->short_case_preserve = True;
     426             : 
     427           0 :         talloc_set_destructor(result, restore_case_semantics);
     428             : 
     429           0 :         return result;
     430             : }
     431             : 
     432             : /*
     433             :  * Calculate the full path name given a relative fid.
     434             :  */
     435           0 : static NTSTATUS get_relative_fid_filename(connection_struct *conn,
     436             :                                           struct smb_request *req,
     437             :                                           uint16_t root_dir_fid,
     438             :                                           char *path,
     439             :                                           char **path_out)
     440             : {
     441           0 :         struct files_struct *dir_fsp = NULL;
     442           0 :         char *new_path = NULL;
     443             : 
     444           0 :         if (root_dir_fid == 0 || path == NULL) {
     445           0 :                 return NT_STATUS_INTERNAL_ERROR;
     446             :         }
     447             : 
     448           0 :         dir_fsp = file_fsp(req, root_dir_fid);
     449           0 :         if (dir_fsp == NULL) {
     450           0 :                 return NT_STATUS_INVALID_HANDLE;
     451             :         }
     452             : 
     453           0 :         if (fsp_is_alternate_stream(dir_fsp)) {
     454           0 :                 return NT_STATUS_INVALID_HANDLE;
     455             :         }
     456             : 
     457           0 :         if (!dir_fsp->fsp_flags.is_directory) {
     458             :                 /*
     459             :                  * Check to see if this is a mac fork of some kind.
     460             :                  */
     461           0 :                 if (conn->fs_capabilities & FILE_NAMED_STREAMS) {
     462           0 :                         char *stream = NULL;
     463             : 
     464           0 :                         stream = strchr_m(path, ':');
     465           0 :                         if (stream != NULL) {
     466           0 :                                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
     467             :                         }
     468             :                 }
     469             : 
     470             :                 /*
     471             :                  * We need to handle the case when we get a relative open
     472             :                  * relative to a file and the pathname is blank - this is a
     473             :                  * reopen! (hint from demyn plantenberg)
     474             :                  */
     475           0 :                 return NT_STATUS_INVALID_HANDLE;
     476             :         }
     477             : 
     478           0 :         if (ISDOT(dir_fsp->fsp_name->base_name)) {
     479             :                 /*
     480             :                  * We're at the toplevel dir, the final file name
     481             :                  * must not contain ./, as this is filtered out
     482             :                  * normally by srvstr_get_path and unix_convert
     483             :                  * explicitly rejects paths containing ./.
     484             :                  */
     485           0 :                 new_path = talloc_strdup(talloc_tos(), path);
     486             :         } else {
     487             :                 /*
     488             :                  * Copy in the base directory name.
     489             :                  */
     490             : 
     491           0 :                 new_path = talloc_asprintf(talloc_tos(),
     492             :                                            "%s/%s",
     493           0 :                                            dir_fsp->fsp_name->base_name,
     494             :                                            path);
     495             :         }
     496           0 :         if (new_path == NULL) {
     497           0 :                 return NT_STATUS_NO_MEMORY;
     498             :         }
     499             : 
     500           0 :         *path_out = new_path;
     501           0 :         return NT_STATUS_OK;
     502             : }
     503             : 
     504             : /****************************************************************************
     505             :  Reply to an NT create and X call.
     506             : ****************************************************************************/
     507             : 
     508           0 : void reply_ntcreate_and_X(struct smb_request *req)
     509             : {
     510           0 :         connection_struct *conn = req->conn;
     511           0 :         struct files_struct *dirfsp = NULL;
     512           0 :         struct smb_filename *smb_fname = NULL;
     513           0 :         char *fname = NULL;
     514             :         uint32_t flags;
     515             :         uint32_t access_mask;
     516             :         uint32_t file_attributes;
     517             :         uint32_t share_access;
     518             :         uint32_t create_disposition;
     519             :         uint32_t create_options;
     520             :         uint16_t root_dir_fid;
     521             :         uint64_t allocation_size;
     522             :         /* Breakout the oplock request bits so we can set the
     523             :            reply bits separately. */
     524           0 :         uint32_t fattr=0;
     525           0 :         off_t file_len = 0;
     526           0 :         int info = 0;
     527           0 :         files_struct *fsp = NULL;
     528           0 :         char *p = NULL;
     529             :         struct timespec create_timespec;
     530             :         struct timespec c_timespec;
     531             :         struct timespec a_timespec;
     532             :         struct timespec m_timespec;
     533             :         NTSTATUS status;
     534             :         int oplock_request;
     535           0 :         uint8_t oplock_granted = NO_OPLOCK_RETURN;
     536           0 :         struct case_semantics_state *case_state = NULL;
     537             :         uint32_t ucf_flags;
     538           0 :         NTTIME twrp = 0;
     539           0 :         TALLOC_CTX *ctx = talloc_tos();
     540             : 
     541           0 :         START_PROFILE(SMBntcreateX);
     542             : 
     543           0 :         if (req->wct < 24) {
     544           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     545           0 :                 goto out;
     546             :         }
     547             : 
     548           0 :         flags = IVAL(req->vwv+3, 1);
     549           0 :         access_mask = IVAL(req->vwv+7, 1);
     550           0 :         file_attributes = IVAL(req->vwv+13, 1);
     551           0 :         share_access = IVAL(req->vwv+15, 1);
     552           0 :         create_disposition = IVAL(req->vwv+17, 1);
     553           0 :         create_options = IVAL(req->vwv+19, 1);
     554           0 :         root_dir_fid = (uint16_t)IVAL(req->vwv+5, 1);
     555             : 
     556           0 :         allocation_size = BVAL(req->vwv+9, 1);
     557             : 
     558           0 :         srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
     559             :                             STR_TERMINATE, &status);
     560             : 
     561           0 :         if (!NT_STATUS_IS_OK(status)) {
     562           0 :                 reply_nterror(req, status);
     563           0 :                 goto out;
     564             :         }
     565             : 
     566           0 :         DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
     567             :                   "file_attributes = 0x%x, share_access = 0x%x, "
     568             :                   "create_disposition = 0x%x create_options = 0x%x "
     569             :                   "root_dir_fid = 0x%x, fname = %s\n",
     570             :                         (unsigned int)flags,
     571             :                         (unsigned int)access_mask,
     572             :                         (unsigned int)file_attributes,
     573             :                         (unsigned int)share_access,
     574             :                         (unsigned int)create_disposition,
     575             :                         (unsigned int)create_options,
     576             :                         (unsigned int)root_dir_fid,
     577             :                         fname));
     578             : 
     579             :         /*
     580             :          * we need to remove ignored bits when they come directly from the client
     581             :          * because we reuse some of them for internal stuff
     582             :          */
     583           0 :         create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
     584             : 
     585             :         /*
     586             :          * If it's an IPC, use the pipe handler.
     587             :          */
     588             : 
     589           0 :         if (IS_IPC(conn)) {
     590           0 :                 if (lp_nt_pipe_support()) {
     591           0 :                         do_ntcreate_pipe_open(conn, req);
     592           0 :                         goto out;
     593             :                 }
     594           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
     595           0 :                 goto out;
     596             :         }
     597             : 
     598           0 :         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
     599           0 :         if (oplock_request) {
     600           0 :                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
     601           0 :                         ? BATCH_OPLOCK : 0;
     602             :         }
     603             : 
     604           0 :         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
     605           0 :                 case_state = set_posix_case_semantics(ctx, conn);
     606           0 :                 if (!case_state) {
     607           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     608           0 :                         goto out;
     609             :                 }
     610             :         }
     611             : 
     612           0 :         if (root_dir_fid != 0) {
     613           0 :                 char *new_fname = NULL;
     614             : 
     615           0 :                 status = get_relative_fid_filename(conn,
     616             :                                                    req,
     617             :                                                    root_dir_fid,
     618             :                                                    fname,
     619             :                                                    &new_fname);
     620           0 :                 if (!NT_STATUS_IS_OK(status)) {
     621           0 :                         reply_nterror(req, status);
     622           0 :                         goto out;
     623             :                 }
     624           0 :                 fname = new_fname;
     625             :         }
     626             : 
     627           0 :         ucf_flags = filename_create_ucf_flags(req, create_disposition);
     628           0 :         if (ucf_flags & UCF_GMT_PATHNAME) {
     629           0 :                 extract_snapshot_token(fname, &twrp);
     630             :         }
     631           0 :         status = filename_convert_dirfsp(
     632             :                 ctx, conn, fname, ucf_flags, twrp, &dirfsp, &smb_fname);
     633             : 
     634           0 :         TALLOC_FREE(case_state);
     635             : 
     636           0 :         if (!NT_STATUS_IS_OK(status)) {
     637           0 :                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
     638           0 :                         reply_botherror(req,
     639             :                                 NT_STATUS_PATH_NOT_COVERED,
     640             :                                 ERRSRV, ERRbadpath);
     641           0 :                         goto out;
     642             :                 }
     643           0 :                 reply_nterror(req, status);
     644           0 :                 goto out;
     645             :         }
     646             : 
     647             :         /*
     648             :          * Bug #6898 - clients using Windows opens should
     649             :          * never be able to set this attribute into the
     650             :          * VFS.
     651             :          */
     652           0 :         file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
     653             : 
     654           0 :         status = SMB_VFS_CREATE_FILE(
     655             :                 conn,                                   /* conn */
     656             :                 req,                                    /* req */
     657             :                 dirfsp,                                 /* dirfsp */
     658             :                 smb_fname,                              /* fname */
     659             :                 access_mask,                            /* access_mask */
     660             :                 share_access,                           /* share_access */
     661             :                 create_disposition,                     /* create_disposition*/
     662             :                 create_options,                         /* create_options */
     663             :                 file_attributes,                        /* file_attributes */
     664             :                 oplock_request,                         /* oplock_request */
     665             :                 NULL,                                   /* lease */
     666             :                 allocation_size,                        /* allocation_size */
     667             :                 0,                                      /* private_flags */
     668             :                 NULL,                                   /* sd */
     669             :                 NULL,                                   /* ea_list */
     670             :                 &fsp,                                       /* result */
     671             :                 &info,                                      /* pinfo */
     672             :                 NULL, NULL);                            /* create context */
     673             : 
     674           0 :         if (!NT_STATUS_IS_OK(status)) {
     675           0 :                 if (open_was_deferred(req->xconn, req->mid)) {
     676             :                         /* We have re-scheduled this call, no error. */
     677           0 :                         goto out;
     678             :                 }
     679           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
     680           0 :                         bool ok = defer_smb1_sharing_violation(req);
     681           0 :                         if (ok) {
     682           0 :                                 goto out;
     683             :                         }
     684             :                 }
     685           0 :                 reply_openerror(req, status);
     686           0 :                 goto out;
     687             :         }
     688             : 
     689             :         /* Ensure we're pointing at the correct stat struct. */
     690           0 :         smb_fname = fsp->fsp_name;
     691             : 
     692             :         /*
     693             :          * If the caller set the extended oplock request bit
     694             :          * and we granted one (by whatever means) - set the
     695             :          * correct bit for extended oplock reply.
     696             :          */
     697             : 
     698           0 :         if (oplock_request &&
     699           0 :             (lp_fake_oplocks(SNUM(conn))
     700           0 :              || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
     701             : 
     702             :                 /*
     703             :                  * Exclusive oplock granted
     704             :                  */
     705             : 
     706           0 :                 if (flags & REQUEST_BATCH_OPLOCK) {
     707           0 :                         oplock_granted = BATCH_OPLOCK_RETURN;
     708             :                 } else {
     709           0 :                         oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
     710             :                 }
     711           0 :         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
     712           0 :                 oplock_granted = LEVEL_II_OPLOCK_RETURN;
     713             :         } else {
     714           0 :                 oplock_granted = NO_OPLOCK_RETURN;
     715             :         }
     716             : 
     717           0 :         file_len = smb_fname->st.st_ex_size;
     718             : 
     719           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     720             :                 /* This is very strange. We
     721             :                  * return 50 words, but only set
     722             :                  * the wcnt to 42 ? It's definitely
     723             :                  * what happens on the wire....
     724             :                  */
     725           0 :                 reply_smb1_outbuf(req, 50, 0);
     726           0 :                 SCVAL(req->outbuf,smb_wct,42);
     727             :         } else {
     728           0 :                 reply_smb1_outbuf(req, 34, 0);
     729             :         }
     730             : 
     731           0 :         SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
     732           0 :         SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
     733             : 
     734           0 :         p = (char *)req->outbuf + smb_vwv2;
     735             : 
     736           0 :         SCVAL(p, 0, oplock_granted);
     737             : 
     738           0 :         p++;
     739           0 :         SSVAL(p,0,fsp->fnum);
     740           0 :         p += 2;
     741           0 :         if ((create_disposition == FILE_SUPERSEDE)
     742           0 :             && (info == FILE_WAS_OVERWRITTEN)) {
     743           0 :                 SIVAL(p,0,FILE_WAS_SUPERSEDED);
     744             :         } else {
     745           0 :                 SIVAL(p,0,info);
     746             :         }
     747           0 :         p += 4;
     748             : 
     749           0 :         fattr = fdos_mode(fsp);
     750           0 :         if (fattr == 0) {
     751           0 :                 fattr = FILE_ATTRIBUTE_NORMAL;
     752             :         }
     753             : 
     754             :         /* Create time. */
     755           0 :         create_timespec = get_create_timespec(conn, fsp, smb_fname);
     756           0 :         a_timespec = smb_fname->st.st_ex_atime;
     757           0 :         m_timespec = smb_fname->st.st_ex_mtime;
     758           0 :         c_timespec = get_change_timespec(conn, fsp, smb_fname);
     759             : 
     760           0 :         if (lp_dos_filetime_resolution(SNUM(conn))) {
     761           0 :                 dos_filetime_timespec(&create_timespec);
     762           0 :                 dos_filetime_timespec(&a_timespec);
     763           0 :                 dos_filetime_timespec(&m_timespec);
     764           0 :                 dos_filetime_timespec(&c_timespec);
     765             :         }
     766             : 
     767           0 :         put_long_date_full_timespec(conn->ts_res, p, &create_timespec); /* create time. */
     768           0 :         p += 8;
     769           0 :         put_long_date_full_timespec(conn->ts_res, p, &a_timespec); /* access time */
     770           0 :         p += 8;
     771           0 :         put_long_date_full_timespec(conn->ts_res, p, &m_timespec); /* write time */
     772           0 :         p += 8;
     773           0 :         put_long_date_full_timespec(conn->ts_res, p, &c_timespec); /* change time */
     774           0 :         p += 8;
     775           0 :         SIVAL(p,0,fattr); /* File Attributes. */
     776           0 :         p += 4;
     777           0 :         SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&smb_fname->st));
     778           0 :         p += 8;
     779           0 :         SOFF_T(p,0,file_len);
     780           0 :         p += 8;
     781           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     782           0 :                 uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
     783           0 :                 unsigned int num_streams = 0;
     784           0 :                 struct stream_struct *streams = NULL;
     785             : 
     786           0 :                 if (lp_ea_support(SNUM(conn))) {
     787           0 :                         size_t num_names = 0;
     788             :                         /* Do we have any EA's ? */
     789           0 :                         status = get_ea_names_from_fsp(
     790           0 :                             ctx, smb_fname->fsp, NULL, &num_names);
     791           0 :                         if (NT_STATUS_IS_OK(status) && num_names) {
     792           0 :                                 file_status &= ~NO_EAS;
     793             :                         }
     794             :                 }
     795             : 
     796           0 :                 status = vfs_fstreaminfo(smb_fname->fsp, ctx,
     797             :                         &num_streams, &streams);
     798             :                 /* There is always one stream, ::$DATA. */
     799           0 :                 if (NT_STATUS_IS_OK(status) && num_streams > 1) {
     800           0 :                         file_status &= ~NO_SUBSTREAMS;
     801             :                 }
     802           0 :                 TALLOC_FREE(streams);
     803           0 :                 SSVAL(p,2,file_status);
     804             :         }
     805           0 :         p += 4;
     806           0 :         SCVAL(p,0,fsp->fsp_flags.is_directory ? 1 : 0);
     807             : 
     808           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     809           0 :                 uint32_t perms = 0;
     810           0 :                 p += 25;
     811           0 :                 if (fsp->fsp_flags.is_directory ||
     812           0 :                     fsp->fsp_flags.can_write ||
     813           0 :                     can_write_to_fsp(fsp))
     814             :                 {
     815           0 :                         perms = FILE_GENERIC_ALL;
     816             :                 } else {
     817           0 :                         perms = FILE_GENERIC_READ|FILE_EXECUTE;
     818             :                 }
     819           0 :                 SIVAL(p,0,perms);
     820             :         }
     821             : 
     822           0 :         DEBUG(5,("reply_ntcreate_and_X: %s, open name = %s\n",
     823             :                 fsp_fnum_dbg(fsp), smb_fname_str_dbg(smb_fname)));
     824             : 
     825           0 :  out:
     826           0 :         END_PROFILE(SMBntcreateX);
     827           0 :         return;
     828             : }
     829             : 
     830             : /****************************************************************************
     831             :  Reply to a NT_TRANSACT_CREATE call to open a pipe.
     832             : ****************************************************************************/
     833             : 
     834           0 : static void do_nt_transact_create_pipe(connection_struct *conn,
     835             :                                        struct smb_request *req,
     836             :                                        uint16_t **ppsetup, uint32_t setup_count,
     837             :                                        char **ppparams, uint32_t parameter_count,
     838             :                                        char **ppdata, uint32_t data_count)
     839             : {
     840           0 :         char *fname = NULL;
     841           0 :         char *params = *ppparams;
     842           0 :         uint16_t pnum = FNUM_FIELD_INVALID;
     843           0 :         char *p = NULL;
     844             :         NTSTATUS status;
     845             :         size_t param_len;
     846             :         uint32_t flags;
     847           0 :         TALLOC_CTX *ctx = talloc_tos();
     848             : 
     849             :         /*
     850             :          * Ensure minimum number of parameters sent.
     851             :          */
     852             : 
     853           0 :         if(parameter_count < 54) {
     854           0 :                 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
     855           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     856           0 :                 return;
     857             :         }
     858             : 
     859           0 :         flags = IVAL(params,0);
     860             : 
     861           0 :         if (req->posix_pathnames) {
     862           0 :                 srvstr_get_path_posix(ctx,
     863             :                         params,
     864           0 :                         req->flags2,
     865             :                         &fname,
     866           0 :                         params+53,
     867           0 :                         parameter_count-53,
     868             :                         STR_TERMINATE,
     869             :                         &status);
     870             :         } else {
     871           0 :                 srvstr_get_path(ctx,
     872             :                         params,
     873           0 :                         req->flags2,
     874             :                         &fname,
     875           0 :                         params+53,
     876           0 :                         parameter_count-53,
     877             :                         STR_TERMINATE,
     878             :                         &status);
     879             :         }
     880           0 :         if (!NT_STATUS_IS_OK(status)) {
     881           0 :                 reply_nterror(req, status);
     882           0 :                 return;
     883             :         }
     884             : 
     885           0 :         nt_open_pipe(fname, conn, req, &pnum);
     886             : 
     887           0 :         if (req->outbuf) {
     888             :                 /* Error return */
     889           0 :                 return;
     890             :         }
     891             : 
     892             :         /* Realloc the size of parameters and data we will return */
     893           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     894             :                 /* Extended response is 32 more byyes. */
     895           0 :                 param_len = 101;
     896             :         } else {
     897           0 :                 param_len = 69;
     898             :         }
     899           0 :         params = nttrans_realloc(ppparams, param_len);
     900           0 :         if(params == NULL) {
     901           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     902           0 :                 return;
     903             :         }
     904             : 
     905           0 :         p = params;
     906           0 :         SCVAL(p,0,NO_OPLOCK_RETURN);
     907             : 
     908           0 :         p += 2;
     909           0 :         SSVAL(p,0,pnum);
     910           0 :         p += 2;
     911           0 :         SIVAL(p,0,FILE_WAS_OPENED);
     912           0 :         p += 8;
     913             : 
     914           0 :         p += 32;
     915           0 :         SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
     916           0 :         p += 20;
     917             :         /* File type. */
     918           0 :         SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
     919             :         /* Device state. */
     920           0 :         SSVAL(p,2, 0x5FF); /* ? */
     921           0 :         p += 4;
     922             : 
     923           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
     924           0 :                 p += 25;
     925           0 :                 SIVAL(p,0,FILE_GENERIC_ALL);
     926             :                 /*
     927             :                  * For pipes W2K3 seems to return
     928             :                  * 0x12019B next.
     929             :                  * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
     930             :                  */
     931           0 :                 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
     932             :         }
     933             : 
     934           0 :         DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
     935             : 
     936             :         /* Send the required number of replies */
     937           0 :         send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
     938             : 
     939           0 :         return;
     940             : }
     941             : 
     942             : /****************************************************************************
     943             :  Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
     944             : ****************************************************************************/
     945             : 
     946           0 : static void call_nt_transact_create(connection_struct *conn,
     947             :                                     struct smb_request *req,
     948             :                                     uint16_t **ppsetup, uint32_t setup_count,
     949             :                                     char **ppparams, uint32_t parameter_count,
     950             :                                     char **ppdata, uint32_t data_count,
     951             :                                     uint32_t max_data_count)
     952             : {
     953           0 :         struct smb_filename *smb_fname = NULL;
     954           0 :         char *fname = NULL;
     955           0 :         char *params = *ppparams;
     956           0 :         char *data = *ppdata;
     957             :         /* Breakout the oplock request bits so we can set the reply bits separately. */
     958           0 :         uint32_t fattr=0;
     959           0 :         off_t file_len = 0;
     960           0 :         int info = 0;
     961           0 :         struct files_struct *dirfsp = NULL;
     962           0 :         files_struct *fsp = NULL;
     963           0 :         char *p = NULL;
     964             :         uint32_t flags;
     965             :         uint32_t access_mask;
     966             :         uint32_t file_attributes;
     967             :         uint32_t share_access;
     968             :         uint32_t create_disposition;
     969             :         uint32_t create_options;
     970             :         uint32_t sd_len;
     971           0 :         struct security_descriptor *sd = NULL;
     972             :         uint32_t ea_len;
     973             :         uint16_t root_dir_fid;
     974             :         struct timespec create_timespec;
     975             :         struct timespec c_timespec;
     976             :         struct timespec a_timespec;
     977             :         struct timespec m_timespec;
     978           0 :         struct ea_list *ea_list = NULL;
     979             :         NTSTATUS status;
     980             :         size_t param_len;
     981             :         uint64_t allocation_size;
     982             :         int oplock_request;
     983             :         uint8_t oplock_granted;
     984           0 :         struct case_semantics_state *case_state = NULL;
     985             :         uint32_t ucf_flags;
     986           0 :         NTTIME twrp = 0;
     987           0 :         TALLOC_CTX *ctx = talloc_tos();
     988             : 
     989           0 :         DEBUG(5,("call_nt_transact_create\n"));
     990             : 
     991             :         /*
     992             :          * If it's an IPC, use the pipe handler.
     993             :          */
     994             : 
     995           0 :         if (IS_IPC(conn)) {
     996           0 :                 if (lp_nt_pipe_support()) {
     997           0 :                         do_nt_transact_create_pipe(
     998             :                                 conn, req,
     999             :                                 ppsetup, setup_count,
    1000             :                                 ppparams, parameter_count,
    1001             :                                 ppdata, data_count);
    1002           0 :                         goto out;
    1003             :                 }
    1004           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1005           0 :                 goto out;
    1006             :         }
    1007             : 
    1008             :         /*
    1009             :          * Ensure minimum number of parameters sent.
    1010             :          */
    1011             : 
    1012           0 :         if(parameter_count < 54) {
    1013           0 :                 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
    1014           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1015           0 :                 goto out;
    1016             :         }
    1017             : 
    1018           0 :         flags = IVAL(params,0);
    1019           0 :         access_mask = IVAL(params,8);
    1020           0 :         file_attributes = IVAL(params,20);
    1021           0 :         share_access = IVAL(params,24);
    1022           0 :         create_disposition = IVAL(params,28);
    1023           0 :         create_options = IVAL(params,32);
    1024           0 :         sd_len = IVAL(params,36);
    1025           0 :         ea_len = IVAL(params,40);
    1026           0 :         root_dir_fid = (uint16_t)IVAL(params,4);
    1027           0 :         allocation_size = BVAL(params,12);
    1028             : 
    1029             :         /*
    1030             :          * we need to remove ignored bits when they come directly from the client
    1031             :          * because we reuse some of them for internal stuff
    1032             :          */
    1033           0 :         create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
    1034             : 
    1035           0 :         if (req->posix_pathnames) {
    1036           0 :                 srvstr_get_path_posix(ctx,
    1037             :                         params,
    1038           0 :                         req->flags2,
    1039             :                         &fname,
    1040           0 :                         params+53,
    1041           0 :                         parameter_count-53,
    1042             :                         STR_TERMINATE,
    1043             :                         &status);
    1044             :         } else {
    1045           0 :                 srvstr_get_path(ctx,
    1046             :                         params,
    1047           0 :                         req->flags2,
    1048             :                         &fname,
    1049           0 :                         params+53,
    1050           0 :                         parameter_count-53,
    1051             :                         STR_TERMINATE,
    1052             :                         &status);
    1053             :         }
    1054           0 :         if (!NT_STATUS_IS_OK(status)) {
    1055           0 :                 reply_nterror(req, status);
    1056           0 :                 goto out;
    1057             :         }
    1058             : 
    1059           0 :         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
    1060           0 :                 case_state = set_posix_case_semantics(ctx, conn);
    1061           0 :                 if (!case_state) {
    1062           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1063           0 :                         goto out;
    1064             :                 }
    1065             :         }
    1066             : 
    1067           0 :         if (root_dir_fid != 0) {
    1068           0 :                 char *new_fname = NULL;
    1069             : 
    1070           0 :                 status = get_relative_fid_filename(conn,
    1071             :                                                    req,
    1072             :                                                    root_dir_fid,
    1073             :                                                    fname,
    1074             :                                                    &new_fname);
    1075           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1076           0 :                         reply_nterror(req, status);
    1077           0 :                         goto out;
    1078             :                 }
    1079           0 :                 fname = new_fname;
    1080             :         }
    1081             : 
    1082           0 :         ucf_flags = filename_create_ucf_flags(req, create_disposition);
    1083           0 :         if (ucf_flags & UCF_GMT_PATHNAME) {
    1084           0 :                 extract_snapshot_token(fname, &twrp);
    1085             :         }
    1086           0 :         status = filename_convert_dirfsp(ctx,
    1087             :                                          conn,
    1088             :                                          fname,
    1089             :                                          ucf_flags,
    1090             :                                          twrp,
    1091             :                                          &dirfsp,
    1092             :                                          &smb_fname);
    1093             : 
    1094           0 :         TALLOC_FREE(case_state);
    1095             : 
    1096           0 :         if (!NT_STATUS_IS_OK(status)) {
    1097           0 :                 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
    1098           0 :                         reply_botherror(req,
    1099             :                                 NT_STATUS_PATH_NOT_COVERED,
    1100             :                                 ERRSRV, ERRbadpath);
    1101           0 :                         goto out;
    1102             :                 }
    1103           0 :                 reply_nterror(req, status);
    1104           0 :                 goto out;
    1105             :         }
    1106             : 
    1107             :         /* Ensure the data_len is correct for the sd and ea values given. */
    1108           0 :         if ((ea_len + sd_len > data_count)
    1109           0 :             || (ea_len > data_count) || (sd_len > data_count)
    1110           0 :             || (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
    1111           0 :                 DEBUG(10, ("call_nt_transact_create - ea_len = %u, sd_len = "
    1112             :                            "%u, data_count = %u\n", (unsigned int)ea_len,
    1113             :                            (unsigned int)sd_len, (unsigned int)data_count));
    1114           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1115           0 :                 goto out;
    1116             :         }
    1117             : 
    1118           0 :         if (sd_len) {
    1119           0 :                 DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
    1120             :                            sd_len));
    1121             : 
    1122           0 :                 status = unmarshall_sec_desc(ctx, (uint8_t *)data, sd_len,
    1123             :                                              &sd);
    1124           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1125           0 :                         DEBUG(10, ("call_nt_transact_create: "
    1126             :                                    "unmarshall_sec_desc failed: %s\n",
    1127             :                                    nt_errstr(status)));
    1128           0 :                         reply_nterror(req, status);
    1129           0 :                         goto out;
    1130             :                 }
    1131             :         }
    1132             : 
    1133           0 :         if (ea_len) {
    1134           0 :                 if (!lp_ea_support(SNUM(conn))) {
    1135           0 :                         DEBUG(10, ("call_nt_transact_create - ea_len = %u but "
    1136             :                                    "EA's not supported.\n",
    1137             :                                    (unsigned int)ea_len));
    1138           0 :                         reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
    1139           0 :                         goto out;
    1140             :                 }
    1141             : 
    1142           0 :                 if (ea_len < 10) {
    1143           0 :                         DEBUG(10,("call_nt_transact_create - ea_len = %u - "
    1144             :                                   "too small (should be more than 10)\n",
    1145             :                                   (unsigned int)ea_len ));
    1146           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1147           0 :                         goto out;
    1148             :                 }
    1149             : 
    1150             :                 /* We have already checked that ea_len <= data_count here. */
    1151           0 :                 ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len,
    1152             :                                                ea_len);
    1153           0 :                 if (ea_list == NULL) {
    1154           0 :                         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1155           0 :                         goto out;
    1156             :                 }
    1157             : 
    1158           0 :                 if (!req->posix_pathnames &&
    1159           0 :                                 ea_list_has_invalid_name(ea_list)) {
    1160             :                         /* Realloc the size of parameters and data we will return */
    1161           0 :                         if (flags & EXTENDED_RESPONSE_REQUIRED) {
    1162             :                                 /* Extended response is 32 more bytes. */
    1163           0 :                                 param_len = 101;
    1164             :                         } else {
    1165           0 :                                 param_len = 69;
    1166             :                         }
    1167           0 :                         params = nttrans_realloc(ppparams, param_len);
    1168           0 :                         if(params == NULL) {
    1169           0 :                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1170           0 :                                 goto out;
    1171             :                         }
    1172             : 
    1173           0 :                         memset(params, '\0', param_len);
    1174           0 :                         send_nt_replies(conn, req, STATUS_INVALID_EA_NAME,
    1175             :                                 params, param_len, NULL, 0);
    1176           0 :                         goto out;
    1177             :                 }
    1178             :         }
    1179             : 
    1180           0 :         oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
    1181           0 :         if (oplock_request) {
    1182           0 :                 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
    1183           0 :                         ? BATCH_OPLOCK : 0;
    1184             :         }
    1185             : 
    1186             :         /*
    1187             :          * Bug #6898 - clients using Windows opens should
    1188             :          * never be able to set this attribute into the
    1189             :          * VFS.
    1190             :          */
    1191           0 :         file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
    1192             : 
    1193           0 :         status = SMB_VFS_CREATE_FILE(
    1194             :                 conn,                                   /* conn */
    1195             :                 req,                                    /* req */
    1196             :                 dirfsp,                                 /* dirfsp */
    1197             :                 smb_fname,                              /* fname */
    1198             :                 access_mask,                            /* access_mask */
    1199             :                 share_access,                           /* share_access */
    1200             :                 create_disposition,                     /* create_disposition*/
    1201             :                 create_options,                         /* create_options */
    1202             :                 file_attributes,                        /* file_attributes */
    1203             :                 oplock_request,                         /* oplock_request */
    1204             :                 NULL,                                   /* lease */
    1205             :                 allocation_size,                        /* allocation_size */
    1206             :                 0,                                      /* private_flags */
    1207             :                 sd,                                     /* sd */
    1208             :                 ea_list,                                /* ea_list */
    1209             :                 &fsp,                                       /* result */
    1210             :                 &info,                                      /* pinfo */
    1211             :                 NULL, NULL);                            /* create context */
    1212             : 
    1213           0 :         if(!NT_STATUS_IS_OK(status)) {
    1214           0 :                 if (open_was_deferred(req->xconn, req->mid)) {
    1215             :                         /* We have re-scheduled this call, no error. */
    1216           0 :                         return;
    1217             :                 }
    1218           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    1219           0 :                         bool ok = defer_smb1_sharing_violation(req);
    1220           0 :                         if (ok) {
    1221           0 :                                 return;
    1222             :                         }
    1223             :                 }
    1224           0 :                 reply_openerror(req, status);
    1225           0 :                 goto out;
    1226             :         }
    1227             : 
    1228             :         /* Ensure we're pointing at the correct stat struct. */
    1229           0 :         TALLOC_FREE(smb_fname);
    1230           0 :         smb_fname = fsp->fsp_name;
    1231             : 
    1232             :         /*
    1233             :          * If the caller set the extended oplock request bit
    1234             :          * and we granted one (by whatever means) - set the
    1235             :          * correct bit for extended oplock reply.
    1236             :          */
    1237             : 
    1238           0 :         if (oplock_request &&
    1239           0 :             (lp_fake_oplocks(SNUM(conn))
    1240           0 :              || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
    1241             : 
    1242             :                 /*
    1243             :                  * Exclusive oplock granted
    1244             :                  */
    1245             : 
    1246           0 :                 if (flags & REQUEST_BATCH_OPLOCK) {
    1247           0 :                         oplock_granted = BATCH_OPLOCK_RETURN;
    1248             :                 } else {
    1249           0 :                         oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
    1250             :                 }
    1251           0 :         } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
    1252           0 :                 oplock_granted = LEVEL_II_OPLOCK_RETURN;
    1253             :         } else {
    1254           0 :                 oplock_granted = NO_OPLOCK_RETURN;
    1255             :         }
    1256             : 
    1257           0 :         file_len = smb_fname->st.st_ex_size;
    1258             : 
    1259             :         /* Realloc the size of parameters and data we will return */
    1260           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
    1261             :                 /* Extended response is 32 more byyes. */
    1262           0 :                 param_len = 101;
    1263             :         } else {
    1264           0 :                 param_len = 69;
    1265             :         }
    1266           0 :         params = nttrans_realloc(ppparams, param_len);
    1267           0 :         if(params == NULL) {
    1268           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1269           0 :                 goto out;
    1270             :         }
    1271             : 
    1272           0 :         p = params;
    1273           0 :         SCVAL(p, 0, oplock_granted);
    1274             : 
    1275           0 :         p += 2;
    1276           0 :         SSVAL(p,0,fsp->fnum);
    1277           0 :         p += 2;
    1278           0 :         if ((create_disposition == FILE_SUPERSEDE)
    1279           0 :             && (info == FILE_WAS_OVERWRITTEN)) {
    1280           0 :                 SIVAL(p,0,FILE_WAS_SUPERSEDED);
    1281             :         } else {
    1282           0 :                 SIVAL(p,0,info);
    1283             :         }
    1284           0 :         p += 8;
    1285             : 
    1286           0 :         fattr = fdos_mode(fsp);
    1287           0 :         if (fattr == 0) {
    1288           0 :                 fattr = FILE_ATTRIBUTE_NORMAL;
    1289             :         }
    1290             : 
    1291             :         /* Create time. */
    1292           0 :         create_timespec = get_create_timespec(conn, fsp, smb_fname);
    1293           0 :         a_timespec = smb_fname->st.st_ex_atime;
    1294           0 :         m_timespec = smb_fname->st.st_ex_mtime;
    1295           0 :         c_timespec = get_change_timespec(conn, fsp, smb_fname);
    1296             : 
    1297           0 :         if (lp_dos_filetime_resolution(SNUM(conn))) {
    1298           0 :                 dos_filetime_timespec(&create_timespec);
    1299           0 :                 dos_filetime_timespec(&a_timespec);
    1300           0 :                 dos_filetime_timespec(&m_timespec);
    1301           0 :                 dos_filetime_timespec(&c_timespec);
    1302             :         }
    1303             : 
    1304           0 :         put_long_date_full_timespec(conn->ts_res, p, &create_timespec); /* create time. */
    1305           0 :         p += 8;
    1306           0 :         put_long_date_full_timespec(conn->ts_res, p, &a_timespec); /* access time */
    1307           0 :         p += 8;
    1308           0 :         put_long_date_full_timespec(conn->ts_res, p, &m_timespec); /* write time */
    1309           0 :         p += 8;
    1310           0 :         put_long_date_full_timespec(conn->ts_res, p, &c_timespec); /* change time */
    1311           0 :         p += 8;
    1312           0 :         SIVAL(p,0,fattr); /* File Attributes. */
    1313           0 :         p += 4;
    1314           0 :         SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st));
    1315           0 :         p += 8;
    1316           0 :         SOFF_T(p,0,file_len);
    1317           0 :         p += 8;
    1318           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
    1319           0 :                 uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
    1320           0 :                 unsigned int num_streams = 0;
    1321           0 :                 struct stream_struct *streams = NULL;
    1322             : 
    1323           0 :                 if (lp_ea_support(SNUM(conn))) {
    1324           0 :                         size_t num_names = 0;
    1325             :                         /* Do we have any EA's ? */
    1326           0 :                         status = get_ea_names_from_fsp(
    1327           0 :                             ctx, smb_fname->fsp, NULL, &num_names);
    1328           0 :                         if (NT_STATUS_IS_OK(status) && num_names) {
    1329           0 :                                 file_status &= ~NO_EAS;
    1330             :                         }
    1331             :                 }
    1332             : 
    1333           0 :                 status = vfs_fstreaminfo(smb_fname->fsp, ctx,
    1334             :                         &num_streams, &streams);
    1335             :                 /* There is always one stream, ::$DATA. */
    1336           0 :                 if (NT_STATUS_IS_OK(status) && num_streams > 1) {
    1337           0 :                         file_status &= ~NO_SUBSTREAMS;
    1338             :                 }
    1339           0 :                 TALLOC_FREE(streams);
    1340           0 :                 SSVAL(p,2,file_status);
    1341             :         }
    1342           0 :         p += 4;
    1343           0 :         SCVAL(p,0,fsp->fsp_flags.is_directory ? 1 : 0);
    1344             : 
    1345           0 :         if (flags & EXTENDED_RESPONSE_REQUIRED) {
    1346           0 :                 uint32_t perms = 0;
    1347           0 :                 p += 25;
    1348           0 :                 if (fsp->fsp_flags.is_directory ||
    1349           0 :                     fsp->fsp_flags.can_write ||
    1350           0 :                     can_write_to_fsp(fsp))
    1351             :                 {
    1352           0 :                         perms = FILE_GENERIC_ALL;
    1353             :                 } else {
    1354           0 :                         perms = FILE_GENERIC_READ|FILE_EXECUTE;
    1355             :                 }
    1356           0 :                 SIVAL(p,0,perms);
    1357             :         }
    1358             : 
    1359           0 :         DEBUG(5,("call_nt_transact_create: open name = %s\n",
    1360             :                  smb_fname_str_dbg(smb_fname)));
    1361             : 
    1362             :         /* Send the required number of replies */
    1363           0 :         send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
    1364           0 :  out:
    1365           0 :         return;
    1366             : }
    1367             : 
    1368             : /****************************************************************************
    1369             :  Reply to a NT CANCEL request.
    1370             :  conn POINTER CAN BE NULL HERE !
    1371             : ****************************************************************************/
    1372             : 
    1373           0 : void reply_ntcancel(struct smb_request *req)
    1374             : {
    1375           0 :         struct smbXsrv_connection *xconn = req->xconn;
    1376           0 :         struct smbd_server_connection *sconn = req->sconn;
    1377             :         bool found;
    1378             : 
    1379             :         /*
    1380             :          * Go through and cancel any pending change notifies.
    1381             :          */
    1382             : 
    1383           0 :         START_PROFILE(SMBntcancel);
    1384           0 :         smb1_srv_cancel_sign_response(xconn);
    1385           0 :         found = remove_pending_change_notify_requests_by_mid(sconn, req->mid);
    1386           0 :         if (!found) {
    1387           0 :                 smbd_smb1_brl_finish_by_mid(sconn, req->mid);
    1388             :         }
    1389             : 
    1390           0 :         DEBUG(3,("reply_ntcancel: cancel called on mid = %llu.\n",
    1391             :                 (unsigned long long)req->mid));
    1392             : 
    1393           0 :         END_PROFILE(SMBntcancel);
    1394           0 :         return;
    1395             : }
    1396             : 
    1397             : /****************************************************************************
    1398             :  Reply to a NT rename request.
    1399             : ****************************************************************************/
    1400             : 
    1401           0 : void reply_ntrename(struct smb_request *req)
    1402             : {
    1403           0 :         connection_struct *conn = req->conn;
    1404           0 :         struct files_struct *src_dirfsp = NULL;
    1405           0 :         struct smb_filename *smb_fname_old = NULL;
    1406           0 :         struct files_struct *dst_dirfsp = NULL;
    1407           0 :         struct smb_filename *smb_fname_new = NULL;
    1408           0 :         char *oldname = NULL;
    1409           0 :         char *newname = NULL;
    1410           0 :         const char *dst_original_lcomp = NULL;
    1411             :         const char *p;
    1412             :         NTSTATUS status;
    1413             :         uint32_t attrs;
    1414           0 :         uint32_t ucf_flags_src = ucf_flags_from_smb_request(req);
    1415           0 :         NTTIME src_twrp = 0;
    1416           0 :         uint32_t ucf_flags_dst = ucf_flags_from_smb_request(req);
    1417           0 :         NTTIME dst_twrp = 0;
    1418             :         uint16_t rename_type;
    1419           0 :         TALLOC_CTX *ctx = talloc_tos();
    1420           0 :         bool stream_rename = false;
    1421             : 
    1422           0 :         START_PROFILE(SMBntrename);
    1423             : 
    1424           0 :         if (req->wct < 4) {
    1425           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1426           0 :                 goto out;
    1427             :         }
    1428             : 
    1429           0 :         attrs = SVAL(req->vwv+0, 0);
    1430           0 :         rename_type = SVAL(req->vwv+1, 0);
    1431             : 
    1432           0 :         p = (const char *)req->buf + 1;
    1433           0 :         p += srvstr_get_path_req(ctx, req, &oldname, p, STR_TERMINATE,
    1434             :                                        &status);
    1435           0 :         if (!NT_STATUS_IS_OK(status)) {
    1436           0 :                 reply_nterror(req, status);
    1437           0 :                 goto out;
    1438             :         }
    1439             : 
    1440           0 :         if (!req->posix_pathnames && ms_has_wild(oldname)) {
    1441           0 :                 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
    1442           0 :                 goto out;
    1443             :         }
    1444             : 
    1445           0 :         p++;
    1446           0 :         p += srvstr_get_path_req(ctx, req, &newname, p, STR_TERMINATE,
    1447             :                                        &status);
    1448           0 :         if (!NT_STATUS_IS_OK(status)) {
    1449           0 :                 reply_nterror(req, status);
    1450           0 :                 goto out;
    1451             :         }
    1452             : 
    1453           0 :         if (!req->posix_pathnames && ms_has_wild(newname)) {
    1454           0 :                 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
    1455           0 :                 goto out;
    1456             :         }
    1457             : 
    1458           0 :         if (!req->posix_pathnames) {
    1459             :                 /* The newname must begin with a ':' if the
    1460             :                    oldname contains a ':'. */
    1461           0 :                 if (strchr_m(oldname, ':')) {
    1462           0 :                         if (newname[0] != ':') {
    1463           0 :                                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1464           0 :                                 goto out;
    1465             :                         }
    1466           0 :                         stream_rename = true;
    1467             :                 }
    1468             :         }
    1469             : 
    1470           0 :         if (ucf_flags_src & UCF_GMT_PATHNAME) {
    1471           0 :                 extract_snapshot_token(oldname, &src_twrp);
    1472             :         }
    1473           0 :         status = filename_convert_dirfsp(ctx,
    1474             :                                          conn,
    1475             :                                          oldname,
    1476             :                                          ucf_flags_src,
    1477             :                                          src_twrp,
    1478             :                                          &src_dirfsp,
    1479             :                                          &smb_fname_old);
    1480           0 :         if (!NT_STATUS_IS_OK(status)) {
    1481           0 :                 if (NT_STATUS_EQUAL(status,
    1482             :                                     NT_STATUS_PATH_NOT_COVERED)) {
    1483           0 :                         reply_botherror(req,
    1484             :                                         NT_STATUS_PATH_NOT_COVERED,
    1485             :                                         ERRSRV, ERRbadpath);
    1486           0 :                         goto out;
    1487             :                 }
    1488           0 :                 reply_nterror(req, status);
    1489           0 :                 goto out;
    1490             :         }
    1491             : 
    1492           0 :         if (stream_rename) {
    1493             :                 /*
    1494             :                  * No point in calling filename_convert()
    1495             :                  * on a raw stream name. It can never find
    1496             :                  * the file anyway. Use the same logic as
    1497             :                  * SMB2_FILE_RENAME_INFORMATION_INTERNAL
    1498             :                  * and generate smb_fname_new directly.
    1499             :                  */
    1500           0 :                 smb_fname_new = synthetic_smb_fname(talloc_tos(),
    1501           0 :                                         smb_fname_old->base_name,
    1502             :                                         newname,
    1503             :                                         NULL,
    1504           0 :                                         smb_fname_old->twrp,
    1505           0 :                                         smb_fname_old->flags);
    1506           0 :                 if (smb_fname_new == NULL) {
    1507           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1508           0 :                         goto out;
    1509             :                 }
    1510             :         } else {
    1511           0 :                 if (ucf_flags_dst & UCF_GMT_PATHNAME) {
    1512           0 :                         extract_snapshot_token(newname,
    1513             :                                                &dst_twrp);
    1514             :                 }
    1515           0 :                 status = filename_convert_dirfsp(ctx,
    1516             :                                                  conn,
    1517             :                                                  newname,
    1518             :                                                  ucf_flags_dst,
    1519             :                                                  dst_twrp,
    1520             :                                                  &dst_dirfsp,
    1521             :                                                  &smb_fname_new);
    1522           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1523           0 :                         if (NT_STATUS_EQUAL(status,
    1524             :                                             NT_STATUS_PATH_NOT_COVERED)) {
    1525           0 :                                 reply_botherror(req,
    1526             :                                                 NT_STATUS_PATH_NOT_COVERED,
    1527             :                                                 ERRSRV, ERRbadpath);
    1528           0 :                                 goto out;
    1529             :                         }
    1530           0 :                         reply_nterror(req, status);
    1531           0 :                         goto out;
    1532             :                 }
    1533             :         }
    1534             : 
    1535             :         /* Get the last component of the destination for rename_internals(). */
    1536           0 :         dst_original_lcomp = get_original_lcomp(ctx,
    1537             :                                         conn,
    1538             :                                         newname,
    1539             :                                         ucf_flags_dst);
    1540           0 :         if (dst_original_lcomp == NULL) {
    1541           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1542           0 :                 goto out;
    1543             :         }
    1544             : 
    1545             : 
    1546           0 :         DEBUG(3,("reply_ntrename: %s -> %s\n",
    1547             :                  smb_fname_str_dbg(smb_fname_old),
    1548             :                  smb_fname_str_dbg(smb_fname_new)));
    1549             : 
    1550           0 :         switch(rename_type) {
    1551           0 :                 case RENAME_FLAG_RENAME:
    1552           0 :                         status = rename_internals(ctx,
    1553             :                                                 conn,
    1554             :                                                 req,
    1555             :                                                 src_dirfsp,
    1556             :                                                 smb_fname_old,
    1557             :                                                 dst_dirfsp,
    1558             :                                                 smb_fname_new,
    1559             :                                                 dst_original_lcomp,
    1560             :                                                 attrs,
    1561             :                                                 false,
    1562             :                                                 DELETE_ACCESS);
    1563           0 :                         break;
    1564           0 :                 case RENAME_FLAG_HARD_LINK:
    1565           0 :                         status = hardlink_internals(ctx,
    1566             :                                                     conn,
    1567             :                                                     req,
    1568             :                                                     false,
    1569             :                                                     src_dirfsp,
    1570             :                                                     smb_fname_old,
    1571             :                                                     dst_dirfsp,
    1572             :                                                     smb_fname_new);
    1573           0 :                         break;
    1574           0 :                 case RENAME_FLAG_COPY:
    1575           0 :                         status = copy_internals(ctx,
    1576             :                                                 conn,
    1577             :                                                 req,
    1578             :                                                 src_dirfsp,
    1579             :                                                 smb_fname_old,
    1580             :                                                 dst_dirfsp,
    1581             :                                                 smb_fname_new,
    1582             :                                                 attrs);
    1583           0 :                         break;
    1584           0 :                 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
    1585           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    1586           0 :                         break;
    1587           0 :                 default:
    1588           0 :                         status = NT_STATUS_ACCESS_DENIED; /* Default error. */
    1589           0 :                         break;
    1590             :         }
    1591             : 
    1592           0 :         if (!NT_STATUS_IS_OK(status)) {
    1593           0 :                 if (open_was_deferred(req->xconn, req->mid)) {
    1594             :                         /* We have re-scheduled this call. */
    1595           0 :                         goto out;
    1596             :                 }
    1597           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
    1598           0 :                         bool ok = defer_smb1_sharing_violation(req);
    1599           0 :                         if (ok) {
    1600           0 :                                 goto out;
    1601             :                         }
    1602             :                 }
    1603             : 
    1604           0 :                 reply_nterror(req, status);
    1605           0 :                 goto out;
    1606             :         }
    1607             : 
    1608           0 :         reply_smb1_outbuf(req, 0, 0);
    1609           0 :  out:
    1610           0 :         END_PROFILE(SMBntrename);
    1611           0 :         return;
    1612             : }
    1613             : 
    1614             : /****************************************************************************
    1615             :  Reply to a notify change - queue the request and
    1616             :  don't allow a directory to be opened.
    1617             : ****************************************************************************/
    1618             : 
    1619           0 : static void smbd_smb1_notify_reply(struct smb_request *req,
    1620             :                                    NTSTATUS error_code,
    1621             :                                    uint8_t *buf, size_t len)
    1622             : {
    1623           0 :         send_nt_replies(req->conn, req, error_code, (char *)buf, len, NULL, 0);
    1624           0 : }
    1625             : 
    1626           0 : static void call_nt_transact_notify_change(connection_struct *conn,
    1627             :                                            struct smb_request *req,
    1628             :                                            uint16_t **ppsetup,
    1629             :                                            uint32_t setup_count,
    1630             :                                            char **ppparams,
    1631             :                                            uint32_t parameter_count,
    1632             :                                            char **ppdata, uint32_t data_count,
    1633             :                                            uint32_t max_data_count,
    1634             :                                            uint32_t max_param_count)
    1635             : {
    1636           0 :         uint16_t *setup = *ppsetup;
    1637             :         files_struct *fsp;
    1638             :         uint32_t filter;
    1639             :         NTSTATUS status;
    1640             :         bool recursive;
    1641             : 
    1642           0 :         if(setup_count < 6) {
    1643           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1644           0 :                 return;
    1645             :         }
    1646             : 
    1647           0 :         fsp = file_fsp(req, SVAL(setup,4));
    1648           0 :         filter = IVAL(setup, 0);
    1649           0 :         recursive = (SVAL(setup, 6) != 0) ? True : False;
    1650             : 
    1651           0 :         DEBUG(3,("call_nt_transact_notify_change\n"));
    1652             : 
    1653           0 :         if(!fsp) {
    1654           0 :                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    1655           0 :                 return;
    1656             :         }
    1657             : 
    1658             :         {
    1659             :                 char *filter_string;
    1660             : 
    1661           0 :                 if (!(filter_string = notify_filter_string(NULL, filter))) {
    1662           0 :                         reply_nterror(req,NT_STATUS_NO_MEMORY);
    1663           0 :                         return;
    1664             :                 }
    1665             : 
    1666           0 :                 DEBUG(3,("call_nt_transact_notify_change: notify change "
    1667             :                          "called on %s, filter = %s, recursive = %d\n",
    1668             :                          fsp_str_dbg(fsp), filter_string, recursive));
    1669             : 
    1670           0 :                 TALLOC_FREE(filter_string);
    1671             :         }
    1672             : 
    1673           0 :         if((!fsp->fsp_flags.is_directory) || (conn != fsp->conn)) {
    1674           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1675           0 :                 return;
    1676             :         }
    1677             : 
    1678           0 :         if (fsp->notify == NULL) {
    1679             : 
    1680           0 :                 status = change_notify_create(fsp,
    1681             :                                               max_param_count,
    1682             :                                               filter,
    1683             :                                               recursive);
    1684           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1685           0 :                         DEBUG(10, ("change_notify_create returned %s\n",
    1686             :                                    nt_errstr(status)));
    1687           0 :                         reply_nterror(req, status);
    1688           0 :                         return;
    1689             :                 }
    1690             :         }
    1691             : 
    1692           0 :         if (change_notify_fsp_has_changes(fsp)) {
    1693             : 
    1694             :                 /*
    1695             :                  * We've got changes pending, respond immediately
    1696             :                  */
    1697             : 
    1698             :                 /*
    1699             :                  * TODO: write a torture test to check the filtering behaviour
    1700             :                  * here.
    1701             :                  */
    1702             : 
    1703           0 :                 change_notify_reply(req,
    1704           0 :                                     NT_STATUS_OK,
    1705             :                                     max_param_count,
    1706             :                                     fsp->notify,
    1707             :                                     smbd_smb1_notify_reply);
    1708             : 
    1709             :                 /*
    1710             :                  * change_notify_reply() above has independently sent its
    1711             :                  * results
    1712             :                  */
    1713           0 :                 return;
    1714             :         }
    1715             : 
    1716             :         /*
    1717             :          * No changes pending, queue the request
    1718             :          */
    1719             : 
    1720           0 :         status = change_notify_add_request(req,
    1721             :                         max_param_count,
    1722             :                         filter,
    1723             :                         recursive, fsp,
    1724             :                         smbd_smb1_notify_reply);
    1725           0 :         if (!NT_STATUS_IS_OK(status)) {
    1726           0 :                 reply_nterror(req, status);
    1727             :         }
    1728           0 :         return;
    1729             : }
    1730             : 
    1731             : /****************************************************************************
    1732             :  Reply to an NT transact rename command.
    1733             : ****************************************************************************/
    1734             : 
    1735           0 : static void call_nt_transact_rename(connection_struct *conn,
    1736             :                                     struct smb_request *req,
    1737             :                                     uint16_t **ppsetup, uint32_t setup_count,
    1738             :                                     char **ppparams, uint32_t parameter_count,
    1739             :                                     char **ppdata, uint32_t data_count,
    1740             :                                     uint32_t max_data_count)
    1741             : {
    1742           0 :         char *params = *ppparams;
    1743           0 :         char *new_name = NULL;
    1744           0 :         files_struct *fsp = NULL;
    1745             :         NTSTATUS status;
    1746           0 :         TALLOC_CTX *ctx = talloc_tos();
    1747             : 
    1748           0 :         if(parameter_count < 5) {
    1749           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1750           0 :                 return;
    1751             :         }
    1752             : 
    1753           0 :         fsp = file_fsp(req, SVAL(params, 0));
    1754           0 :         if (!check_fsp(conn, req, fsp)) {
    1755           0 :                 return;
    1756             :         }
    1757           0 :         if (req->posix_pathnames) {
    1758           0 :                 srvstr_get_path_posix(ctx,
    1759             :                                 params,
    1760           0 :                                 req->flags2,
    1761             :                                 &new_name,
    1762           0 :                                 params+4,
    1763           0 :                                 parameter_count - 4,
    1764             :                                 STR_TERMINATE,
    1765             :                                 &status);
    1766             :         } else {
    1767           0 :                 srvstr_get_path(ctx,
    1768             :                                 params,
    1769           0 :                                 req->flags2,
    1770             :                                 &new_name,
    1771           0 :                                 params+4,
    1772           0 :                                 parameter_count - 4,
    1773             :                                 STR_TERMINATE,
    1774             :                                 &status);
    1775             :         }
    1776             : 
    1777           0 :         if (!NT_STATUS_IS_OK(status)) {
    1778           0 :                 reply_nterror(req, status);
    1779           0 :                 return;
    1780             :         }
    1781             : 
    1782             :         /*
    1783             :          * W2K3 ignores this request as the RAW-RENAME test
    1784             :          * demonstrates, so we do.
    1785             :          */
    1786           0 :         send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
    1787             : 
    1788           0 :         DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
    1789             :                  fsp_str_dbg(fsp), new_name));
    1790             : 
    1791           0 :         return;
    1792             : }
    1793             : 
    1794             : /****************************************************************************
    1795             :  SMB1 reply to query a security descriptor.
    1796             : ****************************************************************************/
    1797             : 
    1798           0 : static void call_nt_transact_query_security_desc(connection_struct *conn,
    1799             :                                                  struct smb_request *req,
    1800             :                                                  uint16_t **ppsetup,
    1801             :                                                  uint32_t setup_count,
    1802             :                                                  char **ppparams,
    1803             :                                                  uint32_t parameter_count,
    1804             :                                                  char **ppdata,
    1805             :                                                  uint32_t data_count,
    1806             :                                                  uint32_t max_data_count)
    1807             : {
    1808           0 :         char *params = *ppparams;
    1809           0 :         char *data = *ppdata;
    1810           0 :         size_t sd_size = 0;
    1811             :         uint32_t security_info_wanted;
    1812           0 :         files_struct *fsp = NULL;
    1813             :         NTSTATUS status;
    1814           0 :         uint8_t *marshalled_sd = NULL;
    1815             : 
    1816           0 :         if(parameter_count < 8) {
    1817           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1818           0 :                 return;
    1819             :         }
    1820             : 
    1821           0 :         fsp = file_fsp(req, SVAL(params,0));
    1822           0 :         if(!fsp) {
    1823           0 :                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    1824           0 :                 return;
    1825             :         }
    1826             : 
    1827           0 :         security_info_wanted = IVAL(params,4);
    1828             : 
    1829           0 :         DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
    1830             :                  "info_wanted = 0x%x\n", fsp_str_dbg(fsp),
    1831             :                  (unsigned int)security_info_wanted));
    1832             : 
    1833           0 :         params = nttrans_realloc(ppparams, 4);
    1834           0 :         if(params == NULL) {
    1835           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1836           0 :                 return;
    1837             :         }
    1838             : 
    1839             :         /*
    1840             :          * Get the permissions to return.
    1841             :          */
    1842             : 
    1843           0 :         status = smbd_do_query_security_desc(conn,
    1844             :                                         talloc_tos(),
    1845             :                                         fsp,
    1846             :                                         security_info_wanted &
    1847             :                                         SMB_SUPPORTED_SECINFO_FLAGS,
    1848             :                                         max_data_count,
    1849             :                                         &marshalled_sd,
    1850             :                                         &sd_size);
    1851             : 
    1852           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
    1853           0 :                 SIVAL(params,0,(uint32_t)sd_size);
    1854           0 :                 send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
    1855             :                         params, 4, NULL, 0);
    1856           0 :                 return;
    1857             :         }
    1858             : 
    1859           0 :         if (!NT_STATUS_IS_OK(status)) {
    1860           0 :                 reply_nterror(req, status);
    1861           0 :                 return;
    1862             :         }
    1863             : 
    1864           0 :         SMB_ASSERT(sd_size > 0);
    1865             : 
    1866           0 :         SIVAL(params,0,(uint32_t)sd_size);
    1867             : 
    1868           0 :         if (max_data_count < sd_size) {
    1869           0 :                 send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
    1870             :                                 params, 4, NULL, 0);
    1871           0 :                 return;
    1872             :         }
    1873             : 
    1874             :         /*
    1875             :          * Allocate the data we will return.
    1876             :          */
    1877             : 
    1878           0 :         data = nttrans_realloc(ppdata, sd_size);
    1879           0 :         if(data == NULL) {
    1880           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    1881           0 :                 return;
    1882             :         }
    1883             : 
    1884           0 :         memcpy(data, marshalled_sd, sd_size);
    1885             : 
    1886           0 :         send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
    1887             : 
    1888           0 :         return;
    1889             : }
    1890             : 
    1891             : /****************************************************************************
    1892             :  Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
    1893             : ****************************************************************************/
    1894             : 
    1895           0 : static void call_nt_transact_set_security_desc(connection_struct *conn,
    1896             :                                                struct smb_request *req,
    1897             :                                                uint16_t **ppsetup,
    1898             :                                                uint32_t setup_count,
    1899             :                                                char **ppparams,
    1900             :                                                uint32_t parameter_count,
    1901             :                                                char **ppdata,
    1902             :                                                uint32_t data_count,
    1903             :                                                uint32_t max_data_count)
    1904             : {
    1905           0 :         char *params= *ppparams;
    1906           0 :         char *data = *ppdata;
    1907           0 :         files_struct *fsp = NULL;
    1908           0 :         uint32_t security_info_sent = 0;
    1909             :         NTSTATUS status;
    1910             : 
    1911           0 :         if(parameter_count < 8) {
    1912           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1913           0 :                 return;
    1914             :         }
    1915             : 
    1916           0 :         if((fsp = file_fsp(req, SVAL(params,0))) == NULL) {
    1917           0 :                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    1918           0 :                 return;
    1919             :         }
    1920             : 
    1921           0 :         if (!CAN_WRITE(fsp->conn)) {
    1922           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    1923           0 :                 return;
    1924             :         }
    1925             : 
    1926           0 :         if(!lp_nt_acl_support(SNUM(conn))) {
    1927           0 :                 goto done;
    1928             :         }
    1929             : 
    1930           0 :         security_info_sent = IVAL(params,4);
    1931             : 
    1932           0 :         DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
    1933             :                  fsp_str_dbg(fsp), (unsigned int)security_info_sent));
    1934             : 
    1935           0 :         if (data_count == 0) {
    1936           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1937           0 :                 return;
    1938             :         }
    1939             : 
    1940           0 :         status = set_sd_blob(fsp, (uint8_t *)data, data_count,
    1941             :                              security_info_sent & SMB_SUPPORTED_SECINFO_FLAGS);
    1942           0 :         if (!NT_STATUS_IS_OK(status)) {
    1943           0 :                 reply_nterror(req, status);
    1944           0 :                 return;
    1945             :         }
    1946             : 
    1947           0 :   done:
    1948           0 :         send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
    1949           0 :         return;
    1950             : }
    1951             : 
    1952             : /****************************************************************************
    1953             :  Reply to NT IOCTL
    1954             : ****************************************************************************/
    1955             : 
    1956           0 : static void call_nt_transact_ioctl(connection_struct *conn,
    1957             :                                    struct smb_request *req,
    1958             :                                    uint16_t **ppsetup, uint32_t setup_count,
    1959             :                                    char **ppparams, uint32_t parameter_count,
    1960             :                                    char **ppdata, uint32_t data_count,
    1961             :                                    uint32_t max_data_count)
    1962             : {
    1963             :         NTSTATUS status;
    1964             :         uint32_t function;
    1965             :         uint16_t fidnum;
    1966             :         files_struct *fsp;
    1967             :         uint8_t isFSctl;
    1968             :         uint8_t compfilter;
    1969           0 :         char *out_data = NULL;
    1970           0 :         uint32_t out_data_len = 0;
    1971           0 :         char *pdata = *ppdata;
    1972           0 :         TALLOC_CTX *ctx = talloc_tos();
    1973             : 
    1974           0 :         if (setup_count != 8) {
    1975           0 :                 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
    1976           0 :                 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
    1977           0 :                 return;
    1978             :         }
    1979             : 
    1980           0 :         function = IVAL(*ppsetup, 0);
    1981           0 :         fidnum = SVAL(*ppsetup, 4);
    1982           0 :         isFSctl = CVAL(*ppsetup, 6);
    1983           0 :         compfilter = CVAL(*ppsetup, 7);
    1984             : 
    1985           0 :         DEBUG(10, ("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n", 
    1986             :                  function, fidnum, isFSctl, compfilter));
    1987             : 
    1988           0 :         fsp=file_fsp(req, fidnum);
    1989             : 
    1990             :         /*
    1991             :          * We don't really implement IOCTLs, especially on files.
    1992             :          */
    1993           0 :         if (!isFSctl) {
    1994           0 :                 DEBUG(10, ("isFSctl: 0x%02X indicates IOCTL, not FSCTL!\n",
    1995             :                         isFSctl));
    1996           0 :                 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
    1997           0 :                 return;
    1998             :         }
    1999             : 
    2000             :         /* Has to be for an open file! */
    2001           0 :         if (!check_fsp_open(conn, req, fsp)) {
    2002           0 :                 return;
    2003             :         }
    2004             : 
    2005           0 :         SMB_PERFCOUNT_SET_IOCTL(&req->pcd, function);
    2006             : 
    2007             :         /*
    2008             :          * out_data might be allocated by the VFS module, but talloc should be
    2009             :          * used, and should be cleaned up when the request ends.
    2010             :          */
    2011           0 :         status = SMB_VFS_FSCTL(fsp, 
    2012             :                                ctx,
    2013             :                                function, 
    2014             :                                req->flags2,
    2015             :                                (uint8_t *)pdata, 
    2016             :                                data_count, 
    2017             :                                (uint8_t **)&out_data,
    2018             :                                max_data_count,
    2019             :                                &out_data_len);
    2020           0 :         if (!NT_STATUS_IS_OK(status)) {
    2021           0 :                 reply_nterror(req, status);
    2022             :         } else {
    2023           0 :                 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, out_data, out_data_len);
    2024             :         }
    2025             : }
    2026             : 
    2027             : 
    2028             : #ifdef HAVE_SYS_QUOTAS
    2029             : /****************************************************************************
    2030             :  Reply to get user quota
    2031             : ****************************************************************************/
    2032             : 
    2033           0 : static void call_nt_transact_get_user_quota(connection_struct *conn,
    2034             :                                             struct smb_request *req,
    2035             :                                             uint16_t **ppsetup,
    2036             :                                             uint32_t setup_count,
    2037             :                                             char **ppparams,
    2038             :                                             uint32_t parameter_count,
    2039             :                                             char **ppdata,
    2040             :                                             uint32_t data_count,
    2041             :                                             uint32_t max_data_count)
    2042             : {
    2043           0 :         const struct loadparm_substitution *lp_sub =
    2044           0 :                 loadparm_s3_global_substitution();
    2045           0 :         NTSTATUS nt_status = NT_STATUS_OK;
    2046           0 :         char *params = *ppparams;
    2047           0 :         char *pdata = *ppdata;
    2048           0 :         int data_len = 0;
    2049           0 :         int param_len = 0;
    2050           0 :         files_struct *fsp = NULL;
    2051           0 :         DATA_BLOB blob = data_blob_null;
    2052           0 :         struct nttrans_query_quota_params info = {0};
    2053             :         enum ndr_err_code err;
    2054           0 :         TALLOC_CTX *tmp_ctx = NULL;
    2055           0 :         uint32_t resp_len = 0;
    2056           0 :         uint8_t *resp_data = 0;
    2057             : 
    2058           0 :         tmp_ctx = talloc_init("ntquota_list");
    2059           0 :         if (!tmp_ctx) {
    2060           0 :                 nt_status = NT_STATUS_NO_MEMORY;
    2061           0 :                 goto error;
    2062             :         }
    2063             : 
    2064             :         /* access check */
    2065           0 :         if (get_current_uid(conn) != sec_initial_uid()) {
    2066           0 :                 DEBUG(1,("get_user_quota: access_denied service [%s] user "
    2067             :                          "[%s]\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
    2068             :                          conn->session_info->unix_info->unix_name));
    2069           0 :                 nt_status = NT_STATUS_ACCESS_DENIED;
    2070           0 :                 goto error;
    2071             :         }
    2072             : 
    2073           0 :         blob.data = (uint8_t*)params;
    2074           0 :         blob.length = parameter_count;
    2075             : 
    2076           0 :         err = ndr_pull_struct_blob(&blob, tmp_ctx, &info,
    2077             :                 (ndr_pull_flags_fn_t)ndr_pull_nttrans_query_quota_params);
    2078             : 
    2079           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
    2080           0 :                 DEBUG(0,("TRANSACT_GET_USER_QUOTA: failed to pull "
    2081             :                          "query_quota_params."));
    2082           0 :                 nt_status = NT_STATUS_INVALID_PARAMETER;
    2083           0 :                 goto error;
    2084             :         }
    2085           0 :         DBG_DEBUG("info.return_single_entry = %u, info.restart_scan = %u, "
    2086             :                   "info.sid_list_length = %u, info.start_sid_length = %u, "
    2087             :                   "info.start_sid_offset = %u\n",
    2088             :                   (unsigned int)info.return_single_entry,
    2089             :                   (unsigned int)info.restart_scan,
    2090             :                   (unsigned int)info.sid_list_length,
    2091             :                   (unsigned int)info.start_sid_length,
    2092             :                   (unsigned int)info.start_sid_offset);
    2093             : 
    2094             :         /* set blob to point at data for further parsing */
    2095           0 :         blob.data = (uint8_t*)pdata;
    2096           0 :         blob.length = data_count;
    2097             :         /*
    2098             :          * Although MS-SMB ref is ambiguous here, a microsoft client will
    2099             :          * only ever send a start sid (as part of a list) with
    2100             :          * sid_list_length & start_sid_offset both set to the actual list
    2101             :          * length. Note: Only a single result is returned in this case
    2102             :          * In the case where either start_sid_offset or start_sid_length
    2103             :          * are set alone or if both set (but have different values) then
    2104             :          * it seems windows will return a number of entries from the start
    2105             :          * of the list of users with quotas set. This behaviour is undocumented
    2106             :          * and windows clients do not send messages of that type. As such we
    2107             :          * currently will reject these requests.
    2108             :          */
    2109           0 :         if (info.start_sid_length
    2110           0 :         || (info.sid_list_length != info.start_sid_offset)) {
    2111           0 :                 DBG_ERR("TRANSACT_GET_USER_QUOTA: unsupported single or "
    2112             :                         "compound sid format\n");
    2113           0 :                 nt_status = NT_STATUS_INVALID_PARAMETER;
    2114           0 :                 goto error;
    2115             :         }
    2116             : 
    2117             :         /* maybe we can check the quota_fnum */
    2118           0 :         fsp = file_fsp(req, info.fid);
    2119           0 :         if (!check_fsp_ntquota_handle(conn, req, fsp)) {
    2120           0 :                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
    2121           0 :                 nt_status = NT_STATUS_INVALID_HANDLE;
    2122           0 :                 goto error;
    2123             :         }
    2124           0 :         nt_status = smbd_do_query_getinfo_quota(tmp_ctx,
    2125             :                                   fsp,
    2126           0 :                                   info.restart_scan,
    2127           0 :                                   info.return_single_entry,
    2128             :                                   info.sid_list_length,
    2129             :                                   &blob,
    2130             :                                   max_data_count,
    2131             :                                   &resp_data,
    2132             :                                   &resp_len);
    2133           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2134           0 :                 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
    2135           0 :                         goto error;
    2136             :                 }
    2137           0 :                 nt_status = NT_STATUS_OK;
    2138             :         }
    2139             : 
    2140           0 :         param_len = 4;
    2141           0 :         params = nttrans_realloc(ppparams, param_len);
    2142           0 :         if(params == NULL) {
    2143           0 :                 nt_status = NT_STATUS_NO_MEMORY;
    2144           0 :                 goto error;
    2145             :         }
    2146             : 
    2147           0 :         data_len = resp_len;
    2148           0 :         SIVAL(params, 0, data_len);
    2149           0 :         pdata = nttrans_realloc(ppdata, data_len);
    2150           0 :         memcpy(pdata, resp_data, data_len);
    2151             : 
    2152           0 :         TALLOC_FREE(tmp_ctx);
    2153           0 :         send_nt_replies(conn, req, nt_status, params, param_len,
    2154             :                         pdata, data_len);
    2155           0 :         return;
    2156           0 : error:
    2157           0 :         TALLOC_FREE(tmp_ctx);
    2158           0 :         reply_nterror(req, nt_status);
    2159             : }
    2160             : 
    2161             : /****************************************************************************
    2162             :  Reply to set user quota
    2163             : ****************************************************************************/
    2164             : 
    2165           0 : static void call_nt_transact_set_user_quota(connection_struct *conn,
    2166             :                                             struct smb_request *req,
    2167             :                                             uint16_t **ppsetup,
    2168             :                                             uint32_t setup_count,
    2169             :                                             char **ppparams,
    2170             :                                             uint32_t parameter_count,
    2171             :                                             char **ppdata,
    2172             :                                             uint32_t data_count,
    2173             :                                             uint32_t max_data_count)
    2174             : {
    2175           0 :         const struct loadparm_substitution *lp_sub =
    2176           0 :                 loadparm_s3_global_substitution();
    2177           0 :         char *params = *ppparams;
    2178           0 :         char *pdata = *ppdata;
    2179           0 :         int data_len=0,param_len=0;
    2180             :         SMB_NTQUOTA_STRUCT qt;
    2181           0 :         struct file_quota_information info = {0};
    2182             :         enum ndr_err_code err;
    2183             :         struct dom_sid sid;
    2184             :         DATA_BLOB inblob;
    2185           0 :         files_struct *fsp = NULL;
    2186           0 :         TALLOC_CTX *ctx = NULL;
    2187           0 :         NTSTATUS status = NT_STATUS_OK;
    2188           0 :         ZERO_STRUCT(qt);
    2189             : 
    2190             :         /* access check */
    2191           0 :         if (get_current_uid(conn) != sec_initial_uid()) {
    2192           0 :                 DEBUG(1,("set_user_quota: access_denied service [%s] user "
    2193             :                          "[%s]\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
    2194             :                          conn->session_info->unix_info->unix_name));
    2195           0 :                 status = NT_STATUS_ACCESS_DENIED;
    2196           0 :                 goto error;
    2197             :         }
    2198             : 
    2199             :         /*
    2200             :          * Ensure minimum number of parameters sent.
    2201             :          */
    2202             : 
    2203           0 :         if (parameter_count < 2) {
    2204           0 :                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
    2205           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    2206           0 :                 goto error;
    2207             :         }
    2208             : 
    2209             :         /* maybe we can check the quota_fnum */
    2210           0 :         fsp = file_fsp(req, SVAL(params,0));
    2211           0 :         if (!check_fsp_ntquota_handle(conn, req, fsp)) {
    2212           0 :                 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
    2213           0 :                 status = NT_STATUS_INVALID_HANDLE;
    2214           0 :                 goto error;
    2215             :         }
    2216             : 
    2217           0 :         ctx = talloc_init("set_user_quota");
    2218           0 :         if (!ctx) {
    2219           0 :                 status = NT_STATUS_NO_MEMORY;
    2220           0 :                 goto error;
    2221             :         }
    2222           0 :         inblob.data = (uint8_t*)pdata;
    2223           0 :         inblob.length = data_count;
    2224             : 
    2225           0 :         err = ndr_pull_struct_blob(
    2226             :                         &inblob,
    2227             :                         ctx,
    2228             :                         &info,
    2229             :                         (ndr_pull_flags_fn_t)ndr_pull_file_quota_information);
    2230             : 
    2231           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
    2232           0 :                 DEBUG(0,("TRANSACT_SET_USER_QUOTA: failed to pull "
    2233             :                          "file_quota_information\n"));
    2234           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    2235           0 :                 goto error;
    2236             :         }
    2237           0 :         qt.usedspace = info.quota_used;
    2238             : 
    2239           0 :         qt.softlim = info.quota_threshold;
    2240             : 
    2241           0 :         qt.hardlim = info.quota_limit;
    2242             : 
    2243           0 :         sid = info.sid;
    2244             : 
    2245           0 :         if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
    2246           0 :                 status = NT_STATUS_INTERNAL_ERROR;
    2247           0 :                 goto error;
    2248             :         }
    2249             : 
    2250           0 :         send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
    2251             :                         pdata, data_len);
    2252           0 :         TALLOC_FREE(ctx);
    2253           0 :         return;
    2254           0 : error:
    2255           0 :         TALLOC_FREE(ctx);
    2256           0 :         reply_nterror(req, status);
    2257             : }
    2258             : #endif /* HAVE_SYS_QUOTAS */
    2259             : 
    2260           0 : static void handle_nttrans(connection_struct *conn,
    2261             :                            struct trans_state *state,
    2262             :                            struct smb_request *req)
    2263             : {
    2264           0 :         if (get_Protocol() >= PROTOCOL_NT1) {
    2265           0 :                 req->flags2 |= 0x40; /* IS_LONG_NAME */
    2266           0 :                 SSVAL(discard_const_p(uint8_t, req->inbuf),smb_flg2,req->flags2);
    2267             :         }
    2268             : 
    2269             : 
    2270           0 :         SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
    2271             : 
    2272             :         /* Now we must call the relevant NT_TRANS function */
    2273           0 :         switch(state->call) {
    2274           0 :                 case NT_TRANSACT_CREATE:
    2275             :                 {
    2276           0 :                         START_PROFILE(NT_transact_create);
    2277           0 :                         call_nt_transact_create(
    2278             :                                 conn, req,
    2279             :                                 &state->setup, state->setup_count,
    2280           0 :                                 &state->param, state->total_param,
    2281           0 :                                 &state->data, state->total_data,
    2282             :                                 state->max_data_return);
    2283           0 :                         END_PROFILE(NT_transact_create);
    2284           0 :                         break;
    2285             :                 }
    2286             : 
    2287           0 :                 case NT_TRANSACT_IOCTL:
    2288             :                 {
    2289           0 :                         START_PROFILE(NT_transact_ioctl);
    2290           0 :                         call_nt_transact_ioctl(
    2291             :                                 conn, req,
    2292             :                                 &state->setup, state->setup_count,
    2293           0 :                                 &state->param, state->total_param,
    2294           0 :                                 &state->data, state->total_data,
    2295             :                                 state->max_data_return);
    2296           0 :                         END_PROFILE(NT_transact_ioctl);
    2297           0 :                         break;
    2298             :                 }
    2299             : 
    2300           0 :                 case NT_TRANSACT_SET_SECURITY_DESC:
    2301             :                 {
    2302           0 :                         START_PROFILE(NT_transact_set_security_desc);
    2303           0 :                         call_nt_transact_set_security_desc(
    2304             :                                 conn, req,
    2305             :                                 &state->setup, state->setup_count,
    2306           0 :                                 &state->param, state->total_param,
    2307           0 :                                 &state->data, state->total_data,
    2308             :                                 state->max_data_return);
    2309           0 :                         END_PROFILE(NT_transact_set_security_desc);
    2310           0 :                         break;
    2311             :                 }
    2312             : 
    2313           0 :                 case NT_TRANSACT_NOTIFY_CHANGE:
    2314             :                 {
    2315           0 :                         START_PROFILE(NT_transact_notify_change);
    2316           0 :                         call_nt_transact_notify_change(
    2317             :                                 conn, req,
    2318             :                                 &state->setup, state->setup_count,
    2319           0 :                                 &state->param, state->total_param,
    2320           0 :                                 &state->data, state->total_data,
    2321             :                                 state->max_data_return,
    2322             :                                 state->max_param_return);
    2323           0 :                         END_PROFILE(NT_transact_notify_change);
    2324           0 :                         break;
    2325             :                 }
    2326             : 
    2327           0 :                 case NT_TRANSACT_RENAME:
    2328             :                 {
    2329           0 :                         START_PROFILE(NT_transact_rename);
    2330           0 :                         call_nt_transact_rename(
    2331             :                                 conn, req,
    2332             :                                 &state->setup, state->setup_count,
    2333           0 :                                 &state->param, state->total_param,
    2334           0 :                                 &state->data, state->total_data,
    2335             :                                 state->max_data_return);
    2336           0 :                         END_PROFILE(NT_transact_rename);
    2337           0 :                         break;
    2338             :                 }
    2339             : 
    2340           0 :                 case NT_TRANSACT_QUERY_SECURITY_DESC:
    2341             :                 {
    2342           0 :                         START_PROFILE(NT_transact_query_security_desc);
    2343           0 :                         call_nt_transact_query_security_desc(
    2344             :                                 conn, req,
    2345             :                                 &state->setup, state->setup_count,
    2346           0 :                                 &state->param, state->total_param,
    2347           0 :                                 &state->data, state->total_data,
    2348             :                                 state->max_data_return);
    2349           0 :                         END_PROFILE(NT_transact_query_security_desc);
    2350           0 :                         break;
    2351             :                 }
    2352             : 
    2353             : #ifdef HAVE_SYS_QUOTAS
    2354           0 :                 case NT_TRANSACT_GET_USER_QUOTA:
    2355             :                 {
    2356           0 :                         START_PROFILE(NT_transact_get_user_quota);
    2357           0 :                         call_nt_transact_get_user_quota(
    2358             :                                 conn, req,
    2359             :                                 &state->setup, state->setup_count,
    2360           0 :                                 &state->param, state->total_param,
    2361           0 :                                 &state->data, state->total_data,
    2362             :                                 state->max_data_return);
    2363           0 :                         END_PROFILE(NT_transact_get_user_quota);
    2364           0 :                         break;
    2365             :                 }
    2366             : 
    2367           0 :                 case NT_TRANSACT_SET_USER_QUOTA:
    2368             :                 {
    2369           0 :                         START_PROFILE(NT_transact_set_user_quota);
    2370           0 :                         call_nt_transact_set_user_quota(
    2371             :                                 conn, req,
    2372             :                                 &state->setup, state->setup_count,
    2373           0 :                                 &state->param, state->total_param,
    2374           0 :                                 &state->data, state->total_data,
    2375             :                                 state->max_data_return);
    2376           0 :                         END_PROFILE(NT_transact_set_user_quota);
    2377           0 :                         break;
    2378             :                 }
    2379             : #endif /* HAVE_SYS_QUOTAS */
    2380             : 
    2381           0 :                 default:
    2382             :                         /* Error in request */
    2383           0 :                         DEBUG(0,("handle_nttrans: Unknown request %d in "
    2384             :                                  "nttrans call\n", state->call));
    2385           0 :                         reply_nterror(req, NT_STATUS_INVALID_LEVEL);
    2386           0 :                         return;
    2387             :         }
    2388           0 :         return;
    2389             : }
    2390             : 
    2391             : /****************************************************************************
    2392             :  Reply to a SMBNTtrans.
    2393             : ****************************************************************************/
    2394             : 
    2395           0 : void reply_nttrans(struct smb_request *req)
    2396             : {
    2397           0 :         connection_struct *conn = req->conn;
    2398             :         uint32_t pscnt;
    2399             :         uint32_t psoff;
    2400             :         uint32_t dscnt;
    2401             :         uint32_t dsoff;
    2402             :         uint16_t function_code;
    2403             :         NTSTATUS result;
    2404             :         struct trans_state *state;
    2405             : 
    2406           0 :         START_PROFILE(SMBnttrans);
    2407             : 
    2408           0 :         if (req->wct < 19) {
    2409           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2410           0 :                 END_PROFILE(SMBnttrans);
    2411           0 :                 return;
    2412             :         }
    2413             : 
    2414           0 :         pscnt = IVAL(req->vwv+9, 1);
    2415           0 :         psoff = IVAL(req->vwv+11, 1);
    2416           0 :         dscnt = IVAL(req->vwv+13, 1);
    2417           0 :         dsoff = IVAL(req->vwv+15, 1);
    2418           0 :         function_code = SVAL(req->vwv+18, 0);
    2419             : 
    2420           0 :         if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
    2421           0 :                 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    2422           0 :                 END_PROFILE(SMBnttrans);
    2423           0 :                 return;
    2424             :         }
    2425             : 
    2426           0 :         result = allow_new_trans(conn->pending_trans, req->mid);
    2427           0 :         if (!NT_STATUS_IS_OK(result)) {
    2428           0 :                 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
    2429           0 :                 reply_nterror(req, result);
    2430           0 :                 END_PROFILE(SMBnttrans);
    2431           0 :                 return;
    2432             :         }
    2433             : 
    2434           0 :         if ((state = talloc(conn, struct trans_state)) == NULL) {
    2435           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2436           0 :                 END_PROFILE(SMBnttrans);
    2437           0 :                 return;
    2438             :         }
    2439             : 
    2440           0 :         state->cmd = SMBnttrans;
    2441             : 
    2442           0 :         state->mid = req->mid;
    2443           0 :         state->vuid = req->vuid;
    2444           0 :         state->total_data = IVAL(req->vwv+3, 1);
    2445           0 :         state->data = NULL;
    2446           0 :         state->total_param = IVAL(req->vwv+1, 1);
    2447           0 :         state->param = NULL;
    2448           0 :         state->max_data_return = IVAL(req->vwv+7, 1);
    2449           0 :         state->max_param_return = IVAL(req->vwv+5, 1);
    2450             : 
    2451             :         /* setup count is in *words* */
    2452           0 :         state->setup_count = 2*CVAL(req->vwv+17, 1);
    2453           0 :         state->setup = NULL;
    2454           0 :         state->call = function_code;
    2455             : 
    2456           0 :         DEBUG(10, ("num_setup=%u, "
    2457             :                    "param_total=%u, this_param=%u, max_param=%u, "
    2458             :                    "data_total=%u, this_data=%u, max_data=%u, "
    2459             :                    "param_offset=%u, data_offset=%u\n",
    2460             :                    (unsigned)state->setup_count,
    2461             :                    (unsigned)state->total_param, (unsigned)pscnt,
    2462             :                    (unsigned)state->max_param_return,
    2463             :                    (unsigned)state->total_data, (unsigned)dscnt,
    2464             :                    (unsigned)state->max_data_return,
    2465             :                    (unsigned)psoff, (unsigned)dsoff));
    2466             : 
    2467             :         /*
    2468             :          * All nttrans messages we handle have smb_wct == 19 +
    2469             :          * state->setup_count.  Ensure this is so as a sanity check.
    2470             :          */
    2471             : 
    2472           0 :         if(req->wct != 19 + (state->setup_count/2)) {
    2473           0 :                 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
    2474             :                          req->wct, 19 + (state->setup_count/2)));
    2475           0 :                 goto bad_param;
    2476             :         }
    2477             : 
    2478             :         /* Don't allow more than 128mb for each value. */
    2479           0 :         if ((state->total_data > (1024*1024*128)) ||
    2480           0 :             (state->total_param > (1024*1024*128))) {
    2481           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
    2482           0 :                 END_PROFILE(SMBnttrans);
    2483           0 :                 return;
    2484             :         }
    2485             : 
    2486           0 :         if ((dscnt > state->total_data) || (pscnt > state->total_param))
    2487           0 :                 goto bad_param;
    2488             : 
    2489           0 :         if (state->total_data)  {
    2490             : 
    2491           0 :                 if (smb_buffer_oob(state->total_data, 0, dscnt)
    2492           0 :                     || smb_buffer_oob(smb_len(req->inbuf), dsoff, dscnt)) {
    2493           0 :                         goto bad_param;
    2494             :                 }
    2495             : 
    2496             :                 /* Can't use talloc here, the core routines do realloc on the
    2497             :                  * params and data. */
    2498           0 :                 if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
    2499           0 :                         DEBUG(0,("reply_nttrans: data malloc fail for %u "
    2500             :                                  "bytes !\n", (unsigned int)state->total_data));
    2501           0 :                         TALLOC_FREE(state);
    2502           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    2503           0 :                         END_PROFILE(SMBnttrans);
    2504           0 :                         return;
    2505             :                 }
    2506             : 
    2507           0 :                 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
    2508             :         }
    2509             : 
    2510           0 :         if (state->total_param) {
    2511             : 
    2512           0 :                 if (smb_buffer_oob(state->total_param, 0, pscnt)
    2513           0 :                     || smb_buffer_oob(smb_len(req->inbuf), psoff, pscnt)) {
    2514           0 :                         goto bad_param;
    2515             :                 }
    2516             : 
    2517             :                 /* Can't use talloc here, the core routines do realloc on the
    2518             :                  * params and data. */
    2519           0 :                 if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
    2520           0 :                         DEBUG(0,("reply_nttrans: param malloc fail for %u "
    2521             :                                  "bytes !\n", (unsigned int)state->total_param));
    2522           0 :                         SAFE_FREE(state->data);
    2523           0 :                         TALLOC_FREE(state);
    2524           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    2525           0 :                         END_PROFILE(SMBnttrans);
    2526           0 :                         return;
    2527             :                 }
    2528             : 
    2529           0 :                 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
    2530             :         }
    2531             : 
    2532           0 :         state->received_data  = dscnt;
    2533           0 :         state->received_param = pscnt;
    2534             : 
    2535           0 :         if(state->setup_count > 0) {
    2536           0 :                 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
    2537             :                           state->setup_count));
    2538             : 
    2539             :                 /*
    2540             :                  * No overflow possible here, state->setup_count is an
    2541             :                  * unsigned int, being filled by a single byte from
    2542             :                  * CVAL(req->vwv+13, 0) above. The cast in the comparison
    2543             :                  * below is not necessary, it's here to clarify things. The
    2544             :                  * validity of req->vwv and req->wct has been checked in
    2545             :                  * init_smb1_request already.
    2546             :                  */
    2547           0 :                 if ((state->setup_count/2) + 19 > (unsigned int)req->wct) {
    2548           0 :                         goto bad_param;
    2549             :                 }
    2550             : 
    2551           0 :                 state->setup = (uint16_t *)TALLOC(state, state->setup_count);
    2552           0 :                 if (state->setup == NULL) {
    2553           0 :                         DEBUG(0,("reply_nttrans : Out of memory\n"));
    2554           0 :                         SAFE_FREE(state->data);
    2555           0 :                         SAFE_FREE(state->param);
    2556           0 :                         TALLOC_FREE(state);
    2557           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    2558           0 :                         END_PROFILE(SMBnttrans);
    2559           0 :                         return;
    2560             :                 }
    2561             : 
    2562           0 :                 memcpy(state->setup, req->vwv+19, state->setup_count);
    2563           0 :                 dump_data(10, (uint8_t *)state->setup, state->setup_count);
    2564             :         }
    2565             : 
    2566           0 :         if ((state->received_data == state->total_data) &&
    2567           0 :             (state->received_param == state->total_param)) {
    2568           0 :                 handle_nttrans(conn, state, req);
    2569           0 :                 SAFE_FREE(state->param);
    2570           0 :                 SAFE_FREE(state->data);
    2571           0 :                 TALLOC_FREE(state);
    2572           0 :                 END_PROFILE(SMBnttrans);
    2573           0 :                 return;
    2574             :         }
    2575             : 
    2576           0 :         DLIST_ADD(conn->pending_trans, state);
    2577             : 
    2578             :         /* We need to send an interim response then receive the rest
    2579             :            of the parameter/data bytes */
    2580           0 :         reply_smb1_outbuf(req, 0, 0);
    2581           0 :         show_msg((char *)req->outbuf);
    2582           0 :         END_PROFILE(SMBnttrans);
    2583           0 :         return;
    2584             : 
    2585           0 :   bad_param:
    2586             : 
    2587           0 :         DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
    2588           0 :         SAFE_FREE(state->data);
    2589           0 :         SAFE_FREE(state->param);
    2590           0 :         TALLOC_FREE(state);
    2591           0 :         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2592           0 :         END_PROFILE(SMBnttrans);
    2593           0 :         return;
    2594             : }
    2595             : 
    2596             : /****************************************************************************
    2597             :  Reply to a SMBnttranss
    2598             :  ****************************************************************************/
    2599             : 
    2600           0 : void reply_nttranss(struct smb_request *req)
    2601             : {
    2602           0 :         connection_struct *conn = req->conn;
    2603             :         uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
    2604             :         struct trans_state *state;
    2605             : 
    2606           0 :         START_PROFILE(SMBnttranss);
    2607             : 
    2608           0 :         show_msg((const char *)req->inbuf);
    2609             : 
    2610             :         /* Windows clients expect all replies to
    2611             :            an NT transact secondary (SMBnttranss 0xA1)
    2612             :            to have a command code of NT transact
    2613             :            (SMBnttrans 0xA0). See bug #8989 for details. */
    2614           0 :         req->cmd = SMBnttrans;
    2615             : 
    2616           0 :         if (req->wct < 18) {
    2617           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2618           0 :                 END_PROFILE(SMBnttranss);
    2619           0 :                 return;
    2620             :         }
    2621             : 
    2622           0 :         for (state = conn->pending_trans; state != NULL;
    2623           0 :              state = state->next) {
    2624           0 :                 if (state->mid == req->mid) {
    2625           0 :                         break;
    2626             :                 }
    2627             :         }
    2628             : 
    2629           0 :         if ((state == NULL) || (state->cmd != SMBnttrans)) {
    2630           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2631           0 :                 END_PROFILE(SMBnttranss);
    2632           0 :                 return;
    2633             :         }
    2634             : 
    2635             :         /* Revise state->total_param and state->total_data in case they have
    2636             :            changed downwards */
    2637           0 :         if (IVAL(req->vwv+1, 1) < state->total_param) {
    2638           0 :                 state->total_param = IVAL(req->vwv+1, 1);
    2639             :         }
    2640           0 :         if (IVAL(req->vwv+3, 1) < state->total_data) {
    2641           0 :                 state->total_data = IVAL(req->vwv+3, 1);
    2642             :         }
    2643             : 
    2644           0 :         pcnt = IVAL(req->vwv+5, 1);
    2645           0 :         poff = IVAL(req->vwv+7, 1);
    2646           0 :         pdisp = IVAL(req->vwv+9, 1);
    2647             : 
    2648           0 :         dcnt = IVAL(req->vwv+11, 1);
    2649           0 :         doff = IVAL(req->vwv+13, 1);
    2650           0 :         ddisp = IVAL(req->vwv+15, 1);
    2651             : 
    2652           0 :         state->received_param += pcnt;
    2653           0 :         state->received_data += dcnt;
    2654             : 
    2655           0 :         if ((state->received_data > state->total_data) ||
    2656           0 :             (state->received_param > state->total_param))
    2657           0 :                 goto bad_param;
    2658             : 
    2659           0 :         if (pcnt) {
    2660           0 :                 if (smb_buffer_oob(state->total_param, pdisp, pcnt)
    2661           0 :                     || smb_buffer_oob(smb_len(req->inbuf), poff, pcnt)) {
    2662           0 :                         goto bad_param;
    2663             :                 }
    2664           0 :                 memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
    2665             :         }
    2666             : 
    2667           0 :         if (dcnt) {
    2668           0 :                 if (smb_buffer_oob(state->total_data, ddisp, dcnt)
    2669           0 :                     || smb_buffer_oob(smb_len(req->inbuf), doff, dcnt)) {
    2670           0 :                         goto bad_param;
    2671             :                 }
    2672           0 :                 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
    2673             :         }
    2674             : 
    2675           0 :         if ((state->received_param < state->total_param) ||
    2676           0 :             (state->received_data < state->total_data)) {
    2677           0 :                 END_PROFILE(SMBnttranss);
    2678           0 :                 return;
    2679             :         }
    2680             : 
    2681           0 :         handle_nttrans(conn, state, req);
    2682             : 
    2683           0 :         DLIST_REMOVE(conn->pending_trans, state);
    2684           0 :         SAFE_FREE(state->data);
    2685           0 :         SAFE_FREE(state->param);
    2686           0 :         TALLOC_FREE(state);
    2687           0 :         END_PROFILE(SMBnttranss);
    2688           0 :         return;
    2689             : 
    2690           0 :   bad_param:
    2691             : 
    2692           0 :         DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
    2693           0 :         DLIST_REMOVE(conn->pending_trans, state);
    2694           0 :         SAFE_FREE(state->data);
    2695           0 :         SAFE_FREE(state->param);
    2696           0 :         TALLOC_FREE(state);
    2697           0 :         reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    2698           0 :         END_PROFILE(SMBnttranss);
    2699           0 :         return;
    2700             : }

Generated by: LCOV version 1.13