r23792: convert Samba4 to GPLv3
[bbaumbach/samba-autobuild/.git] / source4 / libcli / raw / rawfile.c
index 6981a768002d3ce7b6d52abda0493a63ca92fac2..60a9bf26569e7d21eea2253c2d657e6193bffa95 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "smb.h"
 #include "libcli/raw/libcliraw.h"
+#include "librpc/gen_ndr/ndr_security.h"
 
 #define SETUP_REQUEST(cmd, wct, buflen) do { \
        req = smbcli_request_setup(tree, cmd, wct, buflen); \
@@ -77,14 +78,14 @@ NTSTATUS smb_raw_rename(struct smbcli_tree *tree,
  Delete a file - async interface
 ****************************************************************************/
 struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree,
-                                       struct smb_unlink *parms)
+                                          union smb_unlink *parms)
 {
        struct smbcli_request *req; 
 
        SETUP_REQUEST(SMBunlink, 1, 0);
 
-       SSVAL(req->out.vwv, VWV(0), parms->in.attrib);
-       smbcli_req_append_ascii4(req, parms->in.pattern, STR_TERMINATE);
+       SSVAL(req->out.vwv, VWV(0), parms->unlink.in.attrib);
+       smbcli_req_append_ascii4(req, parms->unlink.in.pattern, STR_TERMINATE);
 
        if (!smbcli_request_send(req)) {
                smbcli_request_destroy(req);
@@ -97,7 +98,7 @@ struct smbcli_request *smb_raw_unlink_send(struct smbcli_tree *tree,
   delete a file - sync interface
 */
 NTSTATUS smb_raw_unlink(struct smbcli_tree *tree,
-                       struct smb_unlink *parms)
+                       union smb_unlink *parms)
 {
        struct smbcli_request *req = smb_raw_unlink_send(tree, parms);
        return smbcli_request_simple_recv(req);
@@ -233,7 +234,7 @@ static NTSTATUS smb_raw_nttrans_create_recv(struct smbcli_request *req,
        params = nt.out.params.data;
 
        parms->ntcreatex.out.oplock_level =                 CVAL(params, 0);
-       parms->ntcreatex.out.fnum =                         SVAL(params, 2);
+       parms->ntcreatex.out.file.fnum =                    SVAL(params, 2);
        parms->ntcreatex.out.create_action =                IVAL(params, 4);
        parms->ntcreatex.out.create_time =   smbcli_pull_nttime(params, 12);
        parms->ntcreatex.out.access_time =   smbcli_pull_nttime(params, 20);
@@ -296,7 +297,7 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr
                                    parms->ntcreatex.in.ea_list->eas);
        }
 
-       nt.in.params = data_blob_talloc(mem_ctx, NULL, 54);
+       nt.in.params = data_blob_talloc(mem_ctx, NULL, 53);
        if (nt.in.params.data == NULL) {
                talloc_free(mem_ctx);
                return NULL;
@@ -317,8 +318,9 @@ static struct smbcli_request *smb_raw_nttrans_create_send(struct smbcli_tree *tr
        SIVAL(params, 40, ea_blob.length);
        SIVAL(params, 48, parms->ntcreatex.in.impersonation);
        SCVAL(params, 52, parms->ntcreatex.in.security_flags);
-       SCVAL(params, 53, 0);
-       
+
+       /* the empty string first forces the correct alignment */
+       smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,"", 0);
        fname_len = smbcli_blob_append_string(tree->session, mem_ctx, &nt.in.params,
                                              parms->ntcreatex.in.fname, STR_TERMINATE);
 
@@ -393,7 +395,7 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree,
 ****************************************************************************/
 static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, union smb_open *parms)
 {
-       struct smbcli_transport *transport = req?req->transport:NULL;
+       struct smbcli_transport *transport = req->transport;
        struct smb_trans2 t2;
        NTSTATUS status;
 
@@ -404,7 +406,7 @@ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_
                return NT_STATUS_INFO_LENGTH_MISMATCH;
        }
 
-       parms->t2open.out.fnum =        SVAL(t2.out.params.data, VWV(0));
+       parms->t2open.out.file.fnum =   SVAL(t2.out.params.data, VWV(0));
        parms->t2open.out.attrib =      SVAL(t2.out.params.data, VWV(1));
        parms->t2open.out.write_time =  raw_pull_dos_date3(transport, t2.out.params.data + VWV(2));
        parms->t2open.out.size =        IVAL(t2.out.params.data, VWV(4));
@@ -542,6 +544,8 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope
                        SIVAL(req->out.vwv, VWV(10),parms->openxreadx.in.offset>>32);
                }
                break;
+       case RAW_OPEN_SMB2:
+               return NULL;
        }
 
        if (!smbcli_request_send(req)) {
@@ -570,7 +574,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
 
        case RAW_OPEN_OPEN:
                SMBCLI_CHECK_WCT(req, 7);
-               parms->openold.out.fnum = SVAL(req->in.vwv, VWV(0));
+               parms->openold.out.file.fnum = SVAL(req->in.vwv, VWV(0));
                parms->openold.out.attrib = SVAL(req->in.vwv, VWV(1));
                parms->openold.out.write_time = raw_pull_dos_date3(req->transport,
                                                                req->in.vwv + VWV(2));
@@ -580,7 +584,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
 
        case RAW_OPEN_OPENX:
                SMBCLI_CHECK_MIN_WCT(req, 15);
-               parms->openx.out.fnum = SVAL(req->in.vwv, VWV(2));
+               parms->openx.out.file.fnum = SVAL(req->in.vwv, VWV(2));
                parms->openx.out.attrib = SVAL(req->in.vwv, VWV(3));
                parms->openx.out.write_time = raw_pull_dos_date3(req->transport,
                                                                 req->in.vwv + VWV(4));
@@ -601,29 +605,29 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
 
        case RAW_OPEN_MKNEW:
                SMBCLI_CHECK_WCT(req, 1);
-               parms->mknew.out.fnum = SVAL(req->in.vwv, VWV(0));
+               parms->mknew.out.file.fnum = SVAL(req->in.vwv, VWV(0));
                break;
 
        case RAW_OPEN_CREATE:
                SMBCLI_CHECK_WCT(req, 1);
-               parms->create.out.fnum = SVAL(req->in.vwv, VWV(0));
+               parms->create.out.file.fnum = SVAL(req->in.vwv, VWV(0));
                break;
 
        case RAW_OPEN_CTEMP:
                SMBCLI_CHECK_WCT(req, 1);
-               parms->ctemp.out.fnum = SVAL(req->in.vwv, VWV(0));
+               parms->ctemp.out.file.fnum = SVAL(req->in.vwv, VWV(0));
                smbcli_req_pull_string(req, mem_ctx, &parms->ctemp.out.name, req->in.data, -1, STR_TERMINATE | STR_ASCII);
                break;
 
        case RAW_OPEN_SPLOPEN:
                SMBCLI_CHECK_WCT(req, 1);
-               parms->splopen.out.fnum = SVAL(req->in.vwv, VWV(0));
+               parms->splopen.out.file.fnum = SVAL(req->in.vwv, VWV(0));
                break;
 
        case RAW_OPEN_NTCREATEX:
                SMBCLI_CHECK_MIN_WCT(req, 34);
                parms->ntcreatex.out.oplock_level =              CVAL(req->in.vwv, 4);
-               parms->ntcreatex.out.fnum =                      SVAL(req->in.vwv, 5);
+               parms->ntcreatex.out.file.fnum =                 SVAL(req->in.vwv, 5);
                parms->ntcreatex.out.create_action =             IVAL(req->in.vwv, 7);
                parms->ntcreatex.out.create_time =   smbcli_pull_nttime(req->in.vwv, 11);
                parms->ntcreatex.out.access_time =   smbcli_pull_nttime(req->in.vwv, 19);
@@ -642,7 +646,7 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
 
        case RAW_OPEN_OPENX_READX:
                SMBCLI_CHECK_MIN_WCT(req, 15);
-               parms->openxreadx.out.fnum = SVAL(req->in.vwv, VWV(2));
+               parms->openxreadx.out.file.fnum = SVAL(req->in.vwv, VWV(2));
                parms->openxreadx.out.attrib = SVAL(req->in.vwv, VWV(3));
                parms->openxreadx.out.write_time = raw_pull_dos_date3(req->transport,
                                                                 req->in.vwv + VWV(4));
@@ -677,6 +681,9 @@ NTSTATUS smb_raw_open_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, unio
                        req->status = NT_STATUS_BUFFER_TOO_SMALL;
                }
                break;
+       case RAW_OPEN_SMB2:
+               req->status = NT_STATUS_INTERNAL_ERROR;
+               break;
        }
 
 failed:
@@ -704,16 +711,19 @@ struct smbcli_request *smb_raw_close_send(struct smbcli_tree *tree, union smb_cl
        switch (parms->generic.level) {
        case RAW_CLOSE_CLOSE:
                SETUP_REQUEST(SMBclose, 3, 0);
-               SSVAL(req->out.vwv, VWV(0), parms->close.in.fnum);
+               SSVAL(req->out.vwv, VWV(0), parms->close.in.file.fnum);
                raw_push_dos_date3(tree->session->transport, 
                                  req->out.vwv, VWV(1), parms->close.in.write_time);
                break;
 
        case RAW_CLOSE_SPLCLOSE:
                SETUP_REQUEST(SMBsplclose, 3, 0);
-               SSVAL(req->out.vwv, VWV(0), parms->splclose.in.fnum);
+               SSVAL(req->out.vwv, VWV(0), parms->splclose.in.file.fnum);
                SIVAL(req->out.vwv, VWV(1), 0); /* reserved */
                break;
+
+       case RAW_CLOSE_SMB2:
+               return NULL;
        }
 
        if (!req) return NULL;
@@ -747,14 +757,14 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc
        switch (parms->generic.level) {
        case RAW_LOCK_LOCK:
                SETUP_REQUEST(SMBlock, 5, 0);
-               SSVAL(req->out.vwv, VWV(0), parms->lock.in.fnum);
+               SSVAL(req->out.vwv, VWV(0), parms->lock.in.file.fnum);
                SIVAL(req->out.vwv, VWV(1), parms->lock.in.count);
                SIVAL(req->out.vwv, VWV(3), parms->lock.in.offset);
                break;
                
        case RAW_LOCK_UNLOCK:
                SETUP_REQUEST(SMBunlock, 5, 0);
-               SSVAL(req->out.vwv, VWV(0), parms->unlock.in.fnum);
+               SSVAL(req->out.vwv, VWV(0), parms->unlock.in.file.fnum);
                SIVAL(req->out.vwv, VWV(1), parms->unlock.in.count);
                SIVAL(req->out.vwv, VWV(3), parms->unlock.in.offset);
                break;
@@ -768,7 +778,7 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc
                SETUP_REQUEST(SMBlockingX, 8, lck_size * lock_count);
                SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
                SSVAL(req->out.vwv, VWV(1), 0);
-               SSVAL(req->out.vwv, VWV(2), parms->lockx.in.fnum);
+               SSVAL(req->out.vwv, VWV(2), parms->lockx.in.file.fnum);
                SSVAL(req->out.vwv, VWV(3), parms->lockx.in.mode);
                SIVAL(req->out.vwv, VWV(4), parms->lockx.in.timeout);
                SSVAL(req->out.vwv, VWV(6), parms->lockx.in.ulock_cnt);
@@ -790,7 +800,10 @@ struct smbcli_request *smb_raw_lock_send(struct smbcli_tree *tree, union smb_loc
                                SIVAL(p, 6, lockp[i].count);
                        }
                }       
+               break;
        }
+       case RAW_LOCK_SMB2:
+               return NULL;
        }
 
        if (!smbcli_request_send(req)) {
@@ -814,13 +827,13 @@ NTSTATUS smb_raw_lock(struct smbcli_tree *tree, union smb_lock *parms)
 /****************************************************************************
  Check for existence of a dir - async send
 ****************************************************************************/
-struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb_chkpath *parms)
+struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, union smb_chkpath *parms)
 {
        struct smbcli_request *req; 
 
        SETUP_REQUEST(SMBchkpth, 0, 0);
 
-       smbcli_req_append_ascii4(req, parms->in.path, STR_TERMINATE);
+       smbcli_req_append_ascii4(req, parms->chkpath.in.path, STR_TERMINATE);
 
        if (!smbcli_request_send(req)) {
                smbcli_request_destroy(req);
@@ -833,25 +846,34 @@ struct smbcli_request *smb_raw_chkpath_send(struct smbcli_tree *tree, struct smb
 /****************************************************************************
  Check for existence of a dir - sync interface
 ****************************************************************************/
-NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, struct smb_chkpath *parms)
+NTSTATUS smb_raw_chkpath(struct smbcli_tree *tree, union smb_chkpath *parms)
 {
        struct smbcli_request *req = smb_raw_chkpath_send(tree, parms);
        return smbcli_request_simple_recv(req);
 }
 
-
-
-
 /****************************************************************************
  flush a file - async send
- a flush to fnum 0xFFFF will flush all files
+ a flush with RAW_FLUSH_ALL will flush all files
 ****************************************************************************/
-struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_flush *parms)
+struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, union smb_flush *parms)
 {
        struct smbcli_request *req; 
+       uint16_t fnum=0;
+
+       switch (parms->generic.level) {
+       case RAW_FLUSH_FLUSH:
+               fnum = parms->flush.in.file.fnum;
+               break;
+       case RAW_FLUSH_ALL:
+               fnum = 0xFFFF;
+               break;
+       case RAW_FLUSH_SMB2:
+               return NULL;
+       }
 
        SETUP_REQUEST(SMBflush, 1, 0);
-       SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
+       SSVAL(req->out.vwv, VWV(0), fnum);
 
        if (!smbcli_request_send(req)) {
                smbcli_request_destroy(req);
@@ -865,7 +887,7 @@ struct smbcli_request *smb_raw_flush_send(struct smbcli_tree *tree, struct smb_f
 /****************************************************************************
  flush a file - sync interface
 ****************************************************************************/
-NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms)
+NTSTATUS smb_raw_flush(struct smbcli_tree *tree, union smb_flush *parms)
 {
        struct smbcli_request *req = smb_raw_flush_send(tree, parms);
        return smbcli_request_simple_recv(req);
@@ -876,15 +898,15 @@ NTSTATUS smb_raw_flush(struct smbcli_tree *tree, struct smb_flush *parms)
  seek a file - async send
 ****************************************************************************/
 struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree,
-                                     struct smb_seek *parms)
+                                        union smb_seek *parms)
 {
        struct smbcli_request *req; 
 
        SETUP_REQUEST(SMBlseek, 4, 0);
 
-       SSVAL(req->out.vwv, VWV(0), parms->in.fnum);
-       SSVAL(req->out.vwv, VWV(1), parms->in.mode);
-       SIVALS(req->out.vwv, VWV(2), parms->in.offset);
+       SSVAL(req->out.vwv, VWV(0), parms->lseek.in.file.fnum);
+       SSVAL(req->out.vwv, VWV(1), parms->lseek.in.mode);
+       SIVALS(req->out.vwv, VWV(2), parms->lseek.in.offset);
 
        if (!smbcli_request_send(req)) {
                smbcli_request_destroy(req);
@@ -897,7 +919,7 @@ struct smbcli_request *smb_raw_seek_send(struct smbcli_tree *tree,
  seek a file - async receive
 ****************************************************************************/
 NTSTATUS smb_raw_seek_recv(struct smbcli_request *req,
-                                     struct smb_seek *parms)
+                          union smb_seek *parms)
 {
        if (!smbcli_request_receive(req) ||
            smbcli_request_is_error(req)) {
@@ -905,7 +927,7 @@ NTSTATUS smb_raw_seek_recv(struct smbcli_request *req,
        }
 
        SMBCLI_CHECK_WCT(req, 2);       
-       parms->out.offset = IVAL(req->in.vwv, VWV(0));
+       parms->lseek.out.offset = IVAL(req->in.vwv, VWV(0));
 
 failed:        
        return smbcli_request_destroy(req);
@@ -915,7 +937,7 @@ failed:
   seek a file - sync interface
 */
 NTSTATUS smb_raw_seek(struct smbcli_tree *tree,
-                     struct smb_seek *parms)
+                     union smb_seek *parms)
 {
        struct smbcli_request *req = smb_raw_seek_send(tree, parms);
        return smb_raw_seek_recv(req, parms);