diff options
author | Stefan Metzmacher <metze@samba.org> | 2016-10-25 13:31:08 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-11-15 11:00:26 +0100 |
commit | 7999e6f6c042a96e2d444407c375cb94f7298996 (patch) | |
tree | e4e86730fb873bdc8cee814d973b33cb8d038d1c /libcli/smb/util.c | |
parent | 482d3b35e99ab8c5b911fc3e863c1c35a500f791 (diff) | |
download | samba-7999e6f6c042a96e2d444407c375cb94f7298996.tar.gz |
libcli/smb: move {smb,trans2}_bytes_push_{str,bytes}() to common code
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'libcli/smb/util.c')
-rw-r--r-- | libcli/smb/util.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/libcli/smb/util.c b/libcli/smb/util.c index b02ae00d0d9..b048cbabb69 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -175,3 +175,143 @@ bool smb_buffer_oob(uint32_t bufsize, uint32_t offset, uint32_t length) } return false; } + +/*********************************************************** + Common function for pushing stings, used by smb_bytes_push_str() + and trans_bytes_push_str(). Only difference is the align_odd + parameter setting. +***********************************************************/ + +static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2, + const char *str, size_t str_len, + bool align_odd, + size_t *pconverted_size) +{ + TALLOC_CTX *frame = talloc_stackframe(); + size_t buflen; + char *converted; + size_t converted_size; + + /* + * This check prevents us from + * (re)alloc buf on a NULL TALLOC_CTX. + */ + if (buf == NULL) { + TALLOC_FREE(frame); + return NULL; + } + + buflen = talloc_get_size(buf); + + if (ucs2 && + ((align_odd && (buflen % 2 == 0)) || + (!align_odd && (buflen % 2 == 1)))) { + /* + * We're pushing into an SMB buffer, align odd + */ + buf = talloc_realloc(NULL, buf, uint8_t, buflen + 1); + if (buf == NULL) { + TALLOC_FREE(frame); + return NULL; + } + buf[buflen] = '\0'; + buflen += 1; + } + + if (!convert_string_talloc(frame, CH_UNIX, + ucs2 ? CH_UTF16LE : CH_DOS, + str, str_len, &converted, + &converted_size)) { + TALLOC_FREE(frame); + return NULL; + } + + buf = talloc_realloc(NULL, buf, uint8_t, + buflen + converted_size); + if (buf == NULL) { + TALLOC_FREE(frame); + return NULL; + } + + memcpy(buf + buflen, converted, converted_size); + + TALLOC_FREE(converted); + + if (pconverted_size) { + *pconverted_size = converted_size; + } + + TALLOC_FREE(frame); + return buf; +} + +/*********************************************************** + Push a string into an SMB buffer, with odd byte alignment + if it's a UCS2 string. +***********************************************************/ + +uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, + const char *str, size_t str_len, + size_t *pconverted_size) +{ + return internal_bytes_push_str(buf, ucs2, str, str_len, + true, pconverted_size); +} + +uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, + const uint8_t *bytes, size_t num_bytes) +{ + size_t buflen; + + /* + * This check prevents us from + * (re)alloc buf on a NULL TALLOC_CTX. + */ + if (buf == NULL) { + return NULL; + } + buflen = talloc_get_size(buf); + + buf = talloc_realloc(NULL, buf, uint8_t, + buflen + 1 + num_bytes); + if (buf == NULL) { + return NULL; + } + buf[buflen] = prefix; + memcpy(&buf[buflen+1], bytes, num_bytes); + return buf; +} + +/*********************************************************** + Same as smb_bytes_push_str(), but without the odd byte + align for ucs2 (we're pushing into a param or data block). + static for now, although this will probably change when + other modules use async trans calls. +***********************************************************/ + +uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2, + const char *str, size_t str_len, + size_t *pconverted_size) +{ + return internal_bytes_push_str(buf, ucs2, str, str_len, + false, pconverted_size); +} + +uint8_t *trans2_bytes_push_bytes(uint8_t *buf, + const uint8_t *bytes, size_t num_bytes) +{ + size_t buflen; + + if (buf == NULL) { + return NULL; + } + buflen = talloc_get_size(buf); + + buf = talloc_realloc(NULL, buf, uint8_t, + buflen + num_bytes); + if (buf == NULL) { + return NULL; + } + memcpy(&buf[buflen], bytes, num_bytes); + return buf; +} |