smb_server: pass down RAW_RENAME_NTTRANS to the ntvfs layer
[samba.git] / source / smb_server / smb / nttrans.c
index 25cddd6654fabf4dcd16e9737c8710dd5f26e098..1b49e235113ccd1e53a18ee0ca08bea870af07c8 100644 (file)
@@ -26,6 +26,7 @@
 #include "ntvfs/ntvfs.h"
 #include "libcli/raw/libcliraw.h"
 #include "librpc/gen_ndr/ndr_security.h"
+#include "param/param.h"
 
 /*
   hold the state of a nttrans op while in progress. Needed to allow for async backend
@@ -133,7 +134,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
        io->ntcreatex.in.sec_desc         = NULL;
        io->ntcreatex.in.ea_list          = NULL;
 
-       req_pull_string(req, &io->ntcreatex.in.fname, 
+       req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, 
                        params + 53, 
                        MIN(fname_len+1, trans->in.params.length - 53),
                        STR_NO_RANGE_CHECK | STR_TERMINATE);
@@ -156,7 +157,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
                if (io->ntcreatex.in.sec_desc == NULL) {
                        return NT_STATUS_NO_MEMORY;
                }
-               ndr_err = ndr_pull_struct_blob(&blob, io,
+               ndr_err = ndr_pull_struct_blob(&blob, io, NULL,
                                               io->ntcreatex.in.sec_desc,
                                               (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -203,7 +204,7 @@ static NTSTATUS nttrans_query_sec_desc_send(struct nttrans_op *op)
        NT_STATUS_NOT_OK_RETURN(status);
        params = op->trans->out.params.data;
 
-       ndr_err = ndr_push_struct_blob(&op->trans->out.data, op,
+       ndr_err = ndr_push_struct_blob(&op->trans->out.data, op, NULL,
                                       io->query_secdesc.out.sd,
                                       (ndr_push_flags_fn_t)ndr_push_security_descriptor);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -269,7 +270,7 @@ static NTSTATUS nttrans_set_sec_desc(struct smbsrv_request *req,
        io->set_secdesc.in.sd = talloc(io, struct security_descriptor);
        NT_STATUS_HAVE_NO_MEMORY(io->set_secdesc.in.sd);
 
-       ndr_err = ndr_pull_struct_blob(&trans->in.data, req,
+       ndr_err = ndr_pull_struct_blob(&trans->in.data, req, NULL,
                                       io->set_secdesc.in.sd,
                                       (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -286,7 +287,30 @@ static NTSTATUS nttrans_set_sec_desc(struct smbsrv_request *req,
 static NTSTATUS nttrans_rename(struct smbsrv_request *req, 
                               struct nttrans_op *op)
 {
-       return NT_STATUS_NOT_IMPLEMENTED;
+       struct smb_nttrans *trans = op->trans;
+       union smb_rename *io;
+
+       if (trans->in.params.length < 5) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* parse the request */
+       io = talloc(req, union smb_rename);
+       NT_STATUS_HAVE_NO_MEMORY(io);
+
+       io->nttrans.level               = RAW_RENAME_NTTRANS;
+       io->nttrans.in.file.ntvfs       = smbsrv_pull_fnum(req, trans->in.params.data, 0);
+       io->nttrans.in.flags            = SVAL(trans->in.params.data, 2);
+
+       smbsrv_blob_pull_string(&req->in.bufinfo, &trans->in.params, 4,
+                               &io->nttrans.in.new_name,
+                               STR_TERMINATE);
+       if (!io->nttrans.in.new_name) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(io->nttrans.in.file.ntvfs);
+       return ntvfs_rename(req->ntvfs, io);
 }
 
 /* 
@@ -372,7 +396,7 @@ static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op)
                ssize_t len;
 
                SIVAL(p, 4, info->nttrans.out.changes[i].action);
-               len = push_string(global_smb_iconv_convenience, p + 12, info->nttrans.out.changes[i].name.s, 
+               len = push_string(lp_iconv_convenience(global_loadparm), p + 12, info->nttrans.out.changes[i].name.s, 
                                  op->trans->out.params.length - 
                                  (p+12 - op->trans->out.params.data), STR_UNICODE);
                SIVAL(p, 8, len);
@@ -459,7 +483,7 @@ static NTSTATUS nttrans_backend(struct smbsrv_request *req,
 static void reply_nttrans_send(struct ntvfs_request *ntvfs)
 {
        struct smbsrv_request *req;
-       uint16_t params_left, data_left;
+       uint32_t params_left, data_left;
        uint8_t *params, *data;
        struct smb_nttrans *trans;
        struct nttrans_op *op;
@@ -501,7 +525,7 @@ static void reply_nttrans_send(struct ntvfs_request *ntvfs)
        /* we need to divide up the reply into chunks that fit into
           the negotiated buffer size */
        do {
-               uint16_t this_data, this_param, max_bytes;
+               uint32_t this_data, this_param, max_bytes;
                uint_t align1 = 1, align2 = (params_left ? 2 : 0);
                struct smbsrv_request *this_req;
 
@@ -526,7 +550,7 @@ static void reply_nttrans_send(struct ntvfs_request *ntvfs)
                        this_req = req;
                }
 
-               req_grow_data(req, this_param + this_data + (align1 + align2));
+               req_grow_data(this_req, this_param + this_data + (align1 + align2));
 
                SSVAL(this_req->out.vwv, 0, 0); /* reserved */
                SCVAL(this_req->out.vwv, 2, 0); /* reserved */
@@ -572,9 +596,9 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
 {
        struct nttrans_op *op;
        struct smb_nttrans *trans;
-       uint16_t param_ofs, data_ofs;
-       uint16_t param_count, data_count;
-       uint16_t param_total, data_total;
+       uint32_t param_ofs, data_ofs;
+       uint32_t param_count, data_count;
+       uint32_t param_total, data_total;
 
        /* parse request */
        if (req->in.wct < 19) {
@@ -621,8 +645,8 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
        memcpy(trans->in.setup, (char *)(req->in.vwv) + VWV(19),
               sizeof(uint16_t) * trans->in.setup_count);
 
-       if (!req_pull_blob(req, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
-           !req_pull_blob(req, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
+       if (!req_pull_blob(&req->in.bufinfo, req->in.hdr + param_ofs, param_count, &trans->in.params) ||
+           !req_pull_blob(&req->in.bufinfo, req->in.hdr + data_ofs, data_count, &trans->in.data)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }