]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smb2_server: rewrite dup_smb2_vec3() using SMBD_SMB2_*_IOV_OFS and helper variables
authorStefan Metzmacher <metze@samba.org>
Wed, 8 Aug 2012 06:32:40 +0000 (08:32 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 8 Aug 2012 10:52:51 +0000 (12:52 +0200)
metze

source3/smbd/smb2_server.c

index e3b6faaf2fafee7076adf70d5afae60a50728006..42f772652ab25e119520b71ac204ae2a1b7f9e51 100644 (file)
@@ -934,68 +934,78 @@ static bool dup_smb2_vec3(TALLOC_CTX *ctx,
                        struct iovec *outvec,
                        const struct iovec *srcvec)
 {
-       /* vec[0] is always boilerplate and must
+       const uint8_t *srchdr;
+       size_t srchdr_len;
+       const uint8_t *srcbody;
+       size_t srcbody_len;
+       const uint8_t *expected_srcbody;
+       const uint8_t *srcdyn;
+       size_t srcdyn_len;
+       const uint8_t *expected_srcdyn;
+       uint8_t *dsthdr;
+       uint8_t *dstbody;
+       uint8_t *dstdyn;
+
+       srchdr  = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
+       srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
+       srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
+       srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
+       expected_srcbody = srchdr + SMB2_HDR_BODY;
+       srcdyn  = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
+       srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
+       expected_srcdyn = srcbody + 8;
+
+       if (srchdr_len != SMB2_HDR_BODY) {
+               return false;
+       }
+
+       /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
         * be allocated with size OUTVEC_ALLOC_SIZE. */
 
-       outvec[0].iov_base = talloc_memdup(ctx,
-                               srcvec[0].iov_base,
-                               OUTVEC_ALLOC_SIZE);
-       if (!outvec[0].iov_base) {
+       dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
+       if (dsthdr == NULL) {
                return false;
        }
-       outvec[0].iov_len = SMB2_HDR_BODY;
+       outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
+       outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
 
        /*
-        * If this is a "standard" vec[1] of length 8,
-        * pointing to srcvec[0].iov_base + SMB2_HDR_BODY,
+        * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
+        * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
         * then duplicate this. Else use talloc_memdup().
         */
 
-       if (srcvec[1].iov_len == 8 &&
-                       srcvec[1].iov_base ==
-                               ((uint8_t *)srcvec[0].iov_base) +
-                                       SMB2_HDR_BODY) {
-               outvec[1].iov_base = ((uint8_t *)outvec[0].iov_base) +
-                                       SMB2_HDR_BODY;
-               outvec[1].iov_len = 8;
+       if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
+               dstbody = dsthdr + SMB2_HDR_BODY;
        } else {
-               outvec[1].iov_base = talloc_memdup(ctx,
-                               srcvec[1].iov_base,
-                               srcvec[1].iov_len);
-               if (!outvec[1].iov_base) {
+               dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
+               if (dstbody == NULL) {
                        return false;
                }
-               outvec[1].iov_len = srcvec[1].iov_len;
        }
+       outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
+       outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
 
        /*
-        * If this is a "standard" vec[2] of length 1,
-        * pointing to srcvec[0].iov_base + (OUTVEC_ALLOC_SIZE - 1)
+        * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
+        * pointing to
+        * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
         * then duplicate this. Else use talloc_memdup().
         */
 
-       if (srcvec[2].iov_base &&
-                       srcvec[2].iov_len) {
-               if (srcvec[2].iov_base ==
-                               ((uint8_t *)srcvec[0].iov_base) +
-                                       (OUTVEC_ALLOC_SIZE - 1) &&
-                               srcvec[2].iov_len == 1) {
-                       /* Common SMB2 error packet case. */
-                       outvec[2].iov_base = ((uint8_t *)outvec[0].iov_base) +
-                               (OUTVEC_ALLOC_SIZE - 1);
-               } else {
-                       outvec[2].iov_base = talloc_memdup(ctx,
-                                       srcvec[2].iov_base,
-                                       srcvec[2].iov_len);
-                       if (!outvec[2].iov_base) {
-                               return false;
-                       }
-               }
-               outvec[2].iov_len = srcvec[2].iov_len;
+       if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
+               dstdyn = dsthdr + SMB2_HDR_BODY + 8;
+       } else if (srcdyn == NULL) {
+               dstdyn = NULL;
        } else {
-               outvec[2].iov_base = NULL;
-               outvec[2].iov_len = 0;
+               dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
+               if (dstdyn == NULL) {
+                       return false;
+               }
        }
+       outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
+       outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
+
        return true;
 }