r204: Turns out that the string in the SEARCH unix_info level is that
authorJeremy Allison <jra@samba.org>
Wed, 14 Apr 2004 01:09:41 +0000 (01:09 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:51:16 +0000 (12:51 -0500)
rare thing, a non-length string (ie. not a WIRE_STRING) but a null
terminated char string. There wasn't a good interface to pull that
out of a blob (all the string interfaces assumed WIRE_STRINGS). Added
a new one, only used for this call. Sucks, I know - but the alternatives
suck more. Added tests for some of the unix info returned.
Jeremy.

source/include/smb_interfaces.h
source/libcli/raw/rawrequest.c
source/libcli/raw/rawsearch.c
source/torture/raw/search.c

index 6f6213931c4ec189b25daddc6a6d014d15110913..1f6208cdb5003c2d1c2d0e75ecdc2dcd088b2a01 100644 (file)
@@ -1919,7 +1919,7 @@ union smb_search_data {
                large_t unique_id;
                large_t permissions;
                large_t nlink;          
-               WIRE_STRING name;
+               const char *name;
        } unix_info;
 };
 
index f03cc5cf16a30e0c855bedc0429c109c2249d4fe..321d43f2202b3577f921482403c153843101b322 100644 (file)
@@ -1007,6 +1007,52 @@ size_t cli_blob_pull_string(struct cli_session *session,
                                           blob->data+str_offset, dest->private_length, flags);
 }
 
+/*
+  pull a string from a blob, returning a talloced char *
+
+  Currently only used by the UNIX search info level.
+
+  the string length is limited by 2 things:
+   - the data size in the blob
+   - the end of string (null termination)
+
+  on failure zero is returned and dest->s is set to NULL, otherwise the number
+  of bytes consumed in the blob is returned
+*/
+size_t cli_blob_pull_unix_string(struct cli_session *session,
+                           TALLOC_CTX *mem_ctx,
+                           DATA_BLOB *blob, 
+                           const char **dest, 
+                           uint16 str_offset, 
+                           unsigned flags)
+{
+       int extra = 0;
+       *dest = NULL;
+       
+       if (!(flags & STR_ASCII) && 
+           ((flags & STR_UNICODE) || 
+            (session->transport->negotiate.capabilities & CAP_UNICODE))) {
+               int align = 0;
+               if ((str_offset&1) && !(flags & STR_NOALIGN)) {
+                       align = 1;
+               }
+               if (flags & STR_LEN_NOTERM) {
+                       extra = 2;
+               }
+               return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, dest, 
+                                                         blob->data+str_offset+align, 
+                                                         -1, flags);
+       }
+
+       if (flags & STR_LEN_NOTERM) {
+               extra = 1;
+       }
+
+       return extra + cli_blob_pull_ascii(mem_ctx, blob, dest,
+                                          blob->data+str_offset, -1, flags);
+}
+
+
 /*
   append a string into a blob
 */
index ef854679dc5a117e2499489e817543deb554f5a6..8b60633fe8db90ee39fc80996b8e16c7841f60ba 100644 (file)
@@ -415,7 +415,7 @@ static int parse_trans2_search(struct cli_tree *tree,
                return ofs;
        
        case RAW_SEARCH_UNIX_INFO:
-               if (blob->length < 105) return -1;
+               if (blob->length < 109) return -1;
                ofs                                  = IVAL(blob->data,             0);
                data->unix_info.file_index           = IVAL(blob->data,             4);
                data->unix_info.size                 = BVAL(blob->data,             8);
@@ -432,10 +432,9 @@ static int parse_trans2_search(struct cli_tree *tree,
                data->unix_info.permissions          = IVAL(blob->data,            92);
                data->unix_info.nlink                = IVAL(blob->data,           100);
                /* There is no length field for this name but we know it's null terminated. */
-               len = cli_blob_pull_string(tree->session, mem_ctx, blob,
-                                          &data->unix_info.name,
-                                          0, 104, 0);
-               if (ofs != 0 && ofs < 104+len) {
+               len = cli_blob_pull_unix_string(tree->session, mem_ctx, blob,
+                                          &data->unix_info.name, 108, 0);
+               if (ofs != 0 && ofs < 108+len) {
                        return -1;
                }
                return ofs;
index 7308533fdaf41b1058b5eb586f2dd31ff4d0d67a..57c6eb2bb9d0e55af6885eceeb64ed307de10591 100644 (file)
@@ -257,6 +257,19 @@ static BOOL test_one_file(struct cli_state *cli, TALLOC_CTX *mem_ctx)
                        ret = False; \
                } \
        }} while (0)
+
+#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
+       s = find(name); \
+       if (s) { \
+               if (!s->sname1.field1 || \
+                   strcmp(s->sname1.field1, fname)) { \
+                       printf("(%d) %s/%s [%s] != %s\n", \
+                              __LINE__, \
+                               #sname1, #field1, s->sname1.field1, \
+                               fname); \
+                       ret = False; \
+               } \
+       }} while (0)
        
        /* check that all the results are as expected */
        CHECK_VAL("SEARCH",              search,              attrib, all_info, all_info, attrib);
@@ -336,6 +349,7 @@ static BOOL test_one_file(struct cli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_NAME("BOTH_DIRECTORY_INFO", both_directory_info, name, fname+1, STR_TERMINATE_ASCII);
        CHECK_NAME("ID_FULL_DIRECTORY_INFO", id_full_directory_info,           name, fname+1, STR_TERMINATE_ASCII);
        CHECK_NAME("ID_BOTH_DIRECTORY_INFO", id_both_directory_info,           name, fname+1, STR_TERMINATE_ASCII);
+       CHECK_UNIX_NAME("UNIX_INFO",           unix_info,           name, fname+1, STR_TERMINATE_ASCII);
 
        CHECK_VAL("ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id);
        CHECK_VAL("ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id);