LCOV - code coverage report
Current view: top level - source3/smbd - smb1_nttrans.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 885 1315 67.3 %
Date: 2023-11-21 12:31:41 Functions: 21 23 91.3 %

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

Generated by: LCOV version 1.14