summaryrefslogtreecommitdiff
path: root/libcli/smb
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2016-10-25 14:50:41 +0200
committerAndreas Schneider <asn@cryptomilk.org>2016-11-15 11:00:26 +0100
commit5b0a54d36c79b92eea68f0ca6550c88d1f552dad (patch)
tree5fe549b57bc2a2274579be948c6a6b3f2f68c32b /libcli/smb
parent7999e6f6c042a96e2d444407c375cb94f7298996 (diff)
downloadsamba-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.h3
-rw-r--r--libcli/smb/util.c60
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);
+}