r3054: use talloc_zero_array_p() in a couple of places
[bbaumbach/samba-autobuild/.git] / source4 / smb_server / trans2.c
index 6e02ddc90d2bcdb36771dcc8bfc9388141ffbdbf..ed58791fbeabc56bb2f983a54cddd85f18327302 100644 (file)
@@ -39,7 +39,7 @@ static void trans2_grow_data_allocation(struct smbsrv_request *req,
        if (new_size <= trans->out.data.length) {
                return;
        }
-       trans->out.data.data = talloc_realloc(trans->out.data.data, new_size);
+       trans->out.data.data = talloc_realloc(req, trans->out.data.data, new_size);
 }
 
 
@@ -73,7 +73,7 @@ static void trans2_setup_reply(struct smbsrv_request *req,
 {
        trans->out.setup_count = setup_count;
        if (setup_count != 0) {
-               trans->out.setup = talloc_zero(req, sizeof(uint16_t) * setup_count);
+               trans->out.setup = talloc_zero_array_p(req, uint16_t, setup_count);
        }
        trans->out.params = data_blob_talloc(req, NULL, param_size);
        trans->out.data = data_blob_talloc(req, NULL, data_size);
@@ -143,10 +143,10 @@ static size_t trans2_push_data_string(struct smbsrv_request *req,
                alignment = 1;
                if (dest_len > 0) {
                        SCVAL(trans->out.data.data + offset, 0, 0);
-                       ret = push_string(NULL, trans->out.data.data + offset + 1, str->s, dest_len-1, flags);
+                       ret = push_string(trans->out.data.data + offset + 1, str->s, dest_len-1, flags);
                }
        } else {
-               ret = push_string(NULL, trans->out.data.data + offset, str->s, dest_len, flags);
+               ret = push_string(trans->out.data.data + offset, str->s, dest_len, flags);
        }
 
        /* sometimes the string needs to be terminated, but the length
@@ -192,6 +192,18 @@ static void trans2_append_data_string(struct smbsrv_request *req,
        trans2_grow_data(req, trans, offset + ret);
 }
 
+/*
+  align the end of the data section of a trans reply on an even boundary
+*/
+static void trans2_align_data(struct smbsrv_request *req, struct smb_trans2 *trans)
+{
+       if ((trans->out.data.length & 1) == 0) {
+               return;
+       }
+       trans2_grow_data(req, trans, trans->out.data.length+1);
+       SCVAL(trans->out.data.data, trans->out.data.length-1, 0);
+}
+
 
 /*
   trans2 qfsinfo implementation
@@ -215,7 +227,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_ALLOCATION:
                fsinfo.allocation.level = RAW_QFS_ALLOCATION;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -233,7 +245,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_VOLUME:
                fsinfo.volume.level = RAW_QFS_VOLUME;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -253,7 +265,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_VOLUME_INFORMATION:
                fsinfo.volume_info.level = RAW_QFS_VOLUME_INFO;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -273,7 +285,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_SIZE_INFORMATION:
                fsinfo.size_info.level = RAW_QFS_SIZE_INFO;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -291,7 +303,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_DEVICE_INFORMATION:
                fsinfo.device_info.level = RAW_QFS_DEVICE_INFO;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -305,7 +317,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_ATTRIBUTE_INFORMATION:
                fsinfo.attribute_info.level = RAW_QFS_ATTRIBUTE_INFO;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -326,7 +338,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_QUOTA_INFORMATION:
                fsinfo.quota_information.level = RAW_QFS_QUOTA_INFORMATION;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -346,7 +358,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_FULL_SIZE_INFORMATION:
                fsinfo.full_size_information.level = RAW_QFS_FULL_SIZE_INFORMATION;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -364,7 +376,7 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct smb_trans2 *tr
        case SMB_QFS_OBJECTID_INFORMATION:
                fsinfo.objectid_information.level = RAW_QFS_OBJECTID_INFORMATION;
 
-               status = req->tcon->ntvfs_ops->fsinfo(req, &fsinfo);
+               status = ntvfs_fsinfo(req, &fsinfo);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -623,7 +635,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct smb_trans2 *
        uint16_t level;
 
        /* make sure we got enough parameters */
-       if (trans->in.params.length < 8) {
+       if (trans->in.params.length < 2) {
                return NT_STATUS_FOOBAR;
        }
 
@@ -641,7 +653,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct smb_trans2 *
        }
 
        /* call the backend */
-       status = req->tcon->ntvfs_ops->qpathinfo(req, &st);
+       status = ntvfs_qpathinfo(req, &st);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -677,7 +689,7 @@ static NTSTATUS trans2_qfileinfo(struct smbsrv_request *req, struct smb_trans2 *
        }
 
        /* call the backend */
-       status = req->tcon->ntvfs_ops->qfileinfo(req, &st);
+       status = ntvfs_qfileinfo(req, &st);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -813,7 +825,7 @@ static NTSTATUS trans2_setfileinfo(struct smbsrv_request *req, struct smb_trans2
                return status;
        }
 
-       status = req->tcon->ntvfs_ops->setfileinfo(req, &st);
+       status = ntvfs_setfileinfo(req, &st);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -852,7 +864,7 @@ static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct smb_trans2
                return status;
        }
 
-       status = req->tcon->ntvfs_ops->setpathinfo(req, &st);
+       status = ntvfs_setpathinfo(req, &st);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -997,6 +1009,7 @@ static void find_fill_info(struct smbsrv_request *req,
                                        24, STR_UNICODE | STR_LEN8BIT);
                trans2_append_data_string(req, trans, &file->both_directory_info.name, 
                                          ofs + 60, STR_TERMINATE_ASCII);
+               trans2_align_data(req, trans);
                data = trans->out.data.data + ofs;
                SIVAL(data,          0, trans->out.data.length - ofs);
                break;
@@ -1114,8 +1127,9 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct smb_trans2 *
        trans2_setup_reply(req, trans, 10, 0, 0);
 
        /* call the backend */
-       status = req->tcon->ntvfs_ops->search_first(req, &search, &state, find_callback);
+       status = ntvfs_search_first(req, &search, &state, find_callback);
        if (!NT_STATUS_IS_OK(status)) {
+               trans2_setup_reply(req, trans, 0, 0, 0);
                return status;
        }
 
@@ -1126,7 +1140,7 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct smb_trans2 *
        SSVAL(param, VWV(2), search.t2ffirst.out.end_of_search);
        SSVAL(param, VWV(3), 0);
        SSVAL(param, VWV(4), state.last_entry_offset);
-       
+
        return NT_STATUS_OK;
 }
 
@@ -1174,7 +1188,7 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct smb_trans2 *t
        trans2_setup_reply(req, trans, 8, 0, 0);
 
        /* call the backend */
-       status = req->tcon->ntvfs_ops->search_next(req, &search, &state, find_callback);
+       status = ntvfs_search_next(req, &search, &state, find_callback);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -1195,9 +1209,12 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct smb_trans2 *t
 */
 static NTSTATUS trans2_backend(struct smbsrv_request *req, struct smb_trans2 *trans)
 {
-       if (req->tcon->ntvfs_ops->trans2 != NULL) {
-               /* direct trans2 pass thru */
-               return req->tcon->ntvfs_ops->trans2(req, trans);
+       NTSTATUS status;
+
+       /* direct trans2 pass thru */
+       status = ntvfs_trans2(req, trans);
+       if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
+               return status;
        }
 
        /* must have at least one setup word */
@@ -1227,19 +1244,6 @@ static NTSTATUS trans2_backend(struct smbsrv_request *req, struct smb_trans2 *tr
        return NT_STATUS_FOOBAR;
 }
 
-
-/*
-  backend for trans requests
-*/
-static NTSTATUS trans_backend(struct smbsrv_request *req, struct smb_trans2 *trans)
-{
-       if (!req->tcon->ntvfs_ops->trans) {
-               return NT_STATUS_NOT_IMPLEMENTED;
-       }
-       return req->tcon->ntvfs_ops->trans(req, trans);
-}
-
-
 /****************************************************************************
  Reply to an SMBtrans or SMBtrans2 request
 ****************************************************************************/
@@ -1307,7 +1311,7 @@ void reply_trans_generic(struct smbsrv_request *req, uint8_t command)
 
        /* its a full request, give it to the backend */
        if (command == SMBtrans) {
-               status = trans_backend(req, &trans);
+               status = ntvfs_trans(req, &trans);
        } else {
                status = trans2_backend(req, &trans);
        }
@@ -1322,8 +1326,6 @@ void reply_trans_generic(struct smbsrv_request *req, uint8_t command)
        params      = trans.out.params.data;
        data        = trans.out.data.data;
 
-       req->control_flags |= REQ_CONTROL_PROTECTED;
-
        /* we need to divide up the reply into chunks that fit into
           the negotiated buffer size */
        do {
@@ -1383,9 +1385,9 @@ void reply_trans_generic(struct smbsrv_request *req, uint8_t command)
                params += this_param;
                data += this_data;
 
-               /* if this is the last chunk then the request can be destroyed */
-               if (params_left == 0 && data_left == 0) {
-                       req->control_flags &= ~REQ_CONTROL_PROTECTED;
+               /* don't destroy unless this is the last chunk */
+               if (params_left != 0 || data_left != 0) {
+                       talloc_increase_ref_count(req);
                }
 
                req_send_reply(req);