libcli/smb: move smb2_create_blob code to libcli/smb/
authorStefan Metzmacher <metze@samba.org>
Wed, 12 Aug 2009 15:43:03 +0000 (17:43 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 12 Aug 2009 17:22:06 +0000 (19:22 +0200)
I want to use this in source3/smbd/

metze

libcli/smb/config.mk [new file with mode: 0644]
libcli/smb/smb2_create_blob.c [new file with mode: 0644]
libcli/smb/smb2_create_blob.h [new file with mode: 0644]
libcli/smb/smb_common.h
source4/libcli/config.mk
source4/libcli/raw/interfaces.h
source4/libcli/smb2/create.c
source4/main.mk

diff --git a/libcli/smb/config.mk b/libcli/smb/config.mk
new file mode 100644 (file)
index 0000000..57c25c3
--- /dev/null
@@ -0,0 +1,11 @@
+# common SMB and SMB2 stuff
+[SUBSYSTEM::LIBCLI_SMB_COMMON]
+PUBLIC_DEPENDENCIES = LIBTALLOC
+
+LIBCLI_SMB_COMMON_OBJ_FILES = $(addprefix ../libcli/smb/, \
+               smb2_create_blob.o)
+
+$(eval $(call proto_header_template, \
+       ../libcli/smb/smb_common_proto.h, \
+       $(LIBCLI_SMB_COMMON_OBJ_FILES:.o=.c)))
+
diff --git a/libcli/smb/smb2_create_blob.c b/libcli/smb/smb2_create_blob.c
new file mode 100644 (file)
index 0000000..0dad224
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   SMB2 Create Context Blob handling
+
+   Copyright (C) Andrew Tridgell 2005
+   Copyright (C) Stefan Metzmacher 2008-2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "../libcli/smb/smb_common.h"
+
+static size_t smb2_create_blob_padding(uint32_t offset, size_t n)
+{
+       if ((offset & (n-1)) == 0) return 0;
+       return n - (offset & (n-1));
+}
+
+/*
+  parse a set of SMB2 create blobs
+*/
+NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer,
+                               struct smb2_create_blobs *blobs)
+{
+       const uint8_t *data = buffer.data;
+       uint32_t remaining = buffer.length;
+
+       while (remaining > 0) {
+               uint32_t next;
+               uint32_t name_offset, name_length;
+               uint32_t reserved, data_offset;
+               uint32_t data_length;
+               char *tag;
+               DATA_BLOB b;
+               NTSTATUS status;
+
+               if (remaining < 16) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+               next        = IVAL(data, 0);
+               name_offset = SVAL(data, 4);
+               name_length = SVAL(data, 6);
+               reserved    = SVAL(data, 8);
+               data_offset = SVAL(data, 10);
+               data_length = IVAL(data, 12);
+
+               if ((next & 0x7) != 0 ||
+                   next > remaining ||
+                   name_offset < 16 ||
+                   name_offset > remaining ||
+                   name_length != 4 || /* windows enforces this */
+                   name_offset + name_length > remaining ||
+                   data_offset < name_offset + name_length ||
+                   data_offset > remaining ||
+                   data_offset + (uint64_t)data_length > remaining) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               tag = talloc_strndup(mem_ctx, (const char *)data + name_offset, name_length);
+               if (tag == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               b = data_blob_const(data+data_offset, data_length);
+               status = smb2_create_blob_add(mem_ctx, blobs, tag, b);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+
+               talloc_free(tag);
+
+               if (next == 0) break;
+
+               remaining -= next;
+               data += next;
+
+               if (remaining < 16) {
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
+
+/*
+  add a blob to a smb2_create attribute blob
+*/
+static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
+                                         const struct smb2_create_blob *blob,
+                                         bool last)
+{
+       uint32_t ofs = buffer->length;
+       size_t tag_length = strlen(blob->tag);
+       uint8_t pad = smb2_create_blob_padding(blob->data.length+tag_length, 4);
+
+       if (!data_blob_realloc(mem_ctx, buffer,
+                              buffer->length + 0x14 + tag_length + blob->data.length + pad))
+               return NT_STATUS_NO_MEMORY;
+
+       if (last) {
+               SIVAL(buffer->data, ofs+0x00, 0);
+       } else {
+               SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad);
+       }
+       SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */
+       SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */
+       SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
+       SIVAL(buffer->data, ofs+0x0C, blob->data.length);
+       memcpy(buffer->data+ofs+0x10, blob->tag, tag_length);
+       SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */
+       memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length);
+       memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad);
+
+       return NT_STATUS_OK;
+}
+
+
+/*
+  create a buffer of a set of create blobs
+*/
+NTSTATUS smb2_create_blob_push(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
+                              const struct smb2_create_blobs blobs)
+{
+       int i;
+       NTSTATUS status;
+
+       *buffer = data_blob(NULL, 0);
+       for (i=0; i < blobs.num_blobs; i++) {
+               bool last = false;
+               const struct smb2_create_blob *c;
+
+               if ((i + 1) == blobs.num_blobs) {
+                       last = true;
+               }
+
+               c = &blobs.blobs[i];
+               status = smb2_create_blob_push_one(mem_ctx, buffer, c, last);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+       return NT_STATUS_OK;
+}
+
+
+NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b,
+                             const char *tag, DATA_BLOB data)
+{
+       struct smb2_create_blob *array;
+
+       array = talloc_realloc(mem_ctx, b->blobs,
+                              struct smb2_create_blob,
+                              b->num_blobs + 1);
+       NT_STATUS_HAVE_NO_MEMORY(array);
+       b->blobs = array;
+
+       b->blobs[b->num_blobs].tag = talloc_strdup(b->blobs, tag);
+       NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].tag);
+
+       if (data.data) {
+               b->blobs[b->num_blobs].data = data_blob_talloc(b->blobs,
+                                                              data.data,
+                                                              data.length);
+               NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].data.data);
+       } else {
+               b->blobs[b->num_blobs].data = data_blob(NULL, 0);
+       }
+
+       b->num_blobs += 1;
+
+       return NT_STATUS_OK;
+}
diff --git a/libcli/smb/smb2_create_blob.h b/libcli/smb/smb2_create_blob.h
new file mode 100644 (file)
index 0000000..e8b8f12
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   SMB2 Create Context Blob handling
+
+   Copyright (C) Andrew Tridgell 2005
+   Copyright (C) Stefan Metzmacher 2008-2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIBCLI_SMB_SMB2_CREATE_BLOB_H_
+#define _LIBCLI_SMB_SMB2_CREATE_BLOB_H_
+
+struct smb2_create_blob {
+       const char *tag;
+       DATA_BLOB data;
+};
+
+struct smb2_create_blobs {
+       uint32_t num_blobs;
+       struct smb2_create_blob *blobs;
+};
+
+/*
+  parse a set of SMB2 create blobs
+*/
+NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer,
+                               struct smb2_create_blobs *blobs);
+
+/*
+  create a buffer of a set of create blobs
+*/
+NTSTATUS smb2_create_blob_push(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
+                              const struct smb2_create_blobs blobs);
+
+NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b,
+                             const char *tag, DATA_BLOB data);
+
+#endif /* _LIBCLI_SMB_SMB2_CREATE_BLOB_H_ */
index f5994d41057b551f8827b9514eb3e8045ab81b6c..d6186ab526511d4c8bd204f5d36ae6dfc891f9a7 100644 (file)
@@ -23,5 +23,6 @@
 #define __LIBCLI_SMB_SMB_COMMON_H__
 
 #include "../libcli/smb/smb2_constants.h"
+#include "../libcli/smb/smb2_create_blob.h"
 
 #endif
index ad7bc311c296307356aca10e95ccf39395c1a48e..b6a9f112a0cad50b25b2b7cbead7e89b5fee680e 100644 (file)
@@ -147,7 +147,7 @@ $(eval $(call proto_header_template,$(libclisrcdir)/libcli_proto.h,$(LIBCLI_SMB_
 [SUBSYSTEM::LIBCLI_RAW]
 PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECURITY LIBNDR
 #LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT)
-PUBLIC_DEPENDENCIES = samba_socket LIBPACKET gensec LIBCRYPTO CREDENTIALS 
+PUBLIC_DEPENDENCIES = samba_socket LIBPACKET gensec LIBCRYPTO CREDENTIALS LIBCLI_SMB_COMMON
 
 LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o clisocket.o \
                                          clitransport.o clisession.o clitree.o clierror.o rawrequest.o \
index ad5f5bf2237363e71a50a359fae53222d75545b6..13217158cbe23302624ecd410cd965b74135da73 100644 (file)
@@ -1660,13 +1660,7 @@ union smb_open {
                        struct smb2_lease *lease_request;
                        
                        /* and any additional blobs the caller wants */
-                       struct smb2_create_blobs {
-                               uint32_t num_blobs;
-                               struct smb2_create_blob {
-                                       const char *tag;
-                                       DATA_BLOB data;
-                               } *blobs;
-                       } blobs;
+                       struct smb2_create_blobs blobs;
                } in;
                struct {
                        union smb_handle file;
index 363210bd03811b51f60ccef8be67396f6e33e89a..c9fb4ea4e010575e7561d49a6bf73af0e3e9ba93 100644 (file)
 #include "libcli/smb2/smb2_calls.h"
 #include "librpc/gen_ndr/ndr_security.h"
 
-
-/*
-  parse a set of SMB2 create blobs
-*/
-NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer,
-                               struct smb2_create_blobs *blobs)
-{
-       const uint8_t *data = buffer.data;
-       uint32_t remaining = buffer.length;
-
-       while (remaining > 0) {
-               uint32_t next;
-               uint32_t name_offset, name_length;
-               uint32_t reserved, data_offset;
-               uint32_t data_length;
-               char *tag;
-               DATA_BLOB b;
-               NTSTATUS status;
-
-               if (remaining < 16) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-               next        = IVAL(data, 0);
-               name_offset = SVAL(data, 4);
-               name_length = SVAL(data, 6);
-               reserved    = SVAL(data, 8);
-               data_offset = SVAL(data, 10);
-               data_length = IVAL(data, 12);
-
-               if ((next & 0x7) != 0 ||
-                   next > remaining ||
-                   name_offset < 16 ||
-                   name_offset > remaining ||
-                   name_length != 4 || /* windows enforces this */
-                   name_offset + name_length > remaining ||
-                   data_offset < name_offset + name_length ||
-                   data_offset > remaining ||
-                   data_offset + (uint64_t)data_length > remaining) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-
-               tag = talloc_strndup(mem_ctx, (const char *)data + name_offset, name_length);
-               if (tag == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-
-               b = data_blob_const(data+data_offset, data_length);
-               status = smb2_create_blob_add(mem_ctx, blobs, tag, b);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-
-               talloc_free(tag);
-
-               if (next == 0) break;
-
-               remaining -= next;
-               data += next;
-
-               if (remaining < 16) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-       }
-
-       return NT_STATUS_OK;
-}
-
-
-/*
-  add a blob to a smb2_create attribute blob
-*/
-static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
-                                         const struct smb2_create_blob *blob,
-                                         bool last)
-{
-       uint32_t ofs = buffer->length;
-       size_t tag_length = strlen(blob->tag);
-       uint8_t pad = smb2_padding_size(blob->data.length+tag_length, 4);
-
-       if (!data_blob_realloc(mem_ctx, buffer,
-                              buffer->length + 0x14 + tag_length + blob->data.length + pad))
-               return NT_STATUS_NO_MEMORY;
-
-       if (last) {
-               SIVAL(buffer->data, ofs+0x00, 0);
-       } else {
-               SIVAL(buffer->data, ofs+0x00, 0x14 + tag_length + blob->data.length + pad);
-       }
-       SSVAL(buffer->data, ofs+0x04, 0x10); /* offset of tag */
-       SIVAL(buffer->data, ofs+0x06, tag_length); /* tag length */
-       SSVAL(buffer->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */
-       SIVAL(buffer->data, ofs+0x0C, blob->data.length);
-       memcpy(buffer->data+ofs+0x10, blob->tag, tag_length);
-       SIVAL(buffer->data, ofs+0x10+tag_length, 0); /* pad? */
-       memcpy(buffer->data+ofs+0x14+tag_length, blob->data.data, blob->data.length);
-       memset(buffer->data+ofs+0x14+tag_length+blob->data.length, 0, pad);
-
-       return NT_STATUS_OK;
-}
-
-
-/*
-  create a buffer of a set of create blobs
-*/
-NTSTATUS smb2_create_blob_push(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
-                              const struct smb2_create_blobs blobs)
-{
-       int i;
-       NTSTATUS status;
-
-       *buffer = data_blob(NULL, 0);
-       for (i=0; i < blobs.num_blobs; i++) {
-               bool last = false;
-               const struct smb2_create_blob *c;
-
-               if ((i + 1) == blobs.num_blobs) {
-                       last = true;
-               }
-
-               c = &blobs.blobs[i];
-               status = smb2_create_blob_push_one(mem_ctx, buffer, c, last);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
-       }
-       return NT_STATUS_OK;
-}
-
-
-NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b,
-                             const char *tag, DATA_BLOB data)
-{
-       struct smb2_create_blob *array;
-
-       array = talloc_realloc(mem_ctx, b->blobs,
-                              struct smb2_create_blob,
-                              b->num_blobs + 1);
-       NT_STATUS_HAVE_NO_MEMORY(array);
-       b->blobs = array;
-
-       b->blobs[b->num_blobs].tag = talloc_strdup(b->blobs, tag);
-       NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].tag);
-
-       if (data.data) {
-               b->blobs[b->num_blobs].data = data_blob_talloc(b->blobs,
-                                                              data.data,
-                                                              data.length);
-               NT_STATUS_HAVE_NO_MEMORY(b->blobs[b->num_blobs].data.data);
-       } else {
-               b->blobs[b->num_blobs].data = data_blob(NULL, 0);
-       }
-
-       b->num_blobs += 1;
-
-       return NT_STATUS_OK;
-}
-
 /*
   send a create request
 */
index 4d7fd584f859b313f95d0a66d1c1c3ece04539d9..63eea36cdffc467d5436a248ab0f3965c0b39854 100644 (file)
@@ -48,6 +48,7 @@ mkinclude torture/config.mk
 mkinclude librpc/config.mk
 mkinclude client/config.mk
 mkinclude libcli/config.mk
+mkinclude ../libcli/smb/config.mk
 mkinclude ../libcli/cldap/config.mk
 mkinclude scripting/python/config.mk
 mkinclude kdc/config.mk