diff options
author | Stefan Metzmacher <metze@samba.org> | 2012-08-08 08:32:40 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2012-08-08 12:52:51 +0200 |
commit | 63d92a192d83878e114febf78b8d71b81b5f8f4f (patch) | |
tree | d60fc9fcf2bb7c450691660d185038102b20453a /source3/smbd | |
parent | fc8e3bd569c379f3fd20104f2dbd1c62c0f78c26 (diff) | |
download | samba-63d92a192d83878e114febf78b8d71b81b5f8f4f.tar.gz samba-63d92a192d83878e114febf78b8d71b81b5f8f4f.tar.bz2 samba-63d92a192d83878e114febf78b8d71b81b5f8f4f.zip |
s3:smb2_server: rewrite dup_smb2_vec3() using SMBD_SMB2_*_IOV_OFS and helper variables
metze
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/smb2_server.c | 94 |
1 files changed, 52 insertions, 42 deletions
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index e3b6faaf2f..42f772652a 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -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; } |