summaryrefslogtreecommitdiff
path: root/libcli/smb/util.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2016-10-25 13:31:08 +0200
committerAndreas Schneider <asn@cryptomilk.org>2016-11-15 11:00:26 +0100
commit7999e6f6c042a96e2d444407c375cb94f7298996 (patch)
treee4e86730fb873bdc8cee814d973b33cb8d038d1c /libcli/smb/util.c
parent482d3b35e99ab8c5b911fc3e863c1c35a500f791 (diff)
downloadsamba-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.c140
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;
+}