libcli/smb: Add smb_bytes_pull_str() helper function
authorStefan Metzmacher <metze@samba.org>
Tue, 25 Oct 2016 12:50:41 +0000 (14:50 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 15 Nov 2016 10:00:26 +0000 (11:00 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
libcli/smb/smb_util.h
libcli/smb/util.c

index 6718b6cb54ec76b5f7f443599c438655d235df11..7e6f0a4ebc437cfbfd70198c3038599856e2b21b 100644 (file)
@@ -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);
index b048cbabb690274c2e3d882023820f44d63b5fb0..ef8c9fafa3561720bbe29f354a5cc14a677b3023 100644 (file)
@@ -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);
+}