Clean up some const and other compiler warnings.
[sharpe/samba-autobuild/.git] / source4 / torture / raw / qfileinfo.c
index 23e9cad2466fe7149ceab8e9fbecb43a993ca8d7..ca5f66795e69a0604f496d045f78396b2c513a42 100644 (file)
@@ -2,10 +2,11 @@
    Unix SMB/CIFS implementation.
    RAW_FILEINFO_* individual test suite
    Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
    
    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 2 of the License, or
+   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,
    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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "libcli/raw/libcliraw.h"
-#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/libcli.h"
+#include "torture/util.h"
+#include "torture/rpc/torture_rpc.h"
+#include "param/param.h"
+#include "torture/raw/proto.h"
 
 static struct {
        const char *name;
        enum smb_fileinfo_level level;
-       uint_t only_paths:1;
-       uint_t only_handles:1;
+       unsigned int only_paths:1;
+       unsigned int only_handles:1;
        uint32_t capability_mask;
+       unsigned int expected_ipc_access_denied:1;
+       NTSTATUS expected_ipc_fnum_status;
        NTSTATUS fnum_status, fname_status;
        union smb_fileinfo fnum_finfo, fname_finfo;
 } levels[] = {
-       { "GETATTR",                   RAW_FILEINFO_GETATTR,           1, 0, },
-       { "GETATTRE",                  RAW_FILEINFO_GETATTRE,          0, 1, },
-       { "STANDARD",                  RAW_FILEINFO_STANDARD, },
-       { "EA_SIZE",                   RAW_FILEINFO_EA_SIZE, },
-       { "ALL_EAS",                   RAW_FILEINFO_ALL_EAS, },
-       { "IS_NAME_VALID",             RAW_FILEINFO_IS_NAME_VALID,     1, 0, },
-       { "BASIC_INFO",                RAW_FILEINFO_BASIC_INFO, },
-       { "STANDARD_INFO",             RAW_FILEINFO_STANDARD_INFO, },
-       { "EA_INFO",                   RAW_FILEINFO_EA_INFO, },
-       { "NAME_INFO",                 RAW_FILEINFO_NAME_INFO, },
-       { "ALL_INFO",                  RAW_FILEINFO_ALL_INFO, },
-       { "ALT_NAME_INFO",             RAW_FILEINFO_ALT_NAME_INFO, },
-       { "STREAM_INFO",               RAW_FILEINFO_STREAM_INFO, },
-       { "COMPRESSION_INFO",          RAW_FILEINFO_COMPRESSION_INFO, },
-       { "UNIX_BASIC_INFO",           RAW_FILEINFO_UNIX_BASIC, 0, 0, CAP_UNIX},
-       { "UNIX_LINK_INFO",            RAW_FILEINFO_UNIX_LINK, 0, 0, CAP_UNIX},
-       { "BASIC_INFORMATION",         RAW_FILEINFO_BASIC_INFORMATION, },
-       { "STANDARD_INFORMATION",      RAW_FILEINFO_STANDARD_INFORMATION, },
-       { "INTERNAL_INFORMATION",      RAW_FILEINFO_INTERNAL_INFORMATION, },
-       { "EA_INFORMATION",            RAW_FILEINFO_EA_INFORMATION, },
-       { "ACCESS_INFORMATION",        RAW_FILEINFO_ACCESS_INFORMATION, },
-       { "NAME_INFORMATION",          RAW_FILEINFO_NAME_INFORMATION, },
-       { "POSITION_INFORMATION",      RAW_FILEINFO_POSITION_INFORMATION, },
-       { "MODE_INFORMATION",          RAW_FILEINFO_MODE_INFORMATION, },
-       { "ALIGNMENT_INFORMATION",     RAW_FILEINFO_ALIGNMENT_INFORMATION, },
-       { "ALL_INFORMATION",           RAW_FILEINFO_ALL_INFORMATION, },
-       { "ALT_NAME_INFORMATION",      RAW_FILEINFO_ALT_NAME_INFORMATION, },
-       { "STREAM_INFORMATION",        RAW_FILEINFO_STREAM_INFORMATION, },
-       { "COMPRESSION_INFORMATION",   RAW_FILEINFO_COMPRESSION_INFORMATION, },
-       { "NETWORK_OPEN_INFORMATION",  RAW_FILEINFO_NETWORK_OPEN_INFORMATION, },
-       { "ATTRIBUTE_TAG_INFORMATION", RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, },
-       { NULL, }
+       { .name = "GETATTR",
+         .level = RAW_FILEINFO_GETATTR,         
+         .only_paths = 1,
+         .only_handles = 0,
+         .expected_ipc_access_denied = 1},
+       {  .name ="GETATTRE",                  
+          .level = RAW_FILEINFO_GETATTRE,         
+          .only_paths = 0, 
+          .only_handles = 1 },
+       {  .name ="STANDARD",                  
+          .level = RAW_FILEINFO_STANDARD, },
+       {  .name ="EA_SIZE",                 
+          .level = RAW_FILEINFO_EA_SIZE },
+       {  .name ="ALL_EAS",                 
+          .level = RAW_FILEINFO_ALL_EAS,
+          .expected_ipc_fnum_status = NT_STATUS_ACCESS_DENIED,
+       },
+       {  .name ="IS_NAME_VALID",          
+          .level =  RAW_FILEINFO_IS_NAME_VALID,
+          .only_paths =  1,
+          .only_handles =  0 },
+       {  .name ="BASIC_INFO",            
+          .level =  RAW_FILEINFO_BASIC_INFO },
+       {  .name ="STANDARD_INFO",         
+          .level =  RAW_FILEINFO_STANDARD_INFO },
+       {  .name ="EA_INFO",               
+          .level =  RAW_FILEINFO_EA_INFO },
+       {  .name ="NAME_INFO",           
+          .level =  RAW_FILEINFO_NAME_INFO },
+       {  .name ="ALL_INFO",              
+          .level =  RAW_FILEINFO_ALL_INFO },
+       {  .name ="ALT_NAME_INFO",        
+          .level =  RAW_FILEINFO_ALT_NAME_INFO,
+          .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       {  .name ="STREAM_INFO",           
+          .level =  RAW_FILEINFO_STREAM_INFO,
+          .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       {  .name ="COMPRESSION_INFO",        
+          .level =  RAW_FILEINFO_COMPRESSION_INFO,
+          .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       {  .name ="UNIX_BASIC_INFO",         
+          .level =  RAW_FILEINFO_UNIX_BASIC,
+          .only_paths =  0, 
+          .only_handles = 0, 
+          .capability_mask = CAP_UNIX},
+       {  .name ="UNIX_LINK_INFO",          
+          .level =  RAW_FILEINFO_UNIX_LINK, 
+          .only_paths = 0, 
+          .only_handles = 0, 
+          .capability_mask = CAP_UNIX},
+       {  .name ="BASIC_INFORMATION",      
+          .level =  RAW_FILEINFO_BASIC_INFORMATION },
+       {  .name ="STANDARD_INFORMATION",   
+          .level =  RAW_FILEINFO_STANDARD_INFORMATION },
+       {  .name ="INTERNAL_INFORMATION",   
+          .level =  RAW_FILEINFO_INTERNAL_INFORMATION },
+       {  .name ="EA_INFORMATION",        
+          .level =  RAW_FILEINFO_EA_INFORMATION },
+       { .name = "ACCESS_INFORMATION",    
+         .level =  RAW_FILEINFO_ACCESS_INFORMATION },
+       { .name = "NAME_INFORMATION",      
+         .level =  RAW_FILEINFO_NAME_INFORMATION },
+       {  .name ="POSITION_INFORMATION",  
+          .level =  RAW_FILEINFO_POSITION_INFORMATION },
+       {  .name ="MODE_INFORMATION",       
+          .level =  RAW_FILEINFO_MODE_INFORMATION },
+       {  .name ="ALIGNMENT_INFORMATION",  
+          .level =  RAW_FILEINFO_ALIGNMENT_INFORMATION },
+       {  .name ="ALL_INFORMATION",       
+          .level =  RAW_FILEINFO_ALL_INFORMATION },
+       {  .name ="ALT_NAME_INFORMATION",  
+          .level =  RAW_FILEINFO_ALT_NAME_INFORMATION,
+          .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       {  .name ="STREAM_INFORMATION",    
+          .level =  RAW_FILEINFO_STREAM_INFORMATION,
+          .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       { .name = "COMPRESSION_INFORMATION", 
+         .level =  RAW_FILEINFO_COMPRESSION_INFORMATION,
+         .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       {  .name ="NETWORK_OPEN_INFORMATION",
+          .level =  RAW_FILEINFO_NETWORK_OPEN_INFORMATION,
+          .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       { .name = "ATTRIBUTE_TAG_INFORMATION",
+         .level =  RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION,
+         .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER
+       },
+       { NULL }
 };
 
 /*
@@ -71,8 +140,8 @@ static struct {
 static int dos_nt_time_cmp(time_t t, NTTIME nt)
 {
        time_t t2 = nt_time_to_unix(nt);
-       if (ABS(t2 - t) <= 2) return 0;
-       return t2 - t;
+       if (abs(t2 - t) <= 2) return 0;
+       return t2 > t ? 1 : -1;
 }
 
 
@@ -95,9 +164,12 @@ static union smb_fileinfo *fnum_find(const char *name)
 /*
   find a level in the levels[] table
 */
-static union smb_fileinfo *fname_find(const char *name)
+static union smb_fileinfo *fname_find(bool is_ipc, const char *name)
 {
        int i;
+       if (is_ipc) {
+               return NULL;
+       }
        for (i=0; levels[i].name; i++) {
                if (NT_STATUS_IS_OK(levels[i].fname_status) &&
                    strcmp(name, levels[i].name) == 0 && 
@@ -111,10 +183,10 @@ static union smb_fileinfo *fname_find(const char *name)
 /* local macros to make the code below more readable */
 #define VAL_EQUAL(n1, v1, n2, v2) do {if (s1->n1.out.v1 != s2->n2.out.v2) { \
         printf("%s/%s [%u] != %s/%s [%u] at %s(%d)\n", \
-               #n1, #v1, (uint_t)s1->n1.out.v1, \
-               #n2, #v2, (uint_t)s2->n2.out.v2, \
+               #n1, #v1, (unsigned int)s1->n1.out.v1, \
+               #n2, #v2, (unsigned int)s2->n2.out.v2, \
               __FILE__, __LINE__); \
-        ret = False; \
+        ret = false; \
 }} while(0)
 
 #define STR_EQUAL(n1, v1, n2, v2) do {if (strcmp_safe(s1->n1.out.v1.s, s2->n2.out.v2.s) || \
@@ -123,7 +195,7 @@ static union smb_fileinfo *fname_find(const char *name)
                #n1, #v1, s1->n1.out.v1.s, s1->n1.out.v1.private_length, \
                #n2, #v2, s2->n2.out.v2.s, s2->n2.out.v2.private_length, \
               __FILE__, __LINE__); \
-        ret = False; \
+        ret = false; \
 }} while(0)
 
 #define STRUCT_EQUAL(n1, v1, n2, v2) do {if (memcmp(&s1->n1.out.v1,&s2->n2.out.v2,sizeof(s1->n1.out.v1))) { \
@@ -131,106 +203,150 @@ static union smb_fileinfo *fname_find(const char *name)
                #n1, #v1, \
                #n2, #v2, \
               __FILE__, __LINE__); \
-        ret = False; \
+        ret = false; \
 }} while(0)
 
 /* used to find hints on unknown values - and to make sure 
    we zero-fill */
+#if 0 /* unused */
 #define VAL_UNKNOWN(n1, v1) do {if (s1->n1.out.v1 != 0) { \
         printf("%s/%s non-zero unknown - %u (0x%x) at %s(%d)\n", \
                #n1, #v1, \
-              (uint_t)s1->n1.out.v1, \
-              (uint_t)s1->n1.out.v1, \
+              (unsigned int)s1->n1.out.v1, \
+              (unsigned int)s1->n1.out.v1, \
               __FILE__, __LINE__); \
-        ret = False; \
+        ret = false; \
 }} while(0)
+#endif
 
 /* basic testing of all RAW_FILEINFO_* calls 
    for each call we test that it succeeds, and where possible test 
    for consistency between the calls. 
 */
-BOOL torture_raw_qfileinfo(void)
+static bool torture_raw_qfileinfo_internals(struct torture_context *torture, 
+                                           TALLOC_CTX *mem_ctx,        
+                                           struct smbcli_tree *tree, 
+                                           int fnum, const char *fname,
+                                           bool is_ipc)
 {
-       struct smbcli_state *cli;
        int i;
-       BOOL ret = True;
+       bool ret = true;
        int count;
        union smb_fileinfo *s1, *s2;    
-       TALLOC_CTX *mem_ctx;
-       int fnum;
-       const char *fname = "\\torture_qfileinfo.txt";
        NTTIME correct_time;
        uint64_t correct_size;
        uint32_t correct_attrib;
        const char *correct_name;
-       BOOL skip_streams = False;
-
-       if (!torture_open_connection(&cli)) {
-               return False;
-       }
-
-       mem_ctx = talloc_init("torture_qfileinfo");
+       bool skip_streams = false;
 
-       fnum = create_complex_file(cli, mem_ctx, fname);
-       if (fnum == -1) {
-               printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
-               ret = False;
-               goto done;
-       }
-       
-       
        /* scan all the fileinfo and pathinfo levels */
        for (i=0; levels[i].name; i++) {
                if (!levels[i].only_paths) {
                        levels[i].fnum_finfo.generic.level = levels[i].level;
-                       levels[i].fnum_finfo.generic.in.fnum = fnum;
-                       levels[i].fnum_status = smb_raw_fileinfo(cli->tree, mem_ctx, 
+                       levels[i].fnum_finfo.generic.in.file.fnum = fnum;
+                       levels[i].fnum_status = smb_raw_fileinfo(tree, mem_ctx, 
                                                                 &levels[i].fnum_finfo);
                }
 
                if (!levels[i].only_handles) {
                        levels[i].fname_finfo.generic.level = levels[i].level;
-                       levels[i].fname_finfo.generic.in.fname = talloc_strdup(mem_ctx, fname);
-                       levels[i].fname_status = smb_raw_pathinfo(cli->tree, mem_ctx, 
+                       levels[i].fname_finfo.generic.in.file.path = talloc_strdup(mem_ctx, fname);
+                       levels[i].fname_status = smb_raw_pathinfo(tree, mem_ctx, 
                                                                  &levels[i].fname_finfo);
                }
        }
 
        /* check for completely broken levels */
        for (count=i=0; levels[i].name; i++) {
-               uint32_t cap = cli->transport->negotiate.capabilities;
+               uint32_t cap = tree->session->transport->negotiate.capabilities;
                /* see if this server claims to support this level */
                if ((cap & levels[i].capability_mask) != levels[i].capability_mask) {
                        continue;
                }
 
-               if (!levels[i].only_paths && !NT_STATUS_IS_OK(levels[i].fnum_status)) {
-                       printf("ERROR: level %s failed - %s\n", 
-                              levels[i].name, nt_errstr(levels[i].fnum_status));
-                       count++;
-               }
-               if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) {
-                       printf("ERROR: level %s failed - %s\n", 
-                              levels[i].name, nt_errstr(levels[i].fname_status));
-                       count++;
+               if (is_ipc) {
+                       if (levels[i].expected_ipc_access_denied && NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, levels[i].fname_status)) {
+                       } else if (!levels[i].only_handles &&
+                                  NT_STATUS_EQUAL(levels[i].fname_status,
+                                  NT_STATUS_NOT_SUPPORTED)) {
+                               torture_warning(torture, "fname level %s %s",
+                                       levels[i].name,
+                                       nt_errstr(levels[i].fname_status));
+                               continue;
+                       } else if (!levels[i].only_handles && !NT_STATUS_EQUAL(NT_STATUS_INVALID_DEVICE_REQUEST, levels[i].fname_status)) {
+                               printf("ERROR: fname level %s failed, expected NT_STATUS_INVALID_DEVICE_REQUEST - %s\n", 
+                                      levels[i].name, nt_errstr(levels[i].fname_status));
+                               count++;
+                       }
+                       if (!levels[i].only_paths &&
+                          (NT_STATUS_EQUAL(levels[i].fnum_status,
+                           NT_STATUS_NOT_SUPPORTED) ||
+                           NT_STATUS_EQUAL(levels[i].fnum_status,
+                           NT_STATUS_NOT_IMPLEMENTED))) {
+                               torture_warning(torture, "fnum level %s %s",
+                                       levels[i].name,
+                                       nt_errstr(levels[i].fnum_status));
+                               continue;
+                       }
+                       if (!levels[i].only_paths && !NT_STATUS_EQUAL(levels[i].expected_ipc_fnum_status, levels[i].fnum_status)) {
+                               printf("ERROR: fnum level %s failed, expected %s - %s\n", 
+                                      levels[i].name, nt_errstr(levels[i].expected_ipc_fnum_status), 
+                                      nt_errstr(levels[i].fnum_status));
+                               count++;
+                       }
+               } else {
+                       if (!levels[i].only_paths &&
+                          (NT_STATUS_EQUAL(levels[i].fnum_status,
+                           NT_STATUS_NOT_SUPPORTED) ||
+                           NT_STATUS_EQUAL(levels[i].fnum_status,
+                           NT_STATUS_NOT_IMPLEMENTED))) {
+                               torture_warning(torture, "fnum level %s %s",
+                                       levels[i].name,
+                                       nt_errstr(levels[i].fnum_status));
+                               continue;
+                       }
+
+                       if (!levels[i].only_handles &&
+                          (NT_STATUS_EQUAL(levels[i].fname_status,
+                           NT_STATUS_NOT_SUPPORTED) ||
+                           NT_STATUS_EQUAL(levels[i].fname_status,
+                           NT_STATUS_NOT_IMPLEMENTED))) {
+                                torture_warning(torture, "fname level %s %s",
+                                       levels[i].name,
+                                       nt_errstr(levels[i].fname_status));
+                               continue;
+                       }
+
+                       if (!levels[i].only_paths && !NT_STATUS_IS_OK(levels[i].fnum_status)) {
+                               printf("ERROR: fnum level %s failed - %s\n", 
+                                      levels[i].name, nt_errstr(levels[i].fnum_status));
+                               count++;
+                       }
+                       if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) {
+                               printf("ERROR: fname level %s failed - %s\n", 
+                                      levels[i].name, nt_errstr(levels[i].fname_status));
+                               count++;
+                       }
                }
+               
        }
 
        if (count != 0) {
-               ret = False;
+               ret = false;
                printf("%d levels failed\n", count);
                if (count > 35) {
-                       printf("too many level failures - giving up\n");
-                       goto done;
+                       torture_fail(torture, "too many level failures - giving up");
                }
        }
 
        /* see if we can do streams */
        s1 = fnum_find("STREAM_INFO");
        if (!s1 || s1->stream_info.out.num_streams == 0) {
-               printf("STREAM_INFO broken (%d) - skipping streams checks\n",
-                      s1 ? s1->stream_info.out.num_streams : -1);
-               skip_streams = True;
+               if (!is_ipc) {
+                       printf("STREAM_INFO broken (%d) - skipping streams checks\n",
+                              s1 ? s1->stream_info.out.num_streams : -1);
+               }
+               skip_streams = true;
        }       
 
 
@@ -246,9 +362,9 @@ BOOL torture_raw_qfileinfo(void)
        do { \
                s1 = fnum_find(sname1);  s2 = fnum_find(sname2); \
                if (s1 && s2) { INFO_CHECK } \
-               s1 = fname_find(sname1); s2 = fname_find(sname2); \
+               s1 = fname_find(is_ipc, sname1); s2 = fname_find(is_ipc, sname2); \
                if (s1 && s2) { INFO_CHECK } \
-               s1 = fnum_find(sname1);  s2 = fname_find(sname2); \
+               s1 = fnum_find(sname1);  s2 = fname_find(is_ipc, sname2); \
                if (s1 && s2) { INFO_CHECK } \
        } while (0)
 
@@ -324,14 +440,14 @@ BOOL torture_raw_qfileinfo(void)
                printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
                       nt_time_string(mem_ctx, s1->stype.out.tfield), \
                       nt_time_string(mem_ctx, correct_time)); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && memcmp(&s1->stype.out.tfield, &correct_time, sizeof(correct_time)) != 0) { \
                printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
                       nt_time_string(mem_ctx, s1->stype.out.tfield), \
                       nt_time_string(mem_ctx, correct_time)); \
-               ret = False; \
+               ret = false; \
        }} while (0)
 
 #define TIME_CHECK_DOS(sname, stype, tfield) do { \
@@ -340,36 +456,38 @@ BOOL torture_raw_qfileinfo(void)
                printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
                       timestring(mem_ctx, s1->stype.out.tfield), \
                       nt_time_string(mem_ctx, correct_time)); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && dos_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
                printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
                       timestring(mem_ctx, s1->stype.out.tfield), \
                       nt_time_string(mem_ctx, correct_time)); \
-               ret = False; \
+               ret = false; \
        }} while (0)
 
+#if 0 /* unused */
 #define TIME_CHECK_UNX(sname, stype, tfield) do { \
        s1 = fnum_find(sname); \
        if (s1 && unx_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
                printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
                       timestring(mem_ctx, s1->stype.out.tfield), \
                       nt_time_string(mem_ctx, correct_time)); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && unx_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
                printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
                       timestring(mem_ctx, s1->stype.out.tfield), \
                       nt_time_string(mem_ctx, correct_time)); \
-               ret = False; \
+               ret = false; \
        }} while (0)
+#endif
 
        /* now check that all the times that are supposed to be equal are correct */
        s1 = fnum_find("BASIC_INFO");
        correct_time = s1->basic_info.out.create_time;
-       printf("create_time: %s\n", nt_time_string(mem_ctx, correct_time));
+       torture_comment(torture, "create_time: %s\n", nt_time_string(mem_ctx, correct_time));
 
        TIME_CHECK_NT ("BASIC_INFO",               basic_info, create_time);
        TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, create_time);
@@ -381,7 +499,7 @@ BOOL torture_raw_qfileinfo(void)
 
        s1 = fnum_find("BASIC_INFO");
        correct_time = s1->basic_info.out.access_time;
-       printf("access_time: %s\n", nt_time_string(mem_ctx, correct_time));
+       torture_comment(torture, "access_time: %s\n", nt_time_string(mem_ctx, correct_time));
 
        TIME_CHECK_NT ("BASIC_INFO",               basic_info, access_time);
        TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, access_time);
@@ -393,7 +511,7 @@ BOOL torture_raw_qfileinfo(void)
 
        s1 = fnum_find("BASIC_INFO");
        correct_time = s1->basic_info.out.write_time;
-       printf("write_time : %s\n", nt_time_string(mem_ctx, correct_time));
+       torture_comment(torture, "write_time : %s\n", nt_time_string(mem_ctx, correct_time));
 
        TIME_CHECK_NT ("BASIC_INFO",               basic_info, write_time);
        TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, write_time);
@@ -406,7 +524,7 @@ BOOL torture_raw_qfileinfo(void)
 
        s1 = fnum_find("BASIC_INFO");
        correct_time = s1->basic_info.out.change_time;
-       printf("change_time: %s\n", nt_time_string(mem_ctx, correct_time));
+       torture_comment(torture, "change_time: %s\n", nt_time_string(mem_ctx, correct_time));
 
        TIME_CHECK_NT ("BASIC_INFO",               basic_info, change_time);
        TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, change_time);
@@ -418,21 +536,21 @@ BOOL torture_raw_qfileinfo(void)
        s1 = fnum_find(sname); \
        if (s1 && s1->stype.out.tfield != correct_size) { \
                printf("(%d) handle %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield,  \
-                      (uint_t)s1->stype.out.tfield, \
-                      (uint_t)correct_size); \
-               ret = False; \
+                      (unsigned int)s1->stype.out.tfield, \
+                      (unsigned int)correct_size); \
+               ret = false; \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && s1->stype.out.tfield != correct_size) { \
                printf("(%d) path %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield,  \
-                      (uint_t)s1->stype.out.tfield, \
-                      (uint_t)correct_size); \
-               ret = False; \
+                      (unsigned int)s1->stype.out.tfield, \
+                      (unsigned int)correct_size); \
+               ret = false; \
        }} while (0)
 
        s1 = fnum_find("STANDARD_INFO");
        correct_size = s1->standard_info.out.size;
-       printf("size: %u\n", (uint_t)correct_size);
+       torture_comment(torture, "size: %u\n", (unsigned int)correct_size);
        
        SIZE_CHECK("GETATTR",                  getattr,                  size);
        SIZE_CHECK("GETATTRE",                 getattre,                 size);
@@ -453,7 +571,7 @@ BOOL torture_raw_qfileinfo(void)
 
        s1 = fnum_find("STANDARD_INFO");
        correct_size = s1->standard_info.out.alloc_size;
-       printf("alloc_size: %u\n", (uint_t)correct_size);
+       torture_comment(torture, "alloc_size: %u\n", (unsigned int)correct_size);
        
        SIZE_CHECK("GETATTRE",                 getattre,                 alloc_size);
        SIZE_CHECK("STANDARD",                 standard,                 alloc_size);
@@ -472,50 +590,52 @@ BOOL torture_raw_qfileinfo(void)
        s1 = fnum_find(sname); \
        if (s1 && s1->stype.out.tfield != correct_attrib) { \
                printf("(%d) handle %s/%s incorrect - 0x%x should be 0x%x\n", __LINE__, #stype, #tfield,  \
-                      (uint_t)s1->stype.out.tfield, \
-                      (uint_t)correct_attrib); \
-               ret = False; \
+                      (unsigned int)s1->stype.out.tfield, \
+                      (unsigned int)correct_attrib); \
+               ret = false; \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && s1->stype.out.tfield != correct_attrib) { \
                printf("(%d) path %s/%s incorrect - 0x%x should be 0x%x\n", __LINE__, #stype, #tfield,  \
-                      (uint_t)s1->stype.out.tfield, \
-                      (uint_t)correct_attrib); \
-               ret = False; \
+                      (unsigned int)s1->stype.out.tfield, \
+                      (unsigned int)correct_attrib); \
+               ret = false; \
        }} while (0)
 
        s1 = fnum_find("BASIC_INFO");
        correct_attrib = s1->basic_info.out.attrib;
-       printf("attrib: 0x%x\n", (uint_t)correct_attrib);
+       torture_comment(torture, "attrib: 0x%x\n", (unsigned int)correct_attrib);
        
        ATTRIB_CHECK("GETATTR",                   getattr,                   attrib);
-       ATTRIB_CHECK("GETATTRE",                  getattre,                  attrib);
-       ATTRIB_CHECK("STANDARD",                  standard,                  attrib);
+       if (!is_ipc) {
+               ATTRIB_CHECK("GETATTRE",                  getattre,                  attrib);
+               ATTRIB_CHECK("STANDARD",                  standard,                  attrib);
+               ATTRIB_CHECK("EA_SIZE",                   ea_size,                   attrib);
+       }
        ATTRIB_CHECK("BASIC_INFO",                basic_info,                attrib);
        ATTRIB_CHECK("BASIC_INFORMATION",         basic_info,                attrib);
-       ATTRIB_CHECK("EA_SIZE",                   ea_size,                   attrib);
        ATTRIB_CHECK("ALL_INFO",                  all_info,                  attrib);
        ATTRIB_CHECK("ALL_INFORMATION",           all_info,                  attrib);
        ATTRIB_CHECK("NETWORK_OPEN_INFORMATION",  network_open_information,  attrib);
        ATTRIB_CHECK("ATTRIBUTE_TAG_INFORMATION", attribute_tag_information, attrib);
 
        correct_name = fname;
-       printf("name: %s\n", correct_name);
+       torture_comment(torture, "name: %s\n", correct_name);
 
 #define NAME_CHECK(sname, stype, tfield, flags) do { \
        s1 = fnum_find(sname); \
        if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \
-                       wire_bad_flags(&s1->stype.out.tfield, flags, cli))) { \
+                       wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \
                printf("(%d) handle %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield,  \
                       s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \
-                       wire_bad_flags(&s1->stype.out.tfield, flags, cli))) { \
+                       wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \
                printf("(%d) path %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield,  \
                       s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \
-               ret = False; \
+               ret = false; \
        }} while (0)
 
        NAME_CHECK("NAME_INFO",        name_info, fname, STR_UNICODE);
@@ -524,58 +644,64 @@ BOOL torture_raw_qfileinfo(void)
        /* the ALL_INFO file name is the full path on the filesystem */
        s1 = fnum_find("ALL_INFO");
        if (s1 && !s1->all_info.out.fname.s) {
-               printf("ALL_INFO didn't give a filename\n");
-               ret = False;
+               torture_fail(torture, "ALL_INFO didn't give a filename");
        }
        if (s1 && s1->all_info.out.fname.s) {
                char *p = strrchr(s1->all_info.out.fname.s, '\\');
                if (!p) {
                        printf("Not a full path in all_info/fname? - '%s'\n", 
                               s1->all_info.out.fname.s);
-                       ret = False;
+                       ret = false;
                } else {
                        if (strcmp_safe(correct_name, p) != 0) {
                                printf("incorrect basename in all_info/fname - '%s'\n",
                                       s1->all_info.out.fname.s);
-                               ret = False;
+                               ret = false;
                        }
                }
-               if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, cli)) {
+               if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, tree->session->transport)) {
                        printf("Should not null terminate all_info/fname\n");
-                       ret = False;
+                       ret = false;
                }
        }
 
        s1 = fnum_find("ALT_NAME_INFO");
-       correct_name = s1->alt_name_info.out.fname.s;
-       printf("alt_name: %s\n", correct_name);
-
-       NAME_CHECK("ALT_NAME_INFO",        alt_name_info, fname, STR_UNICODE);
-       NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE);
-
-       /* and make sure we can open by alternate name */
-       smbcli_close(cli->tree, fnum);
-       fnum = smbcli_nt_create_full(cli->tree, correct_name, 0, 
-                                    SEC_RIGHTS_FULL_CONTROL,
-                                    FILE_ATTRIBUTE_NORMAL,
-                                    NTCREATEX_SHARE_ACCESS_DELETE|
-                                    NTCREATEX_SHARE_ACCESS_READ|
-                                    NTCREATEX_SHARE_ACCESS_WRITE, 
-                                    NTCREATEX_DISP_OVERWRITE_IF, 
-                                    0, 0);
-       if (fnum == -1) {
-               printf("Unable to open by alt_name - %s\n", smbcli_errstr(cli->tree));
-               ret = False;
+       if (s1) {
+               correct_name = s1->alt_name_info.out.fname.s;
        }
 
-       if (!skip_streams) {
-               correct_name = "::$DATA";
-               printf("stream_name: %s\n", correct_name);
-
-               NAME_CHECK("STREAM_INFO",        stream_info, streams[0].stream_name, STR_UNICODE);
-               NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE);
+       if (!correct_name) {
+               torture_comment(torture, "no alternate name information\n");
+       } else {
+               torture_comment(torture, "alt_name: %s\n", correct_name);
+               
+               NAME_CHECK("ALT_NAME_INFO",        alt_name_info, fname, STR_UNICODE);
+               NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE);
+               
+               /* and make sure we can open by alternate name */
+               smbcli_close(tree, fnum);
+               fnum = smbcli_nt_create_full(tree, correct_name, 0, 
+                                            SEC_RIGHTS_FILE_ALL,
+                                            FILE_ATTRIBUTE_NORMAL,
+                                            NTCREATEX_SHARE_ACCESS_DELETE|
+                                            NTCREATEX_SHARE_ACCESS_READ|
+                                            NTCREATEX_SHARE_ACCESS_WRITE, 
+                                            NTCREATEX_DISP_OVERWRITE_IF, 
+                                            0, 0);
+               if (fnum == -1) {
+                       printf("Unable to open by alt_name - %s\n", smbcli_errstr(tree));
+                       ret = false;
+               }
+               
+               if (!skip_streams) {
+                       correct_name = "::$DATA";
+                       torture_comment(torture, "stream_name: %s\n", correct_name);
+                       
+                       NAME_CHECK("STREAM_INFO",        stream_info, streams[0].stream_name, STR_UNICODE);
+                       NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE);
+               }
        }
-
+               
        /* make sure the EAs look right */
        s1 = fnum_find("ALL_EAS");
        s2 = fnum_find("ALL_INFO");
@@ -584,8 +710,8 @@ BOOL torture_raw_qfileinfo(void)
                        printf("  flags=%d %s=%*.*s\n", 
                               s1->all_eas.out.eas[i].flags,
                               s1->all_eas.out.eas[i].name.s,
-                              s1->all_eas.out.eas[i].value.length,
-                              s1->all_eas.out.eas[i].value.length,
+                              (int)s1->all_eas.out.eas[i].value.length,
+                              (int)s1->all_eas.out.eas[i].value.length,
                               s1->all_eas.out.eas[i].value.data);
                }
        }
@@ -599,12 +725,12 @@ BOOL torture_raw_qfileinfo(void)
                        if (s2->all_info.out.ea_size != 
                            ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas)) {
                                printf("ERROR: ea_list_size=%d != fnum all_info.out.ea_size=%d\n",
-                                      ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas),
-                                      s2->all_info.out.ea_size);
+                                      (int)ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas),
+                                      (int)s2->all_info.out.ea_size);
                        }
                }
        }
-       s2 = fname_find("ALL_EAS");
+       s2 = fname_find(is_ipc, "ALL_EAS");
        if (s2) {
                VAL_EQUAL(all_eas, num_eas, all_eas, num_eas);
                for (i=0;i<s1->all_eas.out.num_eas;i++) {
@@ -620,28 +746,28 @@ BOOL torture_raw_qfileinfo(void)
                printf("(%d) handle %s/%s != %s/%s - 0x%x vs 0x%x\n", __LINE__, \
                        #stype1, #tfield1, #stype2, #tfield2,  \
                       s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fname_find(sname1); s2 = fname_find(sname2); \
+       s1 = fname_find(is_ipc, sname1); s2 = fname_find(is_ipc, sname2); \
        if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
                printf("(%d) path %s/%s != %s/%s - 0x%x vs 0x%x\n", __LINE__, \
                        #stype1, #tfield1, #stype2, #tfield2,  \
                       s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fnum_find(sname1); s2 = fname_find(sname2); \
+       s1 = fnum_find(sname1); s2 = fname_find(is_ipc, sname2); \
        if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
                printf("(%d) handle %s/%s != path %s/%s - 0x%x vs 0x%x\n", __LINE__, \
                        #stype1, #tfield1, #stype2, #tfield2,  \
                       s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
-               ret = False; \
+               ret = false; \
        } \
-       s1 = fname_find(sname1); s2 = fnum_find(sname2); \
+       s1 = fname_find(is_ipc, sname1); s2 = fnum_find(sname2); \
        if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
                printf("(%d) path %s/%s != handle %s/%s - 0x%x vs 0x%x\n", __LINE__, \
                        #stype1, #tfield1, #stype2, #tfield2,  \
                       s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
-               ret = False; \
+               ret = false; \
        }} while (0)
 
        VAL_CHECK("STANDARD_INFO", standard_info, delete_pending, 
@@ -650,14 +776,33 @@ BOOL torture_raw_qfileinfo(void)
                  "ALL_INFO",      all_info,      directory);
        VAL_CHECK("STANDARD_INFO", standard_info, nlink, 
                  "ALL_INFO",      all_info,      nlink);
+       s1 = fnum_find("BASIC_INFO");
+       if (s1 && is_ipc) {
+               if (s1->basic_info.out.attrib != FILE_ATTRIBUTE_NORMAL) {
+                       printf("(%d) attrib basic_info/nlink incorrect - %d should be %d\n", __LINE__, s1->basic_info.out.attrib, (int)FILE_ATTRIBUTE_NORMAL);
+                       ret = false;
+               }
+       }
+       s1 = fnum_find("STANDARD_INFO");
+       if (s1 && is_ipc) {
+               if (s1->standard_info.out.nlink != 1) {
+                       printf("(%d) nlinks standard_info/nlink incorrect - %d should be 1\n", __LINE__, s1->standard_info.out.nlink);
+                       ret = false;
+               }
+               if (s1->standard_info.out.delete_pending != 1) {
+                       printf("(%d) nlinks standard_info/delete_pending incorrect - %d should be 1\n", __LINE__, s1->standard_info.out.delete_pending);
+                       ret = false;
+               }
+       }
        VAL_CHECK("EA_INFO",       ea_info,       ea_size, 
                  "ALL_INFO",      all_info,      ea_size);
-       VAL_CHECK("EA_SIZE",       ea_size,       ea_size, 
-                 "ALL_INFO",      all_info,      ea_size);
-
+       if (!is_ipc) {
+               VAL_CHECK("EA_SIZE",       ea_size,       ea_size, 
+                         "ALL_INFO",      all_info,      ea_size);
+       }
 
 #define NAME_PATH_CHECK(sname, stype, field) do { \
-       s1 = fname_find(sname); s2 = fnum_find(sname); \
+       s1 = fname_find(is_ipc, sname); s2 = fnum_find(sname); \
         if (s1 && s2) { \
                VAL_EQUAL(stype, field, stype, field); \
        } \
@@ -666,7 +811,7 @@ BOOL torture_raw_qfileinfo(void)
 
        s1 = fnum_find("INTERNAL_INFORMATION");
        if (s1) {
-               printf("file_id=%.0f\n", (double)s1->internal_information.out.file_id);
+               torture_comment(torture, "file_id=%.0f\n", (double)s1->internal_information.out.file_id);
        }
 
        NAME_PATH_CHECK("INTERNAL_INFORMATION", internal_information, file_id);
@@ -686,31 +831,76 @@ BOOL torture_raw_qfileinfo(void)
        NAME_PATH_CHECK("ACCESS_INFORMATION", access_information, access_flags);
 #endif
 
+#if 0 /* unused */
 #define UNKNOWN_CHECK(sname, stype, tfield) do { \
        s1 = fnum_find(sname); \
        if (s1 && s1->stype.out.tfield != 0) { \
                printf("(%d) handle %s/%s unknown != 0 (0x%x)\n", __LINE__, \
                        #stype, #tfield, \
-                      (uint_t)s1->stype.out.tfield); \
+                      (unsigned int)s1->stype.out.tfield); \
        } \
-       s1 = fname_find(sname); \
+       s1 = fname_find(is_ipc, sname); \
        if (s1 && s1->stype.out.tfield != 0) { \
                printf("(%d) path %s/%s unknown != 0 (0x%x)\n", __LINE__, \
                        #stype, #tfield, \
-                      (uint_t)s1->stype.out.tfield); \
+                      (unsigned int)s1->stype.out.tfield); \
        }} while (0)
-
+#endif
        /* now get a bit fancier .... */
        
        /* when we set the delete disposition then the link count should drop
           to 0 and delete_pending should be 1 */
        
+       return ret;
+}
 
-done:
+/* basic testing of all RAW_FILEINFO_* calls 
+   for each call we test that it succeeds, and where possible test 
+   for consistency between the calls. 
+*/
+bool torture_raw_qfileinfo(struct torture_context *torture, 
+                                                  struct smbcli_state *cli)
+{
+       int fnum;
+       bool ret;
+       const char *fname = "\\torture_qfileinfo.txt";
+
+       fnum = create_complex_file(cli, torture, fname);
+       if (fnum == -1) {
+               printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
+               return false;
+       }
+
+       ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree, fnum, fname, false /* is_ipc */);
+       
        smbcli_close(cli->tree, fnum);
        smbcli_unlink(cli->tree, fname);
 
-       torture_close_connection(cli);
-       talloc_destroy(mem_ctx);
+       return ret;
+}
+
+bool torture_raw_qfileinfo_pipe(struct torture_context *torture, 
+                               struct smbcli_state *cli)
+{
+       bool ret = true;
+       int fnum;
+       const char *fname = "\\lsass";
+       struct dcerpc_pipe *p;
+       struct smbcli_tree *ipc_tree;
+       NTSTATUS status;
+
+       if (!(p = dcerpc_pipe_init(torture, cli->tree->session->transport->socket->event.ctx))) {
+               return false;
+       }
+
+       status = dcerpc_pipe_open_smb(p, cli->tree, fname);
+       torture_assert_ntstatus_ok(torture, status, "dcerpc_pipe_open_smb failed");
+
+       ipc_tree = dcerpc_smb_tree(p->conn);
+       fnum = dcerpc_smb_fnum(p->conn);
+
+       ret = torture_raw_qfileinfo_internals(torture, torture, ipc_tree, fnum, fname, true /* is_ipc */);
+       
+       talloc_free(p);
        return ret;
 }