diff options
author | Stefan Metzmacher <metze@samba.org> | 2016-10-25 14:50:41 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-11-15 11:00:26 +0100 |
commit | 5b0a54d36c79b92eea68f0ca6550c88d1f552dad (patch) | |
tree | 5fe549b57bc2a2274579be948c6a6b3f2f68c32b /libcli/smb | |
parent | 7999e6f6c042a96e2d444407c375cb94f7298996 (diff) | |
download | samba-5b0a54d36c79b92eea68f0ca6550c88d1f552dad.tar.gz |
libcli/smb: Add smb_bytes_pull_str() helper function
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'libcli/smb')
-rw-r--r-- | libcli/smb/smb_util.h | 3 | ||||
-rw-r--r-- | libcli/smb/util.c | 60 |
2 files changed, 63 insertions, 0 deletions
diff --git a/libcli/smb/smb_util.h b/libcli/smb/smb_util.h index 6718b6cb54e..7e6f0a4ebc4 100644 --- a/libcli/smb/smb_util.h +++ b/libcli/smb/smb_util.h @@ -36,3 +36,6 @@ uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2, size_t *pconverted_size); uint8_t *trans2_bytes_push_bytes(uint8_t *buf, const uint8_t *bytes, size_t num_bytes); +NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2, + const uint8_t *buf, size_t buf_len, + size_t *pbuf_consumed); diff --git a/libcli/smb/util.c b/libcli/smb/util.c index b048cbabb69..ef8c9fafa35 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -315,3 +315,63 @@ uint8_t *trans2_bytes_push_bytes(uint8_t *buf, memcpy(&buf[buflen], bytes, num_bytes); return buf; } + +static NTSTATUS internal_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, + bool ucs2, bool align_odd, + const uint8_t *buf, size_t buf_len, + size_t *pbuf_consumed) +{ + size_t pad = 0; + char *str = NULL; + size_t str_len = 0; + bool ok; + + *_str = NULL; + if (pbuf_consumed != NULL) { + *pbuf_consumed = 0; + } + + if (ucs2 && + ((align_odd && (buf_len % 2 == 0)) || + (!align_odd && (buf_len % 2 == 1)))) { + if (buf_len < 1) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + pad = 1; + buf_len -= pad; + buf += pad; + } + + if (ucs2) { + buf_len = utf16_len_n(buf, buf_len); + } else { + size_t tmp = strnlen((const char *)buf, buf_len); + if (tmp < buf_len) { + tmp += 1; + } + buf_len = tmp; + } + + ok = convert_string_talloc(mem_ctx, + ucs2 ? CH_UTF16LE : CH_DOS, + CH_UNIX, + buf, buf_len, + &str, &str_len); + if (!ok) { + return map_nt_error_from_unix_common(errno); + } + + if (pbuf_consumed != NULL) { + *pbuf_consumed = buf_len + pad; + } + *_str = str; + return NT_STATUS_OK;; +} + +NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2, + const uint8_t *buf, size_t buf_len, + size_t *_buf_consumed) +{ + return internal_bytes_pull_str(mem_ctx, _str, ucs2, true, + buf, buf_len, _buf_consumed); +} |